@akanjs/cli 3.0.2 → 3.1.0-rc.0
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/.build-stamp +1 -1
- package/{CodeAgent-szbjv4gv.js → CodeAgent-q7a4srt6.js} +2 -2
- package/{CodeTui-5nw86ab6.js → CodeTui-ak23dxc9.js} +1 -1
- package/{TunnelShare-cwh9ezsm.js → TunnelShare-21mm6dr5.js} +2 -2
- package/{agent.command-np1dffkb.js → agent.command-f3gsc1gd.js} +5 -5
- package/akanCode.js +2 -2
- package/{application.command-gk69v1xs.js → application.command-3v2d53gd.js} +37 -15
- package/{applicationBuildRunner-wx09n9g6.js → applicationBuildRunner-1yaqsrdq.js} +115 -103
- package/buildBatch.proc.js +16 -5
- package/cloud.command-kk2rwkvw.js +187 -0
- package/cloud.script-r7eyfey4.js +20 -0
- package/{code.command-hmtx14b2.js → code.command-30sca09d.js} +6 -6
- package/commandManifest.json +1 -1
- package/{context.command-6aqvdx43.js → context.command-k7eqacq6.js} +13 -13
- package/context.runner-hqd1ppqe.js +21 -0
- package/{guideline.command-axvf68gc.js → guideline.command-dtczrqpf.js} +2 -2
- package/guidelines/agentRule/agentRule.instruction.md +10 -2
- package/guidelines/conventions/conventions.instruction.md +68 -25
- package/guidelines/cssRule/cssRule.instruction.md +19 -0
- package/guidelines/mcpRule/mcpRule.instruction.md +67 -12
- package/guidelines/queryRule/queryRule.instruction.md +11 -1
- package/guidelines/runtimeRule/runtimeRule.instruction.md +97 -16
- package/guidelines/ssrRule/ssrRule.instruction.md +10 -7
- package/guidelines/transportRule/transportRule.instruction.md +19 -0
- package/guidelines/workspaceRecipes/workspaceRecipes.instruction.md +6 -6
- package/incrementalBuilder.proc.js +24 -3
- package/{index-h9ht6s60.js → index-05g3jayg.js} +1 -1
- package/{index-j38qkvkk.js → index-0bm04n5g.js} +12 -10
- package/{index-g38nhv87.js → index-2etcv0sc.js} +1 -1
- package/{index-zyw622y1.js → index-2mx692qq.js} +3 -3
- package/{index-jb0hmt3k.js → index-2t4tqd1c.js} +3 -3
- package/{index-50wb2a26.js → index-55mynnqs.js} +354 -129
- package/{index-q6ft9fkc.js → index-6jjtnhkw.js} +8 -3
- package/index-6w0rbr9d.js +68 -0
- package/{index-2wc41k5w.js → index-7bymavqk.js} +2 -2
- package/{index-gtjgnv36.js → index-aprt7pkz.js} +6 -9
- package/{index-1bjkfvm9.js → index-c1x0be5j.js} +2 -2
- package/{index-z750gk1j.js → index-c2yrsxdh.js} +13 -7
- package/{index-cb6yc5mb.js → index-c76k723e.js} +2 -2
- package/{index-6keyf4sg.js → index-ctanya41.js} +4 -4
- package/{index-f4e08ptp.js → index-e0cvze1s.js} +4 -4
- package/{index-hp3stk1m.js → index-fm46xrf1.js} +3 -3
- package/{index-3xmzr1p1.js → index-gnyf1fqy.js} +2 -2
- package/{index-zwd84m0w.js → index-jyv387qw.js} +4 -4
- package/{index-jk9xnck6.js → index-kjvrq3nc.js} +231 -133
- package/{index-xwprn9nr.js → index-nz15k0b6.js} +1 -1
- package/{index-nwd6qzvv.js → index-p9ystjrp.js} +138 -55
- package/index-q958tqqg.js +77 -0
- package/{index-50jjwg8y.js → index-qt22xstj.js} +1 -1
- package/{index-94s080qm.js → index-r2tpeb3n.js} +127 -1
- package/{index-bsv901fd.js → index-rwq3ekqc.js} +7 -7
- package/{index-t91a7339.js → index-tn4rpqp1.js} +96 -12
- package/{index-1gs9g12n.js → index-v29746vb.js} +4 -4
- package/index-ww9bhp67.js +62 -0
- package/{index-hxnnfy57.js → index-y8q31011.js} +180 -8
- package/index.js +22 -21
- package/{library.command-9m2rdwwz.js → library.command-gaga5bmq.js} +3 -3
- package/{localRegistry.command-kda81jyk.js → localRegistry.command-9e84e32q.js} +9 -9
- package/{module.command-q63dffya.js → module.command-7vpf6db4.js} +5 -5
- package/{package.command-y2jh0m99.js → package.command-twmvvf69.js} +3 -3
- package/package.json +2 -2
- package/{page.command-f3e4cwhh.js → page.command-5asq7fdf.js} +3 -3
- package/pipeline.command-d0v38572.js +1334 -0
- package/{primitive.command-r4kq75qj.js → primitive.command-dyrs2fm8.js} +6 -6
- package/projectTypecheck-cvtkrzp2.js +7 -0
- package/{quality.command-f7gzh26z.js → quality.command-6emsqpbg.js} +5 -4
- package/{repair.command-0qmyr6qa.js → repair.command-8t6aegv5.js} +5 -5
- package/{scalar.command-kddn7av4.js → scalar.command-bnggy1x7.js} +4 -4
- package/{subspace.command-ft65qvc4.js → subspace.command-f02j5tge.js} +158 -91
- package/templates/appSample/page/task/[taskId]/_index.tsx +2 -2
- package/templates/appSample/page/task/[taskId]/edit.tsx +2 -2
- package/templates/appSample/page/task/_index.tsx +2 -2
- package/templates/crudPages/[__model__Id]/edit/page.tsx +2 -2
- package/templates/crudPages/[__model__Id]/page.tsx +3 -3
- package/templates/crudPages/page.tsx +2 -2
- package/templates/crudSinglePage/page.tsx +3 -3
- package/templates/lib/cnst.ts +2 -2
- package/templates/lib/sig.ts +3 -3
- package/{tunnel.command-b3ymdk4f.js → tunnel.command-9x8nfn75.js} +16 -13
- package/{workflow.command-z1srcdfw.js → workflow.command-jx0wag5r.js} +10 -10
- package/{workspace.command-vp6vmx3z.js → workspace.command-cmj6mqyk.js} +57 -27
- package/cloud.command-tw06613r.js +0 -95
- package/cloud.script-64gzba8r.js +0 -20
- package/context.runner-hnkvv3z3.js +0 -21
|
@@ -2,17 +2,17 @@
|
|
|
2
2
|
import {
|
|
3
3
|
Workspace,
|
|
4
4
|
command
|
|
5
|
-
} from "./index-
|
|
5
|
+
} from "./index-6jjtnhkw.js";
|
|
6
6
|
import"./index-52w0fvh8.js";
|
|
7
|
-
import"./index-
|
|
7
|
+
import"./index-55mynnqs.js";
|
|
8
8
|
import {
|
|
9
9
|
renderPrimitiveReport
|
|
10
|
-
} from "./index-
|
|
11
|
-
import"./index-
|
|
12
|
-
import"./index-
|
|
10
|
+
} from "./index-05g3jayg.js";
|
|
11
|
+
import"./index-2etcv0sc.js";
|
|
12
|
+
import"./index-e0cvze1s.js";
|
|
13
13
|
import {
|
|
14
14
|
PrimitiveScript
|
|
15
|
-
} from "./index-
|
|
15
|
+
} from "./index-ctanya41.js";
|
|
16
16
|
|
|
17
17
|
// pkgs/@akanjs/cli/primitive/primitive.command.ts
|
|
18
18
|
import { Logger } from "akanjs/common";
|
|
@@ -3,15 +3,16 @@ import {
|
|
|
3
3
|
Workspace,
|
|
4
4
|
script,
|
|
5
5
|
command
|
|
6
|
-
} from "./index-
|
|
6
|
+
} from "./index-6jjtnhkw.js";
|
|
7
7
|
import"./index-52w0fvh8.js";
|
|
8
8
|
import {
|
|
9
9
|
rootAllowedFiles,
|
|
10
10
|
rootAllowedDirs,
|
|
11
11
|
isAllowedLibFacetRootFile,
|
|
12
|
+
libFacetRootHintOf,
|
|
12
13
|
facetIndexShadowOf,
|
|
13
14
|
rootEntryHintOf
|
|
14
|
-
} from "./index-
|
|
15
|
+
} from "./index-55mynnqs.js";
|
|
15
16
|
|
|
16
17
|
// pkgs/@akanjs/devkit/qualityScanner.ts
|
|
17
18
|
import { createHash } from "crypto";
|
|
@@ -505,7 +506,7 @@ var RULE_FIXES = {
|
|
|
505
506
|
"akan.layout.app-root-folder": "Move the folder's contents into a conventional app folder (common, env, lib, page, private, public, script, srvkit, ui, or webkit) and delete it.",
|
|
506
507
|
"akan.layout.lib-root-file": "Move the file into a conventional lib folder (common, env, lib, page, private, public, srvkit, ui, or webkit).",
|
|
507
508
|
"akan.layout.lib-root-folder": "Move the folder's contents into a conventional lib folder (common, env, lib, page, private, public, srvkit, ui, or webkit) and delete it.",
|
|
508
|
-
"akan.layout.lib-facet-file": "Move the file into a domain module folder under lib
|
|
509
|
+
"akan.layout.lib-facet-file": "Move the file into a domain module folder under lib/ (a test beside the file it covers, or into srvkit/ when it drives several modules); keep the lib facet root limited to generated support facets.",
|
|
509
510
|
"akan.layout.facet-index-shadow": "Delete the hand-written index file and run akan sync; move a namespace it builds into <facet>/<Folder>/index.tsx.",
|
|
510
511
|
"akan.layout.module-ui-file": "Rename the file to an allowed module UI name, or move it to ui/ if it is not a module component.",
|
|
511
512
|
"akan.ssr.unnecessary-use-client": 'Delete the "use client" directive so the file renders on the server. If it exists only to wrap one client child, drop the wrapper and use the child directly.',
|
|
@@ -708,7 +709,7 @@ class AkanQualityScanner {
|
|
|
708
709
|
warnings.push(fileWarning("akan.layout.facet-index-shadow", "layout", sourceFile.file, `${path2.basename(sourceFile.file)} ${facetShadow}.`));
|
|
709
710
|
const libFacetFile = getLibFacetRootFile(sourceFile.file);
|
|
710
711
|
if (libFacetFile && !isAllowedLibFacetRootFile(libFacetFile))
|
|
711
|
-
warnings.push(fileWarning("akan.layout.lib-facet-file", "layout", sourceFile.file, `Unexpected lib facet root file "${libFacetFile}". Keep direct lib/ root files limited to generated support facets
|
|
712
|
+
warnings.push(fileWarning("akan.layout.lib-facet-file", "layout", sourceFile.file, `Unexpected lib facet root file "${libFacetFile}". ${libFacetRootHintOf(libFacetFile) ?? "Keep direct lib/ root files limited to generated support facets."}`));
|
|
712
713
|
const moduleUiWarning = getModuleUiWarning(sourceFile.file);
|
|
713
714
|
if (moduleUiWarning)
|
|
714
715
|
warnings.push(moduleUiWarning);
|
|
@@ -3,15 +3,15 @@ import {
|
|
|
3
3
|
Workspace,
|
|
4
4
|
script,
|
|
5
5
|
command
|
|
6
|
-
} from "./index-
|
|
6
|
+
} from "./index-6jjtnhkw.js";
|
|
7
7
|
import"./index-52w0fvh8.js";
|
|
8
|
-
import"./index-
|
|
8
|
+
import"./index-55mynnqs.js";
|
|
9
9
|
import"./index-hj6w4ka1.js";
|
|
10
|
-
import"./index-
|
|
11
|
-
import"./index-
|
|
10
|
+
import"./index-05g3jayg.js";
|
|
11
|
+
import"./index-2mx692qq.js";
|
|
12
12
|
import {
|
|
13
13
|
RepairRunner
|
|
14
|
-
} from "./index-
|
|
14
|
+
} from "./index-fm46xrf1.js";
|
|
15
15
|
|
|
16
16
|
// pkgs/@akanjs/cli/repair/repair.script.ts
|
|
17
17
|
import { Logger } from "akanjs/common";
|
|
@@ -2,15 +2,15 @@
|
|
|
2
2
|
import {
|
|
3
3
|
Sys,
|
|
4
4
|
command
|
|
5
|
-
} from "./index-
|
|
5
|
+
} from "./index-6jjtnhkw.js";
|
|
6
6
|
import"./index-52w0fvh8.js";
|
|
7
|
-
import"./index-
|
|
7
|
+
import"./index-55mynnqs.js";
|
|
8
8
|
import {
|
|
9
9
|
renderPrimitiveReport
|
|
10
|
-
} from "./index-
|
|
10
|
+
} from "./index-05g3jayg.js";
|
|
11
11
|
import {
|
|
12
12
|
ScalarScript
|
|
13
|
-
} from "./index-
|
|
13
|
+
} from "./index-c76k723e.js";
|
|
14
14
|
|
|
15
15
|
// pkgs/@akanjs/cli/scalar/scalar.command.ts
|
|
16
16
|
import { Logger, lowerlize } from "akanjs/common";
|
|
@@ -1,37 +1,42 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import {
|
|
3
|
-
FileSys2
|
|
4
|
-
} from "./index-52w0fvh8.js";
|
|
5
|
-
import {
|
|
6
|
-
GlobalConfig
|
|
7
|
-
} from "./index-94s080qm.js";
|
|
8
2
|
import {
|
|
9
3
|
Workspace,
|
|
10
4
|
CommandContainer,
|
|
11
5
|
runner,
|
|
12
6
|
script,
|
|
13
7
|
command
|
|
14
|
-
} from "./index-
|
|
8
|
+
} from "./index-6jjtnhkw.js";
|
|
9
|
+
import {
|
|
10
|
+
FileSys2
|
|
11
|
+
} from "./index-52w0fvh8.js";
|
|
15
12
|
import {
|
|
16
13
|
LibSource,
|
|
17
14
|
Executor,
|
|
18
15
|
WorkspaceExecutor,
|
|
19
16
|
AppExecutor
|
|
20
|
-
} from "./index-
|
|
17
|
+
} from "./index-55mynnqs.js";
|
|
18
|
+
import {
|
|
19
|
+
GlobalConfig
|
|
20
|
+
} from "./index-r2tpeb3n.js";
|
|
21
|
+
import {
|
|
22
|
+
SubspaceConfig
|
|
23
|
+
} from "./index-ww9bhp67.js";
|
|
21
24
|
import {
|
|
22
25
|
SlicePlanner
|
|
23
|
-
} from "./index-
|
|
26
|
+
} from "./index-qt22xstj.js";
|
|
24
27
|
|
|
25
28
|
// pkgs/@akanjs/devkit/subspace.ts
|
|
26
29
|
import { mkdir, readdir, rename, rm } from "fs/promises";
|
|
27
30
|
import path from "path";
|
|
28
31
|
class Subspace {
|
|
29
32
|
static anchorFile = "akan.subspace.json";
|
|
30
|
-
static
|
|
33
|
+
static subspaceOwnedRootEntries = ["akan.config.ts", "Jenkinsfile"];
|
|
34
|
+
static syncSubjectPrefix = "chore(subspace): sync from ";
|
|
31
35
|
static memberDirs = ["apps", "libs"];
|
|
32
36
|
static subspaceOwnedDirs = ["env"];
|
|
33
37
|
static secretsMarkers = ["# akan:secrets (managed by akan.config.ts \u2014 do not edit)", "# akan:secrets:end"];
|
|
34
38
|
static holdDir = ".akan-subspace-hold";
|
|
39
|
+
static #loopbackRegistry = /https?:\/\/(?:127\.0\.0\.1|localhost|0\.0\.0\.0|\[::1\])(?::\d+)?/;
|
|
35
40
|
#workspace;
|
|
36
41
|
#config;
|
|
37
42
|
#declaration;
|
|
@@ -58,6 +63,9 @@ class Subspace {
|
|
|
58
63
|
async#git(args) {
|
|
59
64
|
return await this.#workspace.spawn("git", args);
|
|
60
65
|
}
|
|
66
|
+
async#cloneGit(args) {
|
|
67
|
+
return await this.#workspace.spawn("git", ["-C", this.#clonePath, ...args]);
|
|
68
|
+
}
|
|
61
69
|
async branch() {
|
|
62
70
|
return (await this.#git(["rev-parse", "--abbrev-ref", "HEAD"])).trim();
|
|
63
71
|
}
|
|
@@ -97,6 +105,40 @@ class Subspace {
|
|
|
97
105
|
const paths = [...this.#declaration.apps.map((app) => `apps/${app}`), ...libs.map((lib) => `libs/${lib}`)];
|
|
98
106
|
return { plans, libs, paths };
|
|
99
107
|
}
|
|
108
|
+
async plan(branch) {
|
|
109
|
+
const { plans, libs } = await this.slice();
|
|
110
|
+
const rootFiles = plans[0]?.rootFiles ?? [];
|
|
111
|
+
const present = new Set(rootFiles.map((file) => file.split("/")[0] ?? file));
|
|
112
|
+
const owned = Subspace.subspaceOwnedRootEntries;
|
|
113
|
+
const excluded = this.#config.exclude.filter((entry) => !owned.includes(entry));
|
|
114
|
+
const excludedTops = new Set(excluded.map((entry) => entry.replace(/\/+$/, "")));
|
|
115
|
+
const libFiles = new Map(plans.flatMap((plan) => Object.entries(plan.libFiles)));
|
|
116
|
+
const { pruned, warnings } = await SlicePlanner.pruneDependencies(this.#workspace, await this.#workspace.getPackageJson(), plans.flatMap((plan) => plan.requiredDependencies));
|
|
117
|
+
let branchRefusal = null;
|
|
118
|
+
try {
|
|
119
|
+
this.#config.assertPushable(branch);
|
|
120
|
+
} catch (error) {
|
|
121
|
+
branchRefusal = error instanceof Error ? error.message : String(error);
|
|
122
|
+
}
|
|
123
|
+
return {
|
|
124
|
+
name: this.name,
|
|
125
|
+
repo: this.#declaration.repo,
|
|
126
|
+
branch,
|
|
127
|
+
branchRefusal,
|
|
128
|
+
apps: [...this.#declaration.apps],
|
|
129
|
+
libs: libs.map((lib) => ({
|
|
130
|
+
name: lib,
|
|
131
|
+
apps: plans.filter((plan) => plan.libs.includes(lib)).map((plan) => plan.app)
|
|
132
|
+
})),
|
|
133
|
+
files: plans.reduce((sum, plan) => sum + plan.appFiles.length, 0) + [...libFiles.values()].reduce((sum, files) => sum + files.length, 0),
|
|
134
|
+
rootEntries: [...present].filter((entry) => !excludedTops.has(entry) && !owned.includes(entry)).sort((a, b) => a.localeCompare(b)),
|
|
135
|
+
excludedRootEntries: excluded,
|
|
136
|
+
subspaceOwnedRootEntries: owned.filter((entry) => present.has(entry)),
|
|
137
|
+
prunedDependencies: pruned,
|
|
138
|
+
lockProblem: rootFiles.includes("bun.lock") ? await this.#loopbackRegistryLock(this.#workspace.workspaceRoot) : null,
|
|
139
|
+
warnings: [...new Set([...plans.flatMap((plan) => plan.warnings), ...warnings])]
|
|
140
|
+
};
|
|
141
|
+
}
|
|
100
142
|
#isSubspaceOwned(file) {
|
|
101
143
|
const segments = file.split("/");
|
|
102
144
|
if (!Subspace.memberDirs.includes(segments[0] ?? ""))
|
|
@@ -180,6 +222,34 @@ class Subspace {
|
|
|
180
222
|
await Subspace.#copyMissing(to, from);
|
|
181
223
|
await rm(path.join(this.#clonePath, Subspace.holdDir), { recursive: true, force: true });
|
|
182
224
|
}
|
|
225
|
+
async#holdRootEntries() {
|
|
226
|
+
const holdRoot = path.join(this.#clonePath, Subspace.holdDir, "root");
|
|
227
|
+
const held = [];
|
|
228
|
+
for (const entry of Subspace.subspaceOwnedRootEntries) {
|
|
229
|
+
const from = path.join(this.#clonePath, entry);
|
|
230
|
+
if (!await FileSys2.entryExists(from))
|
|
231
|
+
continue;
|
|
232
|
+
if (await this.#isPushedCopy(entry))
|
|
233
|
+
continue;
|
|
234
|
+
await mkdir(holdRoot, { recursive: true });
|
|
235
|
+
await rename(from, path.join(holdRoot, entry));
|
|
236
|
+
held.push(entry);
|
|
237
|
+
}
|
|
238
|
+
return held;
|
|
239
|
+
}
|
|
240
|
+
async#restoreRootEntries(held) {
|
|
241
|
+
const holdRoot = path.join(this.#clonePath, Subspace.holdDir, "root");
|
|
242
|
+
for (const entry of Subspace.subspaceOwnedRootEntries) {
|
|
243
|
+
const target = path.join(this.#clonePath, entry);
|
|
244
|
+
await rm(target, { recursive: true, force: true });
|
|
245
|
+
if (held.includes(entry))
|
|
246
|
+
await rename(path.join(holdRoot, entry), target);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
async#isPushedCopy(entry) {
|
|
250
|
+
const subject = await this.#cloneGit(["log", "-1", "--format=%s", "--", entry]).catch(() => "");
|
|
251
|
+
return subject.trim().startsWith(Subspace.syncSubjectPrefix);
|
|
252
|
+
}
|
|
183
253
|
static async#copyMissing(from, to) {
|
|
184
254
|
await mkdir(to, { recursive: true });
|
|
185
255
|
for (const entry of await readdir(from, { withFileTypes: true })) {
|
|
@@ -255,13 +325,16 @@ class Subspace {
|
|
|
255
325
|
async#applySlice(clone, branch) {
|
|
256
326
|
const { libs, paths, plans } = await this.slice();
|
|
257
327
|
const held = await this.#holdSubspaceOwned();
|
|
328
|
+
const heldRootEntries = await this.#holdRootEntries();
|
|
258
329
|
for (const member of Subspace.memberDirs)
|
|
259
330
|
await rm(path.join(this.#clonePath, member), { recursive: true, force: true });
|
|
260
331
|
await this.#extract(["."], ["apps/*", "libs/*", "pkgs/*"]);
|
|
261
332
|
await this.#extract(paths);
|
|
333
|
+
await this.#restoreRootEntries(heldRootEntries);
|
|
262
334
|
await this.#restoreSubspaceOwned(held);
|
|
263
|
-
for (const entry of
|
|
264
|
-
|
|
335
|
+
for (const entry of this.#config.exclude)
|
|
336
|
+
if (!Subspace.subspaceOwnedRootEntries.includes(entry))
|
|
337
|
+
await rm(path.join(this.#clonePath, entry), { recursive: true, force: true });
|
|
265
338
|
await this.#rewriteGitignore();
|
|
266
339
|
const pruned = await this.#rewriteManifest(plans);
|
|
267
340
|
await this.#rewriteWorkspaceSection(libs);
|
|
@@ -311,9 +384,9 @@ class Subspace {
|
|
|
311
384
|
const [hash, previous] = await Promise.all([this.#hashLib(clone, lib), this.#committedStamp(clone, lib)]);
|
|
312
385
|
const manifest = await FileSys2.readJson(manifestPath);
|
|
313
386
|
const akan = manifest[LibSource.manifestKey] ?? {};
|
|
314
|
-
const unchanged = previous?.origin === origin && previous.
|
|
315
|
-
const
|
|
316
|
-
manifest[LibSource.manifestKey] = { ...akan, source
|
|
387
|
+
const unchanged = previous?.origin === origin && previous.hash === hash;
|
|
388
|
+
const source = unchanged ? previous : { origin, sha, hash, syncedAt: new Date().toISOString() };
|
|
389
|
+
manifest[LibSource.manifestKey] = { ...akan, source };
|
|
317
390
|
await FileSys2.writeJson(manifestPath, manifest);
|
|
318
391
|
}
|
|
319
392
|
async#committedStamp(clone, lib) {
|
|
@@ -363,6 +436,13 @@ class Subspace {
|
|
|
363
436
|
return { files: [], patch: "" };
|
|
364
437
|
return { files, patch: await this.#git(["diff", from, "HEAD", "--", ...files]) };
|
|
365
438
|
}
|
|
439
|
+
async#loopbackRegistryLock(root = this.#clonePath) {
|
|
440
|
+
const lockPath = path.join(root, "bun.lock");
|
|
441
|
+
if (!await FileSys2.fileExists(lockPath))
|
|
442
|
+
return null;
|
|
443
|
+
const registry = (await FileSys2.readText(lockPath)).match(Subspace.#loopbackRegistry)?.[0];
|
|
444
|
+
return registry ? `bun.lock resolves packages from ${registry}, a registry only this machine reaches; reinstall from a public registry and commit that lock first` : null;
|
|
445
|
+
}
|
|
366
446
|
async#verify(clone) {
|
|
367
447
|
const env = { ...process.env, ...this.#localEnv() };
|
|
368
448
|
try {
|
|
@@ -398,9 +478,12 @@ class Subspace {
|
|
|
398
478
|
if (failure)
|
|
399
479
|
return { name: this.name, outcome: "refused", reason: failure, changedFiles };
|
|
400
480
|
}
|
|
481
|
+
const lockProblem = await this.#loopbackRegistryLock();
|
|
482
|
+
if (lockProblem)
|
|
483
|
+
return { name: this.name, outcome: "refused", reason: lockProblem, changedFiles };
|
|
401
484
|
await this.#writeAnchorFile(branch);
|
|
402
485
|
await clone.spawn("git", ["add", "-A"]);
|
|
403
|
-
const message =
|
|
486
|
+
const message = `${Subspace.syncSubjectPrefix}${this.#workspace.repoName}@${await this.headSha()}`;
|
|
404
487
|
await clone.spawn("git", ["commit", "--quiet", "-m", message]);
|
|
405
488
|
await clone.spawn("git", ["push", "--quiet", "origin", branch]);
|
|
406
489
|
return {
|
|
@@ -560,74 +643,37 @@ function formatSubspaceDiff(result) {
|
|
|
560
643
|
return sections.join(`
|
|
561
644
|
`);
|
|
562
645
|
}
|
|
646
|
+
function formatSubspacePlan(plan) {
|
|
647
|
+
const list = (entries) => entries.length ? entries.join(", ") : "(none)";
|
|
648
|
+
const blockers = [plan.branchRefusal, plan.lockProblem].filter((reason) => !!reason);
|
|
649
|
+
const sections = [
|
|
650
|
+
`Akan Subspace Plan \u2014 ${plan.name} (${plan.branch})`,
|
|
651
|
+
`repo: ${plan.repo}`,
|
|
652
|
+
"what `akan subspace push` would ship, worked out from this checkout alone",
|
|
653
|
+
"",
|
|
654
|
+
`apps: ${list(plan.apps)}`,
|
|
655
|
+
`libs: ${plan.libs.length ? "" : "(none)"}`.trimEnd(),
|
|
656
|
+
...plan.libs.map((lib) => ` - ${lib.name} (from ${lib.apps.join(", ")})`),
|
|
657
|
+
`files under apps/ and libs/: ${plan.files}`,
|
|
658
|
+
"",
|
|
659
|
+
`root entries pushed: ${list(plan.rootEntries)}`,
|
|
660
|
+
`root entries excluded: ${list(plan.excludedRootEntries)}`,
|
|
661
|
+
`root entries the subspace keeps its own: ${list(plan.subspaceOwnedRootEntries)}`,
|
|
662
|
+
"",
|
|
663
|
+
`Root dependencies left out of package.json (${plan.prunedDependencies.length}):`,
|
|
664
|
+
...plan.prunedDependencies.length ? plan.prunedDependencies.map((dep) => ` - ${dep}`) : [" (none)"],
|
|
665
|
+
"",
|
|
666
|
+
blockers.length ? "A push would be refused:" : "Nothing here would make a push refuse.",
|
|
667
|
+
...blockers.map((reason) => ` - ${reason}`),
|
|
668
|
+
...plan.warnings.length ? ["", `Warnings (${plan.warnings.length}):`, ...plan.warnings.map((w) => ` - ${w}`)] : []
|
|
669
|
+
];
|
|
670
|
+
return sections.join(`
|
|
671
|
+
`);
|
|
672
|
+
}
|
|
563
673
|
|
|
564
674
|
// pkgs/@akanjs/cli/subspace/subspace.script.ts
|
|
565
675
|
import { Logger } from "akanjs/common";
|
|
566
676
|
|
|
567
|
-
// pkgs/@akanjs/devkit/subspaceConfig.ts
|
|
568
|
-
import path2 from "path";
|
|
569
|
-
class SubspaceConfig {
|
|
570
|
-
static fileName = "akan.subspace.ts";
|
|
571
|
-
static defaultPushableBranches = ["main", "develop", "debug"];
|
|
572
|
-
static async from(workspace) {
|
|
573
|
-
const configPath = path2.join(workspace.workspaceRoot, SubspaceConfig.fileName);
|
|
574
|
-
if (!await FileSys2.fileExists(configPath))
|
|
575
|
-
return null;
|
|
576
|
-
const input = await import(configPath).then((mod) => mod.default);
|
|
577
|
-
return new SubspaceConfig(input);
|
|
578
|
-
}
|
|
579
|
-
pushableBranches;
|
|
580
|
-
exclude;
|
|
581
|
-
subspaces;
|
|
582
|
-
constructor(input) {
|
|
583
|
-
this.pushableBranches = input.pushableBranches ?? SubspaceConfig.defaultPushableBranches;
|
|
584
|
-
this.exclude = input.exclude ?? [];
|
|
585
|
-
this.subspaces = input.subspaces ?? [];
|
|
586
|
-
this.#assertValid();
|
|
587
|
-
}
|
|
588
|
-
#assertValid() {
|
|
589
|
-
const seenNames = new Set;
|
|
590
|
-
const appOwners = new Map;
|
|
591
|
-
const idOwners = new Map;
|
|
592
|
-
for (const subspace of this.subspaces) {
|
|
593
|
-
if (!subspace.name || !subspace.repo)
|
|
594
|
-
throw new Error(`${SubspaceConfig.fileName}: every subspace needs a name and a repo`);
|
|
595
|
-
if (seenNames.has(subspace.name))
|
|
596
|
-
throw new Error(`${SubspaceConfig.fileName}: duplicate subspace "${subspace.name}"`);
|
|
597
|
-
seenNames.add(subspace.name);
|
|
598
|
-
if (!subspace.apps?.length)
|
|
599
|
-
throw new Error(`${SubspaceConfig.fileName}: subspace "${subspace.name}" declares no apps`);
|
|
600
|
-
for (const app of subspace.apps) {
|
|
601
|
-
const owner = appOwners.get(app);
|
|
602
|
-
if (owner)
|
|
603
|
-
throw new Error(`${SubspaceConfig.fileName}: app "${app}" is claimed by both "${owner}" and "${subspace.name}"`);
|
|
604
|
-
appOwners.set(app, subspace.name);
|
|
605
|
-
}
|
|
606
|
-
if (!subspace.workspaceId)
|
|
607
|
-
continue;
|
|
608
|
-
const idOwner = idOwners.get(subspace.workspaceId);
|
|
609
|
-
if (idOwner)
|
|
610
|
-
throw new Error(`${SubspaceConfig.fileName}: subspaces "${idOwner}" and "${subspace.name}" declare the same workspaceId`);
|
|
611
|
-
idOwners.set(subspace.workspaceId, subspace.name);
|
|
612
|
-
}
|
|
613
|
-
}
|
|
614
|
-
select(names) {
|
|
615
|
-
if (!names.length)
|
|
616
|
-
return this.subspaces;
|
|
617
|
-
return names.map((name) => {
|
|
618
|
-
const subspace = this.subspaces.find((candidate) => candidate.name === name);
|
|
619
|
-
if (!subspace)
|
|
620
|
-
throw new Error(`${SubspaceConfig.fileName}: unknown subspace "${name}"`);
|
|
621
|
-
return subspace;
|
|
622
|
-
});
|
|
623
|
-
}
|
|
624
|
-
assertPushable(branch) {
|
|
625
|
-
if (this.pushableBranches.includes(branch))
|
|
626
|
-
return;
|
|
627
|
-
throw new Error(`Branch "${branch}" is not pushable. ${SubspaceConfig.fileName} allows: ${this.pushableBranches.join(", ")}`);
|
|
628
|
-
}
|
|
629
|
-
}
|
|
630
|
-
|
|
631
677
|
// pkgs/@akanjs/cli/subspace/subspace.runner.ts
|
|
632
678
|
var loadPrompts = async () => await import("@inquirer/prompts");
|
|
633
679
|
|
|
@@ -636,7 +682,7 @@ class SubspaceRunner extends runner("subspace") {
|
|
|
636
682
|
async config(workspace) {
|
|
637
683
|
const config = await SubspaceConfig.from(workspace);
|
|
638
684
|
if (!config)
|
|
639
|
-
throw new Error(
|
|
685
|
+
throw new Error("The workspace root akan.config.ts declares no `subspace`. Declare the customer repos there first.");
|
|
640
686
|
return config;
|
|
641
687
|
}
|
|
642
688
|
async subspaces(workspace, names) {
|
|
@@ -655,7 +701,7 @@ class SubspaceRunner extends runner("subspace") {
|
|
|
655
701
|
static async chooseNames(config, action, { interactive, prompts }) {
|
|
656
702
|
const multiple = SubspaceRunner.multiTargetActions.includes(action);
|
|
657
703
|
if (!config.subspaces.length)
|
|
658
|
-
throw new Error(`${SubspaceConfig.
|
|
704
|
+
throw new Error(`${SubspaceConfig.source} declares no subspaces.`);
|
|
659
705
|
if (!interactive) {
|
|
660
706
|
throw new Error(multiple ? `\`akan subspace ${action}\` needs a subspace name when it cannot prompt. Pass one, or run \`akan subspace ${action}-all\` for every subspace.` : `\`akan subspace ${action}\` needs a subspace name when it cannot prompt \u2014 it is reviewed one repo at a time.`);
|
|
661
707
|
}
|
|
@@ -684,6 +730,13 @@ class SubspaceRunner extends runner("subspace") {
|
|
|
684
730
|
results.push(await subspace.push(branch, { verify }));
|
|
685
731
|
return results;
|
|
686
732
|
}
|
|
733
|
+
async plan(workspace, name) {
|
|
734
|
+
const { subspaces, branch } = await this.subspaces(workspace, [name]);
|
|
735
|
+
const [subspace] = subspaces;
|
|
736
|
+
if (!subspace)
|
|
737
|
+
throw new Error(`Unknown subspace "${name}"`);
|
|
738
|
+
return await subspace.plan(branch);
|
|
739
|
+
}
|
|
687
740
|
async diff(workspace, name, filter) {
|
|
688
741
|
const { subspaces, branch } = await this.subspaces(workspace, [name]);
|
|
689
742
|
const [subspace] = subspaces;
|
|
@@ -706,7 +759,7 @@ class SubspaceRunner extends runner("subspace") {
|
|
|
706
759
|
const subspace = new Subspace(workspace, config, declaration);
|
|
707
760
|
const { workspaceId } = subspace;
|
|
708
761
|
if (!workspaceId)
|
|
709
|
-
throw new Error(`Subspace "${subspace.name}" declares no workspaceId. Add its cloud workspace id to ${SubspaceConfig.
|
|
762
|
+
throw new Error(`Subspace "${subspace.name}" declares no workspaceId. Add its cloud workspace id to ${SubspaceConfig.source}.`);
|
|
710
763
|
if (workspaceId === workspace.getWorkspaceId({ allowEmpty: true }))
|
|
711
764
|
throw new Error(`Subspace "${subspace.name}" declares this workspace's own id. Uploading a slice there would replace the workspace's env archive with a subset of it.`);
|
|
712
765
|
const apps = subspace.apps;
|
|
@@ -714,7 +767,7 @@ class SubspaceRunner extends runner("subspace") {
|
|
|
714
767
|
if (!asked)
|
|
715
768
|
return { name: subspace.name, workspaceId, host, apps, libs: [], outcome: "cancelled", files: [] };
|
|
716
769
|
const { libs } = await subspace.slice();
|
|
717
|
-
const { CloudScript } = await import("./cloud.script-
|
|
770
|
+
const { CloudScript } = await import("./cloud.script-r7eyfey4.js");
|
|
718
771
|
const { files } = await CommandContainer.get(CloudScript).uploadEnv(workspace, {
|
|
719
772
|
host,
|
|
720
773
|
workspaceId,
|
|
@@ -758,6 +811,12 @@ class SubspaceScript extends script("subspace", [SubspaceRunner]) {
|
|
|
758
811
|
if (results.some((result) => result.outcome === "refused"))
|
|
759
812
|
process.exitCode = 1;
|
|
760
813
|
}
|
|
814
|
+
async plan(workspace, name, format = "text") {
|
|
815
|
+
const spinner = workspace.spinning(`Planning ${name}...`);
|
|
816
|
+
const plan = await this.subspaceRunner.plan(workspace, name);
|
|
817
|
+
spinner.succeed(`${plan.apps.length} app(s), ${plan.libs.length} librar(ies), ${plan.files} file(s)`);
|
|
818
|
+
Logger.rawLog(format === "json" ? JSON.stringify(plan, null, 2) : formatSubspacePlan(plan));
|
|
819
|
+
}
|
|
761
820
|
async diff(workspace, name, filter, format = "text") {
|
|
762
821
|
const spinner = workspace.spinning(`Diffing ${name}...`);
|
|
763
822
|
const result = await this.subspaceRunner.diff(workspace, name, filter);
|
|
@@ -766,7 +825,10 @@ class SubspaceScript extends script("subspace", [SubspaceRunner]) {
|
|
|
766
825
|
Logger.rawLog(format === "json" ? JSON.stringify(result, null, 2) : formatSubspaceDiff(result));
|
|
767
826
|
}
|
|
768
827
|
async uploadEnv(workspace, name, { host, force, format }) {
|
|
769
|
-
const result = await this.subspaceRunner.uploadEnv(workspace, name, {
|
|
828
|
+
const result = await this.subspaceRunner.uploadEnv(workspace, name, {
|
|
829
|
+
host: await GlobalConfig.hostFor(workspace, host),
|
|
830
|
+
force
|
|
831
|
+
});
|
|
770
832
|
Logger.rawLog(format === "json" ? JSON.stringify(result, null, 2) : formatSubspaceEnvUpload(result));
|
|
771
833
|
}
|
|
772
834
|
async pull(workspace, name, { adoptLibs, format }) {
|
|
@@ -780,9 +842,9 @@ class SubspaceScript extends script("subspace", [SubspaceRunner]) {
|
|
|
780
842
|
// pkgs/@akanjs/cli/subspace/subspace.command.ts
|
|
781
843
|
class SubspaceCommand extends command("subspace", [SubspaceScript], ({ public: target }) => ({
|
|
782
844
|
subspace: target({ desc: "Mirror apps and libraries between this workspace and the customer repos it serves" }).arg("action", String, {
|
|
783
|
-
desc: "subspace action; status-all and push-all take every declared subspace",
|
|
845
|
+
desc: "subspace action; plan reads this checkout alone, status-all and push-all take every declared subspace",
|
|
784
846
|
default: "status",
|
|
785
|
-
enum: ["status", "status-all", "diff", "push", "push-all", "pull", "upload-env"]
|
|
847
|
+
enum: ["status", "status-all", "plan", "diff", "push", "push-all", "pull", "upload-env"]
|
|
786
848
|
}).arg("subspace", String, {
|
|
787
849
|
desc: "subspace name; asks which one(s) when omitted, and is refused by status-all / push-all",
|
|
788
850
|
nullable: true
|
|
@@ -790,7 +852,10 @@ class SubspaceCommand extends command("subspace", [SubspaceScript], ({ public: t
|
|
|
790
852
|
flag: "y",
|
|
791
853
|
desc: "run bun install + akan sync in the subspace before committing",
|
|
792
854
|
default: true
|
|
793
|
-
}).option("adoptLibs", Boolean, { desc: "pull: also apply the subspace's library edits", default: false }).option("path", String, { desc: "diff: limit to one path", nullable: true }).option("host", String, {
|
|
855
|
+
}).option("adoptLibs", Boolean, { desc: "pull: also apply the subspace's library edits", default: false }).option("path", String, { desc: "diff: limit to one path", nullable: true }).option("host", String, {
|
|
856
|
+
desc: "upload-env: host of the cloud to target (default: cloud.host of the root akan.config.ts, else Akan Cloud)",
|
|
857
|
+
nullable: true
|
|
858
|
+
}).option("force", Boolean, {
|
|
794
859
|
flag: "F",
|
|
795
860
|
desc: "upload-env: replace the subspace's env archive without asking",
|
|
796
861
|
default: false
|
|
@@ -798,8 +863,8 @@ class SubspaceCommand extends command("subspace", [SubspaceScript], ({ public: t
|
|
|
798
863
|
const output = format;
|
|
799
864
|
const all = action === "status-all" || action === "push-all";
|
|
800
865
|
const base = all ? action.slice(0, -"-all".length) : action;
|
|
801
|
-
if (base !== "status" && base !== "diff" && base !== "push" && base !== "pull" && base !== "upload-env")
|
|
802
|
-
throw new Error(`Unknown subspace action: ${action}. Use status, status-all, diff, push, push-all, pull or upload-env.`);
|
|
866
|
+
if (base !== "status" && base !== "plan" && base !== "diff" && base !== "push" && base !== "pull" && base !== "upload-env")
|
|
867
|
+
throw new Error(`Unknown subspace action: ${action}. Use status, status-all, plan, diff, push, push-all, pull or upload-env.`);
|
|
803
868
|
if (all && subspace)
|
|
804
869
|
throw new Error(`\`akan subspace ${action}\` takes no name. Run \`akan subspace ${base} ${subspace}\` instead.`);
|
|
805
870
|
const names = subspace ? [subspace] : all ? [] : await this.subspaceScript.select(workspace, base);
|
|
@@ -811,7 +876,9 @@ class SubspaceCommand extends command("subspace", [SubspaceScript], ({ public: t
|
|
|
811
876
|
const [name] = names;
|
|
812
877
|
if (!name)
|
|
813
878
|
throw new Error(`\`akan subspace ${base}\` needs a name \u2014 it is reviewed one repo at a time.`);
|
|
814
|
-
if (base === "
|
|
879
|
+
if (base === "plan")
|
|
880
|
+
await this.subspaceScript.plan(workspace, name, output);
|
|
881
|
+
else if (base === "diff")
|
|
815
882
|
await this.subspaceScript.diff(workspace, name, filePath, output);
|
|
816
883
|
else if (base === "upload-env")
|
|
817
884
|
await this.subspaceScript.uploadEnv(workspace, name, { host, force, format: output });
|
|
@@ -11,9 +11,9 @@ import { Link } from "akanjs/ui";
|
|
|
11
11
|
|
|
12
12
|
export default page()
|
|
13
13
|
.param("taskId", ID)
|
|
14
|
-
.render(
|
|
14
|
+
.render(({ taskId }) => {
|
|
15
15
|
const { l } = usePage();
|
|
16
|
-
const { taskView } =
|
|
16
|
+
const { taskView } = fetch.viewTask(taskId);
|
|
17
17
|
return (
|
|
18
18
|
<main className="mx-auto max-w-4xl px-6 py-8">
|
|
19
19
|
<div className="mb-6 flex items-center justify-between">
|
|
@@ -11,8 +11,8 @@ import { Link, Load } from "akanjs/ui";
|
|
|
11
11
|
|
|
12
12
|
export default page()
|
|
13
13
|
.param("taskId", ID)
|
|
14
|
-
.render(
|
|
15
|
-
const { taskEdit } =
|
|
14
|
+
.render(({ taskId }) => {
|
|
15
|
+
const { taskEdit } = fetch.editTask(taskId);
|
|
16
16
|
|
|
17
17
|
return (
|
|
18
18
|
<main className="mx-auto max-w-2xl px-6 py-8">
|
|
@@ -8,9 +8,9 @@ import { jellyButtonRecipe } from "@apps/${dict.appName}/ui";
|
|
|
8
8
|
import { page } from "akanjs/client";
|
|
9
9
|
import { Link } from "akanjs/ui";
|
|
10
10
|
|
|
11
|
-
export default page().render(
|
|
11
|
+
export default page().render(() => {
|
|
12
12
|
const { l } = usePage();
|
|
13
|
-
const { taskInitInPublic } =
|
|
13
|
+
const { taskInitInPublic } = fetch.initTaskInPublic();
|
|
14
14
|
return (
|
|
15
15
|
<main className="mx-auto max-w-4xl px-6 py-8">
|
|
16
16
|
<div className="mb-6 flex items-center justify-between">
|
|
@@ -18,9 +18,9 @@ import { Load } from "akanjs/ui";
|
|
|
18
18
|
export default page()
|
|
19
19
|
.param("${dict.model}Id", ID)
|
|
20
20
|
.config({ transition: "none" })
|
|
21
|
-
.render(
|
|
21
|
+
.render(({ ${dict.model}Id }) => {
|
|
22
22
|
const { l } = usePage();
|
|
23
|
-
const
|
|
23
|
+
const { ${dict.model}Edit } = fetch.edit${dict.Model}(${dict.model}Id);
|
|
24
24
|
return (
|
|
25
25
|
<div className="container">
|
|
26
26
|
<div className="m-4 mt-8 flex justify-between">
|
|
@@ -26,14 +26,14 @@ export default page()
|
|
|
26
26
|
<meta property="og:description" content={${dict.model}Id} />
|
|
27
27
|
</>
|
|
28
28
|
))
|
|
29
|
-
.render(
|
|
29
|
+
.render(({ ${dict.model}Id }) => {
|
|
30
30
|
const { l } = usePage();
|
|
31
|
-
const
|
|
31
|
+
const { ${dict.model}View } = fetch.view${dict.Model}(${dict.model}Id);
|
|
32
32
|
return (
|
|
33
33
|
<div className="container flex flex-col gap-4">
|
|
34
34
|
<div className="flex items-center gap-4 font-bold text-lg">
|
|
35
35
|
<${dict.Model}.Zone.View view={${dict.model}View} />
|
|
36
|
-
<Link className={buttonRecipe()} href={\`/${dict.model}/\${${dict.model}
|
|
36
|
+
<Link className={buttonRecipe()} href={\`/${dict.model}/\${${dict.model}Id}/edit\`}>
|
|
37
37
|
{l("base.updateModel", { model: l("${dict.model}.modelName") })}
|
|
38
38
|
</Link>
|
|
39
39
|
</div>
|
|
@@ -16,9 +16,9 @@ import { buttonRecipe, Link } from "akanjs/ui";
|
|
|
16
16
|
|
|
17
17
|
export default page()
|
|
18
18
|
.config({ transition: "none" })
|
|
19
|
-
.render(
|
|
19
|
+
.render(() => {
|
|
20
20
|
const { l } = usePage();
|
|
21
|
-
const
|
|
21
|
+
const { ${dict.model}InitInPublic } = fetch.init${dict.Model}InPublic();
|
|
22
22
|
return (
|
|
23
23
|
<div className="container flex flex-col gap-4">
|
|
24
24
|
<div className="mt-5 h-full w-full px-5">
|
|
@@ -16,15 +16,15 @@ import { buttonRecipe, Model } from "akanjs/ui";
|
|
|
16
16
|
|
|
17
17
|
export default page()
|
|
18
18
|
.config({ transition: "none" })
|
|
19
|
-
.render(
|
|
19
|
+
.render(() => {
|
|
20
20
|
const { l } = usePage();
|
|
21
|
-
const
|
|
21
|
+
const { ${dict.model}InitInPublic } = fetch.init${dict.Model}InPublic();
|
|
22
22
|
return (
|
|
23
23
|
<>
|
|
24
24
|
<div className="flex animate-fadeIn items-center gap-4 px-4 pt-4">
|
|
25
25
|
<div className="font-bold text-lg md:text-4xl">{l("${dict.model}.modelName")}</div>
|
|
26
26
|
<Model.New
|
|
27
|
-
className={buttonRecipe({ size: "sm", variant: "ghost" })}
|
|
27
|
+
trigger={<button className={buttonRecipe({ size: "sm", variant: "ghost" })}>{l("base.new")}</button>}
|
|
28
28
|
slice={fetch.slice.${dict.model}InPublic}
|
|
29
29
|
renderTitle="id"
|
|
30
30
|
>
|
package/templates/lib/cnst.ts
CHANGED
|
@@ -21,9 +21,9 @@ ${databaseModules.map((module) => `export * from "./${module}/${module}.constant
|
|
|
21
21
|
${databaseModules
|
|
22
22
|
.map((module) => {
|
|
23
23
|
const names = { Module: capitalize(module) };
|
|
24
|
-
return `export const ${module} = ConstantRegistry.buildModel("${module}" as const, ${module}Cnst.${names.Module}Input, ${module}Cnst.${names.Module}Object, ${module}Cnst.${names.Module}, ${module}Cnst.Light${names.Module}, ${module}Cnst.${names.Module}Insight, ${module}Cnst);`;
|
|
24
|
+
return `export const ${module} = ConstantRegistry.buildModel("${module}" as const, ${module}Cnst.${names.Module}Input, ${module}Cnst.${names.Module}Object, ${module}Cnst.${names.Module}, ${module}Cnst.Light${names.Module}, ${module}Cnst.${names.Module}Insight, ${module}Cnst, "${scanInfo.name}");`;
|
|
25
25
|
})
|
|
26
26
|
.join("\n")}
|
|
27
|
-
${scalarModules.map((module) => `export const ${module} = ConstantRegistry.buildScalar("${module}" as const, ${module}Cnst.${capitalize(module)}, ${module}Cnst);`).join("\n")}
|
|
27
|
+
${scalarModules.map((module) => `export const ${module} = ConstantRegistry.buildScalar("${module}" as const, ${module}Cnst.${capitalize(module)}, ${module}Cnst, "${scanInfo.name}");`).join("\n")}
|
|
28
28
|
`;
|
|
29
29
|
}
|