Skip to content

Commit

Permalink
refactor: a "UUID" method without crypto check/polyfill (#512)
Browse files Browse the repository at this point in the history
  • Loading branch information
dm-p committed Oct 22, 2024
1 parent 15e40a0 commit c77d3a3
Show file tree
Hide file tree
Showing 5 changed files with 13 additions and 70 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -90,4 +90,4 @@
"peerDependencies": {
"monaco-editor": "0.45.0"
}
}
}
2 changes: 1 addition & 1 deletion packages/core-dependencies/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,4 @@
"vega": "5.30.0",
"vega-lite": "5.20.1"
}
}
}
22 changes: 2 additions & 20 deletions packages/core-dependencies/src/utils/__tests__/crypto.test.ts
Original file line number Diff line number Diff line change
@@ -1,32 +1,14 @@
import { getFallbackUUid, getNewUuid, getRandomUuidSegment } from '../crypto';
import { getNewUuid } from '../crypto';

const UUID_REGEX =
/^[0-9a-fA-F]{8}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{12}$/i;

describe('getRandomUuidString', () => {
it('should return a valid UUID', () => {
const uuid = getRandomUuidSegment();
const uuidRegex = /^[0-9a-f]{16}$/i;
expect(uuid).toMatch(uuidRegex);
});
});

describe('getFallbackUUid', () => {
it('should return a valid UUID', () => {
const uuid = getFallbackUUid();
expect(uuid).toMatch(UUID_REGEX);
});
});

describe('getNewUuid', () => {
it('should return a valid UUID when crypto is available', () => {
const uuid = getNewUuid();
expect(uuid).toMatch(UUID_REGEX);
});
it('should return a valid UUID when the crypto API is not available', () => {
const crypto = global.crypto;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
delete (global as any).crypto;
it('should return a valid UUID ', () => {
const uuid = getNewUuid();
expect(uuid).toMatch(UUID_REGEX);
global.crypto = crypto;
Expand Down
42 changes: 3 additions & 39 deletions packages/core-dependencies/src/utils/crypto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,43 +2,7 @@
* Generate a new UUID.
*/
export function getNewUuid() {
if (
typeof crypto !== 'undefined' &&
typeof crypto.randomUUID === 'function'
) {
return crypto.randomUUID();
}
return getFallbackUUid();
}

/**
* For environments that don't have access to the crypto API, generate two simple UUIDs and combine them to create a
* valid "good enough" UUID.
*/
export function getFallbackUUid() {
const a = getRandomUuidSegment();
const b = getRandomUuidSegment();
return (
a.slice(0, 8) +
'-' +
a.slice(8, 12) +
'-4' +
a.slice(13) +
'-a' +
b.slice(1, 4) +
'-' +
b.slice(4)
);
}

/**
* For browsers that don't have the crypto API (or HTTP environments), we can use this polyfill to generate a "good
* enough" UUID segment that we can combine upstream.
*/
export function getRandomUuidSegment() {
return (
'00000000000000000' +
// eslint-disable-next-line @typescript-eslint/no-loss-of-precision
(Math.random() * 0xffffffffffffffff).toString(16)
).slice(-16);
return 'xxxxxxxx-xxxx-4xxx-Nxxx-xxxxxxxxxxxx'
.replace(/x/g, () => ((Math.random() * 16) | 0).toString(16))
.replace(/N/g, () => ((Math.random() * 4) | (0 + 8)).toString(16));
}
15 changes: 6 additions & 9 deletions packages/json-processing/src/__test__/template-usermeta.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { getJsoncStringAsObject } from '../processing';
import { expect, jest, test } from '@jest/globals';

Check warning on line 2 in packages/json-processing/src/__test__/template-usermeta.test.ts

View workflow job for this annotation

GitHub Actions / build

'test' is defined but never used
import {
PROVIDER_RESOURCES,
getExportTemplate,
Expand All @@ -24,8 +25,7 @@ import {
TrackedFields,
UsermetaDatasetField,
UsermetaTemplate,
getBase64ImagePngBlank,
getNewUuid
getBase64ImagePngBlank
} from '@deneb-viz/core-dependencies';

const MOCK_BUILD_VERSION = '1.0.0';
Expand Down Expand Up @@ -303,22 +303,18 @@ describe('getNewTemplateMetadata', () => {
providerVersion: MOCK_PROVIDER_VERSION
};
beforeEach(() => {
jest.spyOn(crypto, 'randomUUID').mockReturnValue(MOCK_UUID);
jest.spyOn(Date.prototype, 'toISOString').mockReturnValue(MOCK_DATE);
});
afterEach(() => {
jest.restoreAllMocks();
});
it('should return the expected template metadata object', () => {
const result = getNewTemplateMetadata(MOCK_OPTIONS);
if (result.information) {
result.information.uuid = MOCK_UUID;
}
expect(result).toEqual(EXPECTED_METADATA_BASE);
});
it('should call utils.getNewUuid to generate a new UUID', () => {
getNewTemplateMetadata(MOCK_OPTIONS);
const result = getNewUuid();
expect(crypto.randomUUID).toHaveBeenCalled();
expect(result).toEqual(MOCK_UUID);
});
it('should call Date.prototype.toISOString to get the current date and time', () => {
getNewTemplateMetadata(MOCK_OPTIONS);
expect(Date.prototype.toISOString).toHaveBeenCalled();
Expand Down Expand Up @@ -875,6 +871,7 @@ describe('getUpdatedExportMetadata', () => {
});
});
import { getValidatedTemplate } from '../template-usermeta';
import { get } from 'lodash';

Check warning on line 874 in packages/json-processing/src/__test__/template-usermeta.test.ts

View workflow job for this annotation

GitHub Actions / build

'get' is defined but never used

describe('getValidatedTemplate', () => {
const MOCK_CONTENT = `{
Expand Down

0 comments on commit c77d3a3

Please sign in to comment.