@akanjs/cli 0.9.60-canary.0 → 0.9.60-canary.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cjs/index.js +126 -110
- package/cjs/src/guidelines/scalarConstant/scalarConstant.generate.json +24 -20
- package/cjs/src/guidelines/scalarConstant/scalarConstant.instruction.md +284 -326
- package/cjs/src/guidelines/scalarDictionary/scalarDictionary.generate.json +32 -32
- package/cjs/src/guidelines/scalarDictionary/scalarDictionary.instruction.md +175 -249
- package/cjs/src/templates/__scalar/__model__/__model__.dictionary.js +6 -13
- package/cjs/src/templates/app/akan.config.js +2 -4
- package/cjs/src/templates/env/{env.server.type.js → _env.server.type.js} +6 -3
- package/cjs/src/templates/lib/__lib/lib.constant.js +1 -1
- package/cjs/src/templates/lib/__lib/lib.dictionary.js +1 -1
- package/cjs/src/templates/libRoot/akan.config.js +1 -3
- package/cjs/src/templates/module/__Model__.Unit.js +1 -1
- package/cjs/src/templates/module/__Model__.View.js +2 -3
- package/cjs/src/templates/module/__model__.constant.js +0 -1
- package/cjs/src/templates/module/__model__.dictionary.js +0 -1
- package/cjs/src/templates/workspaceRoot/package.json.template +5 -5
- package/esm/index.js +126 -110
- package/esm/src/guidelines/scalarConstant/scalarConstant.generate.json +24 -20
- package/esm/src/guidelines/scalarConstant/scalarConstant.instruction.md +284 -326
- package/esm/src/guidelines/scalarDictionary/scalarDictionary.generate.json +32 -32
- package/esm/src/guidelines/scalarDictionary/scalarDictionary.instruction.md +175 -249
- package/esm/src/templates/__scalar/__model__/__model__.dictionary.js +6 -13
- package/esm/src/templates/app/akan.config.js +2 -4
- package/esm/src/templates/env/{env.server.type.js → _env.server.type.js} +6 -3
- package/esm/src/templates/lib/__lib/lib.constant.js +1 -1
- package/esm/src/templates/lib/__lib/lib.dictionary.js +1 -1
- package/esm/src/templates/libRoot/akan.config.js +1 -3
- package/esm/src/templates/module/__Model__.Unit.js +1 -1
- package/esm/src/templates/module/__Model__.View.js +2 -3
- package/esm/src/templates/module/__model__.constant.js +0 -1
- package/esm/src/templates/module/__model__.dictionary.js +0 -1
- package/esm/src/templates/workspaceRoot/package.json.template +5 -5
- package/package.json +5 -4
- package/src/guidelines/scalarConstant/scalarConstant.instruction.md +284 -326
- package/src/guidelines/scalarDictionary/scalarDictionary.instruction.md +175 -249
- package/src/library/library.command.d.ts +0 -2
- package/src/library/library.runner.d.ts +0 -2
- package/src/library/library.script.d.ts +0 -2
- package/src/module/module.runner.d.ts +0 -4
- package/src/scalar/scalar.command.d.ts +2 -2
- package/src/scalar/scalar.runner.d.ts +1 -0
- package/src/scalar/scalar.script.d.ts +1 -0
- package/src/templates/app/akan.config.d.ts +1 -3
- package/src/templates/env/{env.server.type.d.ts → _env.server.type.d.ts} +4 -1
- package/src/workspace/workspace.command.d.ts +1 -1
- package/src/workspace/workspace.runner.d.ts +4 -1
- package/src/workspace/workspace.script.d.ts +5 -1
- package/cjs/src/guidelines/fieldDecorator/fieldDecorator.generate.json +0 -135
- package/cjs/src/guidelines/fieldDecorator/fieldDecorator.instruction.md +0 -606
- package/cjs/src/templates/module/__model__.signal.spec.js +0 -27
- package/cjs/src/templates/module/__model__.signal.test.js +0 -27
- package/esm/src/guidelines/fieldDecorator/fieldDecorator.generate.json +0 -135
- package/esm/src/guidelines/fieldDecorator/fieldDecorator.instruction.md +0 -606
- package/esm/src/templates/module/__model__.signal.spec.js +0 -7
- package/esm/src/templates/module/__model__.signal.test.js +0 -7
- package/src/guidelines/fieldDecorator/fieldDecorator.instruction.md +0 -606
- package/src/templates/module/__model__.signal.spec.d.ts +0 -8
- package/src/templates/module/__model__.signal.test.d.ts +0 -8
package/cjs/index.js
CHANGED
|
@@ -593,7 +593,7 @@ var composePlugins = (...plugins) => {
|
|
|
593
593
|
};
|
|
594
594
|
var commandType = process.env.AKAN_COMMAND_TYPE?.includes("start") ? "start" : process.env.AKAN_COMMAND_TYPE?.includes("build") ? "build" : "deploy";
|
|
595
595
|
var devDomain = process.env.NEXT_PUBLIC_SERVE_DOMAIN ?? "akanjs.com";
|
|
596
|
-
var withBase = (appName, config,
|
|
596
|
+
var withBase = (appName, config, optimizeLibs, routes = []) => {
|
|
597
597
|
const withPWA = (0, import_next_pwa.default)({
|
|
598
598
|
dest: "public",
|
|
599
599
|
register: true,
|
|
@@ -617,8 +617,7 @@ var withBase = (appName, config, libs, routes = []) => {
|
|
|
617
617
|
experimental: {
|
|
618
618
|
...config.experimental ?? {},
|
|
619
619
|
optimizePackageImports: [
|
|
620
|
-
...[appName, ...
|
|
621
|
-
"@contract",
|
|
620
|
+
...[appName, ...optimizeLibs].map((lib) => [`@${lib}/ui`, `@${lib}/next`, `@${lib}/common`, `@${lib}/client`]).flat(),
|
|
622
621
|
"@akanjs/next",
|
|
623
622
|
"@akanjs/common",
|
|
624
623
|
"@akanjs/ui"
|
|
@@ -639,7 +638,7 @@ var withBase = (appName, config, libs, routes = []) => {
|
|
|
639
638
|
},
|
|
640
639
|
webpack: (config2) => {
|
|
641
640
|
const watchOptions = config2.watchOptions;
|
|
642
|
-
const ignored = watchOptions?.ignored ? typeof watchOptions.ignored === "string" ? [watchOptions.ignored] : Array.isArray(watchOptions.ignored) ? watchOptions.ignored.filter((
|
|
641
|
+
const ignored = watchOptions?.ignored ? typeof watchOptions.ignored === "string" ? [watchOptions.ignored] : Array.isArray(watchOptions.ignored) ? watchOptions.ignored.filter((ignore2) => typeof ignore2 === "string") : [] : [];
|
|
643
642
|
config2.watchOptions = {
|
|
644
643
|
...config2.watchOptions ?? {},
|
|
645
644
|
...{ ignored: [...ignored, "**/node_modules/**", "**/.git/**", "**/.next/**", "**/dist/**", "**/local/**"] }
|
|
@@ -708,10 +707,9 @@ var archs = ["amd64", "arm64"];
|
|
|
708
707
|
|
|
709
708
|
// pkgs/@akanjs/config/src/akanConfig.ts
|
|
710
709
|
var import_meta = {};
|
|
711
|
-
var makeAppConfig = (config, props) => {
|
|
710
|
+
var makeAppConfig = (config, props, optimizeLibs) => {
|
|
712
711
|
const { name, repoName } = props;
|
|
713
712
|
return {
|
|
714
|
-
libs: config.libs ?? [],
|
|
715
713
|
backend: {
|
|
716
714
|
docker: makeDockerfile("backend", config.backend?.docker ?? {}, props),
|
|
717
715
|
explicitDependencies: config.backend?.explicitDependencies ?? []
|
|
@@ -721,7 +719,7 @@ var makeAppConfig = (config, props) => {
|
|
|
721
719
|
nextConfig: withBase(
|
|
722
720
|
name,
|
|
723
721
|
config.frontend?.nextConfig ? typeof config.frontend.nextConfig === "function" ? config.frontend.nextConfig() : config.frontend.nextConfig : {},
|
|
724
|
-
|
|
722
|
+
optimizeLibs,
|
|
725
723
|
config.frontend?.routes
|
|
726
724
|
),
|
|
727
725
|
routes: config.frontend?.routes,
|
|
@@ -737,7 +735,7 @@ var makeAppConfig = (config, props) => {
|
|
|
737
735
|
}
|
|
738
736
|
};
|
|
739
737
|
};
|
|
740
|
-
var getAppConfig = async (appRoot, props) => {
|
|
738
|
+
var getAppConfig = async (appRoot, props, tsconfig) => {
|
|
741
739
|
const akanConfigPath = import_path.default.join(appRoot, "akan.config.ts");
|
|
742
740
|
if (!import_fs3.default.existsSync(akanConfigPath))
|
|
743
741
|
throw new Error(`application akan.config.ts is not found ${appRoot}`);
|
|
@@ -748,11 +746,13 @@ var getAppConfig = async (appRoot, props) => {
|
|
|
748
746
|
});
|
|
749
747
|
const configImp = (await jiti.import(akanConfigPath)).default;
|
|
750
748
|
const config = typeof configImp === "function" ? configImp(props) : configImp;
|
|
751
|
-
|
|
749
|
+
const optimizeLibs = Object.entries(tsconfig.compilerOptions.paths ?? {}).filter(
|
|
750
|
+
([key, resolves]) => key.startsWith("@") && resolves.at(0)?.startsWith("libs/") && resolves.at(0)?.endsWith("/index.ts")
|
|
751
|
+
).map(([key]) => key.slice(1));
|
|
752
|
+
return makeAppConfig(config, props, optimizeLibs);
|
|
752
753
|
};
|
|
753
754
|
var makeLibConfig = (config, props) => {
|
|
754
755
|
return {
|
|
755
|
-
libs: config.libs ?? [],
|
|
756
756
|
backend: {
|
|
757
757
|
explicitDependencies: config.backend?.explicitDependencies ?? []
|
|
758
758
|
},
|
|
@@ -856,8 +856,8 @@ CMD [${command.map((c) => `"${c}"`).join(",")}]`;
|
|
|
856
856
|
};
|
|
857
857
|
}
|
|
858
858
|
};
|
|
859
|
-
var increaseBuildNum = async (appRoot, props) => {
|
|
860
|
-
const appConfig = await getAppConfig(appRoot, props);
|
|
859
|
+
var increaseBuildNum = async (appRoot, props, tsconfig) => {
|
|
860
|
+
const appConfig = await getAppConfig(appRoot, props, tsconfig);
|
|
861
861
|
const akanConfigPath = import_path.default.join(appRoot, "akan.config.ts");
|
|
862
862
|
const akanConfig = import_fs3.default.readFileSync(akanConfigPath, "utf8");
|
|
863
863
|
const akanConfigContent = akanConfig.replace(
|
|
@@ -866,8 +866,8 @@ var increaseBuildNum = async (appRoot, props) => {
|
|
|
866
866
|
);
|
|
867
867
|
import_fs3.default.writeFileSync(akanConfigPath, akanConfigContent);
|
|
868
868
|
};
|
|
869
|
-
var decreaseBuildNum = async (appRoot, props) => {
|
|
870
|
-
const appConfig = await getAppConfig(appRoot, props);
|
|
869
|
+
var decreaseBuildNum = async (appRoot, props, tsconfig) => {
|
|
870
|
+
const appConfig = await getAppConfig(appRoot, props, tsconfig);
|
|
871
871
|
const akanConfigPath = import_path.default.join(appRoot, "akan.config.ts");
|
|
872
872
|
const akanConfig = import_fs3.default.readFileSync(akanConfigPath, "utf8");
|
|
873
873
|
const akanConfigContent = akanConfig.replace(
|
|
@@ -1097,6 +1097,7 @@ var import_path3 = __toESM(require("path"));
|
|
|
1097
1097
|
|
|
1098
1098
|
// pkgs/@akanjs/devkit/src/dependencyScanner.ts
|
|
1099
1099
|
var fs6 = __toESM(require("fs"));
|
|
1100
|
+
var import_ignore = __toESM(require("ignore"));
|
|
1100
1101
|
var path4 = __toESM(require("path"));
|
|
1101
1102
|
var ts2 = __toESM(require("typescript"));
|
|
1102
1103
|
var TypeScriptDependencyScanner = class {
|
|
@@ -1105,10 +1106,19 @@ var TypeScriptDependencyScanner = class {
|
|
|
1105
1106
|
directory;
|
|
1106
1107
|
tsconfig;
|
|
1107
1108
|
rootPackageJson;
|
|
1108
|
-
|
|
1109
|
+
ig;
|
|
1110
|
+
workspaceRoot;
|
|
1111
|
+
constructor(directory, {
|
|
1112
|
+
workspaceRoot,
|
|
1113
|
+
tsconfig,
|
|
1114
|
+
rootPackageJson,
|
|
1115
|
+
gitignorePatterns = []
|
|
1116
|
+
}) {
|
|
1109
1117
|
this.directory = directory;
|
|
1110
1118
|
this.tsconfig = tsconfig;
|
|
1111
1119
|
this.rootPackageJson = rootPackageJson;
|
|
1120
|
+
this.ig = (0, import_ignore.default)().add(gitignorePatterns);
|
|
1121
|
+
this.workspaceRoot = workspaceRoot;
|
|
1112
1122
|
}
|
|
1113
1123
|
async getMonorepoDependencies(projectName) {
|
|
1114
1124
|
const npmSet = new Set(
|
|
@@ -1170,6 +1180,9 @@ var TypeScriptDependencyScanner = class {
|
|
|
1170
1180
|
const entries = await fs6.promises.readdir(dir, { withFileTypes: true });
|
|
1171
1181
|
for (const entry of entries) {
|
|
1172
1182
|
const fullPath = path4.join(dir, entry.name);
|
|
1183
|
+
const relativePath = path4.relative(this.workspaceRoot, fullPath);
|
|
1184
|
+
if (this.ig.ignores(relativePath))
|
|
1185
|
+
continue;
|
|
1173
1186
|
if (entry.isDirectory()) {
|
|
1174
1187
|
if (!["node_modules", "dist", "build", ".git", ".next", "public", "ios", "android"].includes(entry.name))
|
|
1175
1188
|
await processDirectory(fullPath);
|
|
@@ -1298,7 +1311,13 @@ var ScanInfo = class {
|
|
|
1298
1311
|
const akanConfig = await exec2.getConfig();
|
|
1299
1312
|
const tsconfig = exec2.getTsConfig();
|
|
1300
1313
|
const rootPackageJson = exec2.workspace.getPackageJson();
|
|
1301
|
-
const
|
|
1314
|
+
const gitignorePatterns = exec2.workspace.getGitignorePatterns();
|
|
1315
|
+
const scanner = new TypeScriptDependencyScanner(exec2.cwdPath, {
|
|
1316
|
+
workspaceRoot: exec2.workspace.cwdPath,
|
|
1317
|
+
tsconfig,
|
|
1318
|
+
rootPackageJson,
|
|
1319
|
+
gitignorePatterns
|
|
1320
|
+
});
|
|
1302
1321
|
const { pkgDeps, libDeps, npmDeps } = await scanner.getMonorepoDependencies(exec2.name);
|
|
1303
1322
|
const files = {
|
|
1304
1323
|
constant: { databases: [], scalars: [] },
|
|
@@ -1402,15 +1421,6 @@ var ScanInfo = class {
|
|
|
1402
1421
|
});
|
|
1403
1422
|
})
|
|
1404
1423
|
]);
|
|
1405
|
-
const missingLibDeps = [];
|
|
1406
|
-
libDeps.forEach((libName) => {
|
|
1407
|
-
if (!akanConfig.libs.includes(libName))
|
|
1408
|
-
missingLibDeps.push(libName);
|
|
1409
|
-
});
|
|
1410
|
-
if (missingLibDeps.length)
|
|
1411
|
-
throw new Error(
|
|
1412
|
-
`Missing libs: ${missingLibDeps.join(", ")}, add these dependencies in akan.config.ts as { libs: [...other deps, ${missingLibDeps.join(", ")}] }`
|
|
1413
|
-
);
|
|
1414
1424
|
const scanResult = {
|
|
1415
1425
|
name: exec2.name,
|
|
1416
1426
|
type: exec2.type,
|
|
@@ -1500,7 +1510,7 @@ var AppInfo = class _AppInfo extends ScanInfo {
|
|
|
1500
1510
|
if (this.#sortedLibs)
|
|
1501
1511
|
return this.#sortedLibs;
|
|
1502
1512
|
const libIndices = LibInfo.getSortedLibIndices();
|
|
1503
|
-
this.#sortedLibs = this.
|
|
1513
|
+
this.#sortedLibs = this.getScanResult().libDeps.sort((libNameA, libNameB) => {
|
|
1504
1514
|
const indexA = libIndices.get(libNameA);
|
|
1505
1515
|
const indexB = libIndices.get(libNameB);
|
|
1506
1516
|
if (indexA === void 0 || indexB === void 0)
|
|
@@ -1540,7 +1550,7 @@ var LibInfo = class _LibInfo extends ScanInfo {
|
|
|
1540
1550
|
if (this.#sortedLibIndices)
|
|
1541
1551
|
return this.#sortedLibIndices;
|
|
1542
1552
|
this.#sortedLibIndices = new Map(
|
|
1543
|
-
[...this.libInfos.entries()].sort(([_, libInfoA], [__, libInfoB]) => libInfoA.
|
|
1553
|
+
[...this.libInfos.entries()].sort(([_, libInfoA], [__, libInfoB]) => libInfoA.getScanResult().libDeps.includes(libInfoB.name) ? 1 : -1).map(([libName], index) => [libName, index])
|
|
1544
1554
|
);
|
|
1545
1555
|
return this.#sortedLibIndices;
|
|
1546
1556
|
}
|
|
@@ -1574,7 +1584,7 @@ var LibInfo = class _LibInfo extends ScanInfo {
|
|
|
1574
1584
|
if (this.#sortedLibs)
|
|
1575
1585
|
return this.#sortedLibs;
|
|
1576
1586
|
const libs = _LibInfo.getSortedLibIndices();
|
|
1577
|
-
this.#sortedLibs = this.
|
|
1587
|
+
this.#sortedLibs = this.scanResult.libDeps.sort((libNameA, libNameB) => {
|
|
1578
1588
|
const indexA = libs.get(libNameA);
|
|
1579
1589
|
const indexB = libs.get(libNameB);
|
|
1580
1590
|
if (indexA === void 0 || indexB === void 0)
|
|
@@ -1587,7 +1597,7 @@ var LibInfo = class _LibInfo extends ScanInfo {
|
|
|
1587
1597
|
return this.#getSortedLibs();
|
|
1588
1598
|
}
|
|
1589
1599
|
getLibInfo(libName) {
|
|
1590
|
-
if (!this.getScanResult().
|
|
1600
|
+
if (!this.getScanResult().libDeps.includes(libName))
|
|
1591
1601
|
return void 0;
|
|
1592
1602
|
const libSet = new Set(this.#getSortedLibs());
|
|
1593
1603
|
if (!libSet.has(libName))
|
|
@@ -1612,7 +1622,13 @@ var PkgInfo = class _PkgInfo {
|
|
|
1612
1622
|
static async getScanResult(exec2) {
|
|
1613
1623
|
const tsconfig = exec2.getTsConfig();
|
|
1614
1624
|
const rootPackageJson = exec2.workspace.getPackageJson();
|
|
1615
|
-
const
|
|
1625
|
+
const gitignorePatterns = exec2.workspace.getGitignorePatterns();
|
|
1626
|
+
const scanner = new TypeScriptDependencyScanner(exec2.cwdPath, {
|
|
1627
|
+
workspaceRoot: exec2.workspace.cwdPath,
|
|
1628
|
+
tsconfig,
|
|
1629
|
+
rootPackageJson,
|
|
1630
|
+
gitignorePatterns
|
|
1631
|
+
});
|
|
1616
1632
|
const npmSet = new Set(Object.keys({ ...rootPackageJson.dependencies, ...rootPackageJson.devDependencies }));
|
|
1617
1633
|
const pkgPathSet = new Set(
|
|
1618
1634
|
Object.keys(tsconfig.compilerOptions.paths ?? {}).filter((path10) => tsconfig.compilerOptions.paths?.[path10]?.some((resolve) => resolve.startsWith("pkgs/"))).map((path10) => path10.replace("/*", ""))
|
|
@@ -1734,7 +1750,8 @@ ${errorMessages}`);
|
|
|
1734
1750
|
const diagnostics = [
|
|
1735
1751
|
...program2.getSemanticDiagnostics(),
|
|
1736
1752
|
...program2.getSyntacticDiagnostics(),
|
|
1737
|
-
|
|
1753
|
+
// Only check declaration diagnostics when declaration emit is enabled
|
|
1754
|
+
...this.config.options.declaration ? program2.getDeclarationDiagnostics() : []
|
|
1738
1755
|
];
|
|
1739
1756
|
const errors = diagnostics.filter((diagnostic) => diagnostic.category === ts3.DiagnosticCategory.Error);
|
|
1740
1757
|
const warnings = diagnostics.filter((diagnostic) => diagnostic.category === ts3.DiagnosticCategory.Warning);
|
|
@@ -2137,6 +2154,14 @@ var Executor = class _Executor {
|
|
|
2137
2154
|
this.writeJson("package.json", packageJson);
|
|
2138
2155
|
this.#packageJson = packageJson;
|
|
2139
2156
|
}
|
|
2157
|
+
#gitignorePatterns = [];
|
|
2158
|
+
getGitignorePatterns() {
|
|
2159
|
+
if (this.#gitignorePatterns.length)
|
|
2160
|
+
return this.#gitignorePatterns;
|
|
2161
|
+
const gitignore = this.readFile(".gitignore");
|
|
2162
|
+
this.#gitignorePatterns = gitignore.split("\n").map((line) => line.trim()).filter((line) => !!line && !line.startsWith("#"));
|
|
2163
|
+
return this.#gitignorePatterns;
|
|
2164
|
+
}
|
|
2140
2165
|
async #applyTemplateFile({
|
|
2141
2166
|
templatePath,
|
|
2142
2167
|
targetPath,
|
|
@@ -2432,7 +2457,12 @@ var SysExecutor = class extends Executor {
|
|
|
2432
2457
|
async getConfig({ refresh } = {}) {
|
|
2433
2458
|
if (this.#akanConfig && !refresh)
|
|
2434
2459
|
return this.#akanConfig;
|
|
2435
|
-
|
|
2460
|
+
const tsconfig = this.getTsConfig();
|
|
2461
|
+
this.#akanConfig = this.type === "app" ? await getAppConfig(
|
|
2462
|
+
this.cwdPath,
|
|
2463
|
+
{ ...this.workspace.getBaseDevEnv(), type: "app", name: this.name },
|
|
2464
|
+
tsconfig
|
|
2465
|
+
) : await getLibConfig(this.cwdPath, { ...this.workspace.getBaseDevEnv(), type: "lib", name: this.name });
|
|
2436
2466
|
return this.#akanConfig;
|
|
2437
2467
|
}
|
|
2438
2468
|
async getModules() {
|
|
@@ -2586,11 +2616,11 @@ var SysExecutor = class extends Executor {
|
|
|
2586
2616
|
return modules.map((module2) => this.getLocalFile(`lib/${module2}/${module2}.constant.ts`));
|
|
2587
2617
|
}
|
|
2588
2618
|
async getConstantFilesWithLibs() {
|
|
2589
|
-
const
|
|
2619
|
+
const scanInfo = this.type === "app" ? await AppInfo.fromExecutor(this) : await LibInfo.fromExecutor(this);
|
|
2590
2620
|
const sysContantFiles = await this.getConstantFiles();
|
|
2591
2621
|
const sysScalarConstantFiles = await this.getScalarConstantFiles();
|
|
2592
2622
|
const libConstantFiles = await Promise.all(
|
|
2593
|
-
|
|
2623
|
+
scanInfo.getLibs().map(async (lib) => [
|
|
2594
2624
|
...await LibExecutor.from(this, lib).getConstantFiles(),
|
|
2595
2625
|
...await LibExecutor.from(this, lib).getScalarConstantFiles()
|
|
2596
2626
|
])
|
|
@@ -2643,11 +2673,11 @@ var AppExecutor = class _AppExecutor extends SysExecutor {
|
|
|
2643
2673
|
async getConfig({ refresh } = {}) {
|
|
2644
2674
|
if (this.#akanConfig && !refresh)
|
|
2645
2675
|
return this.#akanConfig;
|
|
2646
|
-
this.#akanConfig = await getAppConfig(
|
|
2647
|
-
|
|
2648
|
-
type: "app",
|
|
2649
|
-
|
|
2650
|
-
|
|
2676
|
+
this.#akanConfig = await getAppConfig(
|
|
2677
|
+
this.cwdPath,
|
|
2678
|
+
{ ...this.workspace.getBaseDevEnv(), type: "app", name: this.name },
|
|
2679
|
+
this.getTsConfig()
|
|
2680
|
+
);
|
|
2651
2681
|
return this.#akanConfig;
|
|
2652
2682
|
}
|
|
2653
2683
|
async syncAssets(libDeps) {
|
|
@@ -2670,10 +2700,18 @@ var AppExecutor = class _AppExecutor extends SysExecutor {
|
|
|
2670
2700
|
]);
|
|
2671
2701
|
}
|
|
2672
2702
|
async increaseBuildNum() {
|
|
2673
|
-
await increaseBuildNum(
|
|
2703
|
+
await increaseBuildNum(
|
|
2704
|
+
this.cwdPath,
|
|
2705
|
+
{ ...this.workspace.getBaseDevEnv(), type: "app", name: this.name },
|
|
2706
|
+
this.getTsConfig()
|
|
2707
|
+
);
|
|
2674
2708
|
}
|
|
2675
2709
|
async decreaseBuildNum() {
|
|
2676
|
-
await decreaseBuildNum(
|
|
2710
|
+
await decreaseBuildNum(
|
|
2711
|
+
this.cwdPath,
|
|
2712
|
+
{ ...this.workspace.getBaseDevEnv(), type: "app", name: this.name },
|
|
2713
|
+
this.getTsConfig()
|
|
2714
|
+
);
|
|
2677
2715
|
}
|
|
2678
2716
|
};
|
|
2679
2717
|
var LibExecutor = class _LibExecutor extends SysExecutor {
|
|
@@ -4010,7 +4048,11 @@ var LibraryRunner = class {
|
|
|
4010
4048
|
lib.workspace.unsetTsPaths("lib", lib.name);
|
|
4011
4049
|
}
|
|
4012
4050
|
async installLibrary(workspace, libName) {
|
|
4013
|
-
|
|
4051
|
+
workspace.mkdir("node_modules/.akan");
|
|
4052
|
+
if (workspace.exists("node_modules/.akan/akanjs"))
|
|
4053
|
+
await workspace.removeDir("node_modules/.akan/akanjs");
|
|
4054
|
+
await workspace.exec(`cd node_modules/.akan && git clone git@github.com:akan-team/${libName}.git`);
|
|
4055
|
+
await workspace.cp(`node_modules/.akan/akanjs/libs/${libName}`, `libs/${libName}`);
|
|
4014
4056
|
await workspace.cp(`libs/${libName}/env/env.server.example.ts`, `libs/${libName}/env/env.server.testing.ts`);
|
|
4015
4057
|
workspace.setTsPaths("lib", libName);
|
|
4016
4058
|
await workspace.commit(`Add ${libName} library`);
|
|
@@ -4042,16 +4084,6 @@ var LibraryRunner = class {
|
|
|
4042
4084
|
await lib.workspace.spawn("pnpm", ["install", "--reporter=silent"]);
|
|
4043
4085
|
await lib.workspace.commit(`Merge ${lib.name} library dependencies`);
|
|
4044
4086
|
}
|
|
4045
|
-
async pushLibrary(lib, branch) {
|
|
4046
|
-
await lib.workspace.exec(
|
|
4047
|
-
`git subtree push --prefix=libs/${lib.name} git@github.com:akan-team/${lib.name}.git ${branch}`
|
|
4048
|
-
);
|
|
4049
|
-
}
|
|
4050
|
-
async pullLibrary(lib, branch) {
|
|
4051
|
-
await lib.workspace.exec(
|
|
4052
|
-
`git subtree pull --prefix=libs/${lib.name} git@github.com:akan-team/${lib.name}.git ${branch}`
|
|
4053
|
-
);
|
|
4054
|
-
}
|
|
4055
4087
|
#getEnv(lib, env = {}) {
|
|
4056
4088
|
const rootEnv = import_dotenv2.default.parse(lib.workspace.readFile(".env"));
|
|
4057
4089
|
return {
|
|
@@ -4107,19 +4139,6 @@ var LibraryScript = class {
|
|
|
4107
4139
|
await this.#runner.mergeLibraryDependencies(lib);
|
|
4108
4140
|
mergeSpinner.succeed(`${libName} library (libs/${libName}) dependencies merged to root package.json`);
|
|
4109
4141
|
}
|
|
4110
|
-
async pushLibrary(lib, branch) {
|
|
4111
|
-
const pushSpinner = lib.spinning("Pushing library...");
|
|
4112
|
-
await this.#runner.pushLibrary(lib, branch);
|
|
4113
|
-
pushSpinner.succeed(`Library ${lib.name} (libs/${lib.name}) pushed to ${branch} branch`);
|
|
4114
|
-
}
|
|
4115
|
-
async pullLibrary(lib, branch) {
|
|
4116
|
-
const pullSpinner = lib.spinning("Pulling library...");
|
|
4117
|
-
await this.#runner.pullLibrary(lib, branch);
|
|
4118
|
-
pullSpinner.succeed(`Library ${lib.name} (libs/${lib.name}) pulled from ${branch} branch`);
|
|
4119
|
-
const mergeSpinner = lib.spinning("Merging library dependencies...");
|
|
4120
|
-
await this.#runner.mergeLibraryDependencies(lib);
|
|
4121
|
-
mergeSpinner.succeed(`Library ${lib.name} (libs/${lib.name}) dependencies merged to root package.json`);
|
|
4122
|
-
}
|
|
4123
4142
|
async testLibrary(lib) {
|
|
4124
4143
|
const spinner = lib.spinning("Testing library...");
|
|
4125
4144
|
await this.#runner.testLibrary(lib);
|
|
@@ -4476,7 +4495,7 @@ var ApplicationRunner = class {
|
|
|
4476
4495
|
}
|
|
4477
4496
|
async scanSync(app, { refresh = false } = {}) {
|
|
4478
4497
|
const scanInfo = await app.scan({ refresh });
|
|
4479
|
-
await app.syncAssets(scanInfo.getScanResult().
|
|
4498
|
+
await app.syncAssets(scanInfo.getScanResult().libDeps);
|
|
4480
4499
|
return scanInfo;
|
|
4481
4500
|
}
|
|
4482
4501
|
async getScriptFilename(app) {
|
|
@@ -6012,12 +6031,6 @@ var LibraryCommand = class {
|
|
|
6012
6031
|
async installLibrary(libName, workspace) {
|
|
6013
6032
|
await this.libraryScript.installLibrary(workspace, libName);
|
|
6014
6033
|
}
|
|
6015
|
-
async pushLibrary(lib, branch) {
|
|
6016
|
-
await this.libraryScript.pushLibrary(lib, branch);
|
|
6017
|
-
}
|
|
6018
|
-
async pullLibrary(lib, branch) {
|
|
6019
|
-
await this.libraryScript.pullLibrary(lib, branch);
|
|
6020
|
-
}
|
|
6021
6034
|
};
|
|
6022
6035
|
__decorateClass([
|
|
6023
6036
|
Target.Public(),
|
|
@@ -6037,16 +6050,6 @@ __decorateClass([
|
|
|
6037
6050
|
__decorateParam(0, Argument("libName", { desc: "name of library", nullable: true })),
|
|
6038
6051
|
__decorateParam(1, Workspace())
|
|
6039
6052
|
], LibraryCommand.prototype, "installLibrary", 1);
|
|
6040
|
-
__decorateClass([
|
|
6041
|
-
Target.Public({ devOnly: true }),
|
|
6042
|
-
__decorateParam(0, Lib()),
|
|
6043
|
-
__decorateParam(1, Option("branch", { desc: "branch to push", default: "main" }))
|
|
6044
|
-
], LibraryCommand.prototype, "pushLibrary", 1);
|
|
6045
|
-
__decorateClass([
|
|
6046
|
-
Target.Public(),
|
|
6047
|
-
__decorateParam(0, Lib()),
|
|
6048
|
-
__decorateParam(1, Option("branch", { desc: "branch to pull", default: "main" }))
|
|
6049
|
-
], LibraryCommand.prototype, "pullLibrary", 1);
|
|
6050
6053
|
LibraryCommand = __decorateClass([
|
|
6051
6054
|
Commands()
|
|
6052
6055
|
], LibraryCommand);
|
|
@@ -6415,12 +6418,12 @@ var ModuleRunner = class {
|
|
|
6415
6418
|
},
|
|
6416
6419
|
signal: {
|
|
6417
6420
|
filename: `${module2.name}.signal.ts`,
|
|
6418
|
-
content: module2.readFile(`${module2.name}.signal.
|
|
6419
|
-
},
|
|
6420
|
-
test: {
|
|
6421
|
-
filename: `${module2.name}.test.ts`,
|
|
6422
|
-
content: module2.readFile(`${module2.name}.signal.test.ts`)
|
|
6421
|
+
content: module2.readFile(`${module2.name}.signal.ts`)
|
|
6423
6422
|
},
|
|
6423
|
+
// test: {
|
|
6424
|
+
// filename: `${module.name}.test.ts`,
|
|
6425
|
+
// content: module.readFile(`${module.name}.signal.test.ts`),
|
|
6426
|
+
// },
|
|
6424
6427
|
unit: {
|
|
6425
6428
|
filename: `${module2.name}.Unit.tsx`,
|
|
6426
6429
|
content: module2.readFile(`${module2.name}.Unit.tsx`)
|
|
@@ -6688,7 +6691,7 @@ var import_latest_version2 = __toESM(require("latest-version"), 1);
|
|
|
6688
6691
|
var import_path6 = __toESM(require("path"), 1);
|
|
6689
6692
|
var import_uuid2 = require("uuid");
|
|
6690
6693
|
var WorkspaceRunner = class {
|
|
6691
|
-
async createWorkspace(repoName, appName, dirname3 = ".") {
|
|
6694
|
+
async createWorkspace(repoName, appName, { dirname: dirname3 = ".", tag = "latest" }) {
|
|
6692
6695
|
const cwdPath = process.cwd();
|
|
6693
6696
|
const workspaceRoot = import_path6.default.join(cwdPath, dirname3, repoName);
|
|
6694
6697
|
const workspace = WorkspaceExecutor.fromRoot({ workspaceRoot, repoName });
|
|
@@ -6718,7 +6721,7 @@ var WorkspaceRunner = class {
|
|
|
6718
6721
|
"@akanjs/ui"
|
|
6719
6722
|
];
|
|
6720
6723
|
const devDependencies = ["@akanjs/devkit", "@akanjs/lint", "@akanjs/test"];
|
|
6721
|
-
const latestPublishedVersionOfBase = await (0, import_latest_version2.default)("@akanjs/base");
|
|
6724
|
+
const latestPublishedVersionOfBase = await (0, import_latest_version2.default)("@akanjs/base", { version: tag });
|
|
6722
6725
|
const packageJson = {
|
|
6723
6726
|
...rootPackageJson,
|
|
6724
6727
|
dependencies: {
|
|
@@ -6787,8 +6790,8 @@ var WorkspaceScript = class {
|
|
|
6787
6790
|
#runner = new WorkspaceRunner();
|
|
6788
6791
|
applicationScript = new ApplicationScript();
|
|
6789
6792
|
libraryScript = new LibraryScript();
|
|
6790
|
-
async createWorkspace(repoName, appName, dirname3 = ".", installLibs) {
|
|
6791
|
-
const workspace = await this.#runner.createWorkspace(repoName, appName, dirname3);
|
|
6793
|
+
async createWorkspace(repoName, appName, { dirname: dirname3 = ".", installLibs = false, tag = "latest" }) {
|
|
6794
|
+
const workspace = await this.#runner.createWorkspace(repoName, appName, { dirname: dirname3, tag });
|
|
6792
6795
|
if (installLibs) {
|
|
6793
6796
|
await this.libraryScript.installLibrary(workspace, "util");
|
|
6794
6797
|
await this.libraryScript.installLibrary(workspace, "shared");
|
|
@@ -6853,12 +6856,11 @@ var WorkspaceScript = class {
|
|
|
6853
6856
|
// pkgs/@akanjs/cli/src/workspace/workspace.command.ts
|
|
6854
6857
|
var WorkspaceCommand = class {
|
|
6855
6858
|
workspaceScript = new WorkspaceScript();
|
|
6856
|
-
async createWorkspace(workspaceName, app, dir, libs) {
|
|
6859
|
+
async createWorkspace(workspaceName, app, dir, libs, tag) {
|
|
6857
6860
|
await this.workspaceScript.createWorkspace(
|
|
6858
6861
|
workspaceName.toLowerCase().replace(/ /g, "-"),
|
|
6859
6862
|
app.toLowerCase().replace(/ /g, "-"),
|
|
6860
|
-
dir,
|
|
6861
|
-
libs
|
|
6863
|
+
{ dirname: dir, installLibs: libs, tag }
|
|
6862
6864
|
);
|
|
6863
6865
|
}
|
|
6864
6866
|
async generateMongo(workspace) {
|
|
@@ -6895,6 +6897,11 @@ __decorateClass([
|
|
|
6895
6897
|
value: true
|
|
6896
6898
|
}
|
|
6897
6899
|
]
|
|
6900
|
+
})),
|
|
6901
|
+
__decorateParam(4, Option("tag", {
|
|
6902
|
+
desc: "tag of the update",
|
|
6903
|
+
default: "latest",
|
|
6904
|
+
enum: ["latest", "dev", "canary", "beta", "rc", "alpha"]
|
|
6898
6905
|
}))
|
|
6899
6906
|
], WorkspaceCommand.prototype, "createWorkspace", 1);
|
|
6900
6907
|
__decorateClass([
|
|
@@ -7289,8 +7296,8 @@ var ScalarPrompt = class extends Prompter {
|
|
|
7289
7296
|
}
|
|
7290
7297
|
async requestCreateConstant() {
|
|
7291
7298
|
const constantFiles = await this.sys.getConstantFilesWithLibs();
|
|
7292
|
-
const description = await (0, import_prompts10.input)({ message: "description of scalar
|
|
7293
|
-
const schemaDescription = await (0, import_prompts10.input)({ message: "schema description of scalar
|
|
7299
|
+
const description = await (0, import_prompts10.input)({ message: "description of scalar" });
|
|
7300
|
+
const schemaDescription = await (0, import_prompts10.input)({ message: "schema description of scalar" });
|
|
7294
7301
|
await this.sys.applyTemplate({
|
|
7295
7302
|
basePath: "./lib/__scalar",
|
|
7296
7303
|
template: "__scalar",
|
|
@@ -7310,7 +7317,7 @@ var ScalarPrompt = class extends Prompter {
|
|
|
7310
7317
|
boilerplate,
|
|
7311
7318
|
constantFiles
|
|
7312
7319
|
}) {
|
|
7313
|
-
const
|
|
7320
|
+
const scanInfo = await this.sys.scan();
|
|
7314
7321
|
const guideJson = await Prompter.getGuideJson("scalarConstant");
|
|
7315
7322
|
const request = await this.makeTsFileUpdatePrompt({
|
|
7316
7323
|
context: `
|
|
@@ -7323,7 +7330,7 @@ ${await this.getDocumentation("enumConstant")}
|
|
|
7323
7330
|
3. How to write Fields in __scalar/<model>/<model>.constant.ts file
|
|
7324
7331
|
${await this.getDocumentation("fieldDecorator")}
|
|
7325
7332
|
|
|
7326
|
-
4. List of constant.ts files in other libraries connected to current ${this.sys.name} ${this.sys.type === "app" ? "Application" : "Library"} ${
|
|
7333
|
+
4. List of constant.ts files in other libraries connected to current ${this.sys.name} ${this.sys.type === "app" ? "Application" : "Library"} ${scanInfo.getLibs().map((lib) => lib).join(", ")}
|
|
7327
7334
|
Please understand the content and file patterns below, and feel free to reuse any constants or enums if available.
|
|
7328
7335
|
${constantFiles.map(
|
|
7329
7336
|
(constant) => `
|
|
@@ -7401,6 +7408,14 @@ ${boilerplate}
|
|
|
7401
7408
|
|
|
7402
7409
|
// pkgs/@akanjs/cli/src/scalar/scalar.runner.ts
|
|
7403
7410
|
var ScalarRunner = class {
|
|
7411
|
+
async applyScalarTemplate(sys3, scalarName) {
|
|
7412
|
+
await sys3.applyTemplate({
|
|
7413
|
+
basePath: "./lib/__scalar",
|
|
7414
|
+
template: "__scalar",
|
|
7415
|
+
dict: { model: scalarName, models: (0, import_pluralize3.default)(scalarName), sysName: sys3.name },
|
|
7416
|
+
overwrite: false
|
|
7417
|
+
});
|
|
7418
|
+
}
|
|
7404
7419
|
async createScalarConstant(sys3, scalarName) {
|
|
7405
7420
|
const isContinued = sys3.exists(`lib/__scalar/${scalarName}/${scalarName}.constant.ts`);
|
|
7406
7421
|
const prompt = new ScalarPrompt(sys3, scalarName);
|
|
@@ -7409,12 +7424,7 @@ var ScalarRunner = class {
|
|
|
7409
7424
|
const writes = await session.writeTypescripts(request, sys3, { validate });
|
|
7410
7425
|
const scalarNames = writes.map(({ filePath }) => filePath.split("/").at(-2)).filter((name) => !!name);
|
|
7411
7426
|
for (const name of scalarNames)
|
|
7412
|
-
await
|
|
7413
|
-
basePath: "./lib/__scalar",
|
|
7414
|
-
template: "__scalar",
|
|
7415
|
-
dict: { model: name, models: (0, import_pluralize3.default)(name), sysName: sys3.name },
|
|
7416
|
-
overwrite: false
|
|
7417
|
-
});
|
|
7427
|
+
await this.applyScalarTemplate(sys3, name);
|
|
7418
7428
|
return { session, scalarNames, writes, prompt };
|
|
7419
7429
|
}
|
|
7420
7430
|
async updateScalarDictionaries(sys3, scalarNames, { session }) {
|
|
@@ -7434,6 +7444,9 @@ var ScalarRunner = class {
|
|
|
7434
7444
|
var ScalarScript = class {
|
|
7435
7445
|
#runner = new ScalarRunner();
|
|
7436
7446
|
async createScalar(sys3, scalarName) {
|
|
7447
|
+
await this.#runner.applyScalarTemplate(sys3, scalarName);
|
|
7448
|
+
}
|
|
7449
|
+
async createScalarWithAi(sys3, scalarName) {
|
|
7437
7450
|
const { session, scalarNames } = await this.#runner.createScalarConstant(sys3, scalarName);
|
|
7438
7451
|
await this.#runner.updateScalarDictionaries(sys3, scalarNames, { session });
|
|
7439
7452
|
}
|
|
@@ -7445,22 +7458,25 @@ var ScalarScript = class {
|
|
|
7445
7458
|
// pkgs/@akanjs/cli/src/scalar/scalar.command.ts
|
|
7446
7459
|
var ScalarCommand = class {
|
|
7447
7460
|
scalarScript = new ScalarScript();
|
|
7448
|
-
async createScalar(
|
|
7461
|
+
async createScalar(scalarName, ai, sys3) {
|
|
7462
|
+
if (ai)
|
|
7463
|
+
await this.scalarScript.createScalarWithAi(sys3, lowerlize(scalarName.replace(/ /g, "")));
|
|
7449
7464
|
await this.scalarScript.createScalar(sys3, lowerlize(scalarName.replace(/ /g, "")));
|
|
7450
7465
|
}
|
|
7451
|
-
async removeScalar(
|
|
7466
|
+
async removeScalar(scalarName, sys3) {
|
|
7452
7467
|
await this.scalarScript.removeScalar(sys3, scalarName);
|
|
7453
7468
|
}
|
|
7454
7469
|
};
|
|
7455
7470
|
__decorateClass([
|
|
7456
7471
|
Target.Public(),
|
|
7457
|
-
__decorateParam(0,
|
|
7458
|
-
__decorateParam(1,
|
|
7472
|
+
__decorateParam(0, Argument("scalarName", { desc: "name of scalar" })),
|
|
7473
|
+
__decorateParam(1, Option("ai", { type: "boolean", default: false, desc: "use ai to create scalar" })),
|
|
7474
|
+
__decorateParam(2, Sys())
|
|
7459
7475
|
], ScalarCommand.prototype, "createScalar", 1);
|
|
7460
7476
|
__decorateClass([
|
|
7461
7477
|
Target.Public(),
|
|
7462
|
-
__decorateParam(0,
|
|
7463
|
-
__decorateParam(1,
|
|
7478
|
+
__decorateParam(0, Argument("scalarName", { desc: "name of scalar" })),
|
|
7479
|
+
__decorateParam(1, Sys())
|
|
7464
7480
|
], ScalarCommand.prototype, "removeScalar", 1);
|
|
7465
7481
|
ScalarCommand = __decorateClass([
|
|
7466
7482
|
Commands()
|
|
@@ -14,8 +14,8 @@
|
|
|
14
14
|
},
|
|
15
15
|
{
|
|
16
16
|
"type": "source",
|
|
17
|
-
"description": "scalar
|
|
18
|
-
"path": "pkgs/@akanjs/constant/src/
|
|
17
|
+
"description": "via() function and scalar implementation",
|
|
18
|
+
"path": "pkgs/@akanjs/constant/src/baseGql.ts"
|
|
19
19
|
},
|
|
20
20
|
{
|
|
21
21
|
"type": "source",
|
|
@@ -72,30 +72,34 @@
|
|
|
72
72
|
"Purpose of scalar constants in Akan.js",
|
|
73
73
|
"File structure and location conventions",
|
|
74
74
|
"Naming standards for directories, files, classes and enums",
|
|
75
|
-
"Required imports and
|
|
76
|
-
"
|
|
77
|
-
"Field definitions with
|
|
78
|
-
"Field options reference table",
|
|
79
|
-
"
|
|
80
|
-
"
|
|
81
|
-
"
|
|
75
|
+
"Required imports from @akanjs/constant and @akanjs/base",
|
|
76
|
+
"Basic syntax with via() function",
|
|
77
|
+
"Field definitions with field() helper function",
|
|
78
|
+
"Field options reference table (default, min, max, minlength, maxlength, validate, example)",
|
|
79
|
+
"Available field types (String, Int, Float, Boolean, Date, ID)",
|
|
80
|
+
"Array fields using bracket notation [Type]",
|
|
81
|
+
"Optional fields using .optional() chain method",
|
|
82
|
+
"Enum definition with enumOf(name, values) class pattern",
|
|
83
|
+
"Instance methods in scalar classes",
|
|
82
84
|
"Static methods in scalar classes",
|
|
83
|
-
"Validation rules and checklists",
|
|
84
85
|
"Common mistakes and fixes",
|
|
86
|
+
"Implementation checklist",
|
|
85
87
|
"Full examples of scalar.constant.ts files"
|
|
86
88
|
],
|
|
87
89
|
"rules": [
|
|
88
|
-
"One scalar.constant.ts should contain only one
|
|
89
|
-
"The directory and filename convention is camelCase, such as `
|
|
90
|
-
"The class name should be PascalCase, matching the camelCase directory name (e.g.,
|
|
91
|
-
"
|
|
92
|
-
"
|
|
93
|
-
"
|
|
94
|
-
"
|
|
95
|
-
"
|
|
96
|
-
"
|
|
90
|
+
"One scalar.constant.ts should contain only one scalar class extending via(). If you need more than one scalar model, make another scalar.constant.ts file.",
|
|
91
|
+
"The directory and filename convention is camelCase, such as `encourageInfo/encourageInfo.constant.ts`",
|
|
92
|
+
"The class name should be PascalCase, matching the camelCase directory name (e.g., EncourageInfo for encourageInfo)",
|
|
93
|
+
"Use `extends via((field) => ({...}))` pattern to define scalar classes, not decorators",
|
|
94
|
+
"Import `via` from `@akanjs/constant` and `enumOf`, `ID`, `Int`, `Float`, `dayjs` from `@akanjs/base`",
|
|
95
|
+
"The values of enum strings must be camelCase (e.g., 'waitPay', not 'WAIT_PAY')",
|
|
96
|
+
"Define enums using class pattern: `export class EnumName extends enumOf('enumName', [...] as const) {}`",
|
|
97
|
+
"The first argument of enumOf() is the enum name string used in dictionary/GraphQL",
|
|
98
|
+
"Use .optional() chain method for nullable fields, not { nullable: true } option",
|
|
97
99
|
"Use bracket notation for arrays ([Type]) rather than generics (Array<Type>)",
|
|
98
|
-
"
|
|
100
|
+
"Use factory functions for dynamic defaults: { default: () => dayjs() }, not { default: dayjs() }",
|
|
101
|
+
"Always export both the scalar class and enum classes",
|
|
102
|
+
"Add 'as const' to enum value arrays for better TypeScript type inference"
|
|
99
103
|
]
|
|
100
104
|
},
|
|
101
105
|
"page": "/[lang]/akanjs/(docs)/docs/scalar/constant/page.tsx"
|