@akanjs/cli 0.9.55 → 0.9.57

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.
Files changed (65) hide show
  1. package/cjs/index.js +26 -34
  2. package/cjs/src/guidelines/databaseModule/databaseModule.instruction.md +7 -1
  3. package/cjs/src/guidelines/modelSignal/modelSignal.instruction.md +3 -3
  4. package/cjs/src/guidelines/modelTemplate/modelTemplate.instruction.md +5 -5
  5. package/cjs/src/guidelines/sharedUiUsage/sharedUiUsage.generate.json +0 -7
  6. package/cjs/src/guidelines/sharedUiUsage/sharedUiUsage.instruction.md +7 -7
  7. package/cjs/src/templates/__scalar/__model__/__model__.constant.js +0 -1
  8. package/cjs/src/templates/__scalar/__model__/__model__.dictionary.js +1 -3
  9. package/cjs/src/templates/app/instrumentation.js +32 -0
  10. package/cjs/src/templates/app/lib/___appName__/__appName__.dictionary.js +2 -6
  11. package/cjs/src/templates/app/lib/___appName__/__appName__.signal.js +5 -3
  12. package/cjs/src/templates/app/lib/option.js +6 -1
  13. package/cjs/src/templates/app/main.js +2 -2
  14. package/cjs/src/templates/lib/__lib/lib.dictionary.js +1 -2
  15. package/cjs/src/templates/lib/dict.js +22 -6
  16. package/cjs/src/templates/lib/sig.js +5 -2
  17. package/cjs/src/templates/lib/useClient.js +5 -4
  18. package/cjs/src/templates/libRoot/lib/option.js +5 -1
  19. package/cjs/src/templates/module/__Model__.Template.js +2 -2
  20. package/cjs/src/templates/module/__Model__.Util.js +8 -1
  21. package/cjs/src/templates/module/__model__.constant.js +3 -8
  22. package/cjs/src/templates/module/__model__.dictionary.js +21 -61
  23. package/cjs/src/templates/module/__model__.document.js +7 -2
  24. package/cjs/src/templates/module/__model__.signal.js +14 -28
  25. package/cjs/src/templates/module/__model__.store.js +1 -2
  26. package/cjs/src/templates/server.js +11 -3
  27. package/cjs/src/templates/workspaceRoot/.gitignore.template +2 -0
  28. package/esm/index.js +26 -34
  29. package/esm/src/guidelines/databaseModule/databaseModule.instruction.md +7 -1
  30. package/esm/src/guidelines/modelSignal/modelSignal.instruction.md +3 -3
  31. package/esm/src/guidelines/modelTemplate/modelTemplate.instruction.md +5 -5
  32. package/esm/src/guidelines/sharedUiUsage/sharedUiUsage.generate.json +0 -7
  33. package/esm/src/guidelines/sharedUiUsage/sharedUiUsage.instruction.md +7 -7
  34. package/esm/src/templates/__scalar/__model__/__model__.constant.js +0 -1
  35. package/esm/src/templates/__scalar/__model__/__model__.dictionary.js +1 -3
  36. package/esm/src/templates/app/instrumentation.js +12 -0
  37. package/esm/src/templates/app/lib/___appName__/__appName__.dictionary.js +2 -6
  38. package/esm/src/templates/app/lib/___appName__/__appName__.signal.js +5 -3
  39. package/esm/src/templates/app/lib/option.js +6 -1
  40. package/esm/src/templates/app/main.js +2 -2
  41. package/esm/src/templates/lib/__lib/lib.dictionary.js +1 -2
  42. package/esm/src/templates/lib/dict.js +22 -6
  43. package/esm/src/templates/lib/sig.js +5 -2
  44. package/esm/src/templates/lib/useClient.js +5 -4
  45. package/esm/src/templates/libRoot/lib/option.js +5 -1
  46. package/esm/src/templates/module/__Model__.Template.js +2 -2
  47. package/esm/src/templates/module/__Model__.Util.js +8 -1
  48. package/esm/src/templates/module/__model__.constant.js +3 -8
  49. package/esm/src/templates/module/__model__.dictionary.js +21 -61
  50. package/esm/src/templates/module/__model__.document.js +7 -2
  51. package/esm/src/templates/module/__model__.signal.js +14 -28
  52. package/esm/src/templates/module/__model__.store.js +1 -2
  53. package/esm/src/templates/server.js +11 -3
  54. package/esm/src/templates/workspaceRoot/.gitignore.template +2 -0
  55. package/package.json +1 -1
  56. package/src/guidelines/databaseModule/databaseModule.instruction.md +7 -1
  57. package/src/guidelines/modelSignal/modelSignal.instruction.md +3 -3
  58. package/src/guidelines/modelTemplate/modelTemplate.instruction.md +5 -5
  59. package/src/guidelines/sharedUiUsage/sharedUiUsage.instruction.md +7 -7
  60. package/src/module/module.command.d.ts +1 -1
  61. package/src/module/module.runner.d.ts +1 -1
  62. package/src/module/module.script.d.ts +1 -1
  63. package/src/scalar/scalar.command.d.ts +1 -1
  64. package/src/scalar/scalar.script.d.ts +1 -1
  65. package/src/templates/app/instrumentation.d.ts +6 -0
@@ -1,4 +1,5 @@
1
1
  // pkgs/@akanjs/cli/src/templates/lib/dict.ts
2
+ var capitalize = (str) => str.charAt(0).toUpperCase() + str.slice(1);
2
3
  function getContent(scanInfo, dict = {}) {
3
4
  if (!scanInfo)
4
5
  return null;
@@ -6,7 +7,7 @@ function getContent(scanInfo, dict = {}) {
6
7
  const scalarModules = scanInfo.getScalarModules();
7
8
  const serviceModules = scanInfo.getServiceModules();
8
9
  return `
9
- import { makeDictionary, makeTrans } from "@akanjs/dictionary";
10
+ import { makeDictionary, makeTrans, registerScalarTrans, registerServiceTrans, registerModelTrans } from "@akanjs/dictionary";
10
11
 
11
12
  import { allLibs } from "./__lib/lib.dictionary";
12
13
  ${databaseModules.map((module) => `import * as ${module} from "./${module}/${module}.dictionary";`).join("\n")}
@@ -17,15 +18,30 @@ ${databaseModules.map((module) => `export * as ${module} from "./${module}/${mod
17
18
  ${serviceModules.map((module) => `export * as ${module} from "./_${module}/${module}.dictionary";`).join("\n")}
18
19
  ${scalarModules.map((module) => `export * as ${module} from "./__scalar/${module}/${module}.dictionary";`).join("\n")}
19
20
 
21
+ ${databaseModules.map((module) => `import type * as ${module}Cnst from "./${module}/${module}.constant";`).join("\n")}
22
+ ${scalarModules.map((module) => `import type * as ${module}Cnst from "./__scalar/${module}/${module}.constant";`).join("\n")}
23
+
24
+ ${databaseModules.map((module) => `import type * as ${module}Doc from "./${module}/${module}.document";`).join("\n")}
25
+
26
+ ${databaseModules.map((module) => `import type * as ${module}Sig from "./${module}/${module}.signal";`).join("\n")}
27
+ ${serviceModules.map((module) => `import type * as ${module}Sig from "./_${module}/${module}.signal";`).join("\n")}
28
+
20
29
  export const dictionary = makeDictionary(...allLibs, {
21
30
  ${[
22
- ...databaseModules.map((module) => `${module}: { ...${module}.modelDictionary, ...${module}.signalDictionary }`),
23
- ...scalarModules.map((module) => `${module}: ${module}.dictionary`),
24
- ...serviceModules.map((module) => `${module}: ${module}.dictionary`)
31
+ ...databaseModules.map((module) => {
32
+ const Module = capitalize(module);
33
+ return `${module}: registerModelTrans<"${module}", ${module}Cnst.${Module}, ${module}Cnst.${Module}Insight, ${module}Doc.${Module}Filter, ${module}Sig.${Module}Slice, ${module}Sig.${Module}Endpoint, typeof ${module}.dictionary>(${module}.dictionary)`;
34
+ }),
35
+ ...scalarModules.map(
36
+ (module) => `${module}: registerScalarTrans<"${module}", ${module}Cnst.${capitalize(module)}, typeof ${module}.dictionary>(${module}.dictionary)`
37
+ ),
38
+ ...serviceModules.map(
39
+ (module) => `${module}: registerServiceTrans<"${module}", ${module}Sig.${capitalize(module)}Endpoint, typeof ${module}.dictionary>(${module}.dictionary)`
40
+ )
25
41
  ].join(",\n ")}
26
- } as const);
42
+ });
27
43
 
28
- export const { Revert, translate, msg } = makeTrans(dictionary);
44
+ export const { Revert, translate, msg, __Dict_Key__, __Error_Key__ } = makeTrans(dictionary);
29
45
  `;
30
46
  }
31
47
  export {
@@ -7,7 +7,7 @@ function getContent(scanInfo, dict = {}) {
7
7
  const scalarConstantModules = [...scanInfo.scalar.entries()].filter(([_, files]) => files.has("constant")).map(([module]) => module);
8
8
  const serviceModules = [...scanInfo.service.entries()].filter(([_, files]) => files.has("signal")).map(([module]) => module);
9
9
  return `
10
- import { fetchOf, gqlOf, makeFetch, mergeSignals, signalInfo } from "@akanjs/signal";
10
+ import { fetchOf, gqlOf, makeFetch, mergeSignals, serverSignalOf, signalInfo } from "@akanjs/signal";
11
11
 
12
12
  import { root, libFetches } from "./__lib/lib.signal";
13
13
  import * as cnst from "./cnst";
@@ -23,9 +23,12 @@ ${[...scanInfo.database.entries()].filter(([_, files]) => files.has("signal")).m
23
23
  ([module]) => `export class ${capitalize(module)}Signal extends mergeSignals(${module}Sig.${capitalize(module)}Endpoint, ${module}Sig.${capitalize(module)}Internal, ${module}Sig.${capitalize(module)}Slice) {}`
24
24
  ).join("\n")}
25
25
  ${[...scanInfo.service.entries()].filter(([_, files]) => files.has("signal")).map(
26
- ([module]) => `export const ${capitalize(module)}Signal = mergeSignals(${module}Sig.${capitalize(module)}Endpoint, ${module}Sig.${capitalize(module)}Internal);`
26
+ ([module]) => `export class ${capitalize(module)}Signal extends mergeSignals(${module}Sig.${capitalize(module)}Endpoint, ${module}Sig.${capitalize(module)}Internal) {}`
27
27
  ).join("\n")}
28
28
 
29
+ ${[...scanInfo.database.entries()].filter(([_, files]) => files.has("signal")).map(([module]) => `export class ${capitalize(module)} extends serverSignalOf(${capitalize(module)}Signal) {}`).join("\n")}
30
+ ${[...scanInfo.service.entries()].filter(([_, files]) => files.has("signal")).map(([module]) => `export class ${capitalize(module)} extends serverSignalOf(${capitalize(module)}Signal) {}`).join("\n")}
31
+
29
32
  const signals = signalInfo.registerSignals(
30
33
  ${[...databaseModules, ...serviceModules].map((module) => ` ${capitalize(module)}Signal,`).join("\n")}
31
34
  );
@@ -2,13 +2,14 @@
2
2
  function getContent(scanInfo, dict = {}) {
3
3
  return `
4
4
  import { makePageProto } from "@akanjs/client";
5
- import type * as signal from "./sig";
6
- import * as cnst from "./cnst";
7
5
 
8
- import type { dictionary } from "./dict";
6
+ import * as cnst from "./cnst";
7
+ import type { __Dict_Key__, __Error_Key__ } from "./dict";
8
+ import type * as signal from "./sig";
9
9
 
10
10
  export const { msg, Revert, usePage, sig, fetch, registerClient } = makePageProto<
11
- typeof dictionary,
11
+ typeof __Dict_Key__,
12
+ typeof __Error_Key__,
12
13
  typeof signal.fetch,
13
14
  typeof signal
14
15
  >(cnst);
@@ -1,7 +1,7 @@
1
1
  // pkgs/@akanjs/cli/src/templates/libRoot/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,10 @@ export const registerGlobalModule = (options: ModulesOptions) => {
15
15
  useAsyncs: {},
16
16
  });
17
17
  };
18
+
19
+ export const registerGlobalMiddlewares = (options: ModulesOptions) => {
20
+ return [] as Middleware[];
21
+ };
18
22
  `;
19
23
  }
20
24
  export {
@@ -17,8 +17,8 @@ export const General = ({ className }: ${dict.Model}EditProps) => {
17
17
  return (
18
18
  <Layout.Template className={className}>
19
19
  <Field.Text
20
- label={l.field("${dict.model}", "id")}
21
- desc={l.desc("${dict.model}", "id")}
20
+ label={l("${dict.model}.id")}
21
+ desc={l("${dict.model}.id.desc")}
22
22
  value={${dict.model}Form.id}
23
23
  onChange={st.do.setIdOn${dict.Model}}
24
24
  />
@@ -5,12 +5,19 @@ function getContent(scanInfo, dict) {
5
5
  content: `
6
6
  "use client";
7
7
  import { Model } from "@akanjs/ui";
8
+ import { usePage } from "@${dict.sysName}/client";
9
+ import { BiTrash } from "react-icons/bi";
8
10
 
9
11
  interface RemoveProps {
10
12
  ${dict.model}Id: string;
11
13
  }
12
14
  export const Remove = ({ ${dict.model}Id }: RemoveProps) => {
13
- return <Model.Remove modelId={${dict.model}Id} sliceName="${dict.model}" />;
15
+ const { l } = usePage();
16
+ return (
17
+ <Model.Remove modelId={${dict.model}Id} sliceName="${dict.model}">
18
+ <BiTrash /> {l("base.remove")}
19
+ </Model.Remove>
20
+ );
14
21
  };
15
22
  `
16
23
  };
@@ -1,21 +1,16 @@
1
1
  // pkgs/@akanjs/cli/src/templates/module/__model__.constant.ts
2
2
  function getContent(scanInfo, dict) {
3
3
  return `
4
- import { enumOf, Int } from "@akanjs/base";
4
+ import { Int } from "@akanjs/base";
5
5
  import { via } from "@akanjs/constant";
6
6
 
7
- export const ${dict.Model}Status = enumOf(["active"] as const);
8
- export type ${dict.Model}Status = enumOf<typeof ${dict.Model}Status>;
9
-
10
7
  export class ${dict.Model}Input extends via((field) => ({
11
8
  field: field(String).optional(),
12
9
  })) {}
13
10
 
14
- export class ${dict.Model}Object extends via(${dict.Model}Input, (field) => ({
15
- status: field(${dict.Model}Status, { default: "active" }),
16
- })) {}
11
+ export class ${dict.Model}Object extends via(${dict.Model}Input, (field) => ({})) {}
17
12
 
18
- export class Light${dict.Model} extends via(${dict.Model}Object, ["status"] as const, (resolve) => ({})) {}
13
+ export class Light${dict.Model} extends via(${dict.Model}Object, [] as const, (resolve) => ({})) {}
19
14
 
20
15
  export class ${dict.Model} extends via(${dict.Model}Object, Light${dict.Model}, (resolve) => ({})) {}
21
16
 
@@ -1,67 +1,27 @@
1
1
  // pkgs/@akanjs/cli/src/templates/module/__model__.dictionary.ts
2
2
  function getContent(scanInfo, dict) {
3
3
  return `
4
- import { baseTrans, getBaseSignalTrans, ModelDictionary, SignalDictionary } from "@akanjs/dictionary";
5
-
6
- import type { ${dict.Model}, ${dict.Model}Filter, ${dict.Model}Insight, ${dict.Model}Summary } from "./${dict.model}.constant";
7
- import type { ${dict.Model}Signal } from "./${dict.model}.signal";
8
-
9
- export const modelDictionary = {
10
- ...baseTrans,
11
- modelName: ["${dict.Model}", "${dict.Model}"],
12
- modelDesc: [
13
- "${dict.Model} description",
14
- "${dict.Model} \uC124\uBA85",
15
- ],
16
-
17
- // * ==================== Model ==================== * //
18
- field: ["Field", "\uD544\uB4DC"],
19
- "desc-field": ["Field", "\uD544\uB4DC"],
20
- // * ==================== Model ==================== * //
21
-
22
- // * ==================== Insight ==================== * //
23
- count: ["Count", "\uAC1C\uC218"],
24
- "desc-count": ["${dict.Model} count in current query settting", "\uD604\uC7AC \uCFFC\uB9AC \uC124\uC815\uC5D0 \uB9DE\uB294 \uBC30\uB108 \uC218"],
25
- // * ==================== Insight ==================== * //
26
-
27
- // * ==================== Filter ==================== * //
28
- "qry-inStatus": ["In Status", "\uC0C1\uD0DC"],
29
- "qrydesc-inStatus": ["Filter by status", "\uC0C1\uD0DC\uBCC4 \uD544\uD130\uB9C1"],
30
- "qarg-inStatus-status": ["Status", "\uC0C1\uD0DC"],
31
- "qargdesc-inStatus-status": ["Filter by status", "\uC0C1\uD0DC\uBCC4 \uD544\uD130\uB9C1"],
32
- // * ==================== Filter ==================== * //
33
-
34
- // * ==================== Etc ==================== * //
35
- "enum-status-active": ["Active", "\uD65C\uC131"],
36
- "enumdesc-status-active": ["Active status", "\uD65C\uC131 \uC0C1\uD0DC"],
37
- // * ==================== Etc ==================== * //
38
- } satisfies ModelDictionary<${dict.Model}, ${dict.Model}Insight, ${dict.Model}Filter>;
39
-
40
- export const signalDictionary = {
41
- ...getBaseSignalTrans("${dict.model}" as const),
42
- // * ==================== Endpoint ==================== * //
43
- "api-${dict.model}ListInPublic": ["${dict.Model} List In Public", "\uACF5\uAC1C\uB41C ${dict.Model} \uB9AC\uC2A4\uD2B8"],
44
- "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"],
45
- "arg-${dict.model}ListInPublic-statuses": ["Statuses", "\uC0C1\uD0DC"],
46
- "argdesc-${dict.model}ListInPublic-statuses": ["Statuses to filter", "\uD544\uD130\uB9C1\uD560 \uC0C1\uD0DC"],
47
- "arg-${dict.model}ListInPublic-skip": ["Skip", "\uAC74\uB108\uB6F0\uAE30"],
48
- "argdesc-${dict.model}ListInPublic-skip": ["Number of items to skip", "\uAC74\uB108\uB6F8 \uC544\uC774\uD15C \uC218"],
49
- "arg-${dict.model}ListInPublic-limit": ["Limit", "\uC81C\uD55C"],
50
- "argdesc-${dict.model}ListInPublic-limit": ["Maximum number of items to return", "\uBC18\uD658\uD560 \uCD5C\uB300 \uC544\uC774\uD15C \uC218"],
51
- "arg-${dict.model}ListInPublic-sort": ["Sort", "\uC815\uB82C"],
52
- "argdesc-${dict.model}ListInPublic-sort": ["Sort order of the items", "\uC544\uC774\uD15C\uC758 \uC815\uB82C \uC21C\uC11C"],
53
-
54
- "api-${dict.model}InsightInPublic": ["${dict.Model} Insight In Public", "\uACF5\uAC1C\uB41C ${dict.Model} \uC778\uC0AC\uC774\uD2B8"],
55
- "apidesc-${dict.model}InsightInPublic": [
56
- "Get insight data for public ${dict.model}",
57
- "\uACF5\uAC1C\uB41C ${dict.Model}\uC5D0 \uB300\uD55C \uC778\uC0AC\uC774\uD2B8 \uB370\uC774\uD130\uB97C \uAC00\uC838\uC635\uB2C8\uB2E4",
58
- ],
59
- "arg-${dict.model}InsightInPublic-statuses": ["Statuses", "\uC0C1\uD0DC"],
60
- "argdesc-${dict.model}InsightInPublic-statuses": ["Statuses to filter", "\uD544\uD130\uB9C1\uD560 \uC0C1\uD0DC"],
61
- // * ==================== Endpoint ==================== * //
62
- } satisfies SignalDictionary<${dict.Model}Signal, ${dict.Model}>;
63
-
64
- export const ${dict.model}Dictionary = { ...modelDictionary, ...signalDictionary };
4
+ import { modelDictionary } from "@akanjs/dictionary";
5
+
6
+ import type { ${dict.Model}, ${dict.Model}Insight } from "./${dict.model}.constant";
7
+ import type { ${dict.Model}Filter } from "./${dict.model}.document";
8
+ import type { ${dict.Model}Endpoint, ${dict.Model}Slice } from "./${dict.model}.signal";
9
+
10
+ export const dictionary = modelDictionary(["en", "ko"])
11
+ .of((t) =>
12
+ t(["${dict.Model}", "${dict.Model}"]).desc(["${dict.Model} description", "${dict.Model} \uC124\uBA85"])
13
+ )
14
+ .model<${dict.Model}>((t) => ({
15
+ field: t(["Field", "\uD544\uB4DC"]).desc(["Field description", "\uD544\uB4DC \uC124\uBA85"]),
16
+ }))
17
+ .insight<${dict.Model}Insight>((t) => ({}))
18
+ .query<${dict.Model}Filter>((fn) => ({}))
19
+ .slice<${dict.Model}Slice>((fn) => ({
20
+ inPublic: fn(["${dict.Model} In Public", "${dict.Model} \uACF5\uAC1C"]).arg((t) => ({})),
21
+ }))
22
+ .endpoint<${dict.Model}Endpoint>((fn) => ({}))
23
+ .error({})
24
+ .translate({});
65
25
  `;
66
26
  }
67
27
  export {
@@ -1,13 +1,18 @@
1
1
  // pkgs/@akanjs/cli/src/templates/module/__model__.document.ts
2
2
  function getContent(scanInfo, dict) {
3
3
  return `
4
- import { beyond, by, into, type SchemaOf } from "@akanjs/document";
4
+ import { beyond, by, from, into, type SchemaOf } from "@akanjs/document";
5
5
 
6
6
  import * as cnst from "../cnst";
7
7
 
8
+ export class ${dict.Model}Filter extends from(cnst.${dict.Model}, (filter) => ({
9
+ query: {},
10
+ sort: {},
11
+ })) {}
12
+
8
13
  export class ${dict.Model} extends by(cnst.${dict.Model}) {}
9
14
 
10
- export class ${dict.Model}Model extends into(${dict.Model}, cnst.${dict.model}) {}
15
+ export class ${dict.Model}Model extends into(${dict.Model}, ${dict.Model}Filter, cnst.${dict.model}) {}
11
16
 
12
17
  export class ${dict.Model}Middleware extends beyond(${dict.Model}Model, ${dict.Model}) {
13
18
  onSchema(schema: SchemaOf<${dict.Model}Model, ${dict.Model}>) {
@@ -1,37 +1,23 @@
1
1
  // pkgs/@akanjs/cli/src/templates/module/__model__.signal.ts
2
2
  function getContent(scanInfo, dict) {
3
3
  return `
4
- import { Int } from "@akanjs/base";
5
- import type { SortOf } from "@akanjs/document";
6
- import { Arg, signal, Mutation, Query, resolve } from "@akanjs/signal";
4
+ import { Public } from "@akanjs/nest";
5
+ import { endpoint, internal, slice } from "@akanjs/signal";
6
+ import { Admin } from "@shared/nest";
7
7
 
8
8
  import * as cnst from "../cnst";
9
+ import * as srv from "../srv";
9
10
 
10
- export class ${dict.Model}Signal extends signal(cnst.${dict.model}, cnst.Srvs, {
11
- guards: { get: "Public", cru: "Public },
12
- }) {
13
- // * /////////////////////////////////////
14
- // * Public Slice
15
- @Query.Public(() => [cnst.${dict.Model}])
16
- async ${dict.model}ListInPublic(
17
- @Arg.Query("statuses", () => [String], { nullable: true }) statuses: cnst.${dict.Model}Status[] | null,
18
- @Arg.Query("skip", () => Int, { nullable: true }) skip: number | null,
19
- @Arg.Query("limit", () => Int, { nullable: true }) limit: number | null,
20
- @Arg.Query("sort", () => String, { nullable: true }) sort: SortOf<cnst.${dict.Model}Filter> | null
21
- ) {
22
- const ${dict.models} = await this.${dict.model}Service.listByStatuses(statuses, { skip, limit, sort });
23
- return resolve<cnst.${dict.Model}[]>(${dict.models});
24
- }
25
- @Query.Public(() => cnst.${dict.Model}Insight)
26
- async ${dict.model}InsightInPublic(
27
- @Arg.Query("statuses", () => [String], { nullable: true }) statuses: cnst.${dict.Model}Status[] | null
28
- ) {
29
- const ${dict.model}Insight = await this.${dict.model}Service.insightByStatuses(statuses);
30
- return resolve<cnst.${dict.Model}Insight>(${dict.model}Insight);
31
- }
32
- // * Public Slice
33
- // * /////////////////////////////////////
34
- }
11
+ export class ${dict.Model}Internal extends internal(srv.${dict.model}, () => ({})) {}
12
+
13
+ export class ${dict.Model}Slice extends slice(srv.${dict.model}, { guards: { root: Admin, get: Public, cru: Public } }, (init) => ({
14
+ inPublic: init()
15
+ .exec(function () {
16
+ return this.${dict.model}Service.queryAny();
17
+ }),
18
+ })) {}
19
+
20
+ export class ${dict.Model}Endpoint extends endpoint(srv.${dict.model}, () => ({})) {}
35
21
  `;
36
22
  }
37
23
  export {
@@ -3,8 +3,7 @@ function getContent(scanInfo, dict) {
3
3
  return `
4
4
  import { store } from "@akanjs/store";
5
5
 
6
- import * as cnst from "../cnst";
7
- import { fetch, sig } from "../useClient";
6
+ import { sig } from "../useClient";
8
7
 
9
8
  export class ${dict.Model}Store extends store(sig.${dict.model}, {
10
9
  // state
@@ -8,15 +8,15 @@ function getContent(scanInfo, dict = {}) {
8
8
  const serviceModules = [...scanInfo.service.entries()].filter(([_, files]) => files.has("service"));
9
9
  const scalarModules = [...scanInfo.scalar.entries()];
10
10
  return `
11
- import { databaseModuleOf, scalarModulesOf, serviceModuleOf, type Module } from "@akanjs/server";
12
- ${libs.map((lib) => `import { registerModules as register${capitalize(lib)}Modules } from "@${lib}/server";`).join("\n")}
11
+ import { databaseModuleOf, scalarModulesOf, serviceModuleOf, type Module, type Middleware } from "@akanjs/server";
12
+ ${libs.map((lib) => `import { registerModules as register${capitalize(lib)}Modules, registerMiddlewares as register${capitalize(lib)}Middlewares } from "@${lib}/server";`).join("\n")}
13
13
 
14
14
  import * as cnst from "./lib/cnst";
15
15
  import * as db from "./lib/db";
16
16
  import * as srv from "./lib/srv";
17
17
  import { allSrvs } from "./lib/srv";
18
18
  import * as sig from "./lib/sig";
19
- import { type ModulesOptions, registerGlobalModule } from "./lib/option";
19
+ import { type ModulesOptions, registerGlobalModule, registerGlobalMiddlewares } from "./lib/option";
20
20
 
21
21
  // database modules
22
22
  ${databaseModules.map(([model]) => {
@@ -44,6 +44,14 @@ ${databaseModules.map(([model]) => ` register${capitalize(model)}Module(),`).
44
44
  return modules;
45
45
  };
46
46
 
47
+ export const registerMiddlewares = (options: ModulesOptions, isChild?: boolean) => {
48
+ const middlewares = [
49
+ ${libs.map((lib) => ` ...(!isChild ? register${capitalize(lib)}Middlewares(options, true) : []),`).join("\n")}
50
+ ...registerGlobalMiddlewares(options),
51
+ ] as Middleware[];
52
+ return middlewares;
53
+ };
54
+
47
55
  export { env } from "./env/env.server.testing";
48
56
  export * as db from "./lib/db";
49
57
  export * as srv from "./lib/srv";
@@ -11,10 +11,12 @@ apps/*/data
11
11
  /releases
12
12
  apps/*/scripts
13
13
  **/.env
14
+ **/env.client.local.ts
14
15
  **/env.client.debug.ts
15
16
  **/env.client.develop.ts
16
17
  **/env.client.main.ts
17
18
  **/env.client.testing.ts
19
+ **/env.server.local.ts
18
20
  **/env.server.debug.ts
19
21
  **/env.server.develop.ts
20
22
  **/env.server.main.ts
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "type": "module",
3
3
  "sourceType": "module",
4
4
  "name": "@akanjs/cli",
5
- "version": "0.9.55",
5
+ "version": "0.9.57",
6
6
  "bin": {
7
7
  "akan": "esm/index.js"
8
8
  },
@@ -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.field("model", "fieldName")}
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.field("map", "spawnPositions")}
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.field("model", "name")} />
204
+ <Field.Text label={l("model.name")} />
205
205
 
206
206
  // With description
207
207
  <Field.Text
208
- label={l.field("model", "email")}
209
- desc={l.desc("model", "email")}
208
+ label={l("model.email")}
209
+ desc={l("model.email.desc")}
210
210
  />
211
211
 
212
212
  // Dynamic content
@@ -64,8 +64,8 @@ const MyComponent = () => {
64
64
  return (
65
65
  <>
66
66
  <Field.Text
67
- label={l.field("myModel", "title")}
68
- desc={l.desc("myModel", "title")}
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.field("myModel", "amount")}
77
- desc={l.desc("myModel", "amount")}
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.field("myModel", "status")}
87
- desc={l.desc("myModel", "status")}
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.field("user", "name")} desc={l.desc("user", "name")} placeholder={l("user.namePlaceholder")} />;
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
@@ -3,7 +3,7 @@ import { ModuleScript } from "./module.script";
3
3
  export declare class ModuleCommand {
4
4
  moduleScript: ModuleScript;
5
5
  createModule(moduleName: string, sys: Sys, page: boolean): Promise<void>;
6
- removeModule(module: Module): void;
6
+ removeModule(module: Module): Promise<void>;
7
7
  createView(module: Module): Promise<void>;
8
8
  createUnit(module: Module): Promise<void>;
9
9
  createTemplate(module: Module): Promise<void>;
@@ -1,7 +1,7 @@
1
1
  import { type Module, Workspace } from "@akanjs/devkit";
2
2
  export declare class ModuleRunner {
3
3
  createModule(workspace: Workspace, sysType: "app" | "lib", sysName: string, moduleName: string, description: string): Promise<void>;
4
- removeModule(module: Module): void;
4
+ removeModule(module: Module): Promise<void>;
5
5
  createComponentTemplate(module: Module, type: "unit" | "view" | "template" | "zone" | "util"): Promise<{
6
6
  component: {
7
7
  filename: string;
@@ -8,7 +8,7 @@ export declare class ModuleScript {
8
8
  }): Promise<void>;
9
9
  createModule(sys: Sys, name: string, description?: string, schemaDescription?: string): Promise<void>;
10
10
  createModule_(sys: Sys, name: string, description: string, schemaDescription: string): Promise<void>;
11
- removeModule(mod: Module): void;
11
+ removeModule(mod: Module): Promise<void>;
12
12
  createService(workspace: Workspace, name: string): Promise<void>;
13
13
  createTest(workspace: Workspace, name: string): Promise<void>;
14
14
  createTemplate(mod: Module): Promise<void>;
@@ -3,5 +3,5 @@ import { ScalarScript } from "./scalar.script";
3
3
  export declare class ScalarCommand {
4
4
  scalarScript: ScalarScript;
5
5
  createScalar(sys: Sys, scalarName: string): Promise<void>;
6
- removeScalar(sys: Sys, scalarName: string): void;
6
+ removeScalar(sys: Sys, scalarName: string): Promise<void>;
7
7
  }
@@ -2,5 +2,5 @@ import { type Sys } from "@akanjs/devkit";
2
2
  export declare class ScalarScript {
3
3
  #private;
4
4
  createScalar(sys: Sys, scalarName: string): Promise<void>;
5
- removeScalar(sys: Sys, scalarName: string): void;
5
+ removeScalar(sys: Sys, scalarName: string): Promise<void>;
6
6
  }
@@ -0,0 +1,6 @@
1
+ import type { AppInfo, LibInfo } from "@akanjs/devkit";
2
+ interface Dict {
3
+ appName: string;
4
+ }
5
+ export default function getContent(scanInfo: AppInfo | LibInfo | null, dict: Dict): string;
6
+ export {};