From 53c3d0ba0c24a1c36e0e6969f7ad49dda0f08d29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thea=20Sch=C3=B6bl?= Date: Wed, 3 Apr 2024 11:14:47 +0200 Subject: [PATCH] refactor: replace rfdc with native structuredClone --- .../backend/test/routes/search-route.spec.ts | 1 - frontend/app/angular.json | 11 ++++-- .../modules/config/config.provider.spec.ts | 2 +- .../settings/settings.provider.spec.ts | 14 +++---- .../app/modules/settings/settings.provider.ts | 6 +-- packages/api-cli/test/e2e.spec.ts | 8 +--- packages/api/src/connector-client.ts | 5 ++- packages/api/test/connector-client.spec.ts | 2 +- packages/core/package.json | 3 +- packages/core/src/translator.ts | 5 +-- packages/core/test/translator.spec.ts | 5 +-- .../easy-ast/src/types/lightweight-project.ts | 4 +- pnpm-lock.yaml | 37 +------------------ 13 files changed, 33 insertions(+), 70 deletions(-) diff --git a/backend/backend/test/routes/search-route.spec.ts b/backend/backend/test/routes/search-route.spec.ts index 2cf97008..bb78d061 100644 --- a/backend/backend/test/routes/search-route.spec.ts +++ b/backend/backend/test/routes/search-route.spec.ts @@ -44,7 +44,6 @@ describe('Search route', async function () { }); it('should reject GET, PUT with a valid search query', async function () { - // const expectedParams = JSON.parse(JSON.stringify(defaultParams)); const {status} = await testApp.get('/search').set('Accept', 'application/json').send({ query: 'Some search terms', }); diff --git a/frontend/app/angular.json b/frontend/app/angular.json index d24447c5..bbe2eff6 100644 --- a/frontend/app/angular.json +++ b/frontend/app/angular.json @@ -21,10 +21,13 @@ "allowedCommonJsDependencies": [ "moment", "opening_hours", - "leaflet", - "leaflet.markercluster", - "localforge", - "guid-typescript" + "localforage", + "i18next", + "semver", + "suncalc", + "guid-typescript", + "fast-deep-equal", + "maplibre-gl" ], "aot": true, "assets": [ diff --git a/frontend/app/src/app/modules/config/config.provider.spec.ts b/frontend/app/src/app/modules/config/config.provider.spec.ts index c271f153..f159cc51 100644 --- a/frontend/app/src/app/modules/config/config.provider.spec.ts +++ b/frontend/app/src/app/modules/config/config.provider.spec.ts @@ -104,7 +104,7 @@ describe('ConfigProvider', () => { it('should throw error on wrong config version in storage', async () => { storageProviderSpy.has.and.returnValue(Promise.resolve(true)); - const wrongConfig = JSON.parse(JSON.stringify(sampleIndexResponse)); + const wrongConfig = structuredClone(sampleIndexResponse); wrongConfig.backend.SCVersion = '0.1.0'; storageProviderSpy.get.and.returnValue(wrongConfig); spyOn(configProvider.client, 'handshake').and.returnValue(Promise.resolve(sampleIndexResponse)); diff --git a/frontend/app/src/app/modules/settings/settings.provider.spec.ts b/frontend/app/src/app/modules/settings/settings.provider.spec.ts index 14b969c8..f74d2ffe 100644 --- a/frontend/app/src/app/modules/settings/settings.provider.spec.ts +++ b/frontend/app/src/app/modules/settings/settings.provider.spec.ts @@ -59,7 +59,7 @@ describe('SettingsProvider', () => { }); it('should provide and get setting', async () => { - await settingsProvider.provideSetting(JSON.parse(JSON.stringify(CONFIG_SETTINGS_MOCK[0]))); + await settingsProvider.provideSetting(structuredClone(CONFIG_SETTINGS_MOCK[0])); const setting: SCSetting = await settingsProvider.getSetting( CONFIG_SETTINGS_MOCK[0].categories[0], CONFIG_SETTINGS_MOCK[0].name, @@ -68,7 +68,7 @@ describe('SettingsProvider', () => { }); it('should provide and get settings value', async () => { - await settingsProvider.provideSetting(JSON.parse(JSON.stringify(CONFIG_SETTINGS_MOCK[0]))); + await settingsProvider.provideSetting(structuredClone(CONFIG_SETTINGS_MOCK[0])); const value = await settingsProvider.getValue( CONFIG_SETTINGS_MOCK[0].categories[0], CONFIG_SETTINGS_MOCK[0].name, @@ -109,7 +109,7 @@ describe('SettingsProvider', () => { }); it('should set value of a provided setting', async () => { - await settingsProvider.provideSetting(JSON.parse(JSON.stringify(CONFIG_SETTINGS_MOCK[1]))); + await settingsProvider.provideSetting(structuredClone(CONFIG_SETTINGS_MOCK[1])); await settingsProvider.setSettingValue( CONFIG_SETTINGS_MOCK[1].categories[0], CONFIG_SETTINGS_MOCK[1].name, @@ -125,7 +125,7 @@ describe('SettingsProvider', () => { it('should return copy of settingsCache', async () => { const category = CONFIG_SETTINGS_MOCK[0].categories[0]; const name = CONFIG_SETTINGS_MOCK[0].name; - await settingsProvider.provideSetting(JSON.parse(JSON.stringify(CONFIG_SETTINGS_MOCK[0]))); + await settingsProvider.provideSetting(structuredClone(CONFIG_SETTINGS_MOCK[0])); const settings = await settingsProvider.getCache(); settings[category].settings[name].value = 'testValue'; // cached setting value should still be defaultValue @@ -133,7 +133,7 @@ describe('SettingsProvider', () => { }); it('should call storage put on setSettingValue', async () => { - await settingsProvider.provideSetting(JSON.parse(JSON.stringify(CONFIG_SETTINGS_MOCK[0]))); + await settingsProvider.provideSetting(structuredClone(CONFIG_SETTINGS_MOCK[0])); await settingsProvider.setSettingValue( CONFIG_SETTINGS_MOCK[0].categories[0], CONFIG_SETTINGS_MOCK[0].name, @@ -150,7 +150,7 @@ describe('SettingsProvider', () => { it('should reset settings', async () => { const category = CONFIG_SETTINGS_MOCK[0].categories[0]; const name = CONFIG_SETTINGS_MOCK[0].name; - await settingsProvider.provideSetting(JSON.parse(JSON.stringify(CONFIG_SETTINGS_MOCK[0]))); + await settingsProvider.provideSetting(structuredClone(CONFIG_SETTINGS_MOCK[0])); await settingsProvider.setSettingValue(category, name, 'guest'); await settingsProvider.resetDefault(); const value = await settingsProvider.getValue( @@ -203,7 +203,7 @@ describe('SettingsProvider', () => { */ async function testValue(setting: SCSetting, value: unknown) { let error: Error | undefined = undefined; - await settingsProvider.provideSetting(JSON.parse(JSON.stringify(setting))); + await settingsProvider.provideSetting(structuredClone(setting)); try { await settingsProvider.setSettingValue(setting.categories[0], setting.name, value as never); } catch (error_) { diff --git a/frontend/app/src/app/modules/settings/settings.provider.ts b/frontend/app/src/app/modules/settings/settings.provider.ts index 0cb9c75e..67c952c8 100644 --- a/frontend/app/src/app/modules/settings/settings.provider.ts +++ b/frontend/app/src/app/modules/settings/settings.provider.ts @@ -271,7 +271,7 @@ export class SettingsProvider { public async getCache(): Promise { await this.init(); - return JSON.parse(JSON.stringify(this.settingsCache)); + return structuredClone(this.settingsCache); } /** @@ -291,7 +291,7 @@ export class SettingsProvider { await this.init(); if (this.settingExists(category, name)) { // return a copy of the settings - return JSON.parse(JSON.stringify(this.settingsCache[category].settings[name])); + return structuredClone(this.settingsCache[category].settings[name]); } throw new Error(`Setting "${name}" not provided`); } @@ -306,7 +306,7 @@ export class SettingsProvider { await this.init(); if (this.settingExists(category, name)) { // return a copy of the settings value - return JSON.parse(JSON.stringify(this.settingsCache[category].settings[name].value)); + return structuredClone(this.settingsCache[category].settings[name].value)!; } throw new Error(`Setting "${name}" not provided`); } diff --git a/packages/api-cli/test/e2e.spec.ts b/packages/api-cli/test/e2e.spec.ts index 2c1b520a..597533af 100644 --- a/packages/api-cli/test/e2e.spec.ts +++ b/packages/api-cli/test/e2e.spec.ts @@ -92,8 +92,8 @@ describe('e2e Connector', function () { if ( request.url.toString() === `http://localhost${bulkAddRoute.getUrlPath({UID: 'foo'}).toString()}` ) { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - storedThings.set((request.body as any).uid, JSON.parse(JSON.stringify(request.body))); + const thing = request.body as SCThings; + storedThings.set(thing.uid, structuredClone(thing)); return { body: {}, @@ -143,7 +143,6 @@ describe('e2e Connector', function () { }, ); - // tslint:disable-next-line: max-line-length await e2eRun(httpClient, { to: 'http://localhost', samplesLocation: './node_modules/@openstapps/core/test/resources', @@ -151,7 +150,6 @@ describe('e2e Connector', function () { failOnLookup = true; failOnCompare = false; - // tslint:disable-next-line: max-line-length await e2eRun(httpClient, { to: 'http://localhost', samplesLocation: './node_modules/@openstapps/core/test/resources', @@ -161,7 +159,6 @@ describe('e2e Connector', function () { failOnLookup = false; failOnCompare = true; - // tslint:disable-next-line: max-line-length await e2eRun(httpClient, { to: 'http://localhost', samplesLocation: './node_modules/@openstapps/core/test/resources', @@ -178,7 +175,6 @@ describe('e2e Connector', function () { }; }); - // tslint:disable-next-line: max-line-length return e2eRun(httpClient, { to: 'http://localhost', samplesLocation: './node_modules/@openstapps/core/test/resources', diff --git a/packages/api/src/connector-client.ts b/packages/api/src/connector-client.ts index 202ca1b8..7287b6c4 100644 --- a/packages/api/src/connector-client.ts +++ b/packages/api/src/connector-client.ts @@ -76,8 +76,9 @@ export class ConnectorClient extends Client { * @param thing Thing to remove references from */ static removeReferences(thing: THING): SCAssociatedThingWithoutReferences { - const thingWithoutReferences = JSON.parse(JSON.stringify(thing)); + const thingWithoutReferences = structuredClone(thing); + // @ts-expect-error it still thinks it's a thing with references delete thingWithoutReferences.origin; // iterate over all properties @@ -134,7 +135,7 @@ export class ConnectorClient extends Client { } } - return thingWithoutReferences as SCAssociatedThingWithoutReferences; + return thingWithoutReferences as unknown as SCAssociatedThingWithoutReferences; } /** diff --git a/packages/api/test/connector-client.spec.ts b/packages/api/test/connector-client.spec.ts index a9e8c836..1280f4ad 100644 --- a/packages/api/test/connector-client.spec.ts +++ b/packages/api/test/connector-client.spec.ts @@ -378,7 +378,7 @@ describe('ConnectorClient', function () { ); for (const testInstance of testInstances) { - const checkInstance = JSON.parse(JSON.stringify(testInstance)); + const checkInstance = structuredClone(testInstance); const testInstanceWithoutReferences = ConnectorClient.removeReferences(testInstance); expect(doesContainThings(testInstanceWithoutReferences)).to.be.equal( diff --git a/packages/core/package.json b/packages/core/package.json index dc4463b2..f131d5af 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -49,8 +49,7 @@ "fast-deep-equal": "3.1.3", "http-status-codes": "2.2.0", "json-patch": "0.7.0", - "json-schema": "0.4.0", - "rfdc": "1.3.0" + "json-schema": "0.4.0" }, "devDependencies": { "@openstapps/easy-ast": "workspace:*", diff --git a/packages/core/src/translator.ts b/packages/core/src/translator.ts index 0684b43b..dd5b15f0 100644 --- a/packages/core/src/translator.ts +++ b/packages/core/src/translator.ts @@ -14,7 +14,6 @@ * this program. If not, see . */ import equal from 'fast-deep-equal/es6/index.js'; -import clone from 'rfdc'; import {SCLanguageCode} from './general/i18n.js'; import {isThing} from './guards.js'; import {SCClasses} from './meta.js'; @@ -223,7 +222,7 @@ export class SCThingTranslator { return cachedInstance as T; } } - const translatedInstance = this.translateThingInPlaceDestructively(clone()(thing)); + const translatedInstance = this.translateThingInPlaceDestructively(structuredClone(thing)); delete translatedInstance.translations; this.cache.putObject(translatedInstance); this.sourceCache.putObject(thing); @@ -254,7 +253,7 @@ export class SCThingTranslator { return this.deeptranslate((objectTranslatedFromCache as any)[key]); } } - const objectTranslated = this.translateThingInPlaceDestructively(clone()(object)); + const objectTranslated = this.translateThingInPlaceDestructively(structuredClone(object)); this.cache.putObject(objectTranslated); this.sourceCache.putObject(thing); diff --git a/packages/core/test/translator.spec.ts b/packages/core/test/translator.spec.ts index 5c330809..2ae7fd47 100644 --- a/packages/core/test/translator.spec.ts +++ b/packages/core/test/translator.spec.ts @@ -13,7 +13,6 @@ * this program. If not, see . */ import {expect} from 'chai'; -import clone from 'rfdc'; import {SCThingRemoteOrigin} from '../src/index.js'; import {SCDishMeta} from '../src/index.js'; import {SCThingTranslator} from '../src/index.js'; @@ -164,7 +163,7 @@ describe('Translator', function () { it('should omit LRU cache with changed source', function () { const translatorDE = new SCThingTranslator('de'); - const dishCopy = clone()(dish); + const dishCopy = structuredClone(dish); const translatedDish = translatorDE.translatedAccess(dish); const destructivelyTranslatedDish = translatorDE.translate(dish); @@ -224,7 +223,7 @@ describe('MetaTranslator', function () { }); it('should translate thing without meta class', function () { - const dishCopy = clone()(dish); + const dishCopy = structuredClone(dish); const typeNonExistent = eval("(x) => x + 'typeNonExistent';"); // this will assign a non-existent SCThingType to dishCopy dishCopy.type = typeNonExistent(); diff --git a/packages/easy-ast/src/types/lightweight-project.ts b/packages/easy-ast/src/types/lightweight-project.ts index 27f1494f..18810103 100644 --- a/packages/easy-ast/src/types/lightweight-project.ts +++ b/packages/easy-ast/src/types/lightweight-project.ts @@ -68,10 +68,10 @@ export class LightweightProjectWithIndex { return (deep ?? true) && isLightweightClass(object) ? this.applyInheritance(object) - : JSON.parse(JSON.stringify(object)); + : structuredClone(object); }, ), - JSON.parse(JSON.stringify(classLike)), + structuredClone(classLike), ); } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index aba14e52..08880060 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1511,9 +1511,6 @@ importers: json-schema: specifier: 0.4.0 version: 0.4.0 - rfdc: - specifier: 1.3.0 - version: 1.3.0 devDependencies: '@openstapps/easy-ast': specifier: workspace:* @@ -4546,7 +4543,7 @@ packages: object-assign: 4.1.1 open: 8.4.0 proxy-middleware: 0.15.0 - send: 1.0.0-beta.2 + send: 0.18.0 serve-index: 1.9.1 transitivePeerDependencies: - supports-color @@ -10089,17 +10086,6 @@ packages: dependencies: ms: 2.0.0 - /debug@3.1.0: - resolution: {integrity: sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - dependencies: - ms: 2.0.0 - dev: true - /debug@3.2.7(supports-color@5.5.0): resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} peerDependencies: @@ -17023,6 +17009,7 @@ packages: /rfdc@1.3.0: resolution: {integrity: sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==} + dev: true /rimraf@2.7.1: resolution: {integrity: sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==} @@ -17306,26 +17293,6 @@ packages: transitivePeerDependencies: - supports-color - /send@1.0.0-beta.2: - resolution: {integrity: sha512-k1yHu/FNK745PULKdsGpQ+bVSXYNwSk+bWnYzbxGZbt5obZc0JKDVANsCRuJD1X/EG15JtP9eZpwxkhUxIYEcg==} - engines: {node: '>= 0.10'} - dependencies: - debug: 3.1.0 - destroy: 1.2.0 - encodeurl: 1.0.2 - escape-html: 1.0.3 - etag: 1.8.1 - fresh: 0.5.2 - http-errors: 2.0.0 - mime-types: 2.1.35 - ms: 2.1.3 - on-finished: 2.4.1 - range-parser: 1.2.1 - statuses: 2.0.1 - transitivePeerDependencies: - - supports-color - dev: true - /serialize-javascript@6.0.0: resolution: {integrity: sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==} dependencies: