From bfd8591878574e4add890eeb9ccf98f78f24cd5c Mon Sep 17 00:00:00 2001 From: Xc Date: Sat, 16 Dec 2023 22:12:02 +0800 Subject: [PATCH 1/6] 4.0.2-dev --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 21524b8..e99a1b9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "oak-domain", - "version": "4.0.1", + "version": "4.0.2", "author": { "name": "XuChang" }, From 9b033e57ff2873361f7f921fcff03b20d33e4836 Mon Sep 17 00:00:00 2001 From: Xc Date: Wed, 20 Dec 2023 12:07:40 +0800 Subject: [PATCH 2/6] =?UTF-8?q?count=E4=B9=9F=E8=A6=81=E7=BB=8F=E8=BF=87ca?= =?UTF-8?q?scadeStore=E4=B8=AD=E7=9A=84=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/compiler/localeBuilder.js | 45 ++++++++++++++++++++++++++++------- lib/store/CascadeStore.d.ts | 5 +++- lib/store/CascadeStore.js | 10 +++++++- lib/store/actionDef.js | 8 +++---- lib/utils/assert.d.ts | 1 + src/compiler/localeBuilder.ts | 11 +++++---- src/store/CascadeStore.ts | 41 ++++++++++++++++++++++++------- 7 files changed, 93 insertions(+), 28 deletions(-) diff --git a/lib/compiler/localeBuilder.js b/lib/compiler/localeBuilder.js index 9ede377..ba8475b 100644 --- a/lib/compiler/localeBuilder.js +++ b/lib/compiler/localeBuilder.js @@ -54,9 +54,23 @@ class LocaleBuilder { const statements = [ factory.createImportDeclaration(undefined, factory.createImportClause(false, undefined, factory.createNamedImports([factory.createImportSpecifier(false, factory.createIdentifier("CreateOperationData"), factory.createIdentifier("I18n"))])), factory.createStringLiteral("../oak-app-domain/I18n/Schema"), undefined) ]; - if (this.dependencies) { - this.dependencies.forEach((ele, idx) => statements.push(factory.createImportDeclaration(undefined, factory.createImportClause(false, factory.createIdentifier(`i18ns${idx}`), undefined), factory.createStringLiteral(`${ele}/lib/data/i18n`), undefined))); - } + // 改为在初始化时合并 + /* if (this.dependencies) { + this.dependencies.forEach( + (ele, idx) => statements.push( + factory.createImportDeclaration( + undefined, + factory.createImportClause( + false, + factory.createIdentifier(`i18ns${idx}`), + undefined + ), + factory.createStringLiteral(`${ele}/lib/data/i18n`), + undefined + ) + ) + ) + } */ statements.push(factory.createVariableStatement(undefined, factory.createVariableDeclarationList([factory.createVariableDeclaration(factory.createIdentifier("i18ns"), undefined, factory.createArrayTypeNode(factory.createTypeReferenceNode(factory.createIdentifier("I18n"), undefined)), factory.createArrayLiteralExpression(Object.keys(this.locales).map((k) => { const [module, position, language, data] = this.locales[k]; // 用哈希计算来保证id唯一性 @@ -73,12 +87,27 @@ class LocaleBuilder { factory.createPropertyAssignment(factory.createIdentifier("data"), transferObjectToObjectLiteral(data)) ], true); }), true))], ts.NodeFlags.Const))); - if (this.dependencies.length > 0) { - statements.push(factory.createExportAssignment(undefined, undefined, factory.createCallExpression(factory.createPropertyAccessExpression(factory.createIdentifier("i18ns"), factory.createIdentifier("concat")), undefined, this.dependencies.map((ele, idx) => factory.createIdentifier(`i18ns${idx}`))))); - } - else { - statements.push(factory.createExportAssignment(undefined, undefined, factory.createIdentifier("i18ns"))); + /* if (this.dependencies.length > 0) { + statements.push( + factory.createExportAssignment( + undefined, + undefined, + factory.createCallExpression( + factory.createPropertyAccessExpression( + factory.createIdentifier("i18ns"), + factory.createIdentifier("concat") + ), + undefined, + this.dependencies.map( + (ele, idx) => factory.createIdentifier(`i18ns${idx}`) + ) + ) + ) + ); } + else { */ + statements.push(factory.createExportAssignment(undefined, undefined, factory.createIdentifier("i18ns"))); + /* } */ const printer = ts.createPrinter({ newLine: ts.NewLineKind.LineFeed }); const result = printer.printList(ts.ListFormat.SourceFileStatements, factory.createNodeArray(statements), ts.createSourceFile("someFileName.ts", "", ts.ScriptTarget.Latest, false, ts.ScriptKind.TS)); const filename = (0, path_1.join)(this.pwd, 'src', 'data', 'i18n.ts'); diff --git a/lib/store/CascadeStore.d.ts b/lib/store/CascadeStore.d.ts index 3438057..c147dc9 100644 --- a/lib/store/CascadeStore.d.ts +++ b/lib/store/CascadeStore.d.ts @@ -18,9 +18,10 @@ export declare abstract class CascadeStore | SyncContext, OperateOption>): void; registerSelectionRewriter(rewriter: SelectionRewriter | SyncContext, SelectOption>): void; protected abstract selectAbjointRow>(entity: T, selection: ED[T]['Selection'], context: Cxt, option: OP): Partial[]; + protected abstract countAbjointRow>(entity: T, selection: Pick, context: Cxt, option: OP): number; + protected abstract countAbjointRowAsync>(entity: T, selection: Pick, context: Cxt, option: OP): Promise; protected abstract updateAbjointRow>(entity: T, operation: ED[T]['Operation'], context: Cxt, option: OP): number; protected abstract selectAbjointRowAsync>(entity: T, selection: ED[T]['Selection'], context: Cxt, option: OP): Promise[]>; - protected abstract countAsync>(entity: T, selection: Pick, context: Cxt, option: OP): Promise; protected abstract updateAbjointRowAsync>(entity: T, operation: ED[T]['Create'] | ED[T]['Update'] | ED[T]['Remove'], context: Cxt, option: OP): Promise; protected abstract aggregateAbjointRowSync>(entity: T, aggregation: ED[T]['Aggregation'], context: Cxt, option: OP): AggregationResult; protected abstract aggregateAbjointRowAsync>(entity: T, aggregation: ED[T]['Aggregation'], context: Cxt, option: OP): Promise>; @@ -103,4 +104,6 @@ export declare abstract class CascadeStore>(entity: T, selection: ED[T]['Selection'], context: Cxt, option: OP): Partial[]; protected operateSync, OP extends OperateOption>(entity: T, operation: ED[T]['Operation'], context: Cxt, option: OP): OperationResult; protected operateAsync, OP extends OperateOption>(entity: T, operation: ED[T]['Operation'], context: Cxt, option: OP): Promise>; + protected countSync>(entity: T, selection: Pick, context: Cxt, option: OP): number; + protected countAsync>(entity: T, selection: Pick, context: Cxt, option: OP): Promise; } diff --git a/lib/store/CascadeStore.js b/lib/store/CascadeStore.js index 3253f2c..a63bbd7 100644 --- a/lib/store/CascadeStore.js +++ b/lib/store/CascadeStore.js @@ -34,7 +34,7 @@ class CascadeStore extends RowStore_1.RowStore { this.reinforceSelectionInner(entity, selection, context); } this.selectionRewriters.forEach(ele => { - const result = ele(this.getSchema(), entity, selection, context, option); + const result = ele(this.getSchema(), entity, selection, context, option, isAggr); (0, assert_1.default)(!(result instanceof Promise)); }); } @@ -1736,5 +1736,13 @@ class CascadeStore extends RowStore_1.RowStore { await this.reinforceOperation(entity, operation, context, option); return this.cascadeUpdateAsync(entity, operation, context, option); } + countSync(entity, selection, context, option) { + this.reinforceSelectionSync(entity, selection, context, option, true); // 这样写可能有问题的,虽然能跳过本地的projection补全,但如果有更多的selectionRewriter注入可能会出问题。by Xc 20231220 + return this.countAbjointRow(entity, selection, context, option); + } + countAsync(entity, selection, context, option) { + this.reinforceSelectionAsync(entity, selection, context, option, true); // 这样写可能有问题的,虽然能跳过本地的projection补全,但如果有更多的selectionRewriter注入可能会出问题。by Xc 20231220 + return this.countAbjointRowAsync(entity, selection, context, option); + } } exports.CascadeStore = CascadeStore; diff --git a/lib/store/actionDef.js b/lib/store/actionDef.js index 1f812ce..5d1fa8f 100644 --- a/lib/store/actionDef.js +++ b/lib/store/actionDef.js @@ -146,7 +146,7 @@ function makeIntrinsicCTWs(schema, actionDefDict) { action: 'create', type: 'data', entity, - priority: 10, + priority: 10, // 优先级要高,先于真正的data检查进行 checker: (data) => { if (data instanceof Array) { data.forEach(ele => { @@ -181,7 +181,7 @@ function makeIntrinsicCTWs(schema, actionDefDict) { entity, action: 'create', type: 'logicalData', - priority: types_1.CHECKER_MAX_PRIORITY, + priority: types_1.CHECKER_MAX_PRIORITY, // 优先级要放在最低,所有前置的checker/trigger将数据完整之后再在这里检测 checker: (operation, context) => { const { data } = operation; if (data instanceof Array) { @@ -197,9 +197,9 @@ function makeIntrinsicCTWs(schema, actionDefDict) { } }, { entity, - action: 'update', + action: 'update', // 只检查update,其它状态转换的action应该不会涉及unique约束的属性 type: 'logicalData', - priority: types_1.CHECKER_MAX_PRIORITY, + priority: types_1.CHECKER_MAX_PRIORITY, // 优先级要放在最低,所有前置的checker/trigger将数据完整之后再在这里检测 checker: (operation, context) => { const { data, filter: operationFilter } = operation; if (data) { diff --git a/lib/utils/assert.d.ts b/lib/utils/assert.d.ts index c502695..932ffd1 100644 --- a/lib/utils/assert.d.ts +++ b/lib/utils/assert.d.ts @@ -1,3 +1,4 @@ +/// /** * 防止assert打包体积过大,从这里引用 */ diff --git a/src/compiler/localeBuilder.ts b/src/compiler/localeBuilder.ts index 186f530..a6e78ad 100644 --- a/src/compiler/localeBuilder.ts +++ b/src/compiler/localeBuilder.ts @@ -80,7 +80,8 @@ export default class LocaleBuilder { ) ]; - if (this.dependencies) { + // 改为在初始化时合并 + /* if (this.dependencies) { this.dependencies.forEach( (ele, idx) => statements.push( factory.createImportDeclaration( @@ -95,7 +96,7 @@ export default class LocaleBuilder { ) ) ) - } + } */ statements.push( factory.createVariableStatement( @@ -159,7 +160,7 @@ export default class LocaleBuilder { ), ); - if (this.dependencies.length > 0) { + /* if (this.dependencies.length > 0) { statements.push( factory.createExportAssignment( undefined, @@ -177,7 +178,7 @@ export default class LocaleBuilder { ) ); } - else { + else { */ statements.push( factory.createExportAssignment( undefined, @@ -185,7 +186,7 @@ export default class LocaleBuilder { factory.createIdentifier("i18ns") ) ); - } + /* } */ const printer = ts.createPrinter({ newLine: ts.NewLineKind.LineFeed }); const result = printer.printList( diff --git a/src/store/CascadeStore.ts b/src/store/CascadeStore.ts index 9e6e459..be875b8 100644 --- a/src/store/CascadeStore.ts +++ b/src/store/CascadeStore.ts @@ -62,7 +62,7 @@ export abstract class CascadeStore exten this.selectionRewriters.forEach( ele => { - const result = ele(this.getSchema(), entity, selection, context, option); + const result = ele(this.getSchema(), entity, selection, context, option, isAggr); assert(!(result instanceof Promise)); } ); @@ -377,7 +377,6 @@ export abstract class CascadeStore exten $$createAt$$: 1, }); } - } private async reinforceOperation, Op extends OperateOption>( @@ -403,6 +402,19 @@ export abstract class CascadeStore exten selection: ED[T]['Selection'], context: Cxt, option: OP): Partial[]; + + protected abstract countAbjointRow>( + entity: T, + selection: Pick, + context: Cxt, + option: OP): number; + + + protected abstract countAbjointRowAsync>( + entity: T, + selection: Pick, + context: Cxt, + option: OP): Promise; protected abstract updateAbjointRow>( entity: T, @@ -416,13 +428,6 @@ export abstract class CascadeStore exten context: Cxt, option: OP): Promise[]>; - protected abstract countAsync>( - entity: T, - selection: Pick, - context: Cxt, - option: OP - ): Promise; - protected abstract updateAbjointRowAsync>( entity: T, operation: ED[T]['Create'] | ED[T]['Update'] | ED[T]['Remove'], @@ -2169,4 +2174,22 @@ export abstract class CascadeStore exten await this.reinforceOperation(entity, operation, context, option); return this.cascadeUpdateAsync(entity, operation, context, option); } + + protected countSync>( + entity: T, + selection: Pick, + context: Cxt, + option: OP) { + this.reinforceSelectionSync(entity, selection as ED[T]['Selection'], context, option, true); // 这样写可能有问题的,虽然能跳过本地的projection补全,但如果有更多的selectionRewriter注入可能会出问题。by Xc 20231220 + return this.countAbjointRow(entity, selection as ED[T]['Selection'], context, option); + } + + protected countAsync>( + entity: T, + selection: Pick, + context: Cxt, + option: OP) { + this.reinforceSelectionAsync(entity, selection as ED[T]['Selection'], context, option, true); // 这样写可能有问题的,虽然能跳过本地的projection补全,但如果有更多的selectionRewriter注入可能会出问题。by Xc 20231220 + return this.countAbjointRowAsync(entity, selection as ED[T]['Selection'], context, option); + } } \ No newline at end of file From 55307705e82c957af6378e946eb8427155da55fb Mon Sep 17 00:00:00 2001 From: "Xc@centOs" Date: Fri, 22 Dec 2023 20:39:07 +0800 Subject: [PATCH 3/6] =?UTF-8?q?routerBuilder=E6=9C=AA=E5=AE=8C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/compiler/routerBuilder.ts | 186 ++++++++++++++++++++++++++++++++++ src/store/TriggerExecutor.ts | 2 +- test/test.ts | 8 +- 3 files changed, 193 insertions(+), 3 deletions(-) create mode 100644 src/compiler/routerBuilder.ts diff --git a/src/compiler/routerBuilder.ts b/src/compiler/routerBuilder.ts new file mode 100644 index 0000000..4bd1999 --- /dev/null +++ b/src/compiler/routerBuilder.ts @@ -0,0 +1,186 @@ +import { join } from 'path'; +import { readdirSync, statSync, existsSync } from 'fs-extra'; +import assert from 'assert'; +import * as ts from 'typescript'; +const { factory } = ts; + +/** + * 一个项目,根据其pages下的目录结构,构建出web/native工程下的router以及pageMap + * wechatMp暂不处理 + * 项目目录结构应为: + * + * -src + * --pages + * ---${namespace1} + * -----${page1} + * -------${subPage1.1} + * -------${subPage1.2} + * -----${page2} + * ---${namespace2} + * -----${page3} + * + * -web + * --src + * ---${appName} + * -----namespaces + * -------${namespace1} + * ---------index.json (此namespace下的配置) + * ---------pageMap.json (编译器将pageMap注入到这里) + * -------${namespace2} + * -----router + * ---------index.ts (编译器将router.ts注入到这里) + * + * -native + * --namspaces + * ----${namespace1} + * -------index.json (此namespace下的配置) + * -------pageMap.json (编译器将pageMap注入到这里) + * --router + * ----index.ts (编译器将router.ts注入到这里) + * + */ + +type PageDesc = { + path: string; + oakDisablePulldownRefresh: boolean; + hasWeb: boolean; + hasNative: boolean; + hasWechatMp: boolean; +} + +type NamespaceDesc = { + pages: Record; +} + +const NameSpaceDescDict: Record = {}; + +function traverseNsDir(nsDir: string, ns: string) { + NameSpaceDescDict[ns] = { + pages: {} + }; + const { pages } = NameSpaceDescDict[ns]; + const traverse = (dir: string, relativePath: string) => { + const files = readdirSync(dir); + files.forEach((file) => { + const filepath = join(dir, file); + const stat = statSync(filepath); + if (stat.isFile() && + ['web.tsx', 'web.pc.tsx', 'render.native.tsx', 'render.ios.tsx', 'render.android.tsx', 'index.xml'].includes( + file + )) { + if (!pages.hasOwnProperty(dir)) { + const indexJsonFile = join(dir, 'index.json'); + let oakDisablePulldownRefresh = false; + if (existsSync(indexJsonFile)) { + const { + enablePullDownRefresh = true, + } = require(indexJsonFile); + oakDisablePulldownRefresh = + !enablePullDownRefresh; + } + pages[dir] = { + path: relativePath.replace(/\\/g, '/'), + oakDisablePulldownRefresh, + hasNative: ['render.native.tsx', 'render.ios.tsx', 'render.android.tsx'].includes(file), + hasWeb: ['web.tsx', 'web.pc.tsx'].includes(file), + hasWechatMp: file === 'index.xml', + }; + } + else { + if (['render.native.tsx', 'render.ios.tsx', 'render.android.tsx'].includes(file)) { + pages[dir].hasNative = true; + } + else if (['web.tsx', 'web.pc.tsx'].includes(file)) { + pages[dir].hasWeb = true; + } + else { + pages[dir].hasWechatMp = true; + } + } + } else if (stat.isDirectory()) { + const dir2 = join(dir, file); + const relativePath2 = join(relativePath, file); + traverse(dir2, relativePath2); + } + }); + }; + + traverse(nsDir, ''); +} + +function traversePageDir(projectDir: string) { + const pageDir = join(projectDir, 'src', 'pages'); + + const namespaces = readdirSync(pageDir); + namespaces.forEach( + (ns) => { + const nsDir = join(pageDir, ns); + const stat = statSync(nsDir); + if (stat.isDirectory()) { + traverseNsDir(nsDir, ns); + } + } + ); +} + + +function outputInWebDir(dir: string, ns?: string) { + const srcAppDir = join (dir, 'src', 'app'); + const apps = readdirSync(srcAppDir); + apps.forEach( + (app) => { + const appDir = join(srcAppDir, app); + const stat = statSync(appDir); + + if (stat.isDirectory()) { + const routerFileName = join(appDir, 'router', 'index.ts'); + const namespaceDir = join(appDir, 'namespaces'); + const program = ts.createProgram([routerFileName], {}); + const routerFile = program.getSourceFile(routerFileName); + assert(routerFile); + if (routerFile.text.includes('using-oak-router-builder')) { + routerFile.statements.forEach( + (statement) => { + if (ts.isVariableStatement(statement)) { + statement.declarationList.declarations.forEach( + (declaration) => { + if (ts.isIdentifier(declaration.name) && declaration.name.text === 'allRouters') { + const { initializer } = declaration; + + console.log(initializer); + } + } + ) + } + } + ); + } + + + const nss = readdirSync(namespaceDir); + + if (ns) { + assert(nss.includes(ns)); + } + } + } + ) +} + +export function buildRouter(projectDir: string) { + traversePageDir(projectDir); + + const subDir = readdirSync(projectDir); + + subDir.forEach( + (dirname) => { + if (dirname.startsWith('web')) { + const webPrjDir = join(projectDir, dirname); + const stat = statSync(webPrjDir); + if (stat.isDirectory()) { + outputInWebDir(webPrjDir); + } + } + } + ) +} \ No newline at end of file diff --git a/src/store/TriggerExecutor.ts b/src/store/TriggerExecutor.ts index bde73a4..b0636eb 100644 --- a/src/store/TriggerExecutor.ts +++ b/src/store/TriggerExecutor.ts @@ -563,7 +563,7 @@ export class TriggerExecutor ele.id!), context, option); } await context.commit(); diff --git a/test/test.ts b/test/test.ts index c19c838..1a6c22a 100644 --- a/test/test.ts +++ b/test/test.ts @@ -1,8 +1,12 @@ -import { generateNewId } from '../src/utils/uuid'; +/* import { generateNewId } from '../src/utils/uuid'; let iter = 20; while (iter > 0) { console.log(generateNewId()); iter --; -} \ No newline at end of file +} */ +import { join } from 'path'; +import { buildRouter } from '../src/compiler/routerBuilder'; + +buildRouter(join(process.cwd(), '..', 'taicang')); \ No newline at end of file From 2b43b36c26c2ce9fbf15488dc5cac0f7f73cd34c Mon Sep 17 00:00:00 2001 From: Xc Date: Sun, 24 Dec 2023 11:57:26 +0800 Subject: [PATCH 4/6] routerBuilder --- lib/compiler/routerBuilder.d.ts | 1 + lib/compiler/routerBuilder.js | 248 +++++++++++++++++ lib/store/TriggerExecutor.js | 2 +- package.json | 1 + src/compiler/routerBuilder.ts | 454 +++++++++++++++++++++++++------- test/test.ts | 2 +- 6 files changed, 616 insertions(+), 92 deletions(-) create mode 100644 lib/compiler/routerBuilder.d.ts create mode 100644 lib/compiler/routerBuilder.js diff --git a/lib/compiler/routerBuilder.d.ts b/lib/compiler/routerBuilder.d.ts new file mode 100644 index 0000000..0b2e791 --- /dev/null +++ b/lib/compiler/routerBuilder.d.ts @@ -0,0 +1 @@ +export declare function buildRouter(projectDir: string, startupDir: string, watch?: boolean): void; diff --git a/lib/compiler/routerBuilder.js b/lib/compiler/routerBuilder.js new file mode 100644 index 0000000..0c661ca --- /dev/null +++ b/lib/compiler/routerBuilder.js @@ -0,0 +1,248 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.buildRouter = void 0; +const tslib_1 = require("tslib"); +const path_1 = require("path"); +const fs_extra_1 = require("fs-extra"); +const assert_1 = tslib_1.__importDefault(require("assert")); +const ts = tslib_1.__importStar(require("typescript")); +const node_watch_1 = tslib_1.__importDefault(require("node-watch")); +const { factory } = ts; +const NameSpaceDescDict = {}; +function checkPageDir(dir, relativePath, ns, type) { + let changed = false; + const { pages } = NameSpaceDescDict[ns]; + const subdirs = []; + const files = (0, fs_extra_1.readdirSync)(dir); + files.forEach((file) => { + const filepath = (0, path_1.join)(dir, file); + const stat = (0, fs_extra_1.statSync)(filepath); + if (stat.isFile() && + ['web.tsx', 'web.pc.tsx', 'render.native.tsx', 'render.ios.tsx', 'render.android.tsx', 'index.xml'].includes(file)) { + if (!pages.hasOwnProperty(dir)) { + const indexJsonFile = (0, path_1.join)(dir, 'index.json'); + let oakDisablePulldownRefresh = false; + if ((0, fs_extra_1.existsSync)(indexJsonFile)) { + const { enablePullDownRefresh = true, } = require(indexJsonFile); + oakDisablePulldownRefresh = + !enablePullDownRefresh; + } + pages[dir] = { + path: relativePath.replace(/\\/g, '/'), + oakDisablePulldownRefresh, + hasNative: ['render.native.tsx', 'render.ios.tsx', 'render.android.tsx'].includes(file), + hasWeb: ['web.tsx', 'web.pc.tsx'].includes(file), + hasWechatMp: file === 'index.xml', + }; + changed = true; + } + else { + if (['render.native.tsx', 'render.ios.tsx', 'render.android.tsx'].includes(file) && type === 'native') { + if (pages[dir].hasNative === false) { + pages[dir].hasNative = true; + changed = true; + } + } + else if (['web.tsx', 'web.pc.tsx'].includes(file) && type === 'web') { + if (pages[dir].hasWeb === false) { + pages[dir].hasWeb = true; + changed = true; + } + } + else { + if (pages[dir].hasWechatMp === false && type === 'wechatMp') { + pages[dir].hasWechatMp = true; + } + } + } + } + else if (stat.isDirectory()) { + subdirs.push(file); + } + }); + return { + subdirs, + changed, + }; +} +function traverseNsDir(nsDir, ns, type) { + NameSpaceDescDict[ns] = { + pages: {} + }; + const { pages } = NameSpaceDescDict[ns]; + const traverse = (dir, relativePath) => { + const { subdirs } = checkPageDir(dir, relativePath, ns, type); + subdirs.forEach((subdir) => { + const dir2 = (0, path_1.join)(dir, subdir); + const relativePath2 = (0, path_1.join)(relativePath, subdir); + traverse(dir2, relativePath2); + }); + }; + traverse(nsDir, ''); +} +function traversePageDir(projectDir, type) { + const pageDir = (0, path_1.join)(projectDir, 'src', 'pages'); + const namespaces = (0, fs_extra_1.readdirSync)(pageDir); + namespaces.forEach((ns) => { + const nsDir = (0, path_1.join)(pageDir, ns); + const stat = (0, fs_extra_1.statSync)(nsDir); + if (stat.isDirectory()) { + traverseNsDir(nsDir, ns, type); + } + }); +} +function makeWebAllRouters(namespaceDir, projectDir, routerFileDir) { + const nss = (0, fs_extra_1.readdirSync)(namespaceDir); + return factory.createArrayLiteralExpression(nss.map((ns) => { + (0, assert_1.default)(NameSpaceDescDict[ns], `${ns}在pages下没有对应的目录`); + const { pages } = NameSpaceDescDict[ns]; + const nsIndexJsonFile = (0, path_1.join)(namespaceDir, ns, 'index.json'); + let path2 = `/${ns}`; + let notFound2 = '', first2 = ''; + if ((0, fs_extra_1.existsSync)(nsIndexJsonFile)) { + const { path, notFound, first } = require(nsIndexJsonFile); + path2 = path.replace(/\\/g, '/'); + notFound2 = notFound.replace(/\\/g, '/'); + first2 = first.replace(/\\/g, '/'); + } + const children = Object.values(pages).filter((ele) => ele.hasWeb).map(({ path, oakDisablePulldownRefresh }) => { + const properties = [ + factory.createPropertyAssignment('path', factory.createStringLiteral(path)), + factory.createPropertyAssignment('namespace', factory.createStringLiteral(path2)), + factory.createPropertyAssignment('meta', factory.createObjectLiteralExpression([ + factory.createPropertyAssignment('oakDisablePulldownRefresh', oakDisablePulldownRefresh ? factory.createTrue() : factory.createFalse()) + ])), + factory.createPropertyAssignment(factory.createIdentifier("Component"), factory.createCallExpression(factory.createPropertyAccessExpression(factory.createIdentifier("React"), factory.createIdentifier("lazy")), undefined, [factory.createArrowFunction(undefined, undefined, [], undefined, factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken), factory.createCallExpression(factory.createIdentifier('import'), undefined, [ + factory.createStringLiteral((0, path_1.relative)(routerFileDir, (0, path_1.join)(projectDir, 'src', 'pages', ns, path)).replace(/\\/g, '/')) + ]))])) + ]; + if (first2 === path) { + properties.push(factory.createPropertyAssignment('isFirst', factory.createTrue())); + } + return factory.createObjectLiteralExpression(properties, true); + }); + if (notFound2) { + children.push(factory.createObjectLiteralExpression([ + factory.createPropertyAssignment('path', factory.createStringLiteral('*')), + factory.createPropertyAssignment('namespace', factory.createStringLiteral(path2)), + factory.createPropertyAssignment(factory.createIdentifier("Component"), factory.createCallExpression(factory.createPropertyAccessExpression(factory.createIdentifier("React"), factory.createIdentifier("lazy")), undefined, [factory.createArrowFunction(undefined, undefined, [], undefined, factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken), factory.createCallExpression(factory.createIdentifier('import'), undefined, [ + factory.createStringLiteral((0, path_1.relative)(routerFileDir, (0, path_1.join)(projectDir, 'src', 'pages', ns, notFound2)).replace(/\\/g, '/')) + ]))])) + ], true)); + } + return factory.createObjectLiteralExpression([ + factory.createPropertyAssignment('path', factory.createStringLiteral(path2)), + factory.createPropertyAssignment('namespace', factory.createStringLiteral(path2)), + factory.createPropertyAssignment(factory.createIdentifier("Component"), factory.createCallExpression(factory.createPropertyAccessExpression(factory.createIdentifier("React"), factory.createIdentifier("lazy")), undefined, [factory.createArrowFunction(undefined, undefined, [], undefined, factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken), factory.createCallExpression(factory.createIdentifier('import'), undefined, [ + factory.createStringLiteral((0, path_1.relative)(routerFileDir, (0, path_1.join)(namespaceDir, ns)).replace(/\\/g, '/')) + ]))])), + factory.createPropertyAssignment('children', factory.createArrayLiteralExpression(children)) + ], true); + }), true); +} +function judgeUseOakRouterBuilder(statements) { + const stmt = statements[0]; + return ts.isExpressionStatement(stmt) && ts.isStringLiteral(stmt.expression) && stmt.expression.text === 'use oak router builder'; +} +function outputInWebAppDir(appDir) { + const routerFileName = (0, path_1.join)(appDir, 'router', 'allRouters.ts'); + if ((0, fs_extra_1.existsSync)(routerFileName)) { + const program = ts.createProgram([routerFileName], { + removeComments: false, + }); + const routerFile = program.getSourceFile(routerFileName); + (0, assert_1.default)(routerFile); + const namespaceDir = (0, path_1.join)(appDir, 'namespaces'); + const { statements } = routerFile; + if (judgeUseOakRouterBuilder(statements)) { + statements.forEach((statement) => { + if (ts.isVariableStatement(statement)) { + const declaration = statement.declarationList.declarations.find(declaration => ts.isIdentifier(declaration.name) && declaration.name.text === 'allRouters'); + if (declaration) { + Object.assign(declaration, { + initializer: makeWebAllRouters(namespaceDir, (0, path_1.join)(appDir, '../../../..'), (0, path_1.dirname)(routerFileName)) + }); + } + } + }); + const printer = ts.createPrinter({ newLine: ts.NewLineKind.LineFeed, removeComments: false }); + const result = printer.printNode(ts.EmitHint.Unspecified, routerFile, routerFile); + (0, fs_extra_1.writeFileSync)(routerFileName, result); + } + } + else { + console.warn(`${appDir}的目录结构未按照标准建立,缺少了${routerFileName}`); + } +} +function outputInWebDir(dir) { + const srcAppDir = (0, path_1.join)(dir, 'src', 'app'); + const apps = (0, fs_extra_1.readdirSync)(srcAppDir); + apps.forEach((app) => { + const appDir = (0, path_1.join)(srcAppDir, app); + const stat = (0, fs_extra_1.statSync)(appDir); + if (stat.isDirectory()) { + outputInWebAppDir(appDir); + } + }); +} +function watchDir(projectDir, startupDir, type) { + const srcPageDir = (0, path_1.join)(projectDir, 'src', 'pages'); + console.log('watch dir ', srcPageDir); + if (startupDir.startsWith('web')) { + const srcAppDir = (0, path_1.join)(projectDir, startupDir, 'src', 'app'); + const apps = (0, fs_extra_1.readdirSync)(srcAppDir); + const tryOutputAppDir = (ns) => { + apps.forEach((app) => { + const appDir = (0, path_1.join)(srcAppDir, app); + const namespaceDir = (0, path_1.join)(appDir, 'namespaces'); + const namespaces = (0, fs_extra_1.readdirSync)(namespaceDir); + if (namespaces.includes(ns)) { + outputInWebAppDir(appDir); + } + }); + }; + (0, node_watch_1.default)(srcPageDir, { + recursive: true, + filter: new RegExp('web\.tsx|web\.pc\.tsx|index\.xml|render\.(native|ios|android)\.tsx'), + }, (evt, filepath) => { + const dir = (0, path_1.dirname)(filepath); + const relativeDir = (0, path_1.relative)((0, path_1.join)(projectDir, 'src', 'pages'), filepath); + const ns = relativeDir.split('\\')[0]; + const relativePath = (0, path_1.relative)(ns, (0, path_1.dirname)(relativeDir)); + const { pages } = NameSpaceDescDict[ns]; + console.log(filepath, dir, ns); + if (evt === 'remove') { + if ((0, fs_extra_1.existsSync)(dir)) { + const { changed } = checkPageDir(dir, relativePath, ns, type); + if (changed) { + tryOutputAppDir(ns); + } + } + else { + delete pages[dir]; + tryOutputAppDir(ns); + } + } + else { + const { changed } = checkPageDir(dir, relativePath, ns, type); + if (changed) { + tryOutputAppDir(ns); + } + } + }); + } +} +function buildRouter(projectDir, startupDir, watch) { + const type = startupDir.startsWith('web') ? 'web' : (startupDir.startsWith('native') ? 'native' : 'wechatMp'); + traversePageDir(projectDir, type); + const subDir = (0, fs_extra_1.readdirSync)(projectDir); + (0, assert_1.default)(subDir.includes(startupDir)); + if (startupDir.startsWith('web')) { + outputInWebDir((0, path_1.join)(projectDir, startupDir)); + } + // todo native + if (watch) { + watchDir(projectDir, startupDir, type); + } +} +exports.buildRouter = buildRouter; diff --git a/lib/store/TriggerExecutor.js b/lib/store/TriggerExecutor.js index 684d1e4..2b7bdcd 100644 --- a/lib/store/TriggerExecutor.js +++ b/lib/store/TriggerExecutor.js @@ -452,7 +452,7 @@ class TriggerExecutor { const rs = grouped[uuid]; const { [Entity_1.TriggerDataAttribute]: triggerData } = rs[0]; const { name, cxtStr, option } = triggerData; - await context.initialize(JSON.parse(cxtStr)); + // await context.initialize(JSON.parse(cxtStr)); // 这里token有可能过期(用户注销),先用root态模拟吧 await this.execVolatileTrigger(entity, name, rs.map(ele => ele.id), context, option); } await context.commit(); diff --git a/package.json b/package.json index e99a1b9..829b147 100644 --- a/package.json +++ b/package.json @@ -37,6 +37,7 @@ "fs-extra": "^10.0.0", "lodash": "^4.17.21", "mocha": "^8.2.1", + "node-watch": "^0.7.4", "ts-node": "^10.9.1", "tslib": "^2.4.0", "typescript": "^5.2.2" diff --git a/src/compiler/routerBuilder.ts b/src/compiler/routerBuilder.ts index 4bd1999..bc1652c 100644 --- a/src/compiler/routerBuilder.ts +++ b/src/compiler/routerBuilder.ts @@ -1,7 +1,8 @@ -import { join } from 'path'; -import { readdirSync, statSync, existsSync } from 'fs-extra'; +import { join, relative, dirname } from 'path'; +import { readdirSync, statSync, existsSync, writeFileSync } from 'fs-extra'; import assert from 'assert'; import * as ts from 'typescript'; +import NodeWatch from 'node-watch'; const { factory } = ts; /** @@ -54,61 +55,86 @@ type NamespaceDesc = { const NameSpaceDescDict: Record = {}; -function traverseNsDir(nsDir: string, ns: string) { +function checkPageDir(dir: string, relativePath: string, ns: string, type: 'native' | 'web' | 'wechatMp') { + let changed = false; + const { pages } = NameSpaceDescDict[ns]; + const subdirs: string[] = []; + const files = readdirSync(dir); + files.forEach((file) => { + const filepath = join(dir, file); + const stat = statSync(filepath); + if (stat.isFile() && + ['web.tsx', 'web.pc.tsx', 'render.native.tsx', 'render.ios.tsx', 'render.android.tsx', 'index.xml'].includes( + file + )) { + if (!pages.hasOwnProperty(dir)) { + const indexJsonFile = join(dir, 'index.json'); + let oakDisablePulldownRefresh = false; + if (existsSync(indexJsonFile)) { + const { + enablePullDownRefresh = true, + } = require(indexJsonFile); + oakDisablePulldownRefresh = + !enablePullDownRefresh; + } + pages[dir] = { + path: relativePath.replace(/\\/g, '/'), + oakDisablePulldownRefresh, + hasNative: ['render.native.tsx', 'render.ios.tsx', 'render.android.tsx'].includes(file), + hasWeb: ['web.tsx', 'web.pc.tsx'].includes(file), + hasWechatMp: file === 'index.xml', + }; + changed = true; + } + else { + if (['render.native.tsx', 'render.ios.tsx', 'render.android.tsx'].includes(file) && type === 'native') { + if (pages[dir].hasNative === false) { + pages[dir].hasNative = true; + changed = true; + } + } + else if (['web.tsx', 'web.pc.tsx'].includes(file) && type === 'web') { + if (pages[dir].hasWeb === false) { + pages[dir].hasWeb = true; + changed = true; + } + } + else { + if (pages[dir].hasWechatMp === false && type === 'wechatMp') { + pages[dir].hasWechatMp = true; + } + } + } + } else if (stat.isDirectory()) { + subdirs.push(file); + } + }); + return { + subdirs, + changed, + }; +} + +function traverseNsDir(nsDir: string, ns: string, type: 'native' | 'web' | 'wechatMp') { NameSpaceDescDict[ns] = { pages: {} }; const { pages } = NameSpaceDescDict[ns]; const traverse = (dir: string, relativePath: string) => { - const files = readdirSync(dir); - files.forEach((file) => { - const filepath = join(dir, file); - const stat = statSync(filepath); - if (stat.isFile() && - ['web.tsx', 'web.pc.tsx', 'render.native.tsx', 'render.ios.tsx', 'render.android.tsx', 'index.xml'].includes( - file - )) { - if (!pages.hasOwnProperty(dir)) { - const indexJsonFile = join(dir, 'index.json'); - let oakDisablePulldownRefresh = false; - if (existsSync(indexJsonFile)) { - const { - enablePullDownRefresh = true, - } = require(indexJsonFile); - oakDisablePulldownRefresh = - !enablePullDownRefresh; - } - pages[dir] = { - path: relativePath.replace(/\\/g, '/'), - oakDisablePulldownRefresh, - hasNative: ['render.native.tsx', 'render.ios.tsx', 'render.android.tsx'].includes(file), - hasWeb: ['web.tsx', 'web.pc.tsx'].includes(file), - hasWechatMp: file === 'index.xml', - }; - } - else { - if (['render.native.tsx', 'render.ios.tsx', 'render.android.tsx'].includes(file)) { - pages[dir].hasNative = true; - } - else if (['web.tsx', 'web.pc.tsx'].includes(file)) { - pages[dir].hasWeb = true; - } - else { - pages[dir].hasWechatMp = true; - } - } - } else if (stat.isDirectory()) { - const dir2 = join(dir, file); - const relativePath2 = join(relativePath, file); + const { subdirs } = checkPageDir(dir, relativePath, ns, type); + subdirs.forEach( + (subdir) => { + const dir2 = join(dir, subdir); + const relativePath2 = join(relativePath, subdir); traverse(dir2, relativePath2); } - }); + ); }; traverse(nsDir, ''); } -function traversePageDir(projectDir: string) { +function traversePageDir(projectDir: string, type: 'native' | 'web' | 'wechatMp') { const pageDir = join(projectDir, 'src', 'pages'); const namespaces = readdirSync(pageDir); @@ -117,15 +143,239 @@ function traversePageDir(projectDir: string) { const nsDir = join(pageDir, ns); const stat = statSync(nsDir); if (stat.isDirectory()) { - traverseNsDir(nsDir, ns); + traverseNsDir(nsDir, ns, type); } } ); } +function makeWebAllRouters(namespaceDir: string, projectDir: string, routerFileDir: string) { + const nss = readdirSync(namespaceDir); -function outputInWebDir(dir: string, ns?: string) { - const srcAppDir = join (dir, 'src', 'app'); + return factory.createArrayLiteralExpression( + nss.map( + (ns) => { + assert(NameSpaceDescDict[ns], `${ns}在pages下没有对应的目录`); + const { pages } = NameSpaceDescDict[ns]; + const nsIndexJsonFile = join(namespaceDir, ns, 'index.json'); + let path2 = `/${ns}`; + let notFound2 = '', first2 = ''; + if (existsSync(nsIndexJsonFile)) { + const { path, notFound, first } = require(nsIndexJsonFile); + path2 = path.replace(/\\/g, '/'); + notFound2 = notFound.replace(/\\/g, '/'); + first2 = first.replace(/\\/g, '/'); + } + const children = Object.values(pages).filter( + (ele) => ele.hasWeb + ).map( + ({ path, oakDisablePulldownRefresh }) => { + const properties = [ + factory.createPropertyAssignment( + 'path', + factory.createStringLiteral(path) + ), + factory.createPropertyAssignment( + 'namespace', + factory.createStringLiteral(path2) + ), + factory.createPropertyAssignment( + 'meta', + factory.createObjectLiteralExpression( + [ + factory.createPropertyAssignment( + 'oakDisablePulldownRefresh', + oakDisablePulldownRefresh ? factory.createTrue() : factory.createFalse() + ) + ] + ) + ), + factory.createPropertyAssignment( + factory.createIdentifier("Component"), + factory.createCallExpression( + factory.createPropertyAccessExpression( + factory.createIdentifier("React"), + factory.createIdentifier("lazy") + ), + undefined, + [factory.createArrowFunction( + undefined, + undefined, + [], + undefined, + factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken), + factory.createCallExpression( + factory.createIdentifier('import'), + undefined, + [ + factory.createStringLiteral( + relative(routerFileDir, join(projectDir, 'src', 'pages', ns, path)).replace(/\\/g, '/') + ) + ] + ) + )] + ) + ) + ]; + if (first2 === path) { + properties.push( + factory.createPropertyAssignment( + 'isFirst', + factory.createTrue() + ) + ) + } + return factory.createObjectLiteralExpression( + properties, + true, + ); + } + ); + + if (notFound2) { + children.push( + factory.createObjectLiteralExpression( + [ + factory.createPropertyAssignment( + 'path', + factory.createStringLiteral('*') + ), + factory.createPropertyAssignment( + 'namespace', + factory.createStringLiteral(path2) + ), + factory.createPropertyAssignment( + factory.createIdentifier("Component"), + factory.createCallExpression( + factory.createPropertyAccessExpression( + factory.createIdentifier("React"), + factory.createIdentifier("lazy") + ), + undefined, + [factory.createArrowFunction( + undefined, + undefined, + [], + undefined, + factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken), + factory.createCallExpression( + factory.createIdentifier('import'), + undefined, + [ + factory.createStringLiteral( + relative(routerFileDir, join(projectDir, 'src', 'pages', ns, notFound2)).replace(/\\/g, '/') + ) + ] + ) + )] + ) + ) + ], + true + ) + ) + } + + return factory.createObjectLiteralExpression( + [ + factory.createPropertyAssignment( + 'path', + factory.createStringLiteral(path2) + ), + factory.createPropertyAssignment( + 'namespace', + factory.createStringLiteral(path2) + ), + factory.createPropertyAssignment( + factory.createIdentifier("Component"), + factory.createCallExpression( + factory.createPropertyAccessExpression( + factory.createIdentifier("React"), + factory.createIdentifier("lazy") + ), + undefined, + [factory.createArrowFunction( + undefined, + undefined, + [], + undefined, + factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken), + factory.createCallExpression( + factory.createIdentifier('import'), + undefined, + [ + factory.createStringLiteral( + relative(routerFileDir, join(namespaceDir, ns)).replace(/\\/g, '/') + ) + ] + ) + )] + ) + ), + factory.createPropertyAssignment( + 'children', + factory.createArrayLiteralExpression( + children + ) + ) + ], + true + ) + } + ), + true + ); +} + +function judgeUseOakRouterBuilder(statements: ts.NodeArray) { + const stmt = statements[0]; + return ts.isExpressionStatement(stmt) && ts.isStringLiteral(stmt.expression) && stmt.expression.text === 'use oak router builder'; +} + +function outputInWebAppDir(appDir: string) { + const routerFileName = join(appDir, 'router', 'allRouters.ts'); + if (existsSync(routerFileName)) { + const program = ts.createProgram([routerFileName], { + removeComments: false, + }); + const routerFile = program.getSourceFile(routerFileName); + assert(routerFile); + const namespaceDir = join(appDir, 'namespaces'); + const { statements } = routerFile; + if (judgeUseOakRouterBuilder(statements)) { + statements.forEach( + (statement) => { + if (ts.isVariableStatement(statement)) { + const declaration = statement.declarationList.declarations.find( + declaration => ts.isIdentifier(declaration.name) && declaration.name.text === 'allRouters' + ); + if (declaration) { + Object.assign(declaration, { + initializer: makeWebAllRouters(namespaceDir, join(appDir, '../../../..'), dirname(routerFileName)) + }); + } + } + } + ); + + + const printer = ts.createPrinter({ newLine: ts.NewLineKind.LineFeed, removeComments: false }); + const result = printer.printNode( + ts.EmitHint.Unspecified, + routerFile, + routerFile, + ); + + writeFileSync(routerFileName, result); + } + } + else { + console.warn(`${appDir}的目录结构未按照标准建立,缺少了${routerFileName}`); + } +} + +function outputInWebDir(dir: string) { + const srcAppDir = join(dir, 'src', 'app'); const apps = readdirSync(srcAppDir); apps.forEach( (app) => { @@ -133,54 +383,78 @@ function outputInWebDir(dir: string, ns?: string) { const stat = statSync(appDir); if (stat.isDirectory()) { - const routerFileName = join(appDir, 'router', 'index.ts'); - const namespaceDir = join(appDir, 'namespaces'); - const program = ts.createProgram([routerFileName], {}); - const routerFile = program.getSourceFile(routerFileName); - assert(routerFile); - if (routerFile.text.includes('using-oak-router-builder')) { - routerFile.statements.forEach( - (statement) => { - if (ts.isVariableStatement(statement)) { - statement.declarationList.declarations.forEach( - (declaration) => { - if (ts.isIdentifier(declaration.name) && declaration.name.text === 'allRouters') { - const { initializer } = declaration; - - console.log(initializer); - } - } - ) - } - } - ); - } - - - const nss = readdirSync(namespaceDir); - - if (ns) { - assert(nss.includes(ns)); - } + outputInWebAppDir(appDir); } } ) } -export function buildRouter(projectDir: string) { - traversePageDir(projectDir); +function watchDir(projectDir: string, startupDir: string, type: 'native' | 'web' | 'wechatMp') { + const srcPageDir = join(projectDir, 'src', 'pages'); + console.log('watch dir ', srcPageDir); - const subDir = readdirSync(projectDir); - - subDir.forEach( - (dirname) => { - if (dirname.startsWith('web')) { - const webPrjDir = join(projectDir, dirname); - const stat = statSync(webPrjDir); - if (stat.isDirectory()) { - outputInWebDir(webPrjDir); + if (startupDir.startsWith('web')) { + const srcAppDir = join(projectDir, startupDir, 'src', 'app'); + const apps = readdirSync(srcAppDir); + const tryOutputAppDir = (ns: string) => { + apps.forEach( + (app) => { + const appDir = join(srcAppDir, app); + const namespaceDir = join(appDir, 'namespaces'); + const namespaces = readdirSync(namespaceDir); + if (namespaces.includes(ns)) { + outputInWebAppDir(appDir); + } + } + ); + } + + NodeWatch(srcPageDir, { + recursive: true, + filter: new RegExp('web\.tsx|web\.pc\.tsx|index\.xml|render\.(native|ios|android)\.tsx'), + }, (evt, filepath) => { + const dir = dirname(filepath); + const relativeDir = relative(join(projectDir, 'src', 'pages'), filepath); + const ns = relativeDir.split('\\')[0]; + const relativePath = relative(ns, dirname(relativeDir)); + const { pages } = NameSpaceDescDict[ns]; + console.log(filepath, dir, ns); + if (evt === 'remove') { + if (existsSync(dir)) { + const { changed } = checkPageDir(dir, relativePath, ns, type); + if (changed) { + tryOutputAppDir(ns); + } + } + else { + delete pages[dir]; + tryOutputAppDir(ns); } } - } - ) + else { + const { changed } = checkPageDir(dir, relativePath, ns, type); + if (changed) { + tryOutputAppDir(ns); + } + } + }); + } +} + +export function buildRouter(projectDir: string, startupDir: string, watch?: boolean) { + const type = startupDir.startsWith('web') ? 'web' : (startupDir.startsWith('native') ? 'native' : 'wechatMp'); + traversePageDir(projectDir, type); + + const subDir = readdirSync(projectDir); + assert(subDir.includes(startupDir)); + + if (startupDir.startsWith('web')) { + outputInWebDir(join(projectDir, startupDir)); + } + + // todo native + + if (watch) { + watchDir(projectDir, startupDir, type); + } } \ No newline at end of file diff --git a/test/test.ts b/test/test.ts index 1a6c22a..bfba4b0 100644 --- a/test/test.ts +++ b/test/test.ts @@ -9,4 +9,4 @@ while (iter > 0) { import { join } from 'path'; import { buildRouter } from '../src/compiler/routerBuilder'; -buildRouter(join(process.cwd(), '..', 'taicang')); \ No newline at end of file +buildRouter(join(process.cwd(), '..', 'taicang'), 'web', true); \ No newline at end of file From 4e11d40e3cbf0d2ca1369c09b902fc1ed3e7c391 Mon Sep 17 00:00:00 2001 From: wkj <278599135@.com> Date: Sun, 24 Dec 2023 18:08:09 +0800 Subject: [PATCH 5/6] =?UTF-8?q?=E7=BC=96=E8=AF=91routerr=E6=97=B6=EF=BC=8C?= =?UTF-8?q?namespaces=E4=B8=8B=E7=9A=84index.json=E7=9A=84path=E4=B8=8D?= =?UTF-8?q?=E4=B8=80=E5=AE=9A=E9=85=8D=E7=BD=AE=EF=BC=8C=E8=BF=99=E9=87=8C?= =?UTF-8?q?=E5=88=A4=E6=96=AD=E4=B8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/compiler/routerBuilder.js | 12 +++++++++--- lib/utils/SimpleConnector.js | 2 +- src/compiler/routerBuilder.ts | 12 +++++++++--- src/utils/SimpleConnector.ts | 2 +- 4 files changed, 20 insertions(+), 8 deletions(-) diff --git a/lib/compiler/routerBuilder.js b/lib/compiler/routerBuilder.js index 0c661ca..3bd615b 100644 --- a/lib/compiler/routerBuilder.js +++ b/lib/compiler/routerBuilder.js @@ -101,9 +101,15 @@ function makeWebAllRouters(namespaceDir, projectDir, routerFileDir) { let notFound2 = '', first2 = ''; if ((0, fs_extra_1.existsSync)(nsIndexJsonFile)) { const { path, notFound, first } = require(nsIndexJsonFile); - path2 = path.replace(/\\/g, '/'); - notFound2 = notFound.replace(/\\/g, '/'); - first2 = first.replace(/\\/g, '/'); + if (path) { + path2 = path.replace(/\\/g, '/'); + } + if (notFound) { + notFound2 = notFound.replace(/\\/g, '/'); + } + if (first) { + first2 = first.replace(/\\/g, '/'); + } } const children = Object.values(pages).filter((ele) => ele.hasWeb).map(({ path, oakDisablePulldownRefresh }) => { const properties = [ diff --git a/lib/utils/SimpleConnector.js b/lib/utils/SimpleConnector.js index 72affb7..85cc4d7 100644 --- a/lib/utils/SimpleConnector.js +++ b/lib/utils/SimpleConnector.js @@ -65,7 +65,7 @@ class SimpleConnector { } catch (err) { // fetch返回异常一定是网络异常 - throw new types_1.OakNetworkException(); + throw new types_1.OakNetworkException(`请求[${this.serverAspectUrl}],发生网络异常`); } if (response.status > 299) { const err = new types_1.OakServerProxyException(`网络请求返回status是${response.status}`); diff --git a/src/compiler/routerBuilder.ts b/src/compiler/routerBuilder.ts index bc1652c..db11403 100644 --- a/src/compiler/routerBuilder.ts +++ b/src/compiler/routerBuilder.ts @@ -162,9 +162,15 @@ function makeWebAllRouters(namespaceDir: string, projectDir: string, routerFileD let notFound2 = '', first2 = ''; if (existsSync(nsIndexJsonFile)) { const { path, notFound, first } = require(nsIndexJsonFile); - path2 = path.replace(/\\/g, '/'); - notFound2 = notFound.replace(/\\/g, '/'); - first2 = first.replace(/\\/g, '/'); + if (path) { + path2 = path.replace(/\\/g, '/'); + } + if (notFound) { + notFound2 = notFound.replace(/\\/g, '/'); + } + if (first) { + first2 = first.replace(/\\/g, '/'); + } } const children = Object.values(pages).filter( (ele) => ele.hasWeb diff --git a/src/utils/SimpleConnector.ts b/src/utils/SimpleConnector.ts index 8a49198..8151fd0 100644 --- a/src/utils/SimpleConnector.ts +++ b/src/utils/SimpleConnector.ts @@ -83,7 +83,7 @@ export class SimpleConnector 299) { const err = new OakServerProxyException( From ede0f5e4ff11a186bca09f26a3788211206e1c1b Mon Sep 17 00:00:00 2001 From: Xc Date: Mon, 25 Dec 2023 15:34:58 +0800 Subject: [PATCH 6/6] =?UTF-8?q?routerBuilder=E4=B8=AD=E7=9A=84=E5=B0=8F?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/compiler/routerBuilder.js | 3 +++ src/compiler/routerBuilder.ts | 3 +++ 2 files changed, 6 insertions(+) diff --git a/lib/compiler/routerBuilder.js b/lib/compiler/routerBuilder.js index 0c661ca..780c10a 100644 --- a/lib/compiler/routerBuilder.js +++ b/lib/compiler/routerBuilder.js @@ -104,6 +104,9 @@ function makeWebAllRouters(namespaceDir, projectDir, routerFileDir) { path2 = path.replace(/\\/g, '/'); notFound2 = notFound.replace(/\\/g, '/'); first2 = first.replace(/\\/g, '/'); + if (first2.startsWith('/')) { + first2 = first2.slice(1); + } } const children = Object.values(pages).filter((ele) => ele.hasWeb).map(({ path, oakDisablePulldownRefresh }) => { const properties = [ diff --git a/src/compiler/routerBuilder.ts b/src/compiler/routerBuilder.ts index bc1652c..c6f61f6 100644 --- a/src/compiler/routerBuilder.ts +++ b/src/compiler/routerBuilder.ts @@ -165,6 +165,9 @@ function makeWebAllRouters(namespaceDir: string, projectDir: string, routerFileD path2 = path.replace(/\\/g, '/'); notFound2 = notFound.replace(/\\/g, '/'); first2 = first.replace(/\\/g, '/'); + if (first2.startsWith('/')) { + first2 = first2.slice(1); + } } const children = Object.values(pages).filter( (ele) => ele.hasWeb