@akanjs/cli 0.9.56 → 0.9.58-canary.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/cjs/index.js +76 -45
- package/cjs/src/guidelines/databaseModule/databaseModule.instruction.md +7 -1
- package/cjs/src/guidelines/modelSignal/modelSignal.instruction.md +3 -3
- package/cjs/src/guidelines/modelTemplate/modelTemplate.instruction.md +5 -5
- package/cjs/src/guidelines/sharedUiUsage/sharedUiUsage.generate.json +0 -7
- package/cjs/src/guidelines/sharedUiUsage/sharedUiUsage.instruction.md +7 -7
- package/cjs/src/templates/app/app/[lang]/layout.js +2 -0
- package/cjs/src/templates/app/app/[lang]/styles.css.template +1 -0
- package/cjs/src/templates/app/lib/option.js +6 -1
- package/cjs/src/templates/app/main.js +2 -2
- package/cjs/src/templates/lib/__lib/lib.dictionary.js +1 -2
- package/cjs/src/templates/lib/dict.js +22 -6
- package/cjs/src/templates/lib/sig.js +5 -2
- package/cjs/src/templates/lib/useClient.js +5 -4
- package/cjs/src/templates/libRoot/lib/option.js +5 -1
- package/cjs/src/templates/module/__Model__.Template.js +2 -2
- package/cjs/src/templates/module/__Model__.Util.js +8 -1
- package/cjs/src/templates/module/__model__.constant.js +3 -8
- package/cjs/src/templates/module/__model__.dictionary.js +21 -59
- package/cjs/src/templates/module/__model__.document.js +1 -1
- package/cjs/src/templates/module/__model__.signal.js +5 -4
- package/cjs/src/templates/server.js +11 -3
- package/esm/index.js +76 -45
- package/esm/src/guidelines/databaseModule/databaseModule.instruction.md +7 -1
- package/esm/src/guidelines/modelSignal/modelSignal.instruction.md +3 -3
- package/esm/src/guidelines/modelTemplate/modelTemplate.instruction.md +5 -5
- package/esm/src/guidelines/sharedUiUsage/sharedUiUsage.generate.json +0 -7
- package/esm/src/guidelines/sharedUiUsage/sharedUiUsage.instruction.md +7 -7
- package/esm/src/templates/app/app/[lang]/layout.js +2 -0
- package/esm/src/templates/app/app/[lang]/styles.css.template +1 -0
- package/esm/src/templates/app/lib/option.js +6 -1
- package/esm/src/templates/app/main.js +2 -2
- package/esm/src/templates/lib/__lib/lib.dictionary.js +1 -2
- package/esm/src/templates/lib/dict.js +22 -6
- package/esm/src/templates/lib/sig.js +5 -2
- package/esm/src/templates/lib/useClient.js +5 -4
- package/esm/src/templates/libRoot/lib/option.js +5 -1
- package/esm/src/templates/module/__Model__.Template.js +2 -2
- package/esm/src/templates/module/__Model__.Util.js +8 -1
- package/esm/src/templates/module/__model__.constant.js +3 -8
- package/esm/src/templates/module/__model__.dictionary.js +21 -59
- package/esm/src/templates/module/__model__.document.js +1 -1
- package/esm/src/templates/module/__model__.signal.js +5 -4
- package/esm/src/templates/server.js +11 -3
- package/package.json +1 -1
- package/src/guidelines/databaseModule/databaseModule.instruction.md +7 -1
- package/src/guidelines/modelSignal/modelSignal.instruction.md +3 -3
- package/src/guidelines/modelTemplate/modelTemplate.instruction.md +5 -5
- package/src/guidelines/sharedUiUsage/sharedUiUsage.instruction.md +7 -7
- package/src/module/module.command.d.ts +1 -1
- package/src/module/module.runner.d.ts +1 -1
- package/src/module/module.script.d.ts +1 -1
- package/src/scalar/scalar.command.d.ts +1 -1
- package/src/scalar/scalar.script.d.ts +1 -1
- package/src/workspace/workspace.command.d.ts +2 -0
- package/src/workspace/workspace.script.d.ts +2 -0
|
@@ -24,64 +24,26 @@ __export(model_dictionary_exports, {
|
|
|
24
24
|
module.exports = __toCommonJS(model_dictionary_exports);
|
|
25
25
|
function getContent(scanInfo, dict) {
|
|
26
26
|
return `
|
|
27
|
-
import {
|
|
28
|
-
|
|
29
|
-
import type { ${dict.Model}, ${dict.Model}
|
|
30
|
-
import type { ${dict.Model}
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
// * ==================== Insight ==================== * //
|
|
49
|
-
|
|
50
|
-
// * ==================== Filter ==================== * //
|
|
51
|
-
"qry-inStatus": ["In Status", "\uC0C1\uD0DC"],
|
|
52
|
-
"qrydesc-inStatus": ["Filter by status", "\uC0C1\uD0DC\uBCC4 \uD544\uD130\uB9C1"],
|
|
53
|
-
"qarg-inStatus-status": ["Status", "\uC0C1\uD0DC"],
|
|
54
|
-
"qargdesc-inStatus-status": ["Filter by status", "\uC0C1\uD0DC\uBCC4 \uD544\uD130\uB9C1"],
|
|
55
|
-
// * ==================== Filter ==================== * //
|
|
56
|
-
|
|
57
|
-
// * ==================== Etc ==================== * //
|
|
58
|
-
"enum-status-active": ["Active", "\uD65C\uC131"],
|
|
59
|
-
"enumdesc-status-active": ["Active status", "\uD65C\uC131 \uC0C1\uD0DC"],
|
|
60
|
-
// * ==================== Etc ==================== * //
|
|
61
|
-
} satisfies ModelDictionary<${dict.Model}, ${dict.Model}Insight, ${dict.Model}Filter>;
|
|
62
|
-
|
|
63
|
-
export const signalDictionary = {
|
|
64
|
-
...getBaseSignalTrans("${dict.model}" as const),
|
|
65
|
-
// * ==================== Endpoint ==================== * //
|
|
66
|
-
"api-${dict.model}ListInPublic": ["${dict.Model} List In Public", "\uACF5\uAC1C\uB41C ${dict.Model} \uB9AC\uC2A4\uD2B8"],
|
|
67
|
-
"apidesc-${dict.model}ListInPublic": ["Get a list of public ${dict.model}", "\uACF5\uAC1C\uB41C ${dict.Model}\uC758 \uB9AC\uC2A4\uD2B8\uB97C \uAC00\uC838\uC635\uB2C8\uB2E4"],
|
|
68
|
-
"arg-${dict.model}ListInPublic-statuses": ["Statuses", "\uC0C1\uD0DC"],
|
|
69
|
-
"argdesc-${dict.model}ListInPublic-statuses": ["Statuses to filter", "\uD544\uD130\uB9C1\uD560 \uC0C1\uD0DC"],
|
|
70
|
-
"arg-${dict.model}ListInPublic-skip": ["Skip", "\uAC74\uB108\uB6F0\uAE30"],
|
|
71
|
-
"argdesc-${dict.model}ListInPublic-skip": ["Number of items to skip", "\uAC74\uB108\uB6F8 \uC544\uC774\uD15C \uC218"],
|
|
72
|
-
"arg-${dict.model}ListInPublic-limit": ["Limit", "\uC81C\uD55C"],
|
|
73
|
-
"argdesc-${dict.model}ListInPublic-limit": ["Maximum number of items to return", "\uBC18\uD658\uD560 \uCD5C\uB300 \uC544\uC774\uD15C \uC218"],
|
|
74
|
-
"arg-${dict.model}ListInPublic-sort": ["Sort", "\uC815\uB82C"],
|
|
75
|
-
"argdesc-${dict.model}ListInPublic-sort": ["Sort order of the items", "\uC544\uC774\uD15C\uC758 \uC815\uB82C \uC21C\uC11C"],
|
|
76
|
-
|
|
77
|
-
"api-${dict.model}InsightInPublic": ["${dict.Model} Insight In Public", "\uACF5\uAC1C\uB41C ${dict.Model} \uC778\uC0AC\uC774\uD2B8"],
|
|
78
|
-
"apidesc-${dict.model}InsightInPublic": [
|
|
79
|
-
"Get insight data for public ${dict.model}",
|
|
80
|
-
"\uACF5\uAC1C\uB41C ${dict.Model}\uC5D0 \uB300\uD55C \uC778\uC0AC\uC774\uD2B8 \uB370\uC774\uD130\uB97C \uAC00\uC838\uC635\uB2C8\uB2E4",
|
|
81
|
-
],
|
|
82
|
-
"arg-${dict.model}InsightInPublic-statuses": ["Statuses", "\uC0C1\uD0DC"],
|
|
83
|
-
"argdesc-${dict.model}InsightInPublic-statuses": ["Statuses to filter", "\uD544\uD130\uB9C1\uD560 \uC0C1\uD0DC"],
|
|
84
|
-
// * ==================== Endpoint ==================== * //
|
|
85
|
-
} satisfies SignalDictionary<${dict.Model}Signal, ${dict.Model}>;
|
|
27
|
+
import { modelDictionary } from "@akanjs/dictionary";
|
|
28
|
+
|
|
29
|
+
import type { ${dict.Model}, ${dict.Model}Insight } from "./${dict.model}.constant";
|
|
30
|
+
import type { ${dict.Model}Filter } from "./${dict.model}.document";
|
|
31
|
+
import type { ${dict.Model}Endpoint, ${dict.Model}Slice } from "./${dict.model}.signal";
|
|
32
|
+
|
|
33
|
+
export const dictionary = modelDictionary(["en", "ko"])
|
|
34
|
+
.of((t) =>
|
|
35
|
+
t(["${dict.Model}", "${dict.Model}"]).desc(["${dict.Model} description", "${dict.Model} \uC124\uBA85"])
|
|
36
|
+
)
|
|
37
|
+
.model<${dict.Model}>((t) => ({
|
|
38
|
+
field: t(["Field", "\uD544\uB4DC"]).desc(["Field description", "\uD544\uB4DC \uC124\uBA85"]),
|
|
39
|
+
}))
|
|
40
|
+
.insight<${dict.Model}Insight>((t) => ({}))
|
|
41
|
+
.query<${dict.Model}Filter>((fn) => ({}))
|
|
42
|
+
.slice<${dict.Model}Slice>((fn) => ({
|
|
43
|
+
inPublic: fn(["${dict.Model} In Public", "${dict.Model} \uACF5\uAC1C"]).arg((t) => ({})),
|
|
44
|
+
}))
|
|
45
|
+
.endpoint<${dict.Model}Endpoint>((fn) => ({}))
|
|
46
|
+
.error({})
|
|
47
|
+
.translate({});
|
|
86
48
|
`;
|
|
87
49
|
}
|
|
@@ -24,7 +24,7 @@ __export(model_document_exports, {
|
|
|
24
24
|
module.exports = __toCommonJS(model_document_exports);
|
|
25
25
|
function getContent(scanInfo, dict) {
|
|
26
26
|
return `
|
|
27
|
-
import { beyond, by, into, type SchemaOf } from "@akanjs/document";
|
|
27
|
+
import { beyond, by, from, into, type SchemaOf } from "@akanjs/document";
|
|
28
28
|
|
|
29
29
|
import * as cnst from "../cnst";
|
|
30
30
|
|
|
@@ -24,18 +24,19 @@ __export(model_signal_exports, {
|
|
|
24
24
|
module.exports = __toCommonJS(model_signal_exports);
|
|
25
25
|
function getContent(scanInfo, dict) {
|
|
26
26
|
return `
|
|
27
|
+
import { Public } from "@akanjs/nest";
|
|
27
28
|
import { endpoint, internal, slice } from "@akanjs/signal";
|
|
29
|
+
import { Admin } from "@shared/nest";
|
|
28
30
|
|
|
29
31
|
import * as cnst from "../cnst";
|
|
30
32
|
import * as srv from "../srv";
|
|
31
33
|
|
|
32
34
|
export class ${dict.Model}Internal extends internal(srv.${dict.model}, () => ({})) {}
|
|
33
35
|
|
|
34
|
-
export class ${dict.Model}Slice extends slice(srv.${dict.model}, { guards: { get:
|
|
36
|
+
export class ${dict.Model}Slice extends slice(srv.${dict.model}, { guards: { root: Admin, get: Public, cru: Public } }, (init) => ({
|
|
35
37
|
inPublic: init()
|
|
36
|
-
.
|
|
37
|
-
|
|
38
|
-
return this.${dict.model}Service.queryByStatuses(statuses);
|
|
38
|
+
.exec(function () {
|
|
39
|
+
return this.${dict.model}Service.queryAny();
|
|
39
40
|
}),
|
|
40
41
|
})) {}
|
|
41
42
|
|
|
@@ -31,15 +31,15 @@ function getContent(scanInfo, dict = {}) {
|
|
|
31
31
|
const serviceModules = [...scanInfo.service.entries()].filter(([_, files]) => files.has("service"));
|
|
32
32
|
const scalarModules = [...scanInfo.scalar.entries()];
|
|
33
33
|
return `
|
|
34
|
-
import { databaseModuleOf, scalarModulesOf, serviceModuleOf, type Module } from "@akanjs/server";
|
|
35
|
-
${libs.map((lib) => `import { registerModules as register${capitalize(lib)}Modules } from "@${lib}/server";`).join("\n")}
|
|
34
|
+
import { databaseModuleOf, scalarModulesOf, serviceModuleOf, type Module, type Middleware } from "@akanjs/server";
|
|
35
|
+
${libs.map((lib) => `import { registerModules as register${capitalize(lib)}Modules, registerMiddlewares as register${capitalize(lib)}Middlewares } from "@${lib}/server";`).join("\n")}
|
|
36
36
|
|
|
37
37
|
import * as cnst from "./lib/cnst";
|
|
38
38
|
import * as db from "./lib/db";
|
|
39
39
|
import * as srv from "./lib/srv";
|
|
40
40
|
import { allSrvs } from "./lib/srv";
|
|
41
41
|
import * as sig from "./lib/sig";
|
|
42
|
-
import { type ModulesOptions, registerGlobalModule } from "./lib/option";
|
|
42
|
+
import { type ModulesOptions, registerGlobalModule, registerGlobalMiddlewares } from "./lib/option";
|
|
43
43
|
|
|
44
44
|
// database modules
|
|
45
45
|
${databaseModules.map(([model]) => {
|
|
@@ -67,6 +67,14 @@ ${databaseModules.map(([model]) => ` register${capitalize(model)}Module(),`).
|
|
|
67
67
|
return modules;
|
|
68
68
|
};
|
|
69
69
|
|
|
70
|
+
export const registerMiddlewares = (options: ModulesOptions, isChild?: boolean) => {
|
|
71
|
+
const middlewares = [
|
|
72
|
+
${libs.map((lib) => ` ...(!isChild ? register${capitalize(lib)}Middlewares(options, true) : []),`).join("\n")}
|
|
73
|
+
...registerGlobalMiddlewares(options),
|
|
74
|
+
] as Middleware[];
|
|
75
|
+
return middlewares;
|
|
76
|
+
};
|
|
77
|
+
|
|
70
78
|
export { env } from "./env/env.server.testing";
|
|
71
79
|
export * as db from "./lib/db";
|
|
72
80
|
export * as srv from "./lib/srv";
|
package/esm/index.js
CHANGED
|
@@ -208,7 +208,7 @@ var Logger = class _Logger {
|
|
|
208
208
|
const contentMsg = this.#colorize(content, logLevel);
|
|
209
209
|
const timeDiffMsg = clc.yellow(`+${now.diff(_Logger.#startAt, "ms")}ms`);
|
|
210
210
|
if (typeof window === "undefined")
|
|
211
|
-
process[writeStreamType]
|
|
211
|
+
process[writeStreamType]?.write(
|
|
212
212
|
`${processMsg} ${timestampMsg} ${logLevelMsg} ${contextMsg} ${contentMsg} ${timeDiffMsg}
|
|
213
213
|
`
|
|
214
214
|
);
|
|
@@ -1986,10 +1986,10 @@ var Executor = class _Executor {
|
|
|
1986
1986
|
this.logger.verbose(`Remove file ${readPath}`);
|
|
1987
1987
|
return this;
|
|
1988
1988
|
}
|
|
1989
|
-
removeDir(dirPath) {
|
|
1989
|
+
async removeDir(dirPath) {
|
|
1990
1990
|
const readPath = this.getPath(dirPath);
|
|
1991
1991
|
if (fs8.existsSync(readPath))
|
|
1992
|
-
fs8.
|
|
1992
|
+
await fs8.promises.rm(readPath, { recursive: true });
|
|
1993
1993
|
this.logger.verbose(`Remove directory ${readPath}`);
|
|
1994
1994
|
return this;
|
|
1995
1995
|
}
|
|
@@ -2035,9 +2035,9 @@ var Executor = class _Executor {
|
|
|
2035
2035
|
async cp(srcPath, destPath) {
|
|
2036
2036
|
const src = this.getPath(srcPath);
|
|
2037
2037
|
const dest = this.getPath(destPath);
|
|
2038
|
-
const isDirectory = fs8.statSync(src).isDirectory();
|
|
2039
2038
|
if (!fs8.existsSync(src))
|
|
2040
2039
|
return;
|
|
2040
|
+
const isDirectory = fs8.statSync(src).isDirectory();
|
|
2041
2041
|
if (!fs8.existsSync(dest) && isDirectory)
|
|
2042
2042
|
await fsPromise.mkdir(dest, { recursive: true });
|
|
2043
2043
|
await fsPromise.cp(src, dest, { recursive: true });
|
|
@@ -2593,32 +2593,23 @@ var AppExecutor = class _AppExecutor extends SysExecutor {
|
|
|
2593
2593
|
return this.#akanConfig;
|
|
2594
2594
|
}
|
|
2595
2595
|
async syncAssets(libDeps) {
|
|
2596
|
-
const
|
|
2597
|
-
const
|
|
2596
|
+
const projectPublicPath = `${this.cwdPath}/public`;
|
|
2597
|
+
const projectAssetsPath = `${this.cwdPath}/assets`;
|
|
2598
|
+
const projectPublicLibPath = `${projectPublicPath}/libs`;
|
|
2599
|
+
const projectAssetsLibPath = `${projectAssetsPath}/libs`;
|
|
2600
|
+
await Promise.all([this.removeDir(projectPublicLibPath), this.removeDir(projectAssetsLibPath)]);
|
|
2601
|
+
const targetPublicDeps = libDeps.filter((dep) => this.exists(`${this.workspace.workspaceRoot}/libs/${dep}/public`));
|
|
2602
|
+
const targetAssetsDeps = libDeps.filter((dep) => this.exists(`${this.workspace.workspaceRoot}/libs/${dep}/assets`));
|
|
2598
2603
|
await Promise.all([
|
|
2599
|
-
|
|
2600
|
-
|
|
2601
|
-
]);
|
|
2602
|
-
const targetPublicDeps = libDeps.filter(
|
|
2603
|
-
(dep) => fs8.existsSync(`${this.workspace.workspaceRoot}/libs/${dep}/public`)
|
|
2604
|
-
);
|
|
2605
|
-
const targetAssetsDeps = libDeps.filter(
|
|
2606
|
-
(dep) => fs8.existsSync(`${this.workspace.workspaceRoot}/libs/${dep}/assets`)
|
|
2607
|
-
);
|
|
2608
|
-
await Promise.all([
|
|
2609
|
-
...targetPublicDeps.map((dep) => fsPromise.mkdir(`${projectPublicLibPath}/${dep}`, { recursive: true })),
|
|
2610
|
-
...targetAssetsDeps.map((dep) => fsPromise.mkdir(`${projectAssetsLibPath}/${dep}`, { recursive: true }))
|
|
2604
|
+
...targetPublicDeps.map((dep) => this.mkdir(`${projectPublicLibPath}/${dep}`)),
|
|
2605
|
+
...targetAssetsDeps.map((dep) => this.mkdir(`${projectAssetsLibPath}/${dep}`))
|
|
2611
2606
|
]);
|
|
2612
2607
|
await Promise.all([
|
|
2613
2608
|
...targetPublicDeps.map(
|
|
2614
|
-
(dep) =>
|
|
2615
|
-
recursive: true
|
|
2616
|
-
})
|
|
2609
|
+
(dep) => this.cp(`${this.workspace.workspaceRoot}/libs/${dep}/public`, `${projectPublicLibPath}/${dep}`)
|
|
2617
2610
|
),
|
|
2618
2611
|
...targetAssetsDeps.map(
|
|
2619
|
-
(dep) =>
|
|
2620
|
-
recursive: true
|
|
2621
|
-
})
|
|
2612
|
+
(dep) => this.cp(`${this.workspace.workspaceRoot}/libs/${dep}/assets`, `${projectAssetsLibPath}/${dep}`)
|
|
2622
2613
|
)
|
|
2623
2614
|
]);
|
|
2624
2615
|
}
|
|
@@ -4975,14 +4966,14 @@ var ApplicationScript = class {
|
|
|
4975
4966
|
}
|
|
4976
4967
|
async dumpDatabase(app, environment) {
|
|
4977
4968
|
await this.dbdown(app.workspace);
|
|
4978
|
-
const spinner = app.spinning(
|
|
4969
|
+
const spinner = app.spinning(`Dumping database ${app.name} (${environment})...`);
|
|
4979
4970
|
await this.#runner.dumpDatabase(app, environment);
|
|
4980
|
-
spinner.succeed(`Database dumped to dump/${app.name}-${environment}`);
|
|
4971
|
+
spinner.succeed(`Database ${app.name} (${environment}) dumped to dump/${app.name}-${environment}`);
|
|
4981
4972
|
}
|
|
4982
4973
|
async restoreDatabase(app, source, target) {
|
|
4983
|
-
const spinner = app.spinning(
|
|
4974
|
+
const spinner = app.spinning(`Restoring database ${app.name} (${source}) to ${target}...`);
|
|
4984
4975
|
await this.#runner.restoreDatabase(app, source, target);
|
|
4985
|
-
spinner.succeed(`Database
|
|
4976
|
+
spinner.succeed(`Database ${app.name} (${source}) restored to ${target}`);
|
|
4986
4977
|
}
|
|
4987
4978
|
async pullDatabase(app, environment, dump) {
|
|
4988
4979
|
const hasDump = app.workspace.exists(`dump/${app.name}-${environment}`);
|
|
@@ -5396,19 +5387,19 @@ ${chalk6.green("\u27A4")} Authentication Required`));
|
|
|
5396
5387
|
}
|
|
5397
5388
|
async deployAkan(workspace, akanPkgs) {
|
|
5398
5389
|
const basePackageJson = workspace.readJson("pkgs/@akanjs/base/package.json");
|
|
5399
|
-
const majorVersionOfBase = basePackageJson.version.split(".")
|
|
5400
|
-
const
|
|
5401
|
-
const getNextVersion = async (
|
|
5390
|
+
const [majorVersionOfBase, minorVersionOfBase, patchVersionOfBase, devPatchVersionOfBase] = basePackageJson.version.split(".");
|
|
5391
|
+
const targetVersionPrefix = devPatchVersionOfBase ? `${majorVersionOfBase}.${minorVersionOfBase}.${patchVersionOfBase}` : `${majorVersionOfBase}.${minorVersionOfBase}`;
|
|
5392
|
+
const getNextVersion = async (prefix) => {
|
|
5402
5393
|
try {
|
|
5403
|
-
const latestPublishedVersionOfBase = await latestVersion("@akanjs/base", { version:
|
|
5394
|
+
const latestPublishedVersionOfBase = await latestVersion("@akanjs/base", { version: prefix });
|
|
5404
5395
|
const latestPatch = parseInt(latestPublishedVersionOfBase.split(".")[2]);
|
|
5405
|
-
const nextVersion2 = `${
|
|
5396
|
+
const nextVersion2 = `${prefix}.${latestPatch + 1}`;
|
|
5406
5397
|
return { nextVersion: nextVersion2, latestPublishedVersion: latestPublishedVersionOfBase };
|
|
5407
5398
|
} catch (e) {
|
|
5408
|
-
return { nextVersion: `${
|
|
5399
|
+
return { nextVersion: `${prefix}.0`, latestPublishedVersion: null };
|
|
5409
5400
|
}
|
|
5410
5401
|
};
|
|
5411
|
-
const { nextVersion, latestPublishedVersion } = await getNextVersion(
|
|
5402
|
+
const { nextVersion, latestPublishedVersion } = await getNextVersion(targetVersionPrefix);
|
|
5412
5403
|
Logger.info(`Latest published version of @akanjs/base: ${latestPublishedVersion ?? "none"}`);
|
|
5413
5404
|
Logger.info(`Next version of @akanjs/base: ${nextVersion}`);
|
|
5414
5405
|
for (const library of akanPkgs) {
|
|
@@ -5924,8 +5915,8 @@ var requestUnit = ({
|
|
|
5924
5915
|
var ModuleRunner = class {
|
|
5925
5916
|
async createModule(workspace, sysType, sysName, moduleName, description) {
|
|
5926
5917
|
}
|
|
5927
|
-
removeModule(module) {
|
|
5928
|
-
module.sys.removeDir(`lib/${module.name}`);
|
|
5918
|
+
async removeModule(module) {
|
|
5919
|
+
await module.sys.removeDir(`lib/${module.name}`);
|
|
5929
5920
|
}
|
|
5930
5921
|
async createComponentTemplate(module, type) {
|
|
5931
5922
|
await module.sys.applyTemplate({
|
|
@@ -6062,8 +6053,8 @@ var ModuleScript = class {
|
|
|
6062
6053
|
await this.createTemplate(executor);
|
|
6063
6054
|
sys3.log(`Module ${name} created in ${sys3.type}s/${sys3.name}/lib/${name}`);
|
|
6064
6055
|
}
|
|
6065
|
-
removeModule(mod) {
|
|
6066
|
-
this.#runner.removeModule(mod);
|
|
6056
|
+
async removeModule(mod) {
|
|
6057
|
+
await this.#runner.removeModule(mod);
|
|
6067
6058
|
}
|
|
6068
6059
|
async createService(workspace, name) {
|
|
6069
6060
|
}
|
|
@@ -6141,8 +6132,8 @@ var ModuleCommand = class {
|
|
|
6141
6132
|
const name = lowerlize(moduleName.replace(/ /g, ""));
|
|
6142
6133
|
await this.moduleScript.createModuleTemplate(sys3, name, { page });
|
|
6143
6134
|
}
|
|
6144
|
-
removeModule(module) {
|
|
6145
|
-
this.moduleScript.removeModule(module);
|
|
6135
|
+
async removeModule(module) {
|
|
6136
|
+
await this.moduleScript.removeModule(module);
|
|
6146
6137
|
}
|
|
6147
6138
|
async createView(module) {
|
|
6148
6139
|
await this.moduleScript.createView(module);
|
|
@@ -6395,6 +6386,16 @@ var WorkspaceScript = class {
|
|
|
6395
6386
|
for (const appName of appNames)
|
|
6396
6387
|
await this.applicationScript.syncApplication(AppExecutor.from(workspace, appName));
|
|
6397
6388
|
}
|
|
6389
|
+
async dumpDatabaseAll(workspace, environment) {
|
|
6390
|
+
const appNames = await workspace.getApps();
|
|
6391
|
+
for (const appName of appNames)
|
|
6392
|
+
await this.applicationScript.dumpDatabase(AppExecutor.from(workspace, appName), environment);
|
|
6393
|
+
}
|
|
6394
|
+
async restoreDatabaseAll(workspace, source, target) {
|
|
6395
|
+
const appNames = await workspace.getApps();
|
|
6396
|
+
for (const appName of appNames)
|
|
6397
|
+
await this.applicationScript.restoreDatabase(AppExecutor.from(workspace, appName), source, target);
|
|
6398
|
+
}
|
|
6398
6399
|
};
|
|
6399
6400
|
|
|
6400
6401
|
// pkgs/@akanjs/cli/src/workspace/workspace.command.ts
|
|
@@ -6419,6 +6420,12 @@ var WorkspaceCommand = class {
|
|
|
6419
6420
|
async syncAll(workspace) {
|
|
6420
6421
|
await this.workspaceScript.syncAll(workspace);
|
|
6421
6422
|
}
|
|
6423
|
+
async dumpDatabaseAll(environment, workspace) {
|
|
6424
|
+
await this.workspaceScript.dumpDatabaseAll(workspace, environment);
|
|
6425
|
+
}
|
|
6426
|
+
async restoreDatabaseAll(source, target, workspace) {
|
|
6427
|
+
await this.workspaceScript.restoreDatabaseAll(workspace, source, target);
|
|
6428
|
+
}
|
|
6422
6429
|
};
|
|
6423
6430
|
__decorateClass([
|
|
6424
6431
|
Target.Public(),
|
|
@@ -6445,6 +6452,30 @@ __decorateClass([
|
|
|
6445
6452
|
Target.Public(),
|
|
6446
6453
|
__decorateParam(0, Workspace())
|
|
6447
6454
|
], WorkspaceCommand.prototype, "syncAll", 1);
|
|
6455
|
+
__decorateClass([
|
|
6456
|
+
Target.Public(),
|
|
6457
|
+
__decorateParam(0, Option("environment", {
|
|
6458
|
+
desc: "environment",
|
|
6459
|
+
default: "debug",
|
|
6460
|
+
enum: ["debug", "develop", "main"],
|
|
6461
|
+
ask: "Select the environment to dump the database"
|
|
6462
|
+
})),
|
|
6463
|
+
__decorateParam(1, Workspace())
|
|
6464
|
+
], WorkspaceCommand.prototype, "dumpDatabaseAll", 1);
|
|
6465
|
+
__decorateClass([
|
|
6466
|
+
Target.Public(),
|
|
6467
|
+
__decorateParam(0, Option("source", {
|
|
6468
|
+
desc: "source environment",
|
|
6469
|
+
enum: ["debug", "develop", "main"],
|
|
6470
|
+
ask: "Select the source environment of local dump"
|
|
6471
|
+
})),
|
|
6472
|
+
__decorateParam(1, Option("target", {
|
|
6473
|
+
desc: "target environment",
|
|
6474
|
+
enum: ["debug", "develop", "main"],
|
|
6475
|
+
ask: "Select the target environment to restore the database"
|
|
6476
|
+
})),
|
|
6477
|
+
__decorateParam(2, Workspace())
|
|
6478
|
+
], WorkspaceCommand.prototype, "restoreDatabaseAll", 1);
|
|
6448
6479
|
WorkspaceCommand = __decorateClass([
|
|
6449
6480
|
Commands()
|
|
6450
6481
|
], WorkspaceCommand);
|
|
@@ -6941,8 +6972,8 @@ var ScalarScript = class {
|
|
|
6941
6972
|
const { session, scalarNames } = await this.#runner.createScalarConstant(sys3, scalarName);
|
|
6942
6973
|
await this.#runner.updateScalarDictionaries(sys3, scalarNames, { session });
|
|
6943
6974
|
}
|
|
6944
|
-
removeScalar(sys3, scalarName) {
|
|
6945
|
-
sys3.removeDir(`lib/__scalar/${scalarName}`);
|
|
6975
|
+
async removeScalar(sys3, scalarName) {
|
|
6976
|
+
await sys3.removeDir(`lib/__scalar/${scalarName}`);
|
|
6946
6977
|
}
|
|
6947
6978
|
};
|
|
6948
6979
|
|
|
@@ -6952,8 +6983,8 @@ var ScalarCommand = class {
|
|
|
6952
6983
|
async createScalar(sys3, scalarName) {
|
|
6953
6984
|
await this.scalarScript.createScalar(sys3, lowerlize(scalarName.replace(/ /g, "")));
|
|
6954
6985
|
}
|
|
6955
|
-
removeScalar(sys3, scalarName) {
|
|
6956
|
-
this.scalarScript.removeScalar(sys3, scalarName);
|
|
6986
|
+
async removeScalar(sys3, scalarName) {
|
|
6987
|
+
await this.scalarScript.removeScalar(sys3, scalarName);
|
|
6957
6988
|
}
|
|
6958
6989
|
};
|
|
6959
6990
|
__decorateClass([
|
|
@@ -207,7 +207,7 @@ import * as cnst from "../cnst";
|
|
|
207
207
|
import type * as db from "../db";
|
|
208
208
|
|
|
209
209
|
export class UserSignal extends DbSignal(cnst.userCnst, cnst.Srvs, {
|
|
210
|
-
guards: { get: Query.Public, cru: Mutation.Admin },
|
|
210
|
+
guards: { root: Admin, get: Query.Public, cru: Mutation.Admin },
|
|
211
211
|
}) {
|
|
212
212
|
@Mutation.Public(() => cnst.util.AccessToken)
|
|
213
213
|
async signin(
|
|
@@ -578,30 +578,36 @@ export const Layout = () => (
|
|
|
578
578
|
## Best Practices
|
|
579
579
|
|
|
580
580
|
1. **Naming Conventions**
|
|
581
|
+
|
|
581
582
|
- Use PascalCase for classes and components (e.g., `UserService`, `User.Unit.tsx`)
|
|
582
583
|
- Use camelCase for files (e.g., `user.service.ts`, `user.document.ts`)
|
|
583
584
|
|
|
584
585
|
2. **Security**
|
|
586
|
+
|
|
585
587
|
- Use `@Field.Secret` for sensitive data like passwords
|
|
586
588
|
- Apply proper permission guards to queries and mutations (`@Query.Admin`, `@Mutation.Public`)
|
|
587
589
|
- Validate input data using the `validate` option in `@Field.Prop`
|
|
588
590
|
|
|
589
591
|
3. **Code Organization**
|
|
592
|
+
|
|
590
593
|
- Keep business logic in service files
|
|
591
594
|
- Use signals for API calls only, not for business logic
|
|
592
595
|
- Define reusable utility methods in document models
|
|
593
596
|
|
|
594
597
|
4. **Performance**
|
|
598
|
+
|
|
595
599
|
- Use dataloader pattern (`@Loader.ByField`) for efficient database access
|
|
596
600
|
- Create proper indexes in the middleware
|
|
597
601
|
- Use projections to limit returned fields when appropriate
|
|
598
602
|
|
|
599
603
|
5. **Testing**
|
|
604
|
+
|
|
600
605
|
- Create signal tests for each API endpoint
|
|
601
606
|
- Mock services for unit testing signals
|
|
602
607
|
- Use integration tests for testing complex workflows
|
|
603
608
|
|
|
604
609
|
6. **UI Components**
|
|
610
|
+
|
|
605
611
|
- Follow the separation between Template, Unit, View, and Zone components
|
|
606
612
|
- Make components reusable across different parts of the application
|
|
607
613
|
- Use dictionary files for all UI text to support internationalization
|
|
@@ -27,7 +27,7 @@ import * as cnst from "../cnst";
|
|
|
27
27
|
import type * as db from "../db";
|
|
28
28
|
|
|
29
29
|
export class ModelNameSignal extends DbSignal(cnst.modelNameCnst, cnst.Srvs, {
|
|
30
|
-
guards: { get: Query.Public, cru: Mutation.User },
|
|
30
|
+
guards: { root: Admin, get: Query.Public, cru: Mutation.User },
|
|
31
31
|
}) {
|
|
32
32
|
// Signal methods here...
|
|
33
33
|
}
|
|
@@ -259,7 +259,7 @@ DbSignal creates standard operations that you don't need to implement:
|
|
|
259
259
|
|
|
260
260
|
```typescript
|
|
261
261
|
export class BoardSignal extends DbSignal(cnst.boardCnst, cnst.Srvs, {
|
|
262
|
-
guards: { get: Query.Public, cru: Mutation.Admin },
|
|
262
|
+
guards: { root: Admin, get: Query.Public, cru: Mutation.Admin },
|
|
263
263
|
}) {
|
|
264
264
|
// Custom methods beyond CRUD go here
|
|
265
265
|
}
|
|
@@ -378,7 +378,7 @@ async getProjectDetails(
|
|
|
378
378
|
|
|
379
379
|
```typescript
|
|
380
380
|
export class ProductSignal extends DbSignal(cnst.productCnst, cnst.Srvs, {
|
|
381
|
-
guards: { get: Query.Public, cru: Mutation.Admin },
|
|
381
|
+
guards: { root: Admin, get: Query.Public, cru: Mutation.Admin },
|
|
382
382
|
}) {
|
|
383
383
|
// Custom methods beyond auto-generated CRUD
|
|
384
384
|
@Query.Public(() => [cnst.Product])
|
|
@@ -49,7 +49,7 @@ export const General = ({ id }: { id?: string }) => {
|
|
|
49
49
|
return (
|
|
50
50
|
<div className="grid grid-cols-1 gap-4">
|
|
51
51
|
<Field.Text
|
|
52
|
-
label={l
|
|
52
|
+
label={l("model.fieldName")}
|
|
53
53
|
value={form.fieldName}
|
|
54
54
|
onChange={(v) => st.do.setFieldNameOn[Model](v)}
|
|
55
55
|
/>
|
|
@@ -139,7 +139,7 @@ useEffect(() => {
|
|
|
139
139
|
|
|
140
140
|
```tsx
|
|
141
141
|
<Field.List
|
|
142
|
-
label={l
|
|
142
|
+
label={l("map.spawnPositions")}
|
|
143
143
|
value={form.spawnPositions}
|
|
144
144
|
onAdd={() => st.do.addSpawnPosition(defaultPosition)}
|
|
145
145
|
renderItem={(position, idx) => (
|
|
@@ -201,12 +201,12 @@ useEffect(() => {
|
|
|
201
201
|
const { l } = usePage();
|
|
202
202
|
|
|
203
203
|
// Basic field
|
|
204
|
-
<Field.Text label={l
|
|
204
|
+
<Field.Text label={l("model.name")} />
|
|
205
205
|
|
|
206
206
|
// With description
|
|
207
207
|
<Field.Text
|
|
208
|
-
label={l
|
|
209
|
-
desc={l
|
|
208
|
+
label={l("model.email")}
|
|
209
|
+
desc={l("model.email.desc")}
|
|
210
210
|
/>
|
|
211
211
|
|
|
212
212
|
// Dynamic content
|
|
@@ -85,13 +85,6 @@
|
|
|
85
85
|
"path": "{apps,libs}/*/lib/*/*.{Template,Unit,View,Zone}.tsx",
|
|
86
86
|
"filterText": "sliceName",
|
|
87
87
|
"sample": 5
|
|
88
|
-
},
|
|
89
|
-
{
|
|
90
|
-
"type": "example",
|
|
91
|
-
"description": "Internationalization usage examples",
|
|
92
|
-
"path": "{apps,libs}/*/lib/*/*.{Template,Unit,View}.tsx",
|
|
93
|
-
"filterText": "l.field",
|
|
94
|
-
"sample": 3
|
|
95
88
|
}
|
|
96
89
|
],
|
|
97
90
|
"update": {
|
|
@@ -64,8 +64,8 @@ const MyComponent = () => {
|
|
|
64
64
|
return (
|
|
65
65
|
<>
|
|
66
66
|
<Field.Text
|
|
67
|
-
label={l
|
|
68
|
-
desc={l
|
|
67
|
+
label={l("myModel.title")}
|
|
68
|
+
desc={l("myModel.title.desc")}
|
|
69
69
|
value={formState.title}
|
|
70
70
|
onChange={(value) => st.do.setTitleOnMyModel(value)}
|
|
71
71
|
nullable={false}
|
|
@@ -73,8 +73,8 @@ const MyComponent = () => {
|
|
|
73
73
|
/>
|
|
74
74
|
|
|
75
75
|
<Field.Number
|
|
76
|
-
label={l
|
|
77
|
-
desc={l
|
|
76
|
+
label={l("myModel.amount")}
|
|
77
|
+
desc={l("myModel.amount.desc")}
|
|
78
78
|
value={formState.amount}
|
|
79
79
|
onChange={(value) => st.do.setAmountOnMyModel(value)}
|
|
80
80
|
min={0}
|
|
@@ -83,8 +83,8 @@ const MyComponent = () => {
|
|
|
83
83
|
/>
|
|
84
84
|
|
|
85
85
|
<Field.ToggleSelect
|
|
86
|
-
label={l
|
|
87
|
-
desc={l
|
|
86
|
+
label={l("myModel.status")}
|
|
87
|
+
desc={l("myModel.status.desc")}
|
|
88
88
|
value={formState.status}
|
|
89
89
|
items={cnst.Status}
|
|
90
90
|
onChange={(status) => st.do.setStatusOnMyModel(status)}
|
|
@@ -266,7 +266,7 @@ Components automatically integrate with the internationalization system:
|
|
|
266
266
|
```tsx
|
|
267
267
|
const { l } = usePage();
|
|
268
268
|
|
|
269
|
-
<Field.Text label={l
|
|
269
|
+
<Field.Text label={l("user.name")} desc={l("user.name.desc")} placeholder={l("user.namePlaceholder")} />;
|
|
270
270
|
```
|
|
271
271
|
|
|
272
272
|
### State Management Integration
|
|
@@ -8,6 +8,7 @@ import { RootLayoutProps } from "@akanjs/client";
|
|
|
8
8
|
import { System } from "@akanjs/ui";
|
|
9
9
|
import { env } from "@${dict.appName}/env/env.client";
|
|
10
10
|
import { fetch } from "@${dict.appName}/client";
|
|
11
|
+
import { Auth } from "@shared/ui";
|
|
11
12
|
|
|
12
13
|
export const metadata = { title: "${dict.appName}" };
|
|
13
14
|
|
|
@@ -22,6 +23,7 @@ export default function Layout({ children, params }: RootLayoutProps) {
|
|
|
22
23
|
env={env}
|
|
23
24
|
>
|
|
24
25
|
{children}
|
|
26
|
+
<Auth.User />
|
|
25
27
|
</System.Provider>
|
|
26
28
|
);
|
|
27
29
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// pkgs/@akanjs/cli/src/templates/app/lib/option.ts
|
|
2
2
|
function getContent(scanInfo, dict = {}) {
|
|
3
3
|
return `
|
|
4
|
-
import { useGlobals } from "@akanjs/server";
|
|
4
|
+
import { Middleware, useGlobals } from "@akanjs/server";
|
|
5
5
|
|
|
6
6
|
import type { LibOptions } from "./__lib/lib.service";
|
|
7
7
|
|
|
@@ -15,6 +15,11 @@ export const registerGlobalModule = (options: ModulesOptions) => {
|
|
|
15
15
|
useAsyncs: {},
|
|
16
16
|
});
|
|
17
17
|
};
|
|
18
|
+
|
|
19
|
+
export const registerGlobalMiddlewares = (options: ModulesOptions) => {
|
|
20
|
+
return [] as Middleware[];
|
|
21
|
+
};
|
|
22
|
+
|
|
18
23
|
`;
|
|
19
24
|
}
|
|
20
25
|
export {
|
|
@@ -4,12 +4,12 @@ function getContent(scanInfo, dict) {
|
|
|
4
4
|
import { createNestApp } from "@akanjs/server";
|
|
5
5
|
|
|
6
6
|
import { env } from "./env/env.server";
|
|
7
|
-
import { registerModules } from "./server";
|
|
7
|
+
import { registerModules, registerMiddlewares } from "./server";
|
|
8
8
|
|
|
9
9
|
const bootstrap = async () => {
|
|
10
10
|
const serverMode = process.env.SERVER_MODE as "federation" | "batch" | "all" | null;
|
|
11
11
|
if (!serverMode) throw new Error("SERVER_MODE environment variable is not defined");
|
|
12
|
-
await createNestApp({ registerModules, serverMode, env });
|
|
12
|
+
await createNestApp({ registerModules, registerMiddlewares, serverMode, env });
|
|
13
13
|
};
|
|
14
14
|
void bootstrap();
|
|
15
15
|
`;
|
|
@@ -19,8 +19,7 @@ ${libs.map((lib) => `import { dict as ${lib} } from "@${lib}/server";`).join("\n
|
|
|
19
19
|
|
|
20
20
|
${Object.entries(extendedModels).map(([modelName, extendedModels2]) => {
|
|
21
21
|
return `export const ${modelName} = {
|
|
22
|
-
|
|
23
|
-
signals: Object.assign({}, ${extendedModels2.map((libName) => `${libName}.${modelName}.signalDictionary`).join(", ")}),
|
|
22
|
+
dictionaries: [${extendedModels2.map((libName) => `${libName}.${modelName}.dictionary`).join(", ")}] as const,
|
|
24
23
|
};`;
|
|
25
24
|
}).join("\n")}
|
|
26
25
|
|