diff --git a/package-lock.json b/package-lock.json index ce158c1d6b..c9b1fe9bad 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10743,12 +10743,6 @@ "url": "https://opencollective.com/storybook" } }, - "node_modules/@storybook/addon-actions/node_modules/@types/uuid": { - "version": "9.0.7", - "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.7.tgz", - "integrity": "sha512-WUtIVRUZ9i5dYXefDEAI7sh9/O7jGvHg7Df/5O/gtH3Yabe5odI3UWopVR1qbPXQtvOxWu3mM4XxlYeZtMWF4g==", - "dev": true - }, "node_modules/@storybook/addon-actions/node_modules/uuid": { "version": "9.0.1", "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", @@ -16152,9 +16146,9 @@ "dev": true }, "node_modules/@types/uuid": { - "version": "8.3.4", - "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-8.3.4.tgz", - "integrity": "sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw==", + "version": "9.0.8", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.8.tgz", + "integrity": "sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA==", "dev": true }, "node_modules/@types/validator": { @@ -46114,7 +46108,7 @@ "tough-cookie": "^4.0.0", "tsscmp": "^1.0.6", "utf-8-validate": "^5.0.2", - "uuid": "^3.0.1", + "uuid": "^9.0.1", "valid-data-url": "^2.0.0", "valid-url": "^1.0.9", "w3c-keyname": "^2.2.8", @@ -46195,7 +46189,7 @@ "@types/react-linkify": "^1.0.0", "@types/recurly__recurly-js": "^4.22.0", "@types/sinon-chai": "^3.2.8", - "@types/uuid": "^8.3.4", + "@types/uuid": "^9.0.8", "@typescript-eslint/eslint-plugin": "^6.7.4", "@typescript-eslint/parser": "^6.7.4", "@uppy/core": "^3.8.0", @@ -47711,14 +47705,6 @@ "node": ">=12" } }, - "services/web/node_modules/teeny-request/node_modules/uuid": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz", - "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==", - "bin": { - "uuid": "dist/bin/uuid" - } - }, "services/web/node_modules/universalify": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", @@ -47727,6 +47713,18 @@ "node": ">= 4.0.0" } }, + "services/web/node_modules/uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "bin": { + "uuid": "dist/bin/uuid" + } + }, "services/web/node_modules/webpack-assets-manifest": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/webpack-assets-manifest/-/webpack-assets-manifest-5.1.0.tgz", @@ -55032,7 +55030,7 @@ "@types/react-linkify": "^1.0.0", "@types/recurly__recurly-js": "^4.22.0", "@types/sinon-chai": "^3.2.8", - "@types/uuid": "^8.3.4", + "@types/uuid": "^9.0.8", "@typescript-eslint/eslint-plugin": "^6.7.4", "@typescript-eslint/parser": "^6.7.4", "@uppy/core": "^3.8.0", @@ -55215,7 +55213,7 @@ "tsscmp": "^1.0.6", "typescript": "^5.0.4", "utf-8-validate": "^5.0.2", - "uuid": "^3.0.1", + "uuid": "^9.0.1", "valid-data-url": "^2.0.0", "valid-url": "^1.0.9", "w3c-keyname": "^2.2.8", @@ -56255,13 +56253,6 @@ "node-fetch": "^2.6.1", "stream-events": "^1.0.5", "uuid": "^9.0.0" - }, - "dependencies": { - "uuid": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz", - "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==" - } } }, "universalify": { @@ -56269,6 +56260,11 @@ "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" }, + "uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==" + }, "webpack-assets-manifest": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/webpack-assets-manifest/-/webpack-assets-manifest-5.1.0.tgz", @@ -57676,12 +57672,6 @@ "ts-dedent": "^2.0.0" } }, - "@types/uuid": { - "version": "9.0.7", - "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.7.tgz", - "integrity": "sha512-WUtIVRUZ9i5dYXefDEAI7sh9/O7jGvHg7Df/5O/gtH3Yabe5odI3UWopVR1qbPXQtvOxWu3mM4XxlYeZtMWF4g==", - "dev": true - }, "uuid": { "version": "9.0.1", "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", @@ -61811,9 +61801,9 @@ "dev": true }, "@types/uuid": { - "version": "8.3.4", - "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-8.3.4.tgz", - "integrity": "sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw==", + "version": "9.0.8", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.8.tgz", + "integrity": "sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA==", "dev": true }, "@types/validator": { diff --git a/services/web/frontend/js/features/chat/context/chat-context.tsx b/services/web/frontend/js/features/chat/context/chat-context.tsx index 89c464737e..65e6093c7c 100644 --- a/services/web/frontend/js/features/chat/context/chat-context.tsx +++ b/services/web/frontend/js/features/chat/context/chat-context.tsx @@ -68,6 +68,17 @@ type Action = error: any } +// Wrap uuid in an object method so that it can be stubbed +export const chatClientIdGenerator = { + generate: () => uuid(), +} + +let nextChatMessageId = 1 + +function generateChatMessageId() { + return '' + nextChatMessageId++ +} + function chatReducer(state: State, action: Action): State { switch (action.type) { case 'INITIAL_FETCH_MESSAGES': @@ -103,10 +114,10 @@ function chatReducer(state: State, action: Action): State { state.messages, { // Messages are sent optimistically, so don't have an id (used for - // React keys). The uuid is valid for this session, and ensures all + // React keys). The id is valid for this session, and ensures all // messages have an id. It will be overwritten by the actual ids on // refresh - id: uuid(), + id: generateChatMessageId(), user: action.user, content: action.content, timestamp: Date.now(), @@ -178,7 +189,7 @@ export const ChatContext = createContext< export const ChatProvider: FC = ({ children }) => { const clientId = useRef() if (clientId.current === undefined) { - clientId.current = uuid() + clientId.current = chatClientIdGenerator.generate() } const user = useUserContext() const { _id: projectId } = useProjectContext() diff --git a/services/web/frontend/js/features/pdf-preview/util/output-files.js b/services/web/frontend/js/features/pdf-preview/util/output-files.js index bcbb7d48a7..f74d040f79 100644 --- a/services/web/frontend/js/features/pdf-preview/util/output-files.js +++ b/services/web/frontend/js/features/pdf-preview/util/output-files.js @@ -1,7 +1,6 @@ import getMeta from '../../../utils/meta' import HumanReadableLogs from '../../../ide/human-readable-logs/HumanReadableLogs' import BibLogParser from '../../../ide/log-parser/bib-log-parser' -import { v4 as uuid } from 'uuid' import { enablePdfCaching } from './pdf-caching-flags' import { debugConsole } from '@/utils/debugging' import { dirname, findEntityByPath } from '@/features/file-tree/util/path' @@ -40,6 +39,12 @@ export function handleOutputFiles(outputFiles, projectId, data) { return outputFile } +let nextEntryId = 1 + +function generateEntryKey() { + return '' + nextEntryId++ +} + export const handleLogFiles = async (outputFiles, data, signal) => { const result = { log: null, @@ -60,7 +65,7 @@ export const handleLogFiles = async (outputFiles, data, signal) => { if (entry.file) { entry.file = normalizeFilePath(entry.file) } - entry.key = uuid() + entry.key = generateEntryKey() } result.logEntries[key].push(...newEntries[key]) } diff --git a/services/web/frontend/stories/fixtures/chat-messages.js b/services/web/frontend/stories/fixtures/chat-messages.js index f9fa2180b0..78b91fa8f0 100644 --- a/services/web/frontend/stories/fixtures/chat-messages.js +++ b/services/web/frontend/stories/fixtures/chat-messages.js @@ -1,5 +1,3 @@ -import { v4 as uuid } from 'uuid' - const ONE_MINUTE = 60 * 1000 const user = { @@ -14,6 +12,8 @@ const user2 = { email: 'another_fake@example.com', } +let nextMessageId = 1 + export function generateMessages(count) { const messages = [] let timestamp = new Date().getTime() // newest message goes first @@ -24,7 +24,7 @@ export function generateMessages(count) { timestamp -= (4.3 + Math.random()) * ONE_MINUTE messages.push({ - id: uuid(), + id: '' + nextMessageId++, content: `message #${i}`, user: author, timestamp, diff --git a/services/web/frontend/stories/project-list/project-list.stories.tsx b/services/web/frontend/stories/project-list/project-list.stories.tsx index eaae919eb4..858d419bd4 100644 --- a/services/web/frontend/stories/project-list/project-list.stories.tsx +++ b/services/web/frontend/stories/project-list/project-list.stories.tsx @@ -7,7 +7,7 @@ import { } from '../../../test/frontend/features/project-list/fixtures/projects-data' import { useMeta } from '../hooks/use-meta' import { tags } from '../../../test/frontend/features/project-list/fixtures/tags-data' -import uuid from 'uuid' +import { v4 as uuid } from 'uuid' const MOCK_DELAY = 500 @@ -22,7 +22,7 @@ export const Interactive = (args: any) => { fetchMock.post( 'express:/project/:projectId/clone', () => ({ - project_id: uuid.v4(), + project_id: uuid(), name: copyableProject.name, lastUpdated: new Date().toISOString(), owner: { diff --git a/services/web/package.json b/services/web/package.json index f196862658..b9293ee2e2 100644 --- a/services/web/package.json +++ b/services/web/package.json @@ -160,7 +160,7 @@ "tough-cookie": "^4.0.0", "tsscmp": "^1.0.6", "utf-8-validate": "^5.0.2", - "uuid": "^3.0.1", + "uuid": "^9.0.1", "valid-data-url": "^2.0.0", "valid-url": "^1.0.9", "w3c-keyname": "^2.2.8", @@ -241,7 +241,7 @@ "@types/react-linkify": "^1.0.0", "@types/recurly__recurly-js": "^4.22.0", "@types/sinon-chai": "^3.2.8", - "@types/uuid": "^8.3.4", + "@types/uuid": "^9.0.8", "@typescript-eslint/eslint-plugin": "^6.7.4", "@typescript-eslint/parser": "^6.7.4", "@uppy/core": "^3.8.0", diff --git a/services/web/test/frontend/features/chat/context/chat-context.test.jsx b/services/web/test/frontend/features/chat/context/chat-context.test.jsx index a02756e101..14beb70aa3 100644 --- a/services/web/test/frontend/features/chat/context/chat-context.test.jsx +++ b/services/web/test/frontend/features/chat/context/chat-context.test.jsx @@ -6,8 +6,10 @@ import { expect } from 'chai' import sinon from 'sinon' import fetchMock from 'fetch-mock' import EventEmitter from 'events' -import uuid from 'uuid' -import { useChatContext } from '../../../../../frontend/js/features/chat/context/chat-context' +import { + useChatContext, + chatClientIdGenerator, +} from '@/features/chat/context/chat-context' import { ChatProviders, cleanUpContext, @@ -31,7 +33,7 @@ describe('ChatContext', function () { window.metaAttributesCache = new Map() window.metaAttributesCache.set('ol-user', user) - this.stub = sinon.stub(uuid, 'v4').returns(uuidValue) + this.stub = sinon.stub(chatClientIdGenerator, 'generate').returns(uuidValue) }) afterEach(function () {