@akanjs/cli 0.0.88 → 0.0.90

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 (27) hide show
  1. package/index.js +1248 -486
  2. package/package.json +1 -1
  3. package/pkgs/@akanjs/cli/src/application/application.command.d.ts +6 -6
  4. package/pkgs/@akanjs/cli/src/application/application.runner.d.ts +15 -7
  5. package/pkgs/@akanjs/cli/src/application/application.script.d.ts +46 -16
  6. package/pkgs/@akanjs/cli/src/cloud/cloud.command.d.ts +3 -0
  7. package/pkgs/@akanjs/cli/src/cloud/cloud.runner.d.ts +2 -0
  8. package/pkgs/@akanjs/cli/src/cloud/cloud.script.d.ts +3 -0
  9. package/pkgs/@akanjs/cli/src/library/library.command.d.ts +1 -1
  10. package/pkgs/@akanjs/cli/src/library/library.runner.d.ts +2 -0
  11. package/pkgs/@akanjs/cli/src/library/library.script.d.ts +2 -0
  12. package/pkgs/@akanjs/cli/src/module/module.prompt.d.ts +17 -8
  13. package/pkgs/@akanjs/cli/src/module/module.runner.d.ts +1 -3
  14. package/pkgs/@akanjs/cli/src/module/module.script.d.ts +1 -1
  15. package/pkgs/@akanjs/cli/src/package/package.command.d.ts +1 -1
  16. package/pkgs/@akanjs/cli/src/package/package.runner.d.ts +3 -2
  17. package/pkgs/@akanjs/cli/src/package/package.script.d.ts +3 -2
  18. package/pkgs/@akanjs/devkit/src/aiEditor.d.ts +14 -0
  19. package/pkgs/@akanjs/devkit/src/constants.d.ts +8 -1
  20. package/pkgs/@akanjs/devkit/src/executors.d.ts +24 -31
  21. package/pkgs/@akanjs/devkit/src/getRelatedCnsts.d.ts +52 -8
  22. package/pkgs/@akanjs/devkit/src/index.d.ts +0 -1
  23. package/src/templates/workspaceRoot/package.json.template +5 -0
  24. package/pkgs/@akanjs/devkit/src/installExternalLib.d.ts +0 -2
  25. /package/pkgs/@akanjs/cli/src/{package/page → page}/page.command.d.ts +0 -0
  26. /package/pkgs/@akanjs/cli/src/{package/page → page}/page.runner.d.ts +0 -0
  27. /package/pkgs/@akanjs/cli/src/{package/page → page}/page.script.d.ts +0 -0
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "type": "commonjs",
3
3
  "name": "@akanjs/cli",
4
- "version": "0.0.88",
4
+ "version": "0.0.90",
5
5
  "bin": {
6
6
  "akan": "index.js"
7
7
  },
@@ -2,8 +2,8 @@ import { App, Sys, Workspace } from "@akanjs/devkit";
2
2
  import { ApplicationScript } from "./application.script";
3
3
  export declare class ApplicationCommand {
4
4
  applicationScript: ApplicationScript;
5
- createApplication(name: string, workspace: Workspace): Promise<void>;
6
- removeApplication(app: App, workspace: Workspace): Promise<void>;
5
+ createApplication(name: string, serve: boolean, workspace: Workspace): Promise<void>;
6
+ removeApplication(app: App): Promise<void>;
7
7
  scanApplication(app: App): Promise<void>;
8
8
  build(app: App): Promise<void>;
9
9
  buildBackend(app: App): Promise<void>;
@@ -11,10 +11,10 @@ export declare class ApplicationCommand {
11
11
  buildCsr(app: App): Promise<void>;
12
12
  buildIos(app: App): Promise<void>;
13
13
  buildAndroid(app: App): Promise<void>;
14
- serve(app: App): Promise<void>;
15
- serveBackend(app: App): Promise<void>;
16
- serveFrontend(app: App): Promise<void>;
17
- serveCsr(app: App): Promise<void>;
14
+ serve(app: App, open: boolean): Promise<void>;
15
+ serveBackend(app: App, open: boolean): Promise<void>;
16
+ serveFrontend(app: App, open: boolean, turbo: boolean): Promise<void>;
17
+ serveCsr(app: App, open: boolean): Promise<void>;
18
18
  serveIos(app: App, open: boolean, release: boolean): Promise<void>;
19
19
  serveAndroid(app: App, open: boolean, release: boolean): Promise<void>;
20
20
  releaseIos(app: App): Promise<void>;
@@ -1,4 +1,4 @@
1
- import { App, AppExecutor, DistAppExecutor, type Workspace } from "@akanjs/devkit";
1
+ import { App, AppExecutor, type Workspace } from "@akanjs/devkit";
2
2
  export interface ReleaseSourceOptions {
3
3
  rebuild?: boolean;
4
4
  buildNum?: number;
@@ -8,13 +8,21 @@ export interface ReleaseSourceOptions {
8
8
  export declare class ApplicationRunner {
9
9
  #private;
10
10
  createApplication(appName: string, workspace: Workspace): Promise<AppExecutor>;
11
+ removeApplication(app: App): Promise<void>;
11
12
  scanSync(app: App): Promise<import("@akanjs/config").AppScanResult | import("@akanjs/config").LibScanResult>;
12
- buildBackend(app: App, distApp: DistAppExecutor): Promise<void>;
13
- serveBackend(app: App, distApp: DistAppExecutor): Promise<void>;
14
- buildFrontend(app: App, distApp: DistAppExecutor): Promise<void>;
15
- serveFrontend(app: App, distApp: DistAppExecutor): Promise<void>;
16
- buildCsr(app: App, distApp: DistAppExecutor): Promise<void>;
17
- serveCsr(app: App, distApp: DistAppExecutor): Promise<void>;
13
+ buildBackend(app: App): Promise<void>;
14
+ serveBackend(app: App, { open }?: {
15
+ open?: boolean;
16
+ }): Promise<void>;
17
+ buildFrontend(app: App): Promise<void>;
18
+ serveFrontend(app: App, { open, turbo }?: {
19
+ open?: boolean;
20
+ turbo?: boolean;
21
+ }): Promise<void>;
22
+ buildCsr(app: App): Promise<void>;
23
+ serveCsr(app: App, { open }?: {
24
+ open?: boolean;
25
+ }): Promise<void>;
18
26
  buildIos(app: App): Promise<void>;
19
27
  serveIos(app: App, { open, operation }?: {
20
28
  open?: boolean;
@@ -1,35 +1,65 @@
1
1
  import type { App, Sys, Workspace } from "@akanjs/devkit";
2
- import { DistAppExecutor } from "@akanjs/devkit";
3
2
  import { LibraryScript } from "../library/library.script";
4
3
  import { type ReleaseSourceOptions } from "./application.runner";
5
4
  export declare class ApplicationScript {
6
5
  #private;
7
6
  libraryScript: LibraryScript;
8
- createApplication(appName: string, workspace: Workspace): Promise<void>;
7
+ createApplication(appName: string, workspace: Workspace, { serve }?: {
8
+ serve?: boolean;
9
+ }): Promise<void>;
10
+ removeApplication(app: App): Promise<void>;
9
11
  scanApplication(app: App, verbose?: boolean): Promise<import("@akanjs/config").AppScanResult | import("@akanjs/config").LibScanResult>;
10
12
  syncApplication(app: App, { recursive }?: {
11
13
  recursive?: boolean;
12
14
  }): Promise<void>;
13
- build(app: App, distApp?: DistAppExecutor): Promise<void>;
14
- serve(app: App, distApp?: DistAppExecutor): Promise<void>;
15
- buildBackend(app: App, distApp?: DistAppExecutor): Promise<void>;
16
- serveBackend(app: App, distApp?: DistAppExecutor): Promise<void>;
17
- buildFrontend(app: App, distApp?: DistAppExecutor): Promise<void>;
18
- serveFrontend(app: App, distApp?: DistAppExecutor): Promise<void>;
19
- buildCsr(app: App, distApp?: DistAppExecutor): Promise<void>;
20
- serveCsr(app: App, distApp?: DistAppExecutor): Promise<void>;
21
- buildIos(app: App): Promise<void>;
22
- serveIos(app: App, { open, operation }?: {
15
+ build(app: App): Promise<void>;
16
+ serve(app: App, { open }?: {
17
+ open?: boolean;
18
+ }): Promise<void>;
19
+ buildBackend(app: App, { sync }?: {
20
+ sync?: boolean;
21
+ }): Promise<void>;
22
+ serveBackend(app: App, { open, sync }?: {
23
+ open?: boolean;
24
+ sync?: boolean;
25
+ }): Promise<void>;
26
+ buildFrontend(app: App, { sync }?: {
27
+ sync?: boolean;
28
+ }): Promise<void>;
29
+ serveFrontend(app: App, { open, turbo, sync }?: {
30
+ open?: boolean;
31
+ turbo?: boolean;
32
+ sync?: boolean;
33
+ }): Promise<void>;
34
+ buildCsr(app: App, { sync }?: {
35
+ sync?: boolean;
36
+ }): Promise<void>;
37
+ serveCsr(app: App, { open, sync }?: {
38
+ open?: boolean;
39
+ sync?: boolean;
40
+ }): Promise<void>;
41
+ buildIos(app: App, { sync }?: {
42
+ sync?: boolean;
43
+ }): Promise<void>;
44
+ serveIos(app: App, { open, operation, sync, }?: {
23
45
  open?: boolean;
24
46
  operation?: "local" | "release";
47
+ sync?: boolean;
48
+ }): Promise<void>;
49
+ releaseIos(app: App, { sync }?: {
50
+ sync?: boolean;
25
51
  }): Promise<void>;
26
- releaseIos(app: App): Promise<void>;
27
- buildAndroid(app: App): Promise<void>;
28
- serveAndroid(app: App, { open, operation }?: {
52
+ buildAndroid(app: App, { sync }?: {
53
+ sync?: boolean;
54
+ }): Promise<void>;
55
+ serveAndroid(app: App, { open, operation, sync, }?: {
29
56
  open?: boolean;
30
57
  operation?: "local" | "release";
58
+ sync?: boolean;
59
+ }): Promise<void>;
60
+ releaseAndroid(app: App, { sync }?: {
61
+ sync?: boolean;
31
62
  }): Promise<void>;
32
- releaseAndroid(app: App): Promise<void>;
33
63
  dumpDatabase(app: App, environment: string): Promise<void>;
34
64
  restoreDatabase(app: App, source: string, target: string): Promise<void>;
35
65
  pullDatabase(app: App, environment: string, dump?: boolean): Promise<void>;
@@ -4,5 +4,8 @@ export declare class CloudCommand {
4
4
  cloudScript: CloudScript;
5
5
  login(): Promise<void>;
6
6
  logout(): void;
7
+ setLlm(): Promise<void>;
8
+ resetLlm(): void;
9
+ ask(question: string): Promise<void>;
7
10
  deployAkan(workspace: Workspace): Promise<void>;
8
11
  }
@@ -2,6 +2,8 @@ import { type Workspace } from "@akanjs/devkit";
2
2
  export declare class CloudRunner {
3
3
  login(): Promise<boolean>;
4
4
  logout(): void;
5
+ setLlm(): Promise<void>;
6
+ resetLlm(): void;
5
7
  getAkanPkgs(workspace: Workspace): Promise<string[]>;
6
8
  deployAkan(workspace: Workspace, akanPkgs: string[]): Promise<void>;
7
9
  }
@@ -3,5 +3,8 @@ export declare class CloudScript {
3
3
  #private;
4
4
  login(): Promise<void>;
5
5
  logout(): void;
6
+ setLlm(): Promise<void>;
7
+ resetLlm(): void;
8
+ ask(question: string): Promise<void>;
6
9
  deployAkan(workspace: Workspace): Promise<void>;
7
10
  }
@@ -3,7 +3,7 @@ import { LibraryScript } from "./library.script";
3
3
  export declare class LibraryCommand {
4
4
  libraryScript: LibraryScript;
5
5
  createLibrary(name: string, workspace: Workspace): Promise<void>;
6
- removeLibrary(lib: Lib, workspace: Workspace): Promise<void>;
6
+ removeLibrary(lib: Lib): Promise<void>;
7
7
  scanLibrary(lib: Lib): Promise<void>;
8
8
  buildLibrary(lib: Lib): Promise<void>;
9
9
  installLibrary(name: string, workspace: Workspace): Promise<void>;
@@ -2,6 +2,8 @@ import { Lib, LibExecutor, Workspace } from "@akanjs/devkit";
2
2
  export declare class LibraryRunner {
3
3
  #private;
4
4
  scanSync(lib: Lib): Promise<import("@akanjs/config").AppScanResult | import("@akanjs/config").LibScanResult>;
5
+ createLibrary(libName: string, workspace: Workspace): Promise<void>;
6
+ removeLibrary(lib: Lib): Promise<void>;
5
7
  installLibrary(workspace: Workspace, libName: string): Promise<LibExecutor>;
6
8
  mergeLibraryDependencies(lib: Lib): Promise<void>;
7
9
  pushLibrary(lib: Lib, branch: string): Promise<void>;
@@ -5,6 +5,8 @@ export declare class LibraryScript {
5
5
  syncLibrary(lib: Lib, { recursive }?: {
6
6
  recursive?: boolean;
7
7
  }): Promise<void>;
8
+ createLibrary(libName: string, workspace: Workspace): Promise<void>;
9
+ removeLibrary(lib: Lib): Promise<void>;
8
10
  installLibrary(workspace: Workspace, libName: string): Promise<void>;
9
11
  pushLibrary(lib: Lib, branch: string): Promise<void>;
10
12
  pullLibrary(lib: Lib, branch: string): Promise<void>;
@@ -1,5 +1,9 @@
1
- export declare const frameworkDescription = "\uB098\uB294 \uC880 \uB354 \uD6A8\uC728\uC801\uC73C\uB85C \uCF54\uB529\uC744 \uD558\uAE30 \uC704\uD574\uC11C \uC790\uCCB4 \uD504\uB808\uC784\uC6CC\uD06C\uB97C \uC81C\uC791\uD588\uC5B4. \uADF8\uB798\uC11C \uC6B0\uB9AC \uD504\uB808\uC784\uC6CC\uD06C\uC5D0 \uB300\uD55C \uC124\uBA85\uC744 \uD574\uC904\uD14C\uB2C8\uAE4C \uC798 \uC774\uD574\uD558\uB3C4\uB85D \uD574. \uC6B0\uB9AC \uD504\uB808\uC784\uC6CC\uD06C\uB294 next.js 13\uACFC nest.js, capacitor.js, nx, mongoDB \uAE30\uBC18\uC758 \uD504\uB860\uD2B8\uC5D4\uB4DC, \uC571, \uBC31\uC5D4\uB4DC \uD1B5\uD569 \uD504\uB808\uC784\uC6CC\uD06C\uC57C. \uADF8\uB798\uC11C \uBC31\uC5D4\uB4DC, \uD504\uB860\uD2B8\uC5D4\uB4DC, DB Schema\uC5D0 \uB300\uD55C \uCF54\uB4DC\uAC00 \uBAA8\uB450 \uD55C \uD3F4\uB354 \uC548\uC5D0 \uC788\uC5B4. \uADF8\uB798\uC11C \uC790\uBC14\uC2A4\uD06C\uB9BD\uD2B8, \uD0C0\uC785\uC2A4\uD06C\uB9BD\uD2B8, \uADF8\uB9AC\uACE0 \uD504\uB808\uC784\uC6CC\uD06C\uC5D0 \uB300\uD55C \uC774\uD574\uB9CC \uC788\uB2E4\uBA74 \uAD6C\uBD84\uC9D3\uC9C0 \uC54A\uACE0 \uC0AC\uC6A9\uD560 \uC218 \uC788\uB2E4\uB294 \uC7A5\uC810\uC774 \uC788\uC5B4. \n\n\uAC00\uC7A5 \uC678\uBD80\uC758 \uAD6C\uC870\uB294\n- app\n\t- project1\n\t- project2\n\t- project3\n\t- project4\n- lib\n\t- core\n\t- external\n\t- game\n\t- mint\n\t- platform\n\t- shared\n\t- social\n\t- util\napp\uC740 \uAC01 \uD504\uB85C\uC81D\uD2B8\uB97C \uB9CC\uB4DC\uB294 \uACF3\uC774\uC57C\nlib \uD558\uC704 \uD3F4\uB354\uB4E4\uC740 \uC5EC\uB7EC \uD504\uB85C\uC81D\uD2B8\uC5D0\uC11C \uACF5\uC6A9\uC73C\uB85C \uC0AC\uC6A9\uD560 \uC218 \uC788\uACA0\uB2E4 \uB77C\uACE0 \uD310\uB2E8\uD574\uC11C \uBD84\uB9AC\uD574\uB193\uC740 \uACF3\uC774\uC57C.\n\uB2E4\uC74C\uC740 app/project \uB0B4\uBD80\uC758 \uAD6C\uC870\uB97C \uC54C\uB824\uC904\uAC8C.\n\nproject\n- app\n\t- [lang]\n\t\t- (projectName)\n\t\t\t- (user)\n\t\t\t\t- page.tsx\n\t\t\t\t- layout.tsx\n\t\t\t- (public)\n\t\t\t\t- page.tsx\n\t\t\t\t- layout.tsx\n\t\t\t- (admin)\n\t\t\t\t- page.tsx\n\t\t\t\t- layout.tsx\n\n- lib \n\t- dataName1\n\t- dataName2\n\t- dataName3\n\t- dataName4\n\t- dataName5\n\t- dataName6\n\t- dataName7\n\napp\uC740 \uC9C1\uC811\uC801\uC73C\uB85C \uC720\uC800\uAC00 \uBCF4\uB294 \uD398\uC774\uC9C0\uB97C \uC9DC\uB294 \uACF3\uC774\uC57C. \uD3F4\uB354 \uAD6C\uC870\uB294 next 13\uC758 app directory\uB97C \uB530\uB974\uACE0 \uC788\uC5B4.\npublic/page.tsx\uAC00 \uAC00\uC7A5 \uCD5C\uCD08\uB85C \uC811\uADFC\uB418\uB294 Index \uD398\uC774\uC9C0\uAC00 \uB420 \uAC70\uC57C.\n\uC544\uB798\uB294 public/page.tsx\uC758 \uAE30\uBCF8 \uD15C\uD50C\uB9BF \uC18C\uC2A4\uCF54\uB4DC\uC57C.\n```\nimport {{ Image, Link }} from \"@util/ui\";\nimport {{ getSelf }} from \"@akanjs/client\";\n\nexport default function Page() {{\n const self = getSelf();\n return (\n <div className=\"relative w-full h-screen overflow-hidden flex items-center justify-center\">\n <Image\n className=\"absolute left-0 right-0 top-0 bottom-0 w-full h-screen -z-50\"\n width={{1920}}\n height={{1080}}\n src=\"/back.jpg\"\n />\n <div className=\"max-w-md bg-base-100/50 shadow-lg rounded-xl backdrop-blur-xs w-full py-8 px-16 flex flex-col items-center justify-center gap-3\">\n <h1 className=\"text-4xl mt-2\"><%= project %></h1>\n <h2 className=\"text-lg\"><%= project %> description</h2>\n <Link className=\"w-full\" href={{self ? \"/home\" : \"/signin\"}}>\n <button className=\"btn w-full btn-primary\">Go to dashboard</button>\n </Link>\n </div>\n </div>\n );\n}}\n```\n\nlib\uC740 \uC11C\uBE44\uC2A4\uB97C \uB9CC\uB4E4\uB2E4\uBCF4\uBA74 \uD544\uC694\uD55C \uB370\uC774\uD130\uB97C \uC815\uC758\uD558\uB294 \uACF3\uC774\uC57C.\n\uB530\uB77C\uC11C dataName\uC740 DB\uC774\uB984. \uC989 \uB370\uC774\uD130\uBA85\uC744 \uB530\uB77C. \uB2E4\uB9CC \uD3F4\uB354 \uB0B4\uBD80\uC5D0\uB294 backend, frontend\uC5D0\uC11C \uD1B5\uD569\uC73C\uB85C \uC4F0\uB294 \uC18C\uC2A4\uCF54\uB4DC\uB4E4\uC774 \uC788\uC5B4.\n\n\uC6B0\uB9AC \uD504\uB808\uC784\uC6CC\uD06C\uC758 \uD575\uC2EC\uC740 \uC815\uC758\uD55C \uBA54\uD0C0\uB370\uC774\uD130\uB4E4\uC744 \uC774\uC6A9\uD574\uC11C \uAC01 \uB370\uC774\uD130\uAC04\uC758 \uC5F0\uAD00\uC810\uC774\uB098, \uB370\uC774\uD130 \uD0C0\uC785\uC744 \uBCF4\uACE0 \uBBF8\uB9AC \uC815\uB9AC\uB41C \uACB0\uACFC\uB97C \uB9CC\uB4E4\uC5B4\uC8FC\uACE0 \uD504\uB85C\uC81D\uD2B8\uB97C \uB9CC\uB4E0\uB2E4\uBA74 \uAC70\uC758 \uBAA8\uB450 \uD544\uC694\uD55C \uC791\uC5C5\uB4E4\uC744 \uBBF8\uB9AC \uC815\uB9AC\uD574\uB1A8\uC5B4. \uC608\uB97C \uB4E4\uC5B4 \uB370\uC774\uD130 \uD0C0\uC785\uC5D0 \uC774\uBBF8\uC9C0 \uD30C\uC77C\uC774 \uC788\uB2E4\uACE0 \uD55C\uB2E4\uBA74 \uBC31\uC5D4\uB4DC\uB97C \uD1B5\uD574 \uADF8 \uC774\uBBF8\uC9C0\uB97C \uC11C\uBC84\uC758 \uC2A4\uD1A0\uB9AC\uC9C0\uC5D0 \uC800\uC7A5\uD558\uACE0 \uADF8 \uC800\uC7A5\uB41C \uD30C\uC77C\uC744 \uD2B9\uC815 db\uC5D0 id\uB97C \uCD94\uAC00\uD574\uC8FC\uB294 \uD568\uC218\uB4E4 \uAC19\uC740 \uAC83\uB4E4\uC740 \uC5B4\uB290 \uD504\uB85C\uC81D\uD2B8\uB358 \uAC04\uC5D0 \uBAA8\uB450 \uC0AC\uC6A9\uB418\uB294 \uBC29\uC2DD\uC774\uB77C\uACE0 \uD310\uB2E8\uD588\uC5B4. \uD558\uC9C0\uB9CC \uC6B0\uB9AC\uB294 \uD504\uB85C\uC81D\uD2B8\uB97C \uC791\uC5C5\uD560 \uB54C\uB9C8\uB2E4 \uC774 \uBD88\uD544\uC694\uD55C \uC791\uC5C5\uB4E4\uC744 \uD56D\uC0C1 \uB9CC\uB4E4\uACE0 \uD14C\uC2A4\uD2B8\uB97C \uD558\uB294 \uBD88\uD544\uC694\uD55C \uC77C\uB4E4\uC744 \uD558\uACE0\uC788\uC9C0. \uADF8\uB798\uC11C \uC6B0\uB9AC\uB294 \uAC01 \uD504\uB85C\uC81D\uD2B8\uAC00 \uB9CC\uB4E4 \uB54C\uB9C8\uB2E4 \uD544\uC218\uB85C \uC788\uC5B4\uC57C\uD560 \uC774\uBBF8\uC9C0 \uC5C5\uB85C\uB4DC \uD504\uB85C\uC138\uC2A4\uB97C \uD504\uB808\uC784\uC6CC\uD06C\uB97C \uD1B5\uD574 \uBBF8\uB9AC \uC815\uC758\uB41C \uC0C1\uD0DC\uB85C \uC0AC\uC6A9\uD560 \uC218 \uC788\uC5B4.\n\uACB0\uACFC\uC801\uC73C\uB85C \uC6B0\uB9B0 \uD544\uC694\uD558\uC9C0\uB9CC \uB9E4\uBC88 \uC791\uC5C5\uD558\uAE30\uC5D4 \uC190\uC774 \uB9CE\uC774\uAC00\uB294 \uC791\uC5C5\uB4E4\uC744 \uBBF8\uB9AC \uC815\uC758\uD574\uB1A8\uC5B4.\n\n\uB610\uD55C \uC6B0\uB9B0 CLI\uB97C \uD1B5\uD574\uC11C \uD2B9\uC815 \uD504\uB85C\uC81D\uD2B8 \uD3F4\uB354 \uD15C\uD50C\uB9BF\uC744 \uB9CC\uB4E4\uC5B4\uC8FC\uAC70\uB098, \uD2B9\uC815 \uBAA8\uB378\uC758 \uD544\uB4DC\uB4E4\uC744 \uB9CC\uB4E4 \uC218 \uC788\uB3C4\uB85D \uD574\uB1A8\uC5B4. Model\uC774\uB77C\uB294 \uBCC0\uC218\uC758 \uACB0\uACFC\uAC12\uC744 \uBC1B\uACE0 \uC800 \uD15C\uD50C\uB9BF\uC5D0 \uB9DE\uAC8C\uB054 \uC774\uB984\uC744 \uB123\uC5B4\uC8FC\uB294 \uAC70\uC9C0. \uB9CC\uC57D \uB0B4\uAC00 phone\uC774\uB77C\uB294 \uBCC0\uC218\uB97C \uB123\uC5C8\uB2E4\uBA74 \uC800 \uBAA8\uB378\uC5D0 Phone\uACFC \uAC19\uC740 \uACB0\uACFC\uAC12\uC73C\uB85C \uAC12\uC774 \uB4E4\uC5B4\uAC00\uAC8C \uB428\uC73C\uB85C\uC11C \uD15C\uD50C\uB9BF\uC774 \uC0DD\uC131\uB3FC. \uC774\uB294 \uC6B0\uB9AC\uAC00 \uC774\uBBF8 \uB9CC\uB4E4\uC5B4\uB193\uC740 \uCEE4\uB9E8\uB4DC\uAC00 \uC788\uC5B4.\n\n\uC608\uB97C \uB4E4\uC5B4 \uC5F0\uD544\uC774\uB77C\uB294 \uBAA8\uB378\uC744 \uCEE4\uB9E8\uB4DC\uB97C \uD1B5\uD574 \uC0DD\uC131\uD558\uBA74 \uC544\uB798\uC640 \uAC19\uC740 \uD30C\uC77C\uB4E4\uC774 \uC0DD\uC131\uB3FC.\n\npencil\n- pencil.constant.ts ( pencil\uC5D0 \uB300\uD55C db schema, query, sort \uAD6C\uBB38\uC744 \uC815\uC758 )\n- pencil.document.ts ( model\uC5D0\uC11C \uC790\uC8FC \uC0AC\uC6A9\uD558\uB294 method, static function, middleware\uB85C \uAC04\uB2E8\uD55C db \uAD00\uB9AC \uD568\uC218\uB4F1\uC744 \uAD00\uB9AC\uD568.)\n- pencil.dictionary.ts (\uB2E4\uAD6D\uC5B4\uB97C \uC704\uD574\uC11C schema field, enum, service name\uC758 \uB2E4\uAD6D\uC5B4 \uC815\uBCF4 \uB4F1\uC744 \uBAA8\uB450 \uAD00\uB9AC. )\n- pencil.signal.ts (frontend\uC758 fetch\uB97C \uC5F4\uC5B4\uC8FC\uB294 \uC77C\uC885\uC758 \uCC3D\uAD6C, \uAD8C\uD55C\uAD00\uB9AC\uB4F1\uC744 \uD568 nestjs\uC758 resolver\uC640 \uC720\uC0AC )\n- pencil.service.ts (\uC2E4\uC9C8\uC801\uC778 \uC11C\uBE44\uC2A4 \uCF54\uB4DC\uB97C \uC791\uC131\uD558\uB294 \uACF3. \uAC01\uC885 \uBE44\uC988\uB2C8\uC2A4 \uB85C\uC9C1\uC744 \uCC98\uB9AC\uD568.)\n- pencil.store.ts (pencil field\uC5D0 \uB300\uD55C \uC0C1\uD0DC\uAD00\uB9AC \uC800\uC7A5\uC18C.)\n- pencil.Zone.tsx (\uC544\uB798 Templete, Unit, Util, View, Util\uB4F1\uC744 \uC870\uD569\uD574\uC11C \uB2E4\uC74C \uB808\uBCA8 \uCEF4\uD3EC\uB10C\uD2B8\uB97C \uC791\uC131\uD558\uB294 \uACF3 client component\uB85C \uC815\uC758\uB428. )\n- pencil.Templete.tsx (\uC8FC\uB85C edit\uC5D0 \uC5F0\uAD00\uB41C \uCEF4\uD3EC\uB10C\uD2B8 \uC815\uC758\uD558\uB294 \uACF3. client component\uB85C \uC815\uC758\uB428. )\n- pencil.Unit.tsx (list \uCC98\uB7FC \uBCF5\uC218\uAC1C\uC758 \uCEF4\uD3EC\uB10C\uD2B8\uB97C \uC815\uC758\uD558\uB294 \uACF3. server component\uB85C \uC815\uC758\uB428. )\n- pencil.Util.tsx (Action \uBC84\uD2BC\uC744 \uC815\uC758\uD558\uB294 \uACF3. client component\uB85C \uC815\uC758\uB428. )\n- pencil.View.tsx (\uB2E8\uC77C view \uCEF4\uD3EC\uB10C\uD2B8\uB97C \uC815\uC758\uD558\uB294 \uACF3. server component\uB85C \uC815\uC758\uB428. )\n\n\n\uC5EC\uAE30\uC11C constant\uC5D0 \uC815\uC758 \uB418\uC5B4\uC788\uB294 schema\uB97C \uAE30\uBCF8\uC73C\uB85C \uD574\uC11C \uAC01 document, dictionary, signal, service, store\uB97C \uC0DD\uC131\uD574.\n\ndocument, signal, service\uB294 \uBC31\uC5D4\uB4DC\uC640 \uC5F0\uAD00\uB418\uC5B4\uC788\uB294 \uC18C\uC2A4\uCF54\uB4DC\uC57C.\n\uC11C\uB85C\uAC04\uC758 \uAD00\uACC4\uB294 \uC8FC\uB85C signal\uC5D0\uC11C \uAC00\uC7A5 \uBA3C\uC800 \uC694\uCCAD\uC744 \uBC1B\uACE0 \uC774\uD6C4 \uB85C\uC9C1\uC758 \uBCF5\uC7A1\uB3C4\uC5D0 \uB530\uB77C\uC11C service\uB85C \uCC98\uB9AC\uD560 \uC9C0, docuemnt\uB85C \uCC98\uB9AC\uD560 \uC9C0\uB97C \uACB0\uC815\uD574.\nsignal - document\nsignal - service - document\n\nstore\uB294 \uD504\uB860\uD2B8\uC5D4\uB4DC\uC5D0\uC11C \uC0C1\uD0DC\uAD00\uB9AC\uB97C \uD560 \uB54C \uC0AC\uC6A9\uB3FC.\n\uC6B0\uB9AC\uB294 signal\uC758 \uCF54\uB4DC\uB85C \uB098\uC628 \uBA54\uD0C0\uB370\uC774\uD130\uB97C \uC774\uC6A9\uD574\uC11C store\uC5D0\uC11C \uD754\uD788 \uC0AC\uC6A9\uB420\uB9CC\uD55C \uD568\uC218\uB4E4\uC744 \uBBF8\uB9AC \uC815\uC758\uD558\uAC8C\uB054 \uB9CC\uB4E4\uC5C8\uC5B4.\n\n\uC774\uB807\uAC8C 11\uAC1C\uC758 \uD30C\uC77C\uB85C \uAD6C\uBD84\uD574\uC11C \uC815\uC758\uAC00 \uB3FC. \n\uC9C0\uAE08\uBD80\uD134 \uD55C \uD30C\uC77C\uB4E4\uB9C8\uB2E4 \uC0C1\uC138\uD55C \uC124\uBA85\uC744 \uD574\uC904\uAC8C.\n\nmodel.constant.ts\n\nconstant\uB294 \uAE30\uBCF8 \uC2A4\uD0A4\uB9C8\uAC00 \uAD6C\uC131\uB418\uB294 \uACF3\uC774\uC57C. \uADF8\uB798\uC11C \uC774 \uACF3\uC5D0\uC11C DB \uC2A4\uD0A4\uB9C8, \uCFFC\uB9AC, \uC815\uB82C \uAD6C\uBB38\uC744 \uC815\uC758\uD574.\n\uC8FC\uC758\uD574\uC57C\uD560 \uAC74 decorator\uC5D0\uC11C \uC815\uC758\uD558\uB294 \uD0C0\uC785\uACFC \uC544\uB798\uC5D0 \uC815\uC758\uD558\uB294 \uD0C0\uC785\uC774 \uC57D\uAC04 \uB2E4\uB97C \uC218 \uC788\uC5B4\n\uC608\uB97C \uB4E4\uC5B4 decorator\uC5D0\uC11C\uB294 Int\uB85C \uC815\uC758\uD558\uACE0 constant\uC5D0\uC11C\uB294 number\uB85C \uC815\uC758\uD574\uC57C\uD574.\n\uCD94\uAC00\uB85C createdAt\uACFC updatedAt, status\uB294 \uAE30\uBCF8\uC801\uC73C\uB85C \uC0DD\uC131\uB418\uB294 \uD544\uB4DC\uC774\uB2C8\uAE4C \uB530\uB85C \uC815\uC758\uD558\uC9C0 \uC54A\uC544\uB3C4 \uB3FC.\n\uC774\uB294 decorator\uC5D0\uC11C\uB294 GraphQL\uC5D0\uC11C \uC0AC\uC6A9\uD560 \uD0C0\uC785\uC744 \uC815\uC758\uD558\uACE0 constant\uC5D0\uC11C\uB294 \uC2E4\uC81C \uD0C0\uC785\uC744 \uC815\uC758\uD558\uB294 \uAC70\uC9C0.\n\n```\nimport { enumOf, Int } from \"@akanjs/base\";\nimport { Field, Filter, Model, sortOf, via } from \"@akanjs/constant\";\n\nexport const ${dict.Model}Statuses = [\"active\"] as const;\nexport type ${dict.Model}Status = (typeof ${dict.Model}Statuses)[number];\n\n//\uB370\uC774\uD130\uB97C \uB9CC\uB4E4 \uB54C \uD544\uC694\uD55C \uB370\uC774\uD130 \uD0C0\uC785\uC744 \uC815\uC758\uD558\uB294 \uACF3\n@Model.Input(\"${dict.Model}Input\")\nexport class ${dict.Model}Input {{\n @Field.Prop(() => String)\n field: string;\n\n @Field.Prop(() => Int, {{ nullable: true }})\n fieldInt: number | null;\n\n @Field.Prop(() => Date, {{default: dayjs()}})\n fieldInt: Dayjs;\n}}\n\n//\uB370\uC774\uD130\uAC00 \uB9CC\uB4E4\uC5B4\uC9C4 \uC774\uD6C4 \uC0DD\uC131\uB418\uAC70\uB098 \uC800\uC7A5\uC73C\uB85C \uCD94\uAC00\uD560 \uC218 \uC788\uB294 \uACF3\n@Model.Object(\"${dict.Model}Object\")\nexport class ${dict.Model}Object extends via(${dict.Model}Input) {\n @Field.Prop(() => String, {{ enum: ${dict.Model}Statuses, default: \"active\" }})\n status: ${dict.Model}Status;\n}}\n\n//\uB370\uC774\uD130\uB97C \uB9AC\uC2A4\uD2B8\uB85C \uBCF4\uC5EC\uC904 \uB54C \uD544\uC694\uD55C \uB370\uC774\uD130\uB9CC \uC81C\uACF5\uD558\uB294 \uACF3\n@Model.Light(\"Light${dict.Model}\")\nexport class Light${dict.Model} extends via(${dict.Model}Object, [\n \"field\",\n \"status\",\n] as const) {}\n\n//\uCD5C\uC885 \uB370\uC774\uD130\uC758 Full \uD0C0\uC785\uC774 \uC815\uC758\uB418\uB294 \uACF3\n@Model.Full(\"${dict.Model}\")\nexport class ${dict.Model} extends via(${dict.Model}Object, Light${dict.Model}) {}\n\n//\uB370\uC774\uD130\uC758 \uC778\uC0AC\uC774\uD2B8\uB97C \uCE21\uC815\uD558\uAE30 \uC704\uD574\uC11C \uD544\uC694\uD55C \uB370\uC774\uD130\uB97C \uC815\uC758\uD558\uB294 \uACF3\n@Model.Insight(\"${dict.Model}Insight\")\nexport class ${dict.Model}Insight {{\n @Field.Prop(() => Int, {{ default: 0, accumulate: {{ $sum: 1 }} }})\n count: number;\n}}\n\n//\uB370\uC774\uD130\uC758 \uD1B5\uACC4\uB97C \uACC4\uC0B0\uD558\uB294 \uACF3\n@Model.Summary(\"${dict.Model}Summary\")\nexport class ${dict.Model}Summary {{\n @Field.Prop(() => Int, {{ min: 0, default: 0, query: {{ status: {{}} }} }})\n total${dict.Model}: number;\n}}\n\n@Model.Filter(\"${dict.Model}Filter\")\nexport class ${dict.Model}Filter extends sortOf(${dict.Model}, {}) {}\n```\n\n\nmodel.dictonary.ts\n```\nimport {\n baseTrans,\n getBaseSignalTrans,\n ModelDictionary,\n SignalDictionary,\n SummaryDictionary,\n} from \"@akanjs/dictionary\";\n\nimport type { ${dict.Model}, ${dict.Model}Filter, ${dict.Model}Insight, ${dict.Model}Summary } from \"./${dict.model}.constant\";\nimport type { ${dict.Model}Signal } from \"./${dict.model}.signal\";\n\nconst modelDictionary = {{\n ...baseTrans,\n modelName: [\"${dict.Model}\", \"${dict.Model}\"],\n modelDesc: [\n \"${dict.Model} description\",\n \"${dict.Model} \uC124\uBA85\",\n ],\n\n // * ==================== Model ==================== * //\n field: [\"Field\", \"\uD544\uB4DC\"],\n \"desc-field\": [\"Field\", \"\uD544\uB4DC\"],\n // * ==================== Model ==================== * //\n\n // * ==================== Insight ==================== * //\n count: [\"Count\", \"\uAC1C\uC218\"],\n \"desc-count\": [\"${dict.Model} count in current query settting\", \"\uD604\uC7AC \uCFFC\uB9AC \uC124\uC815\uC5D0 \uB9DE\uB294 ${dict.Model} \uC218\"],\n // * ==================== Insight ==================== * //\n\n // * ==================== Filter ==================== * //\n // * ==================== Filter ==================== * //\n\n // * ==================== Etc ==================== * //\n \"enum-status-active\": [\"Active\", \"\uD65C\uC131\"],\n \"enumdesc-status-active\": [\"Active status\", \"\uD65C\uC131 \uC0C1\uD0DC\"],\n // * ==================== Etc ==================== * //\n}} satisfies ModelDictionary<${dict.Model}, ${dict.Model}Insight, typeof ${dict.Model}Sort>;\n\nexport const ${dict.Model}SummaryDictionary = {{\n // * ==================== Summary ==================== * //\n total${dict.Model}: [\"Total ${dict.Model}\", \"\uCD1D ${dict.Model} \uC218\"],\n \"desc-total${dict.Model}\": [\"Total ${dict.Model} count in the database\", \"\uB370\uC774\uD130\uBCA0\uC774\uC2A4\uC5D0 \uC800\uC7A5\uB41C \uCD1D ${dict.Model} \uC218\"],\n // * ==================== Summary ==================== * //\n}} satisfies SummaryDictionary<${dict.Model}Summary>;\n\nconst signalDictionary = {{\n ...getBaseSignalTrans(\"${dict.Model}\" as const),\n // * ==================== Endpoint ==================== * //\n \"api-${dict.Model}ListInPublic\": [\"${dict.Model} List In Public\", \"\uACF5\uAC1C\uB41C ${dict.Model} \uB9AC\uC2A4\uD2B8\"],\n \"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\"],\n \"arg-${dict.Model}ListInPublic-statuses\": [\"Statuses\", \"\uC0C1\uD0DC\"],\n \"argdesc-${dict.Model}ListInPublic-statuses\": [\"Statuses to filter\", \"\uD544\uD130\uB9C1\uD560 \uC0C1\uD0DC\"],\n \"arg-${dict.Model}ListInPublic-skip\": [\"Skip\", \"\uAC74\uB108\uB6F0\uAE30\"],\n \"argdesc-${dict.Model}ListInPublic-skip\": [\"Number of items to skip\", \"\uAC74\uB108\uB6F8 \uC544\uC774\uD15C \uC218\"],\n \"arg-${dict.Model}ListInPublic-limit\": [\"Limit\", \"\uC81C\uD55C\"],\n \"argdesc-${dict.Model}ListInPublic-limit\": [\"Maximum number of items to return\", \"\uBC18\uD658\uD560 \uCD5C\uB300 \uC544\uC774\uD15C \uC218\"],\n \"arg-${dict.Model}ListInPublic-sort\": [\"Sort\", \"\uC815\uB82C\"],\n \"argdesc-${dict.Model}ListInPublic-sort\": [\"Sort order of the items\", \"\uC544\uC774\uD15C\uC758 \uC815\uB82C \uC21C\uC11C\"],\n\n \"api-${dict.Model}InsightInPublic\": [\"${dict.Model} Insight In Public\", \"\uACF5\uAC1C\uB41C ${dict.Model} \uC778\uC0AC\uC774\uD2B8\"],\n \"apidesc-${dict.Model}InsightInPublic\": [\n \"Get insight data for public ${dict.Model}\",\n \"\uACF5\uAC1C\uB41C ${dict.Model}\uC5D0 \uB300\uD55C \uC778\uC0AC\uC774\uD2B8 \uB370\uC774\uD130\uB97C \uAC00\uC838\uC635\uB2C8\uB2E4\",\n ],\n \"arg-${dict.Model}InsightInPublic-statuses\": [\"Statuses\", \"\uC0C1\uD0DC\"],\n \"argdesc-${dict.Model}InsightInPublic-statuses\": [\"Statuses to filter\", \"\uD544\uD130\uB9C1\uD560 \uC0C1\uD0DC\"],\n // * ==================== Endpoint ==================== * //\n}} satisfies SignalDictionary<${dict.Model}Signal, ${dict.Model}>;\n```\nexport const ${dict.model}Dictionary = {{ ...modelDictionary, ...signalDictionary }};\n\n\n\nmodel.document.ts\n```\nimport { beyond, by, Database, into, type SchemaOf } from \"@akanjs/document\";\n\nimport { cnst } from \"../cnst\";\n@Database.Input(() => cnst.${dict.Model}Input)\nexport class ${dict.Model}Input extends by(cnst.${dict.Model}Input) {}\n\n@Database.Document(() => cnst.${dict.Model})\nexport class ${dict.Model} extends by(cnst.${dict.Model}) {}\n\n@Database.Model(() => cnst.${dict.Model})\nexport class ${dict.Model}Model extends into(${dict.Model}, cnst.${dict.Model}Cnst) {\n async getSummary(): Promise<cnst.${dict.Model}Summary> {\n return {\n ...(await this.getDefaultSummary()),\n };\n }\n}\n\n@Database.Middleware(() => cnst.${dict.Model})\nexport class ${dict.Model}Middleware extends beyond(${dict.Model}Model, ${dict.Model}) {\n onSchema(schema: SchemaOf<${dict.Model}Model, ${dict.Model}>) {\n // schema.index({ status: 1 })\n }\n}\n```\n\n\nmodel.signal.ts\n```\nimport { Int } from \"@akanjs/base\";\nimport { SortOf } from \"@akanjs/constant\";\nimport { Arg, DbSignal, Mutation, Query, resolve, Signal } from \"@akanjs/signal\";\n\nimport { cnst, Srvs } from \"../cnst\";\n\n@Signal(() => cnst.${dict.Model})\nexport class ${dict.Model}Signal extends DbSignal(cnst.${dict.model}Cnst, Srvs, {\n guards: { get: Query.Public, cru: Mutation.Public },\n}) {\n // * /////////////////////////////////////\n // * Public Slice\n @Query.Public(() => [cnst.${dict.Model}])\n async ${dict.model}ListInPublic(\n @Arg.Query(\"statuses\", () => [String], { nullable: true }) statuses: cnst.${dict.Model}Status[] | null,\n @Arg.Query(\"skip\", () => Int, { nullable: true }) skip: number | null,\n @Arg.Query(\"limit\", () => Int, { nullable: true }) limit: number | null,\n @Arg.Query(\"sort\", () => String, { nullable: true }) sort: SortOf<cnst.${dict.Model}Filter> | null\n ) {\n const ${dict.models} = await this.${dict.model}Service.listByStatuses(statuses, { skip, limit, sort });\n return resolve<cnst.${dict.Model}[]>(${dict.models});\n }\n @Query.Public(() => cnst.${dict.Model}Insight)\n async ${dict.model}InsightInPublic(\n @Arg.Query(\"statuses\", () => [String], { nullable: true }) statuses: cnst.${dict.Model}Status[] | null\n ) {\n const ${dict.model}Insight = await this.${dict.model}Service.insightByStatuses(statuses);\n return resolve<cnst.${dict.Model}Insight>(${dict.model}Insight);\n }\n // * Public Slice\n // * /////////////////////////////////////\n}\n```\n\n\nmodel.service.ts\n```\nimport { DbService, Service } from \"@akanjs/service\";\n\nimport { cnst } from \"../cnst\";\nimport * as db from \"../db\";\n\n@Service(\"${dict.Model}Service\")\nexport class ${dict.Model}Service extends DbService(db.${dict.Model}Db) {\n async summarize(): Promise<cnst.${dict.Model}Summary> {\n return {\n ...(await this.${dict.Model}Model.getSummary()),\n };\n }\n}\n```\n\n\nmodel.store.ts\n```\nimport { stateOf, Store } from \"@akanjs/store\";\n\nimport { cnst } from \"../cnst\";\nimport { fetch } from \"../fetch\";\n\n@Store(() => cnst.${dict.Model})\nexport class ${dict.Model}Store extends stateOf(fetch.${dict.model}Gql, {\n // state\n}) {\n // action\n}\n```\n\n\nmodel.Zone.tsx\n```\n\"use client\";\nimport { Data, Load } from \"@shared/ui\";\nimport { ModelsProps } from \"@akanjs/client\";\nimport { cnst, ${dict.Model} } from \"@${dict.appName}/client\";\nimport { ClientInit, ClientView, DefaultOf } from \"@akanjs/signal\";\n\nexport const Admin = ({ sliceName = \"${dict.model}\", init, query }: ModelsProps<cnst.${dict.Model}>>) => {\n return (\n <Data.ListContainer\n init={init}\n query={query}\n sliceName={sliceName}\n renderItem={${dict.Model}.Unit.Card}\n renderDashboard={${dict.Model}.Util.Stat}\n renderInsight={${dict.Model}.Util.Insight}\n renderTemplate={${dict.Model}.Template.General}\n renderTitle={(${dict.model}: DefaultOf<cnst.${dict.Model}>>) => `${dict.Model} - ${${dict.model}.id ? ${dict.model}.id : \"New\"}`}\n renderView={(${dict.model}: cnst.${dict.Model}>) => <${dict.Model}.View.General ${dict.model}={${dict.model}} />}\n columns={[\n \"id\",\n \"status\",\n \"createdAt\",\n \"updatedAt\",\n ]}\n actions={(${dict.model}: cnst.Light${dict.Model}, idx) => [\"remove\", \"edit\", \"view\"]}\n />\n );\n};\n\ninterface CardProps {\n className?: string;\n init: ClientInit<\"${dict.model}\", cnst.Light${dict.Model}>;\n}\nexport const Card = ({ className, init }: CardProps) => {\n return (\n <Load.Units\n className={className}\n init={init}\n renderItem={(${dict.model}: cnst.Light${dict.Model}) => (\n <${dict.Model}.Unit.Card key={${dict.model}.id} href={`/${dict.model}/${${dict.model}.id}`} ${dict.model}={${dict.model}} />\n )}\n />\n );\n};\n\ninterface ViewProps {\n className?: string;\n view: ClientView<\"${dict.model}\", cnst.${dict.Model}>;\n}\nexport const View = ({ view }: ViewProps) => {\n return <Load.View view={view} renderView={(${dict.model}) => <${dict.Model}.View.General ${dict.model}={${dict.model}} />} />;\n};\n```\n\nmodel.Templete.tsx\n```\n\"use client\";\nimport { cnst, st, usePage } from \"@${dict.appName}/client\";\nimport { Field } from \"@shared/ui\";\nimport { Layout } from \"@util/ui\";\n\ninterface ${dict.Model}EditProps {\n ${dict.model}Id?: string | null;\n}\n\nexport const General = ({ ${dict.model}Id = undefined }: ${dict.Model}EditProps) => {\n const ${dict.model}Form = st.use.${dict.model}Form();\n const { l } = usePage();\n return (\n <Layout.Template>\n <Field.Text\n label={l.field(\"${dict.model}\", \"id\")}\n desc={l.desc(\"${dict.model}\", \"id\")}\n value={${dict.model}Form.id}\n onChange={st.do.setIdOn${dict.Model}}\n />\n </Layout.Template>\n );\n};\n```\n\n\nmodel.Unit.tsx\n```\nimport { ModelProps } from \"@akanjs/client\";\nimport { cnst, ${dict.Model} } from \"@${dict.appName}/client\";\nimport { Link } from \"@util/ui\";\n\nexport const Card = ({ ${dict.model}, href }: ModelProps<\"${dict.model}\", cnst.Light${dict.Model}>>) => {\n return (\n <Link href={href} className=\"animate-fadeIn w-full h-36 flex rounded-lg shadow-sm hover:shadow-lg duration-300\">\n <div>{${dict.model}.id}</div>\n </Link>\n );\n};\n```\n\n\nmodel.Util.tsx\n```\n\"use client\";\nimport { ModelDashboardProps, ModelInsightProps } from \"@akanjs/client\";\nimport { getQueryMap } from \"@akanjs/constant\";\nimport { cnst } from \"@${dict.appName}/client\";\nimport { Data } from \"@shared/ui\";\n\nexport const Stat = ({\n className,\n summary,\n sliceName = \"${dict.model}\",\n queryMap = getQueryMap(cnst.${dict.Model}Summary),\n hidePresents,\n}: ModelDashboardProps<cnst.Summary>) => {\n return (\n <Data.Dashboard\n className={className}\n summary={summary}\n sliceName={sliceName}\n queryMap={queryMap}\n columns={[\"total${dict.Model}\"]}\n hidePresents={hidePresents}\n />\n );\n};\n\nexport const Insight = ({\n className,\n insight,\n sliceName = \"${dict.model}\",\n}: ModelInsightProps<cnst.${dict.Model}Insight>) => {\n return (\n <Data.Insight\n className={className}\n insight={insight}\n sliceName={sliceName}\n columns={[\"count\"]}\n />\n );\n};\n```\n\n\nmodel.View.tsx\n```\nimport { clsx } from \"@akanjs/client\";\nimport { cnst } from \"@${dict.appName}/client\";\nimport { Image } from \"@util/ui\";\n\ninterface ${dict.Model}ViewProps {\n className?: string;\n ${dict.model}: cnst.${dict.Model};\n self?: { id?: string } | null;\n}\n\nexport const General = ({ className, ${dict.model}, self }: ${dict.Model}ViewProps) => {\n return (\n <div className={clsx(className, \"animate-fadeIn w-full\")}>\n <div>{${dict.model}.id}</div>\n </div>\n );\n};\n```\n\uC774\uB7F0\uC2DD\uC73C\uB85C \uC6B0\uB9AC\uAC00 \uC9C1\uC811 \uB9CC\uB4E0 \uD504\uB808\uC784\uC6CC\uD06C\uC5D0 \uAE30\uBC18\uD574\uC11C db\uC640 \uC11C\uBE44\uC2A4 \uC2A4\uD1A0\uC5B4\uAE4C\uC9C0 \uBAA8\uB450 \uC5F0\uB3D9\uD574\uC11C \uD558\uB098\uC758 \uBAA8\uB378\uC5D0 \uB9DE\uAC8C\uB054 \uBAA8\uB4C8\uC744 \uD55C \uD3F4\uB354\uC5D0\uC11C \uC791\uC5C5\uD560 \uC218 \uC788\uAC8C\uB054 \uAD6C\uC870\uB97C \uB9CC\uB4E4\uC5C8\uC5B4.\n\n\uC77C\uB2E8 \uD504\uB808\uC784\uC6CC\uD06C\uC5D0 \uB300\uD55C \uC124\uBA85\uC740 \uC774 \uC815\uB3C4\uB85C \uD558\uACE0 \uC774 \uC815\uBCF4\uB4E4\uC744 \uAE30\uBC18\uC73C\uB85C \uB0B4\uAC00 \uC6D0\uD558\uB294 \uC694\uAD6C\uB97C \uB4E4\uC5B4\uC918.\n";
1
+ export declare const frameworkDescription = "\n\uB098\uB294 \uC880 \uB354 \uD6A8\uC728\uC801\uC73C\uB85C \uCF54\uB529\uC744 \uD558\uAE30 \uC704\uD574\uC11C \uC790\uCCB4 \uD504\uB808\uC784\uC6CC\uD06C\uB97C \uC81C\uC791\uD588\uC5B4.\n\uADF8\uB798\uC11C \uC6B0\uB9AC \uD504\uB808\uC784\uC6CC\uD06C\uC5D0 \uB300\uD55C \uC124\uBA85\uC744 \uD574\uC904\uD14C\uB2C8\uAE4C \uC798 \uC774\uD574\uD558\uB3C4\uB85D \uD574. \uC6B0\uB9AC \uD504\uB808\uC784\uC6CC\uD06C\uB294 next.js 13\uACFC nest.js, capacitor.js, nx, mongoDB \uAE30\uBC18\uC758 \uD504\uB860\uD2B8\uC5D4\uB4DC, \uC571, \uBC31\uC5D4\uB4DC \uD1B5\uD569 \uD504\uB808\uC784\uC6CC\uD06C\uC57C. \uADF8\uB798\uC11C \uBC31\uC5D4\uB4DC, \uD504\uB860\uD2B8\uC5D4\uB4DC, DB Schema\uC5D0 \uB300\uD55C \uCF54\uB4DC\uAC00 \uBAA8\uB450 \uD55C \uD3F4\uB354 \uC548\uC5D0 \uC788\uC5B4. \uADF8\uB798\uC11C \uC790\uBC14\uC2A4\uD06C\uB9BD\uD2B8, \uD0C0\uC785\uC2A4\uD06C\uB9BD\uD2B8, \uADF8\uB9AC\uACE0 \uD504\uB808\uC784\uC6CC\uD06C\uC5D0 \uB300\uD55C \uC774\uD574\uB9CC \uC788\uB2E4\uBA74 \uAD6C\uBD84\uC9D3\uC9C0 \uC54A\uACE0 \uC0AC\uC6A9\uD560 \uC218 \uC788\uB2E4\uB294 \uC7A5\uC810\uC774 \uC788\uC5B4. \n\n\uAC00\uC7A5 \uC678\uBD80\uC758 \uAD6C\uC870\uB294\n- app\n\t- project1\n\t- project2\n\t- project3\n\t- project4\n- lib\n\t- core\n\t- external\n\t- game\n\t- mint\n\t- platform\n\t- shared\n\t- social\n\t- util\napp\uC740 \uAC01 \uD504\uB85C\uC81D\uD2B8\uB97C \uB9CC\uB4DC\uB294 \uACF3\uC774\uC57C\nlib \uD558\uC704 \uD3F4\uB354\uB4E4\uC740 \uC5EC\uB7EC \uD504\uB85C\uC81D\uD2B8\uC5D0\uC11C \uACF5\uC6A9\uC73C\uB85C \uC0AC\uC6A9\uD560 \uC218 \uC788\uACA0\uB2E4 \uB77C\uACE0 \uD310\uB2E8\uD574\uC11C \uBD84\uB9AC\uD574\uB193\uC740 \uACF3\uC774\uC57C.\n\uB2E4\uC74C\uC740 app/project \uB0B4\uBD80\uC758 \uAD6C\uC870\uB97C \uC54C\uB824\uC904\uAC8C.\n\nproject\n- app\n\t- [lang]\n\t\t- (projectName)\n\t\t\t- (user)\n\t\t\t\t- page.tsx\n\t\t\t\t- layout.tsx\n\t\t\t- (public)\n\t\t\t\t- page.tsx\n\t\t\t\t- layout.tsx\n\t\t\t- (admin)\n\t\t\t\t- page.tsx\n\t\t\t\t- layout.tsx\n\n- lib \n\t- dataName1\n\t- dataName2\n\t- dataName3\n\t- dataName4\n\t- dataName5\n\t- dataName6\n\t- dataName7\n\napp\uC740 \uC9C1\uC811\uC801\uC73C\uB85C \uC720\uC800\uAC00 \uBCF4\uB294 \uD398\uC774\uC9C0\uB97C \uC9DC\uB294 \uACF3\uC774\uC57C. \uD3F4\uB354 \uAD6C\uC870\uB294 next 13\uC758 app directory\uB97C \uB530\uB974\uACE0 \uC788\uC5B4.\npublic/page.tsx\uAC00 \uAC00\uC7A5 \uCD5C\uCD08\uB85C \uC811\uADFC\uB418\uB294 Index \uD398\uC774\uC9C0\uAC00 \uB420 \uAC70\uC57C.\n\uC544\uB798\uB294 public/page.tsx\uC758 \uAE30\uBCF8 \uD15C\uD50C\uB9BF \uC18C\uC2A4\uCF54\uB4DC\uC57C.\n```\nimport {{ Image, Link }} from \"@util/ui\";\nimport {{ getSelf }} from \"@akanjs/client\";\n\nexport default function Page() {{\n const self = getSelf();\n return (\n <div className=\"relative w-full h-screen overflow-hidden flex items-center justify-center\">\n <Image\n className=\"absolute left-0 right-0 top-0 bottom-0 w-full h-screen -z-50\"\n width={{1920}}\n height={{1080}}\n src=\"/back.jpg\"\n />\n <div className=\"max-w-md bg-base-100/50 shadow-lg rounded-xl backdrop-blur-xs w-full py-8 px-16 flex flex-col items-center justify-center gap-3\">\n <h1 className=\"text-4xl mt-2\"><%= project %></h1>\n <h2 className=\"text-lg\"><%= project %> description</h2>\n <Link className=\"w-full\" href={{self ? \"/home\" : \"/signin\"}}>\n <button className=\"btn w-full btn-primary\">Go to dashboard</button>\n </Link>\n </div>\n </div>\n );\n}}\n```\n\nlib\uC740 \uC11C\uBE44\uC2A4\uB97C \uB9CC\uB4E4\uB2E4\uBCF4\uBA74 \uD544\uC694\uD55C \uB370\uC774\uD130\uB97C \uC815\uC758\uD558\uB294 \uACF3\uC774\uC57C.\n\uB530\uB77C\uC11C dataName\uC740 DB\uC774\uB984. \uC989 \uB370\uC774\uD130\uBA85\uC744 \uB530\uB77C. \uB2E4\uB9CC \uD3F4\uB354 \uB0B4\uBD80\uC5D0\uB294 backend, frontend\uC5D0\uC11C \uD1B5\uD569\uC73C\uB85C \uC4F0\uB294 \uC18C\uC2A4\uCF54\uB4DC\uB4E4\uC774 \uC788\uC5B4.\n\n\uC6B0\uB9AC \uD504\uB808\uC784\uC6CC\uD06C\uC758 \uD575\uC2EC\uC740 \uC815\uC758\uD55C \uBA54\uD0C0\uB370\uC774\uD130\uB4E4\uC744 \uC774\uC6A9\uD574\uC11C \uAC01 \uB370\uC774\uD130\uAC04\uC758 \uC5F0\uAD00\uC810\uC774\uB098, \uB370\uC774\uD130 \uD0C0\uC785\uC744 \uBCF4\uACE0 \uBBF8\uB9AC \uC815\uB9AC\uB41C \uACB0\uACFC\uB97C \uB9CC\uB4E4\uC5B4\uC8FC\uACE0 \uD504\uB85C\uC81D\uD2B8\uB97C \uB9CC\uB4E0\uB2E4\uBA74 \uAC70\uC758 \uBAA8\uB450 \uD544\uC694\uD55C \uC791\uC5C5\uB4E4\uC744 \uBBF8\uB9AC \uC815\uB9AC\uD574\uB1A8\uC5B4. \uC608\uB97C \uB4E4\uC5B4 \uB370\uC774\uD130 \uD0C0\uC785\uC5D0 \uC774\uBBF8\uC9C0 \uD30C\uC77C\uC774 \uC788\uB2E4\uACE0 \uD55C\uB2E4\uBA74 \uBC31\uC5D4\uB4DC\uB97C \uD1B5\uD574 \uADF8 \uC774\uBBF8\uC9C0\uB97C \uC11C\uBC84\uC758 \uC2A4\uD1A0\uB9AC\uC9C0\uC5D0 \uC800\uC7A5\uD558\uACE0 \uADF8 \uC800\uC7A5\uB41C \uD30C\uC77C\uC744 \uD2B9\uC815 db\uC5D0 id\uB97C \uCD94\uAC00\uD574\uC8FC\uB294 \uD568\uC218\uB4E4 \uAC19\uC740 \uAC83\uB4E4\uC740 \uC5B4\uB290 \uD504\uB85C\uC81D\uD2B8\uB358 \uAC04\uC5D0 \uBAA8\uB450 \uC0AC\uC6A9\uB418\uB294 \uBC29\uC2DD\uC774\uB77C\uACE0 \uD310\uB2E8\uD588\uC5B4. \uD558\uC9C0\uB9CC \uC6B0\uB9AC\uB294 \uD504\uB85C\uC81D\uD2B8\uB97C \uC791\uC5C5\uD560 \uB54C\uB9C8\uB2E4 \uC774 \uBD88\uD544\uC694\uD55C \uC791\uC5C5\uB4E4\uC744 \uD56D\uC0C1 \uB9CC\uB4E4\uACE0 \uD14C\uC2A4\uD2B8\uB97C \uD558\uB294 \uBD88\uD544\uC694\uD55C \uC77C\uB4E4\uC744 \uD558\uACE0\uC788\uC9C0. \uADF8\uB798\uC11C \uC6B0\uB9AC\uB294 \uAC01 \uD504\uB85C\uC81D\uD2B8\uAC00 \uB9CC\uB4E4 \uB54C\uB9C8\uB2E4 \uD544\uC218\uB85C \uC788\uC5B4\uC57C\uD560 \uC774\uBBF8\uC9C0 \uC5C5\uB85C\uB4DC \uD504\uB85C\uC138\uC2A4\uB97C \uD504\uB808\uC784\uC6CC\uD06C\uB97C \uD1B5\uD574 \uBBF8\uB9AC \uC815\uC758\uB41C \uC0C1\uD0DC\uB85C \uC0AC\uC6A9\uD560 \uC218 \uC788\uC5B4.\n\uACB0\uACFC\uC801\uC73C\uB85C \uC6B0\uB9B0 \uD544\uC694\uD558\uC9C0\uB9CC \uB9E4\uBC88 \uC791\uC5C5\uD558\uAE30\uC5D4 \uC190\uC774 \uB9CE\uC774\uAC00\uB294 \uC791\uC5C5\uB4E4\uC744 \uBBF8\uB9AC \uC815\uC758\uD574\uB1A8\uC5B4.\n\n\uB610\uD55C \uC6B0\uB9B0 CLI\uB97C \uD1B5\uD574\uC11C \uD2B9\uC815 \uD504\uB85C\uC81D\uD2B8 \uD3F4\uB354 \uD15C\uD50C\uB9BF\uC744 \uB9CC\uB4E4\uC5B4\uC8FC\uAC70\uB098, \uD2B9\uC815 \uBAA8\uB378\uC758 \uD544\uB4DC\uB4E4\uC744 \uB9CC\uB4E4 \uC218 \uC788\uB3C4\uB85D \uD574\uB1A8\uC5B4. Model\uC774\uB77C\uB294 \uBCC0\uC218\uC758 \uACB0\uACFC\uAC12\uC744 \uBC1B\uACE0 \uC800 \uD15C\uD50C\uB9BF\uC5D0 \uB9DE\uAC8C\uB054 \uC774\uB984\uC744 \uB123\uC5B4\uC8FC\uB294 \uAC70\uC9C0. \uB9CC\uC57D \uB0B4\uAC00 phone\uC774\uB77C\uB294 \uBCC0\uC218\uB97C \uB123\uC5C8\uB2E4\uBA74 \uC800 \uBAA8\uB378\uC5D0 Phone\uACFC \uAC19\uC740 \uACB0\uACFC\uAC12\uC73C\uB85C \uAC12\uC774 \uB4E4\uC5B4\uAC00\uAC8C \uB428\uC73C\uB85C\uC11C \uD15C\uD50C\uB9BF\uC774 \uC0DD\uC131\uB3FC. \uC774\uB294 \uC6B0\uB9AC\uAC00 \uC774\uBBF8 \uB9CC\uB4E4\uC5B4\uB193\uC740 \uCEE4\uB9E8\uB4DC\uAC00 \uC788\uC5B4.\n\n\uC608\uB97C \uB4E4\uC5B4 \uC5F0\uD544\uC774\uB77C\uB294 \uBAA8\uB378\uC744 \uCEE4\uB9E8\uB4DC\uB97C \uD1B5\uD574 \uC0DD\uC131\uD558\uBA74 \uC544\uB798\uC640 \uAC19\uC740 \uD30C\uC77C\uB4E4\uC774 \uC0DD\uC131\uB3FC.\n\npencil\n- pencil.constant.ts ( pencil\uC5D0 \uB300\uD55C db schema, query, sort \uAD6C\uBB38\uC744 \uC815\uC758 )\n- pencil.document.ts ( model\uC5D0\uC11C \uC790\uC8FC \uC0AC\uC6A9\uD558\uB294 method, static function, middleware\uB85C \uAC04\uB2E8\uD55C db \uAD00\uB9AC \uD568\uC218\uB4F1\uC744 \uAD00\uB9AC\uD568.)\n- pencil.dictionary.ts (\uB2E4\uAD6D\uC5B4\uB97C \uC704\uD574\uC11C schema field, enum, service name\uC758 \uB2E4\uAD6D\uC5B4 \uC815\uBCF4 \uB4F1\uC744 \uBAA8\uB450 \uAD00\uB9AC. )\n- pencil.signal.ts (frontend\uC758 fetch\uB97C \uC5F4\uC5B4\uC8FC\uB294 \uC77C\uC885\uC758 \uCC3D\uAD6C, \uAD8C\uD55C\uAD00\uB9AC\uB4F1\uC744 \uD568 nestjs\uC758 resolver\uC640 \uC720\uC0AC )\n- pencil.service.ts (\uC2E4\uC9C8\uC801\uC778 \uC11C\uBE44\uC2A4 \uCF54\uB4DC\uB97C \uC791\uC131\uD558\uB294 \uACF3. \uAC01\uC885 \uBE44\uC988\uB2C8\uC2A4 \uB85C\uC9C1\uC744 \uCC98\uB9AC\uD568.)\n- pencil.store.ts (pencil field\uC5D0 \uB300\uD55C \uC0C1\uD0DC\uAD00\uB9AC \uC800\uC7A5\uC18C.)\n- pencil.Zone.tsx (\uC544\uB798 Templete, Unit, Util, View, Util\uB4F1\uC744 \uC870\uD569\uD574\uC11C \uB2E4\uC74C \uB808\uBCA8 \uCEF4\uD3EC\uB10C\uD2B8\uB97C \uC791\uC131\uD558\uB294 \uACF3 client component\uB85C \uC815\uC758\uB428. )\n- pencil.Templete.tsx (\uC8FC\uB85C edit\uC5D0 \uC5F0\uAD00\uB41C \uCEF4\uD3EC\uB10C\uD2B8 \uC815\uC758\uD558\uB294 \uACF3. client component\uB85C \uC815\uC758\uB428. )\n- pencil.Unit.tsx (list \uCC98\uB7FC \uBCF5\uC218\uAC1C\uC758 \uCEF4\uD3EC\uB10C\uD2B8\uB97C \uC815\uC758\uD558\uB294 \uACF3. server component\uB85C \uC815\uC758\uB428. )\n- pencil.Util.tsx (Action \uBC84\uD2BC\uC744 \uC815\uC758\uD558\uB294 \uACF3. client component\uB85C \uC815\uC758\uB428. )\n- pencil.View.tsx (\uB2E8\uC77C view \uCEF4\uD3EC\uB10C\uD2B8\uB97C \uC815\uC758\uD558\uB294 \uACF3. server component\uB85C \uC815\uC758\uB428. )\n\n\n\uC5EC\uAE30\uC11C constant\uC5D0 \uC815\uC758 \uB418\uC5B4\uC788\uB294 schema\uB97C \uAE30\uBCF8\uC73C\uB85C \uD574\uC11C \uAC01 document, dictionary, signal, service, store\uB97C \uC0DD\uC131\uD574.\n\ndocument, signal, service\uB294 \uBC31\uC5D4\uB4DC\uC640 \uC5F0\uAD00\uB418\uC5B4\uC788\uB294 \uC18C\uC2A4\uCF54\uB4DC\uC57C.\n\uC11C\uB85C\uAC04\uC758 \uAD00\uACC4\uB294 \uC8FC\uB85C signal\uC5D0\uC11C \uAC00\uC7A5 \uBA3C\uC800 \uC694\uCCAD\uC744 \uBC1B\uACE0 \uC774\uD6C4 \uB85C\uC9C1\uC758 \uBCF5\uC7A1\uB3C4\uC5D0 \uB530\uB77C\uC11C service\uB85C \uCC98\uB9AC\uD560 \uC9C0, docuemnt\uB85C \uCC98\uB9AC\uD560 \uC9C0\uB97C \uACB0\uC815\uD574.\nsignal - document\nsignal - service - document\n\nstore\uB294 \uD504\uB860\uD2B8\uC5D4\uB4DC\uC5D0\uC11C \uC0C1\uD0DC\uAD00\uB9AC\uB97C \uD560 \uB54C \uC0AC\uC6A9\uB3FC.\n\uC6B0\uB9AC\uB294 signal\uC758 \uCF54\uB4DC\uB85C \uB098\uC628 \uBA54\uD0C0\uB370\uC774\uD130\uB97C \uC774\uC6A9\uD574\uC11C store\uC5D0\uC11C \uD754\uD788 \uC0AC\uC6A9\uB420\uB9CC\uD55C \uD568\uC218\uB4E4\uC744 \uBBF8\uB9AC \uC815\uC758\uD558\uAC8C\uB054 \uB9CC\uB4E4\uC5C8\uC5B4.\n\n\uC774\uB807\uAC8C 11\uAC1C\uC758 \uD30C\uC77C\uB85C \uAD6C\uBD84\uD574\uC11C \uC815\uC758\uAC00 \uB3FC. \n\uC9C0\uAE08\uBD80\uD134 \uD55C \uD30C\uC77C\uB4E4\uB9C8\uB2E4 \uC0C1\uC138\uD55C \uC124\uBA85\uC744 \uD574\uC904\uAC8C.\n\nmodel.constant.ts\n\nconstant\uB294 \uAE30\uBCF8 \uC2A4\uD0A4\uB9C8\uAC00 \uAD6C\uC131\uB418\uB294 \uACF3\uC774\uC57C. \uADF8\uB798\uC11C \uC774 \uACF3\uC5D0\uC11C DB \uC2A4\uD0A4\uB9C8, \uCFFC\uB9AC, \uC815\uB82C \uAD6C\uBB38\uC744 \uC815\uC758\uD574.\n\uC8FC\uC758\uD574\uC57C\uD560 \uAC74 decorator\uC5D0\uC11C \uC815\uC758\uD558\uB294 \uD0C0\uC785\uACFC \uC544\uB798\uC5D0 \uC815\uC758\uD558\uB294 \uD0C0\uC785\uC774 \uC57D\uAC04 \uB2E4\uB97C \uC218 \uC788\uC5B4\n\uC608\uB97C \uB4E4\uC5B4 decorator\uC5D0\uC11C\uB294 Int\uB85C \uC815\uC758\uD558\uACE0 constant\uC5D0\uC11C\uB294 number\uB85C \uC815\uC758\uD574\uC57C\uD574.\n\uCD94\uAC00\uB85C createdAt\uACFC updatedAt, status\uB294 \uAE30\uBCF8\uC801\uC73C\uB85C \uC0DD\uC131\uB418\uB294 \uD544\uB4DC\uC774\uB2C8\uAE4C \uB530\uB85C \uC815\uC758\uD558\uC9C0 \uC54A\uC544\uB3C4 \uB3FC.\n\uC774\uB294 decorator\uC5D0\uC11C\uB294 GraphQL\uC5D0\uC11C \uC0AC\uC6A9\uD560 \uD0C0\uC785\uC744 \uC815\uC758\uD558\uACE0 constant\uC5D0\uC11C\uB294 \uC2E4\uC81C \uD0C0\uC785\uC744 \uC815\uC758\uD558\uB294 \uAC70\uC9C0.\n\n```\nimport { enumOf, Int } from \"@akanjs/base\";\nimport { Field, Filter, Model, sortOf, via } from \"@akanjs/constant\";\n\nexport const ${dict.Model}Statuses = [\"active\"] as const;\nexport type ${dict.Model}Status = (typeof ${dict.Model}Statuses)[number];\n\n//\uB370\uC774\uD130\uB97C \uB9CC\uB4E4 \uB54C \uD544\uC694\uD55C \uB370\uC774\uD130 \uD0C0\uC785\uC744 \uC815\uC758\uD558\uB294 \uACF3\n@Model.Input(\"${dict.Model}Input\")\nexport class ${dict.Model}Input {{\n @Field.Prop(() => String)\n field: string;\n\n @Field.Prop(() => Int, {{ nullable: true }})\n fieldInt: number | null;\n\n @Field.Prop(() => Date, {{default: dayjs()}})\n fieldInt: Dayjs;\n}}\n\n//\uB370\uC774\uD130\uAC00 \uB9CC\uB4E4\uC5B4\uC9C4 \uC774\uD6C4 \uC0DD\uC131\uB418\uAC70\uB098 \uC800\uC7A5\uC73C\uB85C \uCD94\uAC00\uD560 \uC218 \uC788\uB294 \uACF3\n@Model.Object(\"${dict.Model}Object\")\nexport class ${dict.Model}Object extends via(${dict.Model}Input) {\n @Field.Prop(() => String, {{ enum: ${dict.Model}Statuses, default: \"active\" }})\n status: ${dict.Model}Status;\n}}\n\n//\uB370\uC774\uD130\uB97C \uB9AC\uC2A4\uD2B8\uB85C \uBCF4\uC5EC\uC904 \uB54C \uD544\uC694\uD55C \uB370\uC774\uD130\uB9CC \uC81C\uACF5\uD558\uB294 \uACF3\n@Model.Light(\"Light${dict.Model}\")\nexport class Light${dict.Model} extends via(${dict.Model}Object, [\n \"field\",\n \"status\",\n] as const) {}\n\n//\uCD5C\uC885 \uB370\uC774\uD130\uC758 Full \uD0C0\uC785\uC774 \uC815\uC758\uB418\uB294 \uACF3\n@Model.Full(\"${dict.Model}\")\nexport class ${dict.Model} extends via(${dict.Model}Object, Light${dict.Model}) {}\n\n//\uB370\uC774\uD130\uC758 \uC778\uC0AC\uC774\uD2B8\uB97C \uCE21\uC815\uD558\uAE30 \uC704\uD574\uC11C \uD544\uC694\uD55C \uB370\uC774\uD130\uB97C \uC815\uC758\uD558\uB294 \uACF3\n@Model.Insight(\"${dict.Model}Insight\")\nexport class ${dict.Model}Insight {{\n @Field.Prop(() => Int, {{ default: 0, accumulate: {{ $sum: 1 }} }})\n count: number;\n}}\n\n//\uB370\uC774\uD130\uC758 \uD1B5\uACC4\uB97C \uACC4\uC0B0\uD558\uB294 \uACF3\n@Model.Summary(\"${dict.Model}Summary\")\nexport class ${dict.Model}Summary {{\n @Field.Prop(() => Int, {{ min: 0, default: 0, query: {{ status: {{}} }} }})\n total${dict.Model}: number;\n}}\n\n@Model.Filter(\"${dict.Model}Filter\")\nexport class ${dict.Model}Filter extends sortOf(${dict.Model}, {}) {}\n```\n\n\nmodel.dictonary.ts\n```\nimport {\n baseTrans,\n getBaseSignalTrans,\n ModelDictionary,\n SignalDictionary,\n SummaryDictionary,\n} from \"@akanjs/dictionary\";\n\nimport type { ${dict.Model}, ${dict.Model}Filter, ${dict.Model}Insight, ${dict.Model}Summary } from \"./${dict.model}.constant\";\nimport type { ${dict.Model}Signal } from \"./${dict.model}.signal\";\n\nconst modelDictionary = {{\n ...baseTrans,\n modelName: [\"${dict.Model}\", \"${dict.Model}\"],\n modelDesc: [\n \"${dict.Model} description\",\n \"${dict.Model} \uC124\uBA85\",\n ],\n\n // * ==================== Model ==================== * //\n field: [\"Field\", \"\uD544\uB4DC\"],\n \"desc-field\": [\"Field\", \"\uD544\uB4DC\"],\n // * ==================== Model ==================== * //\n\n // * ==================== Insight ==================== * //\n count: [\"Count\", \"\uAC1C\uC218\"],\n \"desc-count\": [\"${dict.Model} count in current query settting\", \"\uD604\uC7AC \uCFFC\uB9AC \uC124\uC815\uC5D0 \uB9DE\uB294 ${dict.Model} \uC218\"],\n // * ==================== Insight ==================== * //\n\n // * ==================== Filter ==================== * //\n // * ==================== Filter ==================== * //\n\n // * ==================== Etc ==================== * //\n \"enum-status-active\": [\"Active\", \"\uD65C\uC131\"],\n \"enumdesc-status-active\": [\"Active status\", \"\uD65C\uC131 \uC0C1\uD0DC\"],\n // * ==================== Etc ==================== * //\n}} satisfies ModelDictionary<${dict.Model}, ${dict.Model}Insight, typeof ${dict.Model}Sort>;\n\nexport const ${dict.Model}SummaryDictionary = {{\n // * ==================== Summary ==================== * //\n total${dict.Model}: [\"Total ${dict.Model}\", \"\uCD1D ${dict.Model} \uC218\"],\n \"desc-total${dict.Model}\": [\"Total ${dict.Model} count in the database\", \"\uB370\uC774\uD130\uBCA0\uC774\uC2A4\uC5D0 \uC800\uC7A5\uB41C \uCD1D ${dict.Model} \uC218\"],\n // * ==================== Summary ==================== * //\n}} satisfies SummaryDictionary<${dict.Model}Summary>;\n\nconst signalDictionary = {{\n ...getBaseSignalTrans(\"${dict.Model}\" as const),\n // * ==================== Endpoint ==================== * //\n \"api-${dict.Model}ListInPublic\": [\"${dict.Model} List In Public\", \"\uACF5\uAC1C\uB41C ${dict.Model} \uB9AC\uC2A4\uD2B8\"],\n \"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\"],\n \"arg-${dict.Model}ListInPublic-statuses\": [\"Statuses\", \"\uC0C1\uD0DC\"],\n \"argdesc-${dict.Model}ListInPublic-statuses\": [\"Statuses to filter\", \"\uD544\uD130\uB9C1\uD560 \uC0C1\uD0DC\"],\n \"arg-${dict.Model}ListInPublic-skip\": [\"Skip\", \"\uAC74\uB108\uB6F0\uAE30\"],\n \"argdesc-${dict.Model}ListInPublic-skip\": [\"Number of items to skip\", \"\uAC74\uB108\uB6F8 \uC544\uC774\uD15C \uC218\"],\n \"arg-${dict.Model}ListInPublic-limit\": [\"Limit\", \"\uC81C\uD55C\"],\n \"argdesc-${dict.Model}ListInPublic-limit\": [\"Maximum number of items to return\", \"\uBC18\uD658\uD560 \uCD5C\uB300 \uC544\uC774\uD15C \uC218\"],\n \"arg-${dict.Model}ListInPublic-sort\": [\"Sort\", \"\uC815\uB82C\"],\n \"argdesc-${dict.Model}ListInPublic-sort\": [\"Sort order of the items\", \"\uC544\uC774\uD15C\uC758 \uC815\uB82C \uC21C\uC11C\"],\n\n \"api-${dict.Model}InsightInPublic\": [\"${dict.Model} Insight In Public\", \"\uACF5\uAC1C\uB41C ${dict.Model} \uC778\uC0AC\uC774\uD2B8\"],\n \"apidesc-${dict.Model}InsightInPublic\": [\n \"Get insight data for public ${dict.Model}\",\n \"\uACF5\uAC1C\uB41C ${dict.Model}\uC5D0 \uB300\uD55C \uC778\uC0AC\uC774\uD2B8 \uB370\uC774\uD130\uB97C \uAC00\uC838\uC635\uB2C8\uB2E4\",\n ],\n \"arg-${dict.Model}InsightInPublic-statuses\": [\"Statuses\", \"\uC0C1\uD0DC\"],\n \"argdesc-${dict.Model}InsightInPublic-statuses\": [\"Statuses to filter\", \"\uD544\uD130\uB9C1\uD560 \uC0C1\uD0DC\"],\n // * ==================== Endpoint ==================== * //\n}} satisfies SignalDictionary<${dict.Model}Signal, ${dict.Model}>;\n```\nexport const ${dict.model}Dictionary = {{ ...modelDictionary, ...signalDictionary }};\n\n\n\nmodel.document.ts\n```\nimport { beyond, by, Database, into, type SchemaOf } from \"@akanjs/document\";\n\nimport { cnst } from \"../cnst\";\n@Database.Input(() => cnst.${dict.Model}Input)\nexport class ${dict.Model}Input extends by(cnst.${dict.Model}Input) {}\n\n@Database.Document(() => cnst.${dict.Model})\nexport class ${dict.Model} extends by(cnst.${dict.Model}) {}\n\n@Database.Model(() => cnst.${dict.Model})\nexport class ${dict.Model}Model extends into(${dict.Model}, cnst.${dict.Model}Cnst) {\n async getSummary(): Promise<cnst.${dict.Model}Summary> {\n return {\n ...(await this.getDefaultSummary()),\n };\n }\n}\n\n@Database.Middleware(() => cnst.${dict.Model})\nexport class ${dict.Model}Middleware extends beyond(${dict.Model}Model, ${dict.Model}) {\n onSchema(schema: SchemaOf<${dict.Model}Model, ${dict.Model}>) {\n // schema.index({ status: 1 })\n }\n}\n```\n\n\nmodel.signal.ts\n```\nimport { Int } from \"@akanjs/base\";\nimport { SortOf } from \"@akanjs/constant\";\nimport { Arg, DbSignal, Mutation, Query, resolve, Signal } from \"@akanjs/signal\";\n\nimport { cnst, Srvs } from \"../cnst\";\n\n@Signal(() => cnst.${dict.Model})\nexport class ${dict.Model}Signal extends DbSignal(cnst.${dict.model}Cnst, Srvs, {\n guards: { get: Query.Public, cru: Mutation.Public },\n}) {\n // * /////////////////////////////////////\n // * Public Slice\n @Query.Public(() => [cnst.${dict.Model}])\n async ${dict.model}ListInPublic(\n @Arg.Query(\"statuses\", () => [String], { nullable: true }) statuses: cnst.${dict.Model}Status[] | null,\n @Arg.Query(\"skip\", () => Int, { nullable: true }) skip: number | null,\n @Arg.Query(\"limit\", () => Int, { nullable: true }) limit: number | null,\n @Arg.Query(\"sort\", () => String, { nullable: true }) sort: SortOf<cnst.${dict.Model}Filter> | null\n ) {\n const ${dict.models} = await this.${dict.model}Service.listByStatuses(statuses, { skip, limit, sort });\n return resolve<cnst.${dict.Model}[]>(${dict.models});\n }\n @Query.Public(() => cnst.${dict.Model}Insight)\n async ${dict.model}InsightInPublic(\n @Arg.Query(\"statuses\", () => [String], { nullable: true }) statuses: cnst.${dict.Model}Status[] | null\n ) {\n const ${dict.model}Insight = await this.${dict.model}Service.insightByStatuses(statuses);\n return resolve<cnst.${dict.Model}Insight>(${dict.model}Insight);\n }\n // * Public Slice\n // * /////////////////////////////////////\n}\n```\n\n\nmodel.service.ts\n```\nimport { DbService, Service } from \"@akanjs/service\";\n\nimport { cnst } from \"../cnst\";\nimport * as db from \"../db\";\n\n@Service(\"${dict.Model}Service\")\nexport class ${dict.Model}Service extends DbService(db.${dict.Model}Db) {\n async summarize(): Promise<cnst.${dict.Model}Summary> {\n return {\n ...(await this.${dict.Model}Model.getSummary()),\n };\n }\n}\n```\n\n\nmodel.store.ts\n```\nimport { stateOf, Store } from \"@akanjs/store\";\n\nimport { cnst } from \"../cnst\";\nimport { fetch } from \"../fetch\";\n\n@Store(() => cnst.${dict.Model})\nexport class ${dict.Model}Store extends stateOf(fetch.${dict.model}Gql, {\n // state\n}) {\n // action\n}\n```\n\n\nmodel.Zone.tsx\n```\n\"use client\";\nimport { Data, Load } from \"@shared/ui\";\nimport { ModelsProps } from \"@akanjs/client\";\nimport { cnst, ${dict.Model} } from \"@${dict.appName}/client\";\nimport { ClientInit, ClientView, DefaultOf } from \"@akanjs/signal\";\n\nexport const Admin = ({ sliceName = \"${dict.model}\", init, query }: ModelsProps<cnst.${dict.Model}>>) => {\n return (\n <Data.ListContainer\n init={init}\n query={query}\n sliceName={sliceName}\n renderItem={${dict.Model}.Unit.Card}\n renderDashboard={${dict.Model}.Util.Stat}\n renderInsight={${dict.Model}.Util.Insight}\n renderTemplate={${dict.Model}.Template.General}\n renderTitle={(${dict.model}: DefaultOf<cnst.${dict.Model}>>) => `${dict.Model} - ${${dict.model}.id ? ${dict.model}.id : \"New\"}`}\n renderView={(${dict.model}: cnst.${dict.Model}>) => <${dict.Model}.View.General ${dict.model}={${dict.model}} />}\n columns={[\n \"id\",\n \"status\",\n \"createdAt\",\n \"updatedAt\",\n ]}\n actions={(${dict.model}: cnst.Light${dict.Model}, idx) => [\"remove\", \"edit\", \"view\"]}\n />\n );\n};\n\ninterface CardProps {\n className?: string;\n init: ClientInit<\"${dict.model}\", cnst.Light${dict.Model}>;\n}\nexport const Card = ({ className, init }: CardProps) => {\n return (\n <Load.Units\n className={className}\n init={init}\n renderItem={(${dict.model}: cnst.Light${dict.Model}) => (\n <${dict.Model}.Unit.Card key={${dict.model}.id} href={`/${dict.model}/${${dict.model}.id}`} ${dict.model}={${dict.model}} />\n )}\n />\n );\n};\n\ninterface ViewProps {\n className?: string;\n view: ClientView<\"${dict.model}\", cnst.${dict.Model}>;\n}\nexport const View = ({ view }: ViewProps) => {\n return <Load.View view={view} renderView={(${dict.model}) => <${dict.Model}.View.General ${dict.model}={${dict.model}} />} />;\n};\n```\n\nmodel.Templete.tsx\n```\n\"use client\";\nimport { cnst, st, usePage } from \"@${dict.appName}/client\";\nimport { Field } from \"@shared/ui\";\nimport { Layout } from \"@util/ui\";\n\ninterface ${dict.Model}EditProps {\n ${dict.model}Id?: string | null;\n}\n\nexport const General = ({ ${dict.model}Id = undefined }: ${dict.Model}EditProps) => {\n const ${dict.model}Form = st.use.${dict.model}Form();\n const { l } = usePage();\n return (\n <Layout.Template>\n <Field.Text\n label={l.field(\"${dict.model}\", \"id\")}\n desc={l.desc(\"${dict.model}\", \"id\")}\n value={${dict.model}Form.id}\n onChange={st.do.setIdOn${dict.Model}}\n />\n </Layout.Template>\n );\n};\n```\n\n\nmodel.Unit.tsx\n```\nimport { ModelProps } from \"@akanjs/client\";\nimport { cnst, ${dict.Model} } from \"@${dict.appName}/client\";\nimport { Link } from \"@util/ui\";\n\nexport const Card = ({ ${dict.model}, href }: ModelProps<\"${dict.model}\", cnst.Light${dict.Model}>>) => {\n return (\n <Link href={href} className=\"animate-fadeIn w-full h-36 flex rounded-lg shadow-sm hover:shadow-lg duration-300\">\n <div>{${dict.model}.id}</div>\n </Link>\n );\n};\n```\n\n\nmodel.Util.tsx\n```\n\"use client\";\nimport { ModelDashboardProps, ModelInsightProps } from \"@akanjs/client\";\nimport { getQueryMap } from \"@akanjs/constant\";\nimport { cnst } from \"@${dict.appName}/client\";\nimport { Data } from \"@shared/ui\";\n\nexport const Stat = ({\n className,\n summary,\n sliceName = \"${dict.model}\",\n queryMap = getQueryMap(cnst.${dict.Model}Summary),\n hidePresents,\n}: ModelDashboardProps<cnst.Summary>) => {\n return (\n <Data.Dashboard\n className={className}\n summary={summary}\n sliceName={sliceName}\n queryMap={queryMap}\n columns={[\"total${dict.Model}\"]}\n hidePresents={hidePresents}\n />\n );\n};\n\nexport const Insight = ({\n className,\n insight,\n sliceName = \"${dict.model}\",\n}: ModelInsightProps<cnst.${dict.Model}Insight>) => {\n return (\n <Data.Insight\n className={className}\n insight={insight}\n sliceName={sliceName}\n columns={[\"count\"]}\n />\n );\n};\n```\n\n\nmodel.View.tsx\n```\nimport { clsx } from \"@akanjs/client\";\nimport { cnst } from \"@${dict.appName}/client\";\nimport { Image } from \"@util/ui\";\n\ninterface ${dict.Model}ViewProps {\n className?: string;\n ${dict.model}: cnst.${dict.Model};\n self?: { id?: string } | null;\n}\n\nexport const General = ({ className, ${dict.model}, self }: ${dict.Model}ViewProps) => {\n return (\n <div className={clsx(className, \"animate-fadeIn w-full\")}>\n <div>{${dict.model}.id}</div>\n </div>\n );\n};\n```\n\uC774\uB7F0\uC2DD\uC73C\uB85C \uC6B0\uB9AC\uAC00 \uC9C1\uC811 \uB9CC\uB4E0 \uD504\uB808\uC784\uC6CC\uD06C\uC5D0 \uAE30\uBC18\uD574\uC11C db\uC640 \uC11C\uBE44\uC2A4 \uC2A4\uD1A0\uC5B4\uAE4C\uC9C0 \uBAA8\uB450 \uC5F0\uB3D9\uD574\uC11C \uD558\uB098\uC758 \uBAA8\uB378\uC5D0 \uB9DE\uAC8C\uB054 \uBAA8\uB4C8\uC744 \uD55C \uD3F4\uB354\uC5D0\uC11C \uC791\uC5C5\uD560 \uC218 \uC788\uAC8C\uB054 \uAD6C\uC870\uB97C \uB9CC\uB4E4\uC5C8\uC5B4.\n\n\uC77C\uB2E8 \uD504\uB808\uC784\uC6CC\uD06C\uC5D0 \uB300\uD55C \uC124\uBA85\uC740 \uC774 \uC815\uB3C4\uB85C \uD558\uACE0 \uC774 \uC815\uBCF4\uB4E4\uC744 \uAE30\uBC18\uC73C\uB85C \uB0B4\uAC00 \uC6D0\uD558\uB294 \uC694\uAD6C\uB97C \uB4E4\uC5B4\uC918.\n";
2
+ export declare const moduleDesription = "\n\nThe project follows a modular architecture with clear separation of concerns. Each module in lib/<model>/ represents a domain\nentity with a standardized file structure that promotes consistency and maintainability.\n\n## Core Components\n\n### <Model>.View.tsx\nPresentation-only components that render data without managing state. \nIt works as a server component, They accept model data as props and display it according to specific layouts.\nThese components focus purely on how data looks to the user. \nonly use the full model.\nThis component is only viewing the component. So don't use click event or other interaction events.\nIf you need interaction, possible to wrapping the component with the <Model>.Zone.tsx component.\nBut useable the Link component for navigation.\nComponents created in Model.View.tsx should primarily be made to show the entire detailed data of the model rather than showing only partial data of the model.\n\n\n### <Model>.Template.tsx\nReusable layout patterns with integrated state management. It works as a client component, These components provide consistent UI patterns and handle data\nbinding, often using store hooks to access application state.\n\n### <Model>.Unit.tsx\nSmall, self-contained UI components representing individual model instances. It works as a server component, They're designed for rendering single items in\nlists or grids, displaying model data in compact formats. only use the light model.\n\n### <Model>.Zone.tsx\nTop-level container components that orchestrate other components. It works as a client component, They compose views, templates, and units into complete UI\nsections while managing data flow to child components.\n\n### <Model>.Util.tsx\nSpecialized components and utility functions specific to a model, It works as a client component, providing both UI components and helper functions for\nmodel-specific functionality.\n\n## Data Management\n\n### <model>.signal.ts\nDefines API endpoints with type safety using decorators for GraphQL queries and mutations, creating a type-safe bridge between\nfrontend and backend.\n\n### <model>.store.ts\nManages client-side state with typed actions and state, handling UI state, form state, and cached data.\n\n### <model>.service.ts\nImplements server-side business logic with dependency injection, handling data processing and complex operations.\n\n### <model>.constant.ts\nDefines type definitions and model schemas using decorators to structure model fields, validation, and relationships.\n\n### <model>.dictionary.ts\nProvides internationalization and label definitions for model properties and operations.\n\n### <model>.document.ts\nDefines database schema and model operations with decorators for database interaction.\n\n## Data Flow\nThe architecture follows a clear data flow pattern:\n- Server-side: Document \u2192 Service \u2192 Signal \u2192 API\n- Client-side: API \u2192 Store \u2192 Components (Zone \u2192 Template/View/Unit)\n\nThis modular structure enables rapid development while maintaining consistency, type safety, and testability throughout the\napplication.\n";
2
3
  export declare const requestModule: (projectName: string, projectDesc: string) => string;
4
+ export declare const utilUiDescription = "\n This UI kit is an internally developed UI kit within the Akan.js framework. \n The libs/util/ui directory contains a comprehensive React component library designed for modern web applications. \n This framework provides a complete set of production-ready, reusable UI components with consistent styling, type safety, and advanced functionality.\n\n - Every component must be used exactly as described in the documentation.\n - Do not add any additional props to the components.\n - Must use the written props exactly.\n - Only the components explicitly listed in the documentation are available\u2014no additional components exist beyond those specified.\n\n\n\n Architecture & Foundation\n\n Core Technologies:\n - Built on React 18+ with TypeScript for strict type safety\n - Styled with Tailwind CSS and DaisyUI for consistent design system\n - Implements modern React patterns including hooks, context providers, and portals\n - Full internationalization (i18n) support for multilingual applications\n - Responsive-first design with mobile optimization\n\n Design Principles:\n - Composable component architecture with predictable APIs\n - Accessibility (a11y) compliance throughout\n - Performance optimization with lazy loading and code splitting\n - Consistent error handling and validation patterns\n - Session storage integration for form state persistence\n\n Component Categories\n\n Core Input Components\n\n Essential form controls with advanced validation and user experience features:\n - Button - Async-aware button with automatic loading/success/error states\n - Input - Comprehensive input system with real-time validation, multiple variants (Text, Password, Email, Number, Checkbox), and\n session caching\n - Select - Advanced dropdown with search, multi-select, and custom rendering\n - DatePicker - Date/time selection with range support and custom formatting\n - CodeInput - PIN/verification code input with auto-focus management\n - Upload - File upload system with drag-drop, progress tracking, image cropping, and multiple file support\n\n Data Display Components\n\n Components for presenting and organizing information:\n - Chart - Visualization suite (Bar, Line, Pie, Doughnut) built on Chart.js\n - Avatar - User profile images with intelligent fallbacks\n - ChatBubble - Chat interface with message grouping and timestamps\n - Empty - Customizable empty state displays\n - QRCode - QR code generation with click-to-open functionality\n\n Layout & Navigation System\n\n Comprehensive layout framework for application structure:\n - Layout - Complete layout system with Header (auto-hide), Sider (collapsible), Navbar (portal-based), BottomTab (with badges),\n and container components\n - Modal/Dialog - Composable dialog system with backdrop, animations, and gesture support\n - BottomSheet - Mobile-optimized bottom sheet with drag gestures\n - Menu - Navigation menus with horizontal/vertical modes and submenu support\n - Tab - Tabbed interfaces with lazy loading and scroll management\n - ScreenNavigator - Gesture-based screen navigation with spring animations\n\n Interactive Components\n\n Advanced user interaction components:\n - Pagination - Smart page navigation with ellipsis and responsive design\n - InfiniteScroll - Automatic content loading with intersection observer\n - DndKit - Drag and drop functionality with provider pattern\n - Radio - Radio button groups with custom styling\n - ToggleSelect - Button-based selection with single/multi-select modes\n - Share - Native share API with copy fallback\n\n Utility & Feedback Components\n\n Supporting components for enhanced user experience:\n - Loading - Comprehensive loading states (Area, Button, Input, Skeleton, Spin, ProgressBar) with animations\n - Link - Adaptive navigation links with SSR/CSR compatibility\n - MapView - Map integration supporting both Google Maps and Pigeon Maps with markers and overlays\n - Image - Optimized image component with blur placeholders and SSR support\n - Portal - Teleportation component for rendering outside component tree\n\n Advanced Features\n\n State Management Integration\n\n - Context-driven architecture for complex components\n - Signal-based real-time communication components\n - Session storage integration for form persistence\n - Theme-aware styling with automatic adaptation\n\n Performance Optimizations\n\n - Lazy loading support for heavy components\n - Code splitting at component level\n - Optimized re-rendering with React.memo patterns\n - Intersection Observer for scroll-based interactions\n\n Developer Experience\n\n - Comprehensive TypeScript interfaces for all props\n - Consistent naming conventions and API patterns\n - Built-in error boundaries and fallback handling\n - Extensive JSDoc documentation\n - Hot reload support for development\n\n Accessibility & Internationalization\n\n - ARIA attributes and keyboard navigation support\n - Screen reader compatibility\n - RTL (right-to-left) language support\n - Localized date/time formatting\n - Color contrast compliance\n\n Usage Patterns\n\n The library follows a consistent component composition pattern where complex components are built from smaller, focused\n subcomponents. For example:\n\n - Chart.Bar, Chart.Line for different visualization types\n - Dialog.Modal, Dialog.Title, Dialog.Content for composable modals\n - Layout.Header, Layout.Sider, Layout.Navbar for layout construction\n - Upload.File, Upload.Image, Upload.Images for different upload scenarios\n\n This design enables maximum flexibility while maintaining consistency across the application. Components are designed to work\n seamlessly together, sharing common styling patterns, validation systems, and state management approaches.\n\n The library serves as a comprehensive foundation for building modern, accessible, and performant web applications with a focus\n on developer productivity and end-user experience.\n\n Avatar\n - Displays user profile images with automatic fallback to user icon\n - Props: className?: string, icon?: ReactNode, src?: string\n\n Button\n - Enhanced button with automatic loading states and error handling\n - Props: onClick: (e, {onError}) => Promise<Result>, onSuccess?: (result) => void, className?, children, standard button props\n\n Input\n - Comprehensive input system with real-time validation and caching\n - Props: value: string, validate: (value) => boolean | string, onChange?, nullable?, inputStyleType?: \"bordered\" | \"borderless\" \n | \"underline\", icon?, cacheKey?\n - Variants: Input.TextArea, Input.Password, Input.Email, Input.Number, Input.Checkbox\n\n Select\n - Advanced dropdown with search and multi-select capabilities\n - Props: value: T | T[], options: {label, value}[], multiple?, searchable?, onChange, onSearch?, renderOption?, renderSelected?\n\n DatePicker\n - Date/time picker with range selection support\n - Props: value?: Dayjs, onChange, showTime?, format?, disabledDate?\n - Variants: DatePicker.RangePicker, DatePicker.TimePicker\n\n CodeInput\n - PIN/code input with individual character boxes\n - Props: maxNum: number, value: string, onChange, unitStyle?: \"box\" | \"underline\", autoComplete?\n\n Display Components\n\n Table\n - Feature-rich data table with pagination and responsive design\n - Props: columns: Column[], dataSource: any[], loading?, pagination?, onRow?, rowClassName?\n\n Modal\n - Dialog modal with backdrop and action buttons\n - Props: open: boolean, onCancel, title?, action?, confirmClose?\n - Variants: Modal.Window\n\n Image\n - Optimized image component with blur placeholder and SSR support\n - Props: src?, file?: ProtoFile, abstractData?, alt?, standard Next.js Image props\n\n ChatBubble\n - Chat message bubble with avatar and timestamp\n - Props: avatar?, hasPrev?, hasNext?, isMe?, name?, at?: Dayjs, children\n\n Empty\n - Empty state placeholder with customizable message\n - Props: description?, minHeight?, children?\n\n QRCode\n - QR code generator with click-to-open functionality\n - Props: href: string, className?\n\n Layout Components\n\n BottomSheet\n - Only mobile bottom sheet with drag gestures\n - Props: open: boolean, onCancel, type: \"full\" | \"half\", children\n\n Layout\n Layout - Complete layout framework with responsive design\n - Layout.Header - Top header with auto-hide functionality\n - Props: className?: string, type?: \"static\" | \"hide\", children?: any, height?: number\n - Features: Auto-hide on scroll, fixed positioning\n - Layout.Sider - Collapsible sidebar\n - Props: className?: string, bgClassName?: string, children?: any\n - Features: Drawer-based with toggle functionality\n - Layout.Navbar - Navigation bar with portal content\n - Props: className?: string, children?: ReactNode, height?: \n\n Menu\n - Navigation menu with horizontal/vertical modes and submenu support\n - Props: items: MenuItem[], mode?: \"horizontal\" | \"inline\", selectedKeys?, onClick?, inlineCollapsed?\n\n\n Tab \n - Tabbed interface system\n - Tab.Provider - Tab context provider\n - Props: className?: string, defaultMenu?: string | null, children?: any\n - Tab.Menu - Tab menu item\n - Props: className?: string, activeClassName?: string, disabledClassName?: string, disabled?: boolean, menu: string, children:\n any, scrollToTop?: boolean, tooltip?: string\n - Tab.Panel - Tab content panel\n - Props: className?: string, menu: string, children?: any, loading?: \"eager\" | \"lazy\" | \"every\"\n - Features: Lazy loading support\n\n ScreenNavigator \n - Gesture-based screen navigation\n - ScreenNavigator.Provider - Navigation context provider\n - Props: setMenu?: (menu: string) => void, children: ReactNode, menus: string[]\n - Features: Gesture-based navigation, spring animations\n - ScreenNavigator.Screen - Individual screen container\n - Props: children: ReactNode, className?: string\n - ScreenNavigator.NavbarItem - Navigation bar item\n - Props: menu: string, children: ReactNode, className?: string \n\n Upload \n - File upload system with multiple modes\n - Upload \n - Basic file upload with drag & drop\n - Props: onChange?: (fileList: FileList) => void; multiple?: boolean; accept?: string; className?: string; uploadClassName?: string; children: React.ReactNode; disabled?: boolean;\n - Upload.File \n - Single file upload with preview\n - Props: multiple?: boolean; file: ProtoFile | null; render?: (file: ProtoFile) => React.ReactNode; onChange?: (e: File | FileList) => void | Promise<void>; onRemove?: (e: any) => void; children?: React.ReactNode; disabled?: boolean; maxCount?: number; className?: string; uploadClassName?: string; accept?: string;\n - Upload.FileList \n - Multiple files with table view and progress tracking\n - Props: multiple?: boolean; fileList: ProtoFile[]; render?: (file: ProtoFile) => React.ReactNode; onChange?: (e: File | FileList) => void | Promise<void>; onRemove?: (e: any) => void; children?: React.ReactNode; disabled?: boolean; maxCount?: number; className?: string; uploadClassName?: string; accept?: string;\n - Upload.Image \n - Image upload with integrated cropping functionality\n - Props: multiple?: boolean; file: ProtoFile | null; render?: (file: ProtoFile) => React.ReactNode; onChange?: (e: File | FileList) => void | Promise<void>; onRemove?: (e: any) => void; children?: React.ReactNode; disabled?: boolean; maxCount?: number; className?: string; uploadClassName?: string; accept?: string;\n - Upload.Images \n - Multiple image upload with gallery preview\n - Props: multiple?: boolean; fileList: ProtoFile[]; render?: (file: ProtoFile) => React.ReactNode; onChange?: (e: File | FileList) => void | Promise<void>; onRemove?: (e: any) => void; children?: React.ReactNode; disabled?: boolean; maxCount?: number; className?: string; uploadClassName?: string; accept?: string;\n\n DndKit \n - Drag and drop functionality built on @dnd-kit\n - DndKit.Provider \n - DnD context provider\n - Props: className?: string + all DndContextProps\n - DndKit.DraggableUnit \n - Draggable item wrapper\n - Props: id: string, children: ReactNode, className?: string, onClick?: () => void | Promise<void>\n - DndKit.DroppableColumn \n - Drop target column\n - Props: id: string, items: T[], className?: string, children: ReactNode, onOver?: (id, items, event) => void, onEnd?: (id, \n item, event) => void\n\n MapView \n - Map integration with multiple providers\n - MapView.Map \n - Main map container with theme awareness\n - Props: className?: string, onLoad?: () => void, onClick?: (coordinate) => void, onRightClick?: (coordinate) => void,\n onMouseMove?: (coordinate) => void, children: any\n - MapView.Marker \n - Map marker component\n - Props: coordinate: cnst.Coordinate, zIndex?: number, children?: any\n - MapView.Google \n - Google Maps implementation\n - Props: id?: string, className?: string, mapKey: string, onClick/onRightClick?: (coordinate) => void, center?: \n cnst.Coordinate, onChangeCenter?: (coordinate) => void, zoom?: number, onChangeZoom?: (zoom) => void, bounds?: {minLat, maxLat, \n minLng, maxLng}, onLoad?: () => void, onMouseMove?: (coordinate, event) => void, options?: google.maps.MapOptions, children: any\n - MapView.Pigeon \n - Pigeon Maps implementation (lightweight alternative)\n - Props: id?: string, className?: string, onLoad?: () => void, onClick/onRightClick?: (coordinate) => void, center?: \n cnst.Coordinate, onChangeCenter?: (coordinate) => void, zoom?: number, onChangeZoom?: (zoom) => void, bounds?: {minLat, maxLat, \n minLng, maxLng}, onChangeBounds?: (bounds) => void, mouseEvents?: boolean, onMouseMove?: (coordinate) => void, mapTiler?: (x, y,\n z, dpr) => string, children?: any, zoomControlStyle?: CSSProperties\n\n\n Pagination\n - Page navigation with smart ellipsis and responsive design\n - Props: currentPage: number, total: number, onPageSelect, itemsPerPage: number\n\n Radio\n - Radio button group with custom styling support\n - Props: value, children: ReactElement[], onChange, disabled?\n\n ToggleSelect\n - Button-based selection with single/multi-select modes\n - Props: items, value, validate, onChange, nullable\n - Variants: ToggleSelect.Multi\n\n Share\n - Native share API with copy fallback\n - Props: title: string, url: string, children\n\n Specialized Component Groups\n\n Chart \n - Visualization components built on Chart.js and react-chartjs-2\n - Chart.Bar - Bar chart component\n - Props: data: ChartData<\"bar\">, options?: ChartOptions<\"bar\">\n - Features: Responsive layout, legend display, title configuration\n - Chart.Line - Line chart component\n - Props: data: ChartData<\"line\">, options?: ChartOptions<\"line\">\n - Features: Line-specific Chart.js configuration with curve interpolation\n - Chart.Pie - Pie chart component\n - Props: data: ChartData<\"pie\">, options?: ChartOptions<\"pie\">\n - Features: ArcElement rendering, responsive design\n - Chart.Doughnut - Doughnut chart component\n - Props: data: ChartData<\"doughnut\">, options?: ChartOptions<\"doughnut\">\n - Features: Similar to pie but with center cutout\n\n Dialog \n - Composable modal dialog system built on Radix UI\n - Dialog.Provider - Dialog context provider\n - Props: className?: string, open?: boolean, defaultOpen?: boolean, children?: any\n - Dialog.Modal - Main modal container\n - Props: className?: string, bodyClassName?: string, confirmClose?: boolean, children?: any, onCancel?: () => void\n - Features: Drag gestures, spring animations, responsive design, close confirmation\n - Dialog.Title - Modal title component\n - Props: children?: ReactNode\n - Dialog.Content - Modal content area\n - Props: className?: string, children?: ReactNode\n - Dialog.Action - Modal action buttons container\n - Props: children?: ReactNode\n - Dialog.Trigger - Modal trigger element\n - Props: className?: string, children?: any\n\n Link \n - Adaptive navigation system\n - Link \n - Main adaptive link (auto-switches between CSR/Next.js based on render mode)\n - Link.Back - Back navigation link\n - Props: className?: string, children?: any\n - Features: Browser history integration\n - Link.Close - Window close link\n - Props: Similar to Back but closes window\n - Link.CsrLink & Link.NextLink - Environment-specific implementations with active state support\n\n\n Loading \n - Loading states for different UI elements\n - Loading.Area - Full-screen loading overlay with animated dots\n - Loading.Button - Button loading skeleton\n - Props: className?: string, active?: boolean, style?: CSSProperties\n - Loading.Input - Input loading skeleton\n - Loading.Skeleton - Multi-line content skeleton with pulse animation\n - Loading.Spin - Custom loading spinner\n - Props: indicator?: ReactNode, isCenter?: boolean\n - Loading.ProgressBar - Animated progress bar\n - Props: className?: string, value: number, max: number\n - Features: React Spring animations\n\n Key Framework Features\n \n - TypeScript support with strict typing\n - Responsive design with mobile-first approach\n - Internationalization (i18n) integration\n - Session storage caching for form inputs\n - Accessibility compliance\n - Consistent DaisyUI/Tailwind CSS styling\n - Modern React patterns (hooks, context, providers)\n - Error handling and validation systems\n ";
5
+ export declare const frameworkAbstract = "\nIntro\n- Build an all-stack application at once.\n- Write one line, deploy on web, app, server, database, and infra.\n- Akan is a framework with least code, highest performance for typescript-written applications.\n\nKey features\n- Integral interface: Akan serves an interface for building from schema, to service logic, api endpoint, state management, and component design.\n- Stable, Scalable, Safe built-in architecture: Fully type-safe, i18n, security, file management, text-search, automatic documentation, admin page, etc are all served with modular development.\n- application as a service: Akan deploys server, database, web, app at once through Akan cloud. Commit once, deploy and manage all.\n\nProcedure\n- add field on database and api at once, with fully typed\n- add backend api endpoint and frontend fetch function at once, with fully typed\n- write query interface and use everywhere!\n- No spaghetti state management anymore, build your global store with domain-driven state&actions.\n- No Spaghetti Components anymore, build your page with domain-driven components\n- write one page, use SSR on Next.js and build Android&iOS CSR app with beautiful page transitions!\n- built-in ai code generation, tell about business, the logic is generated.\n\n\n";
6
+ export declare const eslintDescription = "\nCore ESLint Extensions\n\n Base Configurations:\n - eslint:recommended - Standard ESLint recommended rules\n - next & next/core-web-vitals - Next.js specific linting rules\n - @typescript-eslint/recommended-type-checked - TypeScript recommended rules with type checking\n - @typescript-eslint/strict-type-checked - Strict TypeScript type checking rules\n - @typescript-eslint/stylistic-type-checked - TypeScript stylistic rules with type checking\n\n Third-Party Plugins\n\n 1. eslint-plugin-unused-imports\n - Automatically detects and warns about unused imports\n - Helps keep code clean by removing unnecessary import statements\n\n 2. eslint-plugin-simple-import-sort\n - Automatically sorts import statements in a consistent order\n - Enforces clean import organization throughout the codebase\n\n Custom Plugin: @akanjs/lint\n\n 1. useClientByFile\n - Enforces proper \"use client\" directive usage in Next.js App Router\n - Server files must NOT have \"use client\" directive\n - Client files MUST have \"use client\" directive at the top\n\n 2. noImportClientFunctions\n - Prevents server files from importing client-side functions\n - Ensures proper separation between server and client code\n\n 3. nonScalarPropsRestricted\n - Prevents non-scalar props (functions) in server components\n - Specifically targets page.tsx and layout.tsx files\n - Allows exceptions for specific props like \"loader\", \"render\", and \"of\"\n\n 4. noImportExternalLibrary\n - Restricts external library imports in pure import/re-export files\n - Only allows imports from the same app scope (@appName/...)\n - Promotes clean architecture and prevents dependency leakage\n\n Key Rule Configurations\n\n Disabled Rules:\n - no-console: \"error\" - Prevents console statements in production code\n - Various TypeScript strict rules are disabled for flexibility\n - React and Next.js specific rules are relaxed for development ease\n\n Import Management:\n - unused-imports/no-unused-imports: \"warn\" - Warns about unused imports\n - simple-import-sort/imports: \"warn\" - Enforces import sorting\n - import/first: \"warn\" - Ensures imports come first\n - import/newline-after-import: \"warn\" - Enforces newline after imports\n\n This configuration creates a robust linting setup that enforces Next.js App Router best practices, maintains clean code\n organization, and ensures proper server/client code separation.\n ";
3
7
  interface RequestConstantProps {
4
8
  sysName: string;
5
9
  modelName: string;
@@ -15,12 +19,17 @@ export declare const requestScalarConstant: ({ sysName, modelName, modelDesc, mo
15
19
  interface RequestViewProps {
16
20
  sysName: string;
17
21
  modelName: string;
18
- modelDesc: string;
19
- modelSchemaDesign: string;
20
- boilerplate: string;
21
- paths: Map<string, {
22
- filePath: string;
23
- }>;
22
+ ModelName: string;
23
+ constant: string;
24
+ boilerplate?: string;
25
+ properties: {
26
+ key: string;
27
+ source: string;
28
+ }[];
29
+ exampleFiles: {
30
+ filepath: string;
31
+ content: string;
32
+ }[];
24
33
  }
25
- export declare const requestView: ({ sysName, modelName, modelDesc, modelSchemaDesign, boilerplate, paths, }: RequestViewProps) => string;
34
+ export declare const requestView: ({ sysName, modelName, ModelName, boilerplate, constant, properties, exampleFiles, }: RequestViewProps) => string;
26
35
  export {};
@@ -1,4 +1,4 @@
1
- import { type App, type Lib, type Sys, Workspace } from "@akanjs/devkit";
1
+ import { type Sys, 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
4
  removeModule(workspace: Workspace, name: string): Promise<void>;
@@ -58,6 +58,4 @@ export declare class ModuleRunner {
58
58
  content: string;
59
59
  };
60
60
  }>;
61
- createUnit(sys: App | Lib, modelName: string): Promise<void>;
62
- createView(sys: App | Lib, modelName: string): Promise<void>;
63
61
  }
@@ -6,6 +6,6 @@ export declare class ModuleScript {
6
6
  createScalar(sys: Sys, name: string, description: string, schemaDescription: string): Promise<void>;
7
7
  createService(workspace: Workspace, name: string): Promise<void>;
8
8
  createTest(workspace: Workspace, name: string): Promise<void>;
9
- createUnit(workspace: Workspace, type: "app" | "lib", appOrLibName: string, modelName: string): Promise<void>;
9
+ createUnit(sys: Sys): Promise<void>;
10
10
  createView(sys: Sys): Promise<void>;
11
11
  }
@@ -4,7 +4,7 @@ export declare class PackageCommand {
4
4
  packageScript: PackageScript;
5
5
  version(workspace: Workspace): Promise<void>;
6
6
  createPackage(name: string, workspace: Workspace): Promise<void>;
7
- removePackage(name: string, workspace: Workspace): Promise<void>;
7
+ removePackage(pkg: Pkg): Promise<void>;
8
8
  scanPackage(pkg: Pkg): Promise<void>;
9
9
  buildPackage(pkg: Pkg): Promise<void>;
10
10
  }
@@ -1,7 +1,8 @@
1
- import { type DistPkgExecutor, type Pkg, type Workspace } from "@akanjs/devkit";
1
+ import { type Pkg, type Workspace } from "@akanjs/devkit";
2
2
  export declare class PackageRunner {
3
3
  version(workspace: Workspace): Promise<void>;
4
4
  createPackage(workspace: Workspace, pkgName: string): Promise<void>;
5
+ removePackage(pkg: Pkg): Promise<void>;
5
6
  scanSync(pkg: Pkg): Promise<import("@akanjs/config").PkgScanResult>;
6
- buildPackage(pkg: Pkg, distPkg: DistPkgExecutor): Promise<void>;
7
+ buildPackage(pkg: Pkg): Promise<void>;
7
8
  }
@@ -1,8 +1,9 @@
1
- import { DistPkgExecutor, type Pkg, type Workspace } from "@akanjs/devkit";
1
+ import { type Pkg, type Workspace } from "@akanjs/devkit";
2
2
  export declare class PackageScript {
3
3
  #private;
4
4
  version(workspace: Workspace): Promise<void>;
5
5
  createPackage(workspace: Workspace, pkgName: string): Promise<void>;
6
+ removePackage(pkg: Pkg): Promise<void>;
6
7
  scanPackage(pkg: Pkg): Promise<void>;
7
- buildPackage(pkg: Pkg, distPkg?: DistPkgExecutor): Promise<void>;
8
+ buildPackage(pkg: Pkg): Promise<void>;
8
9
  }
@@ -1,10 +1,24 @@
1
1
  import { BaseMessage } from "@langchain/core/messages";
2
+ export declare const supportedLlmModels: readonly ["deepseek-chat", "deepseek-reasoner"];
3
+ export type SupportedLlmModel = (typeof supportedLlmModels)[number];
2
4
  interface EditOptions {
3
5
  onChunk?: (chunk: string) => void;
4
6
  maxTry?: number;
5
7
  }
6
8
  export declare class AiSession {
7
9
  #private;
10
+ static init({ temperature, useExisting }?: {
11
+ temperature?: number;
12
+ useExisting?: boolean;
13
+ }): Promise<typeof AiSession>;
14
+ static getLlmConfig(): {
15
+ model: SupportedLlmModel;
16
+ apiKey: string;
17
+ } | null;
18
+ static setLlmConfig(llmConfig: {
19
+ model: SupportedLlmModel;
20
+ apiKey: string;
21
+ } | null): typeof AiSession;
8
22
  readonly messageHistory: BaseMessage[];
9
23
  constructor(messageHistory?: BaseMessage[]);
10
24
  ask(question: string, { onChunk, }?: EditOptions): Promise<{
@@ -1,3 +1,4 @@
1
+ import type { SupportedLlmModel } from "./aiEditor";
1
2
  export declare const basePath: string;
2
3
  export declare const configPath: string;
3
4
  export declare const akanCloudHost: string;
@@ -14,6 +15,12 @@ export interface HostConfig {
14
15
  }
15
16
  export declare const defaultHostConfig: HostConfig;
16
17
  export interface AkanGlobalConfig {
17
- [key: string]: HostConfig;
18
+ cloudHost: {
19
+ [key: string]: HostConfig;
20
+ };
21
+ llm: {
22
+ model: SupportedLlmModel;
23
+ apiKey: string;
24
+ } | null;
18
25
  }
19
26
  export declare const defaultAkanGlobalConfig: AkanGlobalConfig;