From dff5ba60c9fae2470db784ceaf370ce3d7eb3ccc Mon Sep 17 00:00:00 2001 From: Bowen Tan Date: Thu, 13 Jan 2022 17:54:12 +0800 Subject: [PATCH 1/3] move addModuleId to editor --- packages/core/src/module.ts | 4 + .../__tests__/addModuleId.spec.ts} | 30 +++-- packages/editor/src/AppStorage.ts | 8 +- packages/editor/src/EditorStore.ts | 11 +- packages/editor/src/constants.ts | 1 + packages/editor/src/utils/addModuleId.ts | 114 ++++++++++++++++++ packages/runtime/src/services/registry.tsx | 5 +- .../runtime/src/utils/parseModuleSchema.ts | 44 ------- 8 files changed, 152 insertions(+), 65 deletions(-) rename packages/{runtime/__tests__/parseModuleSchema.spec.ts => editor/__tests__/addModuleId.spec.ts} (59%) create mode 100644 packages/editor/src/utils/addModuleId.ts delete mode 100644 packages/runtime/src/utils/parseModuleSchema.ts diff --git a/packages/core/src/module.ts b/packages/core/src/module.ts index a7842607..1caede87 100644 --- a/packages/core/src/module.ts +++ b/packages/core/src/module.ts @@ -2,6 +2,7 @@ import { JSONSchema7Object } from 'json-schema'; import { parseVersion } from './version'; import { Metadata } from './metadata'; import { Version } from './version'; +import { ComponentSchema } from './application'; // spec @@ -10,6 +11,7 @@ export type Module = { kind: 'Module'; metadata: Metadata; spec: ModuleSpec; + impl: ComponentSchema[]; }; type ModuleSpec = { @@ -28,6 +30,7 @@ type CreateModuleOptions = { version: string; metadata: Metadata; spec?: Partial; + impl?: ComponentSchema[]; }; export function createModule(options: CreateModuleOptions): RuntimeModule { @@ -45,5 +48,6 @@ export function createModule(options: CreateModuleOptions): RuntimeModule { stateMap: {}, ...options.spec }, + impl: options.impl || [], }; } diff --git a/packages/runtime/__tests__/parseModuleSchema.spec.ts b/packages/editor/__tests__/addModuleId.spec.ts similarity index 59% rename from packages/runtime/__tests__/parseModuleSchema.spec.ts rename to packages/editor/__tests__/addModuleId.spec.ts index 415d0183..2405d5b3 100644 --- a/packages/runtime/__tests__/parseModuleSchema.spec.ts +++ b/packages/editor/__tests__/addModuleId.spec.ts @@ -1,38 +1,37 @@ import { Type } from '@sinclair/typebox'; -import { parseModuleSchema } from '../src/utils/parseModuleSchema'; +import { addModuleId } from '../src/utils/addModuleId'; -describe('parse module schema', () => { +describe('format to module schema', () => { it('will add module id to the expression', () => { expect( - parseModuleSchema({ + addModuleId({ version: 'test/v1', kind: 'Module', - parsedVersion: { - category: 'test/v1', - value: 'test', - }, - metadata: { name: 'test', }, - spec: { properties: { value: Type.Object({ BE_CAREFUL: Type.Number(), }), }, - events: [], stateMap: {}, }, - impl: [ + { + id: 'input1', + type: 'test/v1/input', + properties: {}, + traits: [], + }, { id: 'BE_CAREFUL', type: 'test/v1/child', properties: { test: '{{ value.BE_CAREFUL.toFixed(2) }}', + replace: '{{ input1.value }} / {{ BE_CAREFUL.value }}' }, traits: [], @@ -41,10 +40,17 @@ describe('parse module schema', () => { }).impl ).toMatchInlineSnapshot(` Array [ + Object { + "id": "{{ $moduleId }}__input1", + "properties": Object {}, + "traits": Array [], + "type": "test/v1/input", + }, Object { "id": "{{ $moduleId }}__BE_CAREFUL", "properties": Object { - "test": "{{ value.{{ $moduleId }}__BE_CAREFUL.toFixed(2) }}", + "replace": "{{ {{ $moduleId }}__input1.value }} / {{ {{ $moduleId }}__BE_CAREFUL.value }}", + "test": "{{ value.BE_CAREFUL.toFixed(2) }}", }, "traits": Array [], "type": "test/v1/child", diff --git a/packages/editor/src/AppStorage.ts b/packages/editor/src/AppStorage.ts index 998a7184..f2323277 100644 --- a/packages/editor/src/AppStorage.ts +++ b/packages/editor/src/AppStorage.ts @@ -3,6 +3,8 @@ import { Application, ComponentSchema } from '@sunmao-ui/core'; import { ImplementedRuntimeModule } from '@sunmao-ui/runtime'; import { produce } from 'immer'; import { DefaultNewModule, EmptyAppSchema } from './constants'; +import { addModuleId, removeModuleId } from './utils/addModuleId'; +import { cloneDeep } from 'lodash-es'; export class AppStorage { app: Application = this.getDefaultAppFromLS(); @@ -11,6 +13,7 @@ export class AppStorage { static ModulesLSKey = 'modules'; constructor() { + console.log(this.modules) makeObservable(this, { app: observable.shallow, modules: observable.shallow, @@ -35,7 +38,7 @@ export class AppStorage { try { const modulesFromLS = localStorage.getItem(AppStorage.ModulesLSKey); if (modulesFromLS) { - return JSON.parse(modulesFromLS); + return JSON.parse(modulesFromLS).map(removeModuleId); } return []; } catch (error) { @@ -122,7 +125,8 @@ export class AppStorage { } private saveModulesInLS() { - localStorage.setItem(AppStorage.ModulesLSKey, JSON.stringify(this.modules)); + const modules = cloneDeep(this.modules).map(addModuleId) + localStorage.setItem(AppStorage.ModulesLSKey, JSON.stringify(modules)); } setApp(app: Application) { diff --git a/packages/editor/src/EditorStore.ts b/packages/editor/src/EditorStore.ts index 6d004748..d11c1bb4 100644 --- a/packages/editor/src/EditorStore.ts +++ b/packages/editor/src/EditorStore.ts @@ -1,9 +1,11 @@ import { action, makeAutoObservable, observable, reaction, toJS } from 'mobx'; -import { ComponentSchema } from '@sunmao-ui/core'; +import { ComponentSchema, createModule } from '@sunmao-ui/core'; import { eventBus } from './eventBus'; import { AppStorage } from './AppStorage'; import { registry, stateManager } from './setup'; import { SchemaValidator } from './validator'; +import { addModuleId } from './utils/addModuleId'; +import { cloneDeep } from 'lodash-es'; type EditingTarget = { kind: 'app' | 'module'; @@ -41,7 +43,7 @@ class EditorStore { get selectedComponent() { return this.components.find(c => c.id === this._selectedComponentId); } - + // to avoid get out-of-dated value here, we should use getter to lazy load primitive type get hoverComponentId() { return this._hoverComponentId; @@ -119,7 +121,10 @@ class EditorStore { clearSunmaoGlobalState() { stateManager.clear(); // reregister all modules - this.modules.forEach(m => registry.registerModule(m, true)); + this.modules.forEach(m => { + const modules = createModule(addModuleId(cloneDeep(m))); + registry.registerModule(modules, true); + }); } saveCurrentComponents() { diff --git a/packages/editor/src/constants.ts b/packages/editor/src/constants.ts index 28620ed0..9c7f1bd2 100644 --- a/packages/editor/src/constants.ts +++ b/packages/editor/src/constants.ts @@ -118,6 +118,7 @@ export const EmptyAppSchema: Application = { }, }; +// need not add moduleId, because it is used in runtime of editor export const DefaultNewModule: ImplementedRuntimeModule = { kind: 'Module', parsedVersion: { category: 'custom/v1', value: 'myModule' }, diff --git a/packages/editor/src/utils/addModuleId.ts b/packages/editor/src/utils/addModuleId.ts new file mode 100644 index 00000000..64ff3ade --- /dev/null +++ b/packages/editor/src/utils/addModuleId.ts @@ -0,0 +1,114 @@ +import { Module } from '@sunmao-ui/core'; +import * as acorn from 'acorn'; +import * as acornLoose from 'acorn-loose'; +import { simple as simpleWalk } from 'acorn-walk'; + +const ModuleIdPrefix = '{{ $moduleId }}__'; + +type StringPos = { + start: number; + end: number; + replaceStr: string; +}; + +// add {{$moduleId}} in moduleSchema +export function addModuleId(module: Module): Module { + const ids: string[] = []; + module.impl.forEach(c => { + ids.push(c.id); + if (c.type === 'core/v1/moduleContainer') { + ids.push(c.properties.id as string); + } + + if (c.type === 'chakra_ui/v1/list') { + ids.push((c.properties.template as any).id); + } + }); + function traverse(tree: Record) { + for (const key in tree) { + const val = tree[key]; + if (typeof val === 'string') { + if (ids.includes(val)) { + tree[key] = `${ModuleIdPrefix}${val}`; + } else { + const newField = replaceProperty(val, ids); + tree[key] = newField; + } + } else if (typeof val === 'object') { + traverse(val); + } + } + } + + traverse(module.impl); + traverse(module.spec.stateMap); + return module; +} + +// remove {{$moduleId}} in moduleSchema +export function removeModuleId(module: Module): Module { + function traverse(tree: Record) { + for (const key in tree) { + const val = tree[key]; + if (typeof val === 'string') { + tree[key] = val.replaceAll(ModuleIdPrefix, ''); + } else if (typeof val === 'object') { + traverse(val); + } + } + } + + traverse(module.impl); + traverse(module.spec.stateMap); + return module; +} + +function replaceExp(exp: string, ids: string[]): string | void { + const identifierPos: StringPos[] = []; + simpleWalk((acornLoose as typeof acorn).parse(exp, { ecmaVersion: 2020 }), { + Identifier: node => { + const objectName = exp.slice(node.start, node.end); + if (ids.includes(objectName)) { + identifierPos.push({ + start: node.start, + end: node.end, + replaceStr: `${ModuleIdPrefix}${objectName}`, + }); + } + }, + }); + + if (identifierPos.length === 0) { + null; + } + const newExp = identifierPos.reverse().reduce((result, { start, end, replaceStr }) => { + return result.slice(0, start) + `${replaceStr}` + result.slice(end); + }, exp); + + return newExp; +} + +function replaceProperty(property: string, ids: string[]): string { + const expRegExp = new RegExp('{{(.*?)}}', 'g'); + const matches = [...property.matchAll(expRegExp)]; + + if (matches.length === 0) return property; + + const expPos: StringPos[] = []; + matches.forEach(match => { + const newExp = replaceExp(match[1], ids); + if (newExp) { + expPos.push({ + // + 2 because of '{{' length is 2 + start: match.index! + 2, + end: match.index! + 2 + match[1].length, + replaceStr: newExp, + }); + } + }); + if (expPos.length === 0) return property; + + return expPos.reverse().reduce((result, { start, end, replaceStr }) => { + return result.slice(0, start) + `${replaceStr}` + result.slice(end); + }, property); +} diff --git a/packages/runtime/src/services/registry.tsx b/packages/runtime/src/services/registry.tsx index 8d0842f1..ec785e9c 100644 --- a/packages/runtime/src/services/registry.tsx +++ b/packages/runtime/src/services/registry.tsx @@ -22,8 +22,6 @@ import { ImplementedRuntimeTrait, ImplementedRuntimeModule, } from '../types'; -import { parseModuleSchema } from '../utils/parseModuleSchema'; -import { cloneDeep } from 'lodash-es'; export type SunmaoLib = { components?: ImplementedRuntimeComponent[]; @@ -124,7 +122,6 @@ export class Registry { } registerModule(c: ImplementedRuntimeModule, overWrite = false) { - const parsedModule = parseModuleSchema(cloneDeep(c)); if (!overWrite && this.modules.get(c.version)?.has(c.metadata.name)) { throw new Error( `Already has module ${c.version}/${c.metadata.name} in this registry.` @@ -133,7 +130,7 @@ export class Registry { if (!this.modules.has(c.version)) { this.modules.set(c.version, new Map()); } - this.modules.get(c.version)?.set(c.metadata.name, parsedModule); + this.modules.get(c.version)?.set(c.metadata.name, c); } getModule(version: string, name: string): ImplementedRuntimeModule { diff --git a/packages/runtime/src/utils/parseModuleSchema.ts b/packages/runtime/src/utils/parseModuleSchema.ts deleted file mode 100644 index b925d958..00000000 --- a/packages/runtime/src/utils/parseModuleSchema.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { ImplementedRuntimeModule } from '../types'; - -// add {{$moduleId}} in moduleSchema -export function parseModuleSchema( - module: ImplementedRuntimeModule -): ImplementedRuntimeModule { - const ids: string[] = []; - module.impl.forEach(c => { - ids.push(c.id); - if (c.type === 'core/v1/moduleContainer') { - ids.push(c.properties.id as string); - } - - if (c.type === 'chakra_ui/v1/list') { - ids.push((c.properties.template as any).id); - } - }); - function traverse(tree: Record) { - for (const key in tree) { - const val = tree[key]; - if (typeof val === 'string') { - if (ids.includes(val)) { - tree[key] = `{{ $moduleId }}__${val}`; - } else { - for (const id of ids) { - if (val.includes(`${id}.`)) { - tree[key] = val.replace( - new RegExp(`${id}\\.`, 'g'), - `{{ $moduleId }}__${id}.` - ); - break; - } - } - } - } else if (typeof val === 'object') { - traverse(val); - } - } - } - - traverse(module.impl); - traverse(module.spec.stateMap); - return module; -} From 504cdc69e700891e71e97146b54c1419ed8009e1 Mon Sep 17 00:00:00 2001 From: Bowen Tan Date: Thu, 13 Jan 2022 18:14:39 +0800 Subject: [PATCH 2/3] update examples --- examples/dialog/dialogInList.json | 18 +++--- examples/list/listModule.json | 22 +++---- examples/module/index.json | 14 ++--- packages/editor/__tests__/addModuleId.spec.ts | 4 +- packages/editor/src/AppStorage.ts | 1 - packages/editor/src/utils/addModuleId.ts | 60 ++++++++++--------- 6 files changed, 60 insertions(+), 59 deletions(-) diff --git a/examples/dialog/dialogInList.json b/examples/dialog/dialogInList.json index 1b9a02c4..964f0e82 100644 --- a/examples/dialog/dialogInList.json +++ b/examples/dialog/dialogInList.json @@ -20,7 +20,7 @@ }, "impl": [ { - "id": "hstack", + "id": "{{ $moduleId }}__hstack", "type": "chakra_ui/v1/hstack", "properties": { "spacing": "24px" @@ -28,7 +28,7 @@ "traits": [] }, { - "id": "name", + "id": "{{ $moduleId }}__nameText", "type": "core/v1/text", "properties": { "value": { @@ -41,7 +41,7 @@ "type": "core/v1/slot", "properties": { "container": { - "id": "hstack", + "id": "{{ $moduleId }}__hstack", "slot": "content" } } @@ -49,7 +49,7 @@ ] }, { - "id": "email", + "id": "{{ $moduleId }}__emailText", "type": "core/v1/text", "properties": { "value": { @@ -62,7 +62,7 @@ "type": "core/v1/slot", "properties": { "container": { - "id": "hstack", + "id": "{{ $moduleId }}__hstack", "slot": "content" } } @@ -70,7 +70,7 @@ ] }, { - "id": "deleteButton", + "id": "{{ $moduleId }}__deleteButton", "type": "chakra_ui/v1/button", "properties": { "text": { @@ -106,7 +106,7 @@ "type": "core/v1/slot", "properties": { "container": { - "id": "hstack", + "id": "{{ $moduleId }}__hstack", "slot": "content" } } @@ -114,7 +114,7 @@ ] }, { - "id": "editButton", + "id": "{{ $moduleId }}__editButton", "type": "chakra_ui/v1/button", "properties": { "text": { @@ -150,7 +150,7 @@ "type": "core/v1/slot", "properties": { "container": { - "id": "hstack", + "id": "{{ $moduleId }}__hstack", "slot": "content" } } diff --git a/examples/list/listModule.json b/examples/list/listModule.json index ded0f2e1..8d551515 100644 --- a/examples/list/listModule.json +++ b/examples/list/listModule.json @@ -13,18 +13,18 @@ "properties": {}, "events": ["onEdit"], "stateMap": { - "value": "input.value" + "value": "{{ $moduleId }}__input.value" } }, "impl": [ { - "id": "hstack", + "id": "{{ $moduleId }}__hstack", "type": "chakra_ui/v1/hstack", "properties": {}, "traits": [] }, { - "id": "text", + "id": "{{ $moduleId }}__text", "type": "core/v1/text", "properties": { "value": { @@ -37,7 +37,7 @@ "type": "core/v1/slot", "properties": { "container": { - "id": "hstack", + "id": "{{ $moduleId }}__hstack", "slot": "content" } } @@ -45,11 +45,11 @@ ] }, { - "id": "inputValueText", + "id": "{{ $moduleId }}__inputValueText", "type": "core/v1/text", "properties": { "value": { - "raw": "**{{ input.value }}**", + "raw": "**{{ {{ $moduleId }}__input.value }}**", "format": "md" } }, @@ -58,7 +58,7 @@ "type": "core/v1/slot", "properties": { "container": { - "id": "hstack", + "id": "{{ $moduleId }}__hstack", "slot": "content" } } @@ -66,7 +66,7 @@ ] }, { - "id": "input", + "id": "{{ $moduleId }}__input", "type": "chakra_ui/v1/input", "properties": {}, "traits": [ @@ -74,7 +74,7 @@ "type": "core/v1/slot", "properties": { "container": { - "id": "hstack", + "id": "{{ $moduleId }}__hstack", "slot": "content" } } @@ -82,7 +82,7 @@ ] }, { - "id": "button", + "id": "{{ $moduleId }}__button", "type": "chakra_ui/v1/button", "properties": { "text": { @@ -114,7 +114,7 @@ "type": "core/v1/slot", "properties": { "container": { - "id": "hstack", + "id": "{{ $moduleId }}__hstack", "slot": "content" } } diff --git a/examples/module/index.json b/examples/module/index.json index 7626be65..8a1f74e7 100644 --- a/examples/module/index.json +++ b/examples/module/index.json @@ -18,18 +18,18 @@ }, "events": ["onSubmit"], "stateMap": { - "value": "input.value" + "value": "{{ $moduleId }}__input.value" } }, "impl": [ { - "id": "hstack", + "id": "{{ $moduleId }}__hstack", "type": "chakra_ui/v1/hstack", "properties": {}, "traits": [] }, { - "id": "input", + "id": "{{ $moduleId }}__input", "type": "chakra_ui/v1/input", "properties": {}, "traits": [ @@ -37,7 +37,7 @@ "type": "core/v1/slot", "properties": { "container": { - "id": "hstack", + "id": "{{ $moduleId }}__hstack", "slot": "content" } } @@ -45,11 +45,11 @@ ] }, { - "id": "button", + "id": "{{ $moduleId }}__button", "type": "chakra_ui/v1/button", "properties": { "text": { - "raw": "{{input.value}}", + "raw": "{{{{ $moduleId }}__input.value}}", "format": "md" } }, @@ -77,7 +77,7 @@ "type": "core/v1/slot", "properties": { "container": { - "id": "hstack", + "id": "{{ $moduleId }}__hstack", "slot": "content" } } diff --git a/packages/editor/__tests__/addModuleId.spec.ts b/packages/editor/__tests__/addModuleId.spec.ts index 2405d5b3..cac21c28 100644 --- a/packages/editor/__tests__/addModuleId.spec.ts +++ b/packages/editor/__tests__/addModuleId.spec.ts @@ -31,7 +31,7 @@ describe('format to module schema', () => { type: 'test/v1/child', properties: { test: '{{ value.BE_CAREFUL.toFixed(2) }}', - replace: '{{ input1.value }} / {{ BE_CAREFUL.value }}' + add: '{{ input1.value }} / {{ BE_CAREFUL.value }}' }, traits: [], @@ -49,7 +49,7 @@ describe('format to module schema', () => { Object { "id": "{{ $moduleId }}__BE_CAREFUL", "properties": Object { - "replace": "{{ {{ $moduleId }}__input1.value }} / {{ {{ $moduleId }}__BE_CAREFUL.value }}", + "add": "{{ {{ $moduleId }}__input1.value }} / {{ {{ $moduleId }}__BE_CAREFUL.value }}", "test": "{{ value.BE_CAREFUL.toFixed(2) }}", }, "traits": Array [], diff --git a/packages/editor/src/AppStorage.ts b/packages/editor/src/AppStorage.ts index f2323277..7c5ff884 100644 --- a/packages/editor/src/AppStorage.ts +++ b/packages/editor/src/AppStorage.ts @@ -13,7 +13,6 @@ export class AppStorage { static ModulesLSKey = 'modules'; constructor() { - console.log(this.modules) makeObservable(this, { app: observable.shallow, modules: observable.shallow, diff --git a/packages/editor/src/utils/addModuleId.ts b/packages/editor/src/utils/addModuleId.ts index 64ff3ade..d0f0a51c 100644 --- a/packages/editor/src/utils/addModuleId.ts +++ b/packages/editor/src/utils/addModuleId.ts @@ -31,7 +31,7 @@ export function addModuleId(module: Module): Module { if (ids.includes(val)) { tree[key] = `${ModuleIdPrefix}${val}`; } else { - const newField = replaceProperty(val, ids); + const newField = replaceIdsInProperty(val, ids); tree[key] = newField; } } else if (typeof val === 'object') { @@ -45,7 +45,7 @@ export function addModuleId(module: Module): Module { return module; } -// remove {{$moduleId}} in moduleSchema +// remove '{{$moduleId}}__' in moduleSchema export function removeModuleId(module: Module): Module { function traverse(tree: Record) { for (const key in tree) { @@ -63,7 +63,34 @@ export function removeModuleId(module: Module): Module { return module; } -function replaceExp(exp: string, ids: string[]): string | void { +// example: replaceIdsInExp('{{input1.value}} + {{input2.value}}', ids: ['input1']]) +function replaceIdsInProperty(property: string, ids: string[]): string { + const expRegExp = new RegExp('{{(.*?)}}', 'g'); + const matches = [...property.matchAll(expRegExp)]; + + if (matches.length === 0) return property; + + const expPos: StringPos[] = []; + matches.forEach(match => { + const newExp = replaceIdsInExp(match[1], ids); + if (newExp) { + expPos.push({ + // + 2 because of '{{' length is 2 + start: match.index! + 2, + end: match.index! + 2 + match[1].length, + replaceStr: newExp, + }); + } + }); + if (expPos.length === 0) return property; + + return expPos.reverse().reduce((result, { start, end, replaceStr }) => { + return result.slice(0, start) + `${replaceStr}` + result.slice(end); + }, property); +} + +// example: replaceIdsInExp('input1.value', ids: ['input1']]) +function replaceIdsInExp(exp: string, ids: string[]): string | void { const identifierPos: StringPos[] = []; simpleWalk((acornLoose as typeof acorn).parse(exp, { ecmaVersion: 2020 }), { Identifier: node => { @@ -86,29 +113,4 @@ function replaceExp(exp: string, ids: string[]): string | void { }, exp); return newExp; -} - -function replaceProperty(property: string, ids: string[]): string { - const expRegExp = new RegExp('{{(.*?)}}', 'g'); - const matches = [...property.matchAll(expRegExp)]; - - if (matches.length === 0) return property; - - const expPos: StringPos[] = []; - matches.forEach(match => { - const newExp = replaceExp(match[1], ids); - if (newExp) { - expPos.push({ - // + 2 because of '{{' length is 2 - start: match.index! + 2, - end: match.index! + 2 + match[1].length, - replaceStr: newExp, - }); - } - }); - if (expPos.length === 0) return property; - - return expPos.reverse().reduce((result, { start, end, replaceStr }) => { - return result.slice(0, start) + `${replaceStr}` + result.slice(end); - }, property); -} +} \ No newline at end of file From a5ca6e68981151f6a81f368e56c198c7cebc24ac Mon Sep 17 00:00:00 2001 From: Bowen Tan Date: Wed, 19 Jan 2022 10:41:07 +0800 Subject: [PATCH 3/3] add removeModuleId test --- packages/editor/__tests__/addModuleId.spec.ts | 59 ++++++++++++++++++- packages/editor/src/utils/addModuleId.ts | 4 +- 2 files changed, 60 insertions(+), 3 deletions(-) diff --git a/packages/editor/__tests__/addModuleId.spec.ts b/packages/editor/__tests__/addModuleId.spec.ts index cac21c28..a8db2a6d 100644 --- a/packages/editor/__tests__/addModuleId.spec.ts +++ b/packages/editor/__tests__/addModuleId.spec.ts @@ -1,5 +1,5 @@ import { Type } from '@sinclair/typebox'; -import { addModuleId } from '../src/utils/addModuleId'; +import { addModuleId, removeModuleId } from '../src/utils/addModuleId'; describe('format to module schema', () => { it('will add module id to the expression', () => { @@ -58,4 +58,61 @@ describe('format to module schema', () => { ] `); }); + + it('will remove module id in expression', () => { + expect( + removeModuleId({ + version: 'test/v1', + kind: 'Module', + metadata: { + name: 'test', + }, + spec: { + properties: { + value: Type.Object({ + BE_CAREFUL: Type.Number(), + }), + }, + events: [], + stateMap: {}, + }, + impl: [ + { + id: '{{ $moduleId }}__input1', + type: 'test/v1/input', + properties: {}, + traits: [], + }, + { + id: 'BE_CAREFUL', + type: 'test/v1/child', + properties: { + test: '{{ value.BE_CAREFUL.toFixed(2) }}', + add: '{{ {{ $moduleId }}__input1.value }} / {{ {{ $moduleId }}__BE_CAREFUL.value }}' + }, + + traits: [], + }, + ], + }).impl + ).toMatchInlineSnapshot(` + Array [ + Object { + "id": "input1", + "properties": Object {}, + "traits": Array [], + "type": "test/v1/input", + }, + Object { + "id": "BE_CAREFUL", + "properties": Object { + "add": "{{ input1.value }} / {{ BE_CAREFUL.value }}", + "test": "{{ value.BE_CAREFUL.toFixed(2) }}", + }, + "traits": Array [], + "type": "test/v1/child", + }, + ] + `); + }); }); diff --git a/packages/editor/src/utils/addModuleId.ts b/packages/editor/src/utils/addModuleId.ts index d0f0a51c..987b428c 100644 --- a/packages/editor/src/utils/addModuleId.ts +++ b/packages/editor/src/utils/addModuleId.ts @@ -51,7 +51,7 @@ export function removeModuleId(module: Module): Module { for (const key in tree) { const val = tree[key]; if (typeof val === 'string') { - tree[key] = val.replaceAll(ModuleIdPrefix, ''); + tree[key] = val.replace(/{{ \$moduleId }}__/g, ''); } else if (typeof val === 'object') { traverse(val); } @@ -113,4 +113,4 @@ function replaceIdsInExp(exp: string, ids: string[]): string | void { }, exp); return newExp; -} \ No newline at end of file +}