Skip to content

Commit

Permalink
Use common uuid generator everywhere (#13255)
Browse files Browse the repository at this point in the history
  • Loading branch information
msujew authored Feb 20, 2024
1 parent f6c8fe5 commit 50bb4fc
Show file tree
Hide file tree
Showing 33 changed files with 64 additions and 142 deletions.
2 changes: 0 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
"@types/node": "18",
"@types/sinon": "^10.0.6",
"@types/temp": "^0.9.1",
"@types/uuid": "^7.0.3",
"@typescript-eslint/eslint-plugin": "^4.8.1",
"@typescript-eslint/eslint-plugin-tslint": "^4.8.1",
"@typescript-eslint/parser": "^4.8.1",
Expand Down Expand Up @@ -56,7 +55,6 @@
"typedoc": "^0.22.11",
"typedoc-plugin-external-module-map": "1.3.2",
"typescript": "~4.5.5",
"uuid": "^8.0.0",
"yargs": "^15.3.1"
},
"scripts": {
Expand Down
3 changes: 2 additions & 1 deletion packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
"@types/react-dom": "^18.0.6",
"@types/route-parser": "^0.1.1",
"@types/safer-buffer": "^2.1.0",
"@types/uuid": "^9.0.8",
"@types/ws": "^8.5.5",
"@types/yargs": "^15",
"@vscode/codicons": "*",
Expand Down Expand Up @@ -68,7 +69,7 @@
"safer-buffer": "^2.1.2",
"socket.io": "^4.5.3",
"socket.io-client": "^4.5.3",
"uuid": "^8.3.2",
"uuid": "^9.0.1",
"vscode-languageserver-protocol": "^3.17.2",
"vscode-uri": "^2.1.1",
"ws": "^8.14.1",
Expand Down
4 changes: 2 additions & 2 deletions packages/core/src/browser/tooltip-service.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import * as React from 'react';
import ReactTooltip from 'react-tooltip';
import { ReactRenderer, RendererHost } from './widgets/react-renderer';
import { CorePreferences } from './core-preferences';
import { v4 } from 'uuid';
import { generateUuid } from '../common/uuid';

export const TooltipService = Symbol('TooltipService');

Expand Down Expand Up @@ -59,7 +59,7 @@ export class TooltipServiceImpl extends ReactRenderer implements TooltipService
@inject(RendererHost) @optional() host?: RendererHost
) {
super(host);
this.tooltipId = v4();
this.tooltipId = generateUuid();
}

@postConstruct()
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/common/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,5 +46,6 @@ export * from './strings';
export * from './telemetry';
export * from './types';
export { default as URI } from './uri';
export * from './uuid';
export * from './view-column';
export * from './version';
75 changes: 4 additions & 71 deletions packages/core/src/common/uuid.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,84 +21,17 @@

// based on https://github.com/microsoft/vscode/blob/1.72.2/src/vs/base/common/uuid.ts

import { v5 } from 'uuid';
import { v4, v5 } from 'uuid';

const _UUIDPattern = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;

export function isUUID(value: string): boolean {
return _UUIDPattern.test(value);
}

declare const crypto: undefined | {
// https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues#browser_compatibility
getRandomValues?(data: Uint8Array): Uint8Array;
// https://developer.mozilla.org/en-US/docs/Web/API/Crypto/randomUUID#browser_compatibility
randomUUID?(): string;
};

export const generateUuid = (function (): () => string {

// use `randomUUID` if possible
if (typeof crypto === 'object' && typeof crypto.randomUUID === 'function') {
return crypto.randomUUID.bind(crypto);
}

// use `randomValues` if possible
let getRandomValues: (bucket: Uint8Array) => Uint8Array;
if (typeof crypto === 'object' && typeof crypto.getRandomValues === 'function') {
getRandomValues = crypto.getRandomValues.bind(crypto);

} else {
getRandomValues = function (bucket: Uint8Array): Uint8Array {
for (let i = 0; i < bucket.length; i++) {
bucket[i] = Math.floor(Math.random() * 256);
}
return bucket;
};
}

// prep-work
const _data = new Uint8Array(16);
const _hex: string[] = [];
for (let i = 0; i < 256; i++) {
_hex.push(i.toString(16).padStart(2, '0'));
}

// eslint-disable-next-line @typescript-eslint/no-shadow
return function generateUuid(): string {
// get data
getRandomValues(_data);

// set version bits
_data[6] = (_data[6] & 0x0f) | 0x40;
_data[8] = (_data[8] & 0x3f) | 0x80;

// print as string
let i = 0;
let result = '';
result += _hex[_data[i++]];
result += _hex[_data[i++]];
result += _hex[_data[i++]];
result += _hex[_data[i++]];
result += '-';
result += _hex[_data[i++]];
result += _hex[_data[i++]];
result += '-';
result += _hex[_data[i++]];
result += _hex[_data[i++]];
result += '-';
result += _hex[_data[i++]];
result += _hex[_data[i++]];
result += '-';
result += _hex[_data[i++]];
result += _hex[_data[i++]];
result += _hex[_data[i++]];
result += _hex[_data[i++]];
result += _hex[_data[i++]];
result += _hex[_data[i++]];
return result;
};
})();
export function generateUuid(): string {
return v4();
}

const NAMESPACE = '4c90ee4f-d952-44b1-83ca-f04121ab8e05';
/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
// *****************************************************************************

import { ContainerModule } from 'inversify';
import { v4 } from 'uuid';
import { generateUuid } from '../common/uuid';
import { bindContributionProvider } from '../common/contribution-provider';
import { RpcConnectionHandler } from '../common/messaging/proxy-factory';
import { ElectronSecurityToken } from '../electron-common/electron-token';
Expand All @@ -29,7 +29,7 @@ import { ElectronSecurityTokenService } from './electron-security-token-service'
import { ElectronMessagingService } from './messaging/electron-messaging-service';
import { ElectronConnectionHandler } from './messaging/electron-connection-handler';

const electronSecurityToken: ElectronSecurityToken = { value: v4() };
const electronSecurityToken: ElectronSecurityToken = { value: generateUuid() };
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(global as any)[ElectronSecurityToken] = electronSecurityToken;

Expand Down
2 changes: 0 additions & 2 deletions packages/filesystem/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
"@types/multer": "^1.4.7",
"@types/rimraf": "^2.0.2",
"@types/tar-fs": "^1.16.1",
"@types/uuid": "^7.0.3",
"async-mutex": "^0.3.1",
"body-parser": "^1.18.3",
"browserfs": "^1.4.3",
Expand All @@ -19,7 +18,6 @@
"stat-mode": "^1.0.0",
"tar-fs": "^1.16.2",
"trash": "^7.2.0",
"uuid": "^8.0.0",
"vscode-languageserver-textdocument": "^1.0.1"
},
"publishConfig": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import { equal, fail } from 'assert';
import { promises as fs } from 'fs';
import { join } from 'path';
import * as temp from 'temp';
import { v4 } from 'uuid';
import { generateUuid } from '@theia/core/lib/common/uuid';
import { FilePermission, FileSystemProviderCapabilities, FileSystemProviderError, FileSystemProviderErrorCode } from '../common/files';
import { DiskFileSystemProvider } from './disk-file-system-provider';
import { bindFileSystemWatcherServer } from './filesystem-backend-module';
Expand Down Expand Up @@ -53,7 +53,7 @@ describe('disk-file-system-provider', () => {
describe('stat', () => {
it("should omit the 'permissions' property of the stat if the file can be both read and write", async () => {
const tempDirPath = tracked.mkdirSync();
const tempFilePath = join(tempDirPath, `${v4()}.txt`);
const tempFilePath = join(tempDirPath, `${generateUuid()}.txt`);
await fs.writeFile(tempFilePath, 'some content', { encoding: 'utf8' });

let content = await fs.readFile(tempFilePath, { encoding: 'utf8' });
Expand All @@ -70,7 +70,7 @@ describe('disk-file-system-provider', () => {

it("should set the 'permissions' property to `Readonly` if the file can be read but not write", async () => {
const tempDirPath = tracked.mkdirSync();
const tempFilePath = join(tempDirPath, `${v4()}.txt`);
const tempFilePath = join(tempDirPath, `${generateUuid()}.txt`);
await fs.writeFile(tempFilePath, 'readonly content', {
encoding: 'utf8',
});
Expand Down
4 changes: 2 additions & 2 deletions packages/filesystem/src/node/disk-file-system-provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@

import { injectable, inject, postConstruct } from '@theia/core/shared/inversify';
import { basename, dirname, normalize, join } from 'path';
import { v4 } from 'uuid';
import { generateUuid } from '@theia/core/lib/common/uuid';
import * as os from 'os';
import * as fs from 'fs';
import {
Expand Down Expand Up @@ -530,7 +530,7 @@ export class DiskFileSystemProvider implements Disposable,

protected async rimrafMove(path: string): Promise<void> {
try {
const pathInTemp = join(os.tmpdir(), v4());
const pathInTemp = join(os.tmpdir(), generateUuid());
try {
await promisify(rename)(path, pathInTemp);
} catch (error) {
Expand Down
10 changes: 5 additions & 5 deletions packages/filesystem/src/node/download/file-download-handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
import * as os from 'os';
import * as fs from '@theia/core/shared/fs-extra';
import * as path from 'path';
import { v4 } from 'uuid';
import { generateUuid } from '@theia/core/lib/common/uuid';
import { Request, Response } from '@theia/core/shared/express';
import { inject, injectable } from '@theia/core/shared/inversify';
import { OK, BAD_REQUEST, METHOD_NOT_ALLOWED, NOT_FOUND, INTERNAL_SERVER_ERROR, REQUESTED_RANGE_NOT_SATISFIABLE, PARTIAL_CONTENT } from 'http-status-codes';
Expand Down Expand Up @@ -135,12 +135,12 @@ export abstract class FileDownloadHandler {
end: (isNaN(end) || end > statSize - 1) ? (statSize - 1) : end
};
}
protected async archive(inputPath: string, outputPath: string = path.join(os.tmpdir(), v4()), entries?: string[]): Promise<string> {
protected async archive(inputPath: string, outputPath: string = path.join(os.tmpdir(), generateUuid()), entries?: string[]): Promise<string> {
await this.directoryArchiver.archive(inputPath, outputPath, entries);
return outputPath;
}

protected async createTempDir(downloadId: string = v4()): Promise<string> {
protected async createTempDir(downloadId: string = generateUuid()): Promise<string> {
const outputPath = path.join(os.tmpdir(), downloadId);
await fs.mkdir(outputPath);
return outputPath;
Expand Down Expand Up @@ -221,7 +221,7 @@ export class SingleFileDownloadHandler extends FileDownloadHandler {
return;
}
try {
const downloadId = v4();
const downloadId = generateUuid();
const options: PrepareDownloadOptions = { filePath, downloadId, remove: false };
if (!stat.isDirectory()) {
await this.prepareDownload(request, response, options);
Expand Down Expand Up @@ -271,7 +271,7 @@ export class MultiFileDownloadHandler extends FileDownloadHandler {
}
}
try {
const downloadId = v4();
const downloadId = generateUuid();
const outputRootPath = await this.createTempDir(downloadId);
const distinctUris = Array.from(new Set(body.uris.map(uri => new URI(uri))));
const tarPaths = [];
Expand Down
1 change: 0 additions & 1 deletion packages/mini-browser/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
"@types/mime-types": "^2.1.0",
"mime-types": "^2.1.18",
"pdfobject": "^2.0.201604172",
"uuid": "^8.0.0",
"vhost": "^3.0.2"
},
"publishConfig": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import { Endpoint, FrontendApplicationContribution } from '@theia/core/lib/brows
import { EnvVariablesServer } from '@theia/core/lib/common/env-variables';
import { environment } from '@theia/core/shared/@theia/application-package/lib/environment';
import { inject, injectable, postConstruct } from '@theia/core/shared/inversify';
import { v4 } from 'uuid';
import { generateUuid } from '@theia/core/lib/common/uuid';
import { MiniBrowserEndpoint } from '../../common/mini-browser-endpoint';

/**
Expand Down Expand Up @@ -71,7 +71,7 @@ export class MiniBrowserEnvironment implements FrontendApplicationContribution {
* Throws if `hostPatternPromise` is not yet resolved.
*/
getRandomEndpoint(): Endpoint {
return this.getEndpoint(v4());
return this.getEndpoint(generateUuid());
}

protected async getHostPattern(): Promise<string> {
Expand Down
3 changes: 1 addition & 2 deletions packages/notebook/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@
"@theia/editor": "1.46.0",
"@theia/filesystem": "1.46.0",
"@theia/monaco": "1.46.0",
"react-perfect-scrollbar": "^1.5.8",
"uuid": "^8.3.2"
"react-perfect-scrollbar": "^1.5.8"
},
"publishConfig": {
"access": "public"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import { Disposable, DisposableCollection, Emitter, URI } from '@theia/core';
import { Disposable, DisposableCollection, Emitter, URI, generateUuid } from '@theia/core';
import { inject, injectable } from '@theia/core/shared/inversify';
import { NotebookService } from './notebook-service';
import {
Expand All @@ -27,7 +27,6 @@ import {
} from '../../common';
import { CellPartialInternalMetadataEditByHandle, CellEditOperation } from '../notebook-types';
import { NotebookModel } from '../view-model/notebook-model';
import { v4 } from 'uuid';

export type CellExecuteUpdate = CellExecuteOutputEdit | CellExecuteOutputItemEdit | CellExecutionStateUpdate;

Expand Down Expand Up @@ -178,7 +177,7 @@ export class CellExecution implements Disposable {
editType: CellEditType.PartialInternalMetadata,
handle: this.cellHandle,
internalMetadata: {
executionId: v4(),
executionId: generateUuid(),
runStartTime: undefined,
runEndTime: undefined,
lastRunSuccess: undefined,
Expand Down
1 change: 0 additions & 1 deletion packages/plugin-ext/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@
"mime": "^2.4.4",
"ps-tree": "^1.2.0",
"semver": "^7.5.4",
"uuid": "^8.0.0",
"vhost": "^3.0.2",
"vscode-textmate": "^9.0.0"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ import { URI } from '@theia/core/shared/vscode-uri';
import { CancellationToken } from '@theia/core/lib/common';
import { RPCProtocol } from '../../../common/rpc-protocol';
import { interfaces } from '@theia/core/shared/inversify';
import { v4 as uuidv4 } from 'uuid';
import { generateUuid } from '@theia/core/lib/common/uuid';
import { CommentsContribution } from './comments-contribution';

/*---------------------------------------------------------------------------------------------
Expand Down Expand Up @@ -392,7 +392,7 @@ export class CommentsMainImp implements CommentsMain {
}

$registerCommentController(handle: number, id: string, label: string): void {
const providerId = uuidv4();
const providerId = generateUuid();
this.handlers.set(handle, providerId);

const provider = new CommentController(this.proxy, this.commentService, handle, providerId, id, label, {});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import URI from '@theia/core/lib/common/uri';
import { ApplicationShell, OpenHandler, Widget, WidgetManager, WidgetOpenerOptions } from '@theia/core/lib/browser';
import { CustomEditor, CustomEditorPriority, CustomEditorSelector } from '../../../common';
import { CustomEditorWidget } from './custom-editor-widget';
import { v4 } from 'uuid';
import { generateUuid } from '@theia/core/lib/common/uuid';
import { Emitter } from '@theia/core';
import { match } from '@theia/core/lib/common/glob';

Expand Down Expand Up @@ -77,7 +77,7 @@ export class CustomEditorOpener implements OpenHandler {
const uriString = uri.toString();
let widgetPromise = this.pendingWidgetPromises.get(uriString);
if (!widgetPromise) {
const id = v4();
const id = generateUuid();
widgetPromise = this.widgetManager.getOrCreateWidget<CustomEditorWidget>(CustomEditorWidget.FACTORY_ID, { id });
this.pendingWidgetPromises.set(uriString, widgetPromise);
widget = await widgetPromise;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
import * as React from '@theia/core/shared/react';
import { inject, injectable, interfaces, postConstruct } from '@theia/core/shared/inversify';
import { NotebookRendererMessagingService, CellOutputWebview, NotebookRendererRegistry, NotebookEditorWidgetService, NotebookCellOutputsSplice } from '@theia/notebook/lib/browser';
import { v4 } from 'uuid';
import { generateUuid } from '@theia/core/lib/common/uuid';
import { NotebookCellModel } from '@theia/notebook/lib/browser/view-model/notebook-cell-model';
import { WebviewWidget } from '../../webview/webview';
import { Message, WidgetManager } from '@theia/core/lib/browser';
Expand Down Expand Up @@ -65,7 +65,7 @@ export class CellOutputWebviewImpl implements CellOutputWebview, Disposable {
@inject(QuickPickService)
protected readonly quickPickService: QuickPickService;

readonly id = v4();
readonly id = generateUuid();

protected readonly elementRef = React.createRef<HTMLDivElement>();
protected outputPresentationListeners: DisposableCollection = new DisposableCollection();
Expand Down
Loading

0 comments on commit 50bb4fc

Please sign in to comment.