@akanjs/cli 0.0.82 → 0.0.83
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.js +370 -340
- package/package.json +1 -1
- package/pkgs/@akanjs/cli/src/module/module.command.d.ts +2 -2
- package/pkgs/@akanjs/cli/src/module/module.prompt.d.ts +13 -2
- package/pkgs/@akanjs/cli/src/module/module.runner.d.ts +47 -1
- package/pkgs/@akanjs/cli/src/module/module.script.d.ts +2 -2
- package/pkgs/@akanjs/devkit/src/executors.d.ts +1 -0
- package/src/templates/workspaceRoot/.gitignore.template +1 -0
package/package.json
CHANGED
|
@@ -2,12 +2,12 @@ import { Sys, Workspace } from "@akanjs/devkit";
|
|
|
2
2
|
import { ModuleScript } from "./module.script";
|
|
3
3
|
export declare class ModuleCommand {
|
|
4
4
|
moduleScript: ModuleScript;
|
|
5
|
-
createModule(
|
|
5
|
+
createModule(sys: Sys, workspace: Workspace): Promise<void>;
|
|
6
6
|
removeModule(name: string, workspace: Workspace): Promise<void>;
|
|
7
7
|
scanModule(name: string, workspace: Workspace): Promise<void>;
|
|
8
8
|
createScalar(sys: Sys, name: string, description: string, schemaDescription: string, workspace: Workspace): Promise<void>;
|
|
9
9
|
createService(name: string, workspace: Workspace): Promise<void>;
|
|
10
10
|
createTest(name: string, workspace: Workspace): Promise<void>;
|
|
11
|
-
createView(
|
|
11
|
+
createView(sys: Sys, workspace: Workspace): Promise<void>;
|
|
12
12
|
createUnit(name: string, workspace: Workspace): Promise<void>;
|
|
13
13
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
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 Nx\uC5D0\uC11C \uC81C\uACF5\uD558\uB294 \uD15C\uD50C\uB9BF \uC81C\uC791 \uBB38\uBC95\uC744 \uC0AC\uC6A9\uD574\uC11C \uCEE4\uB9E8\uB4DC \uD55C \uC904\uB85C \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 )\n- pencil.Templete.tsx (\uC8FC\uB85C edit\uC5D0 \uC5F0\uAD00\uB41C \uCEF4\uD3EC\uB10C\uD2B8 \uC815\uC758\uD558\uB294 \uACF3 )\n- pencil.Unit.tsx (list \uCC98\uB7FC \uBCF5\uC218\uAC1C\uC758 \uCEF4\uD3EC\uB10C\uD2B8\uB97C \uC815\uC758\uD558\uB294 \uACF3 )\n- pencil.Util.tsx (Action \uBC84\uD2BC\uC744 \uC815\uC758\uD558\uB294 \uACF3 )\n- pencil.View.tsx (\uB2E8\uC77C view \uCEF4\uD3EC\uB10C\uD2B8\uB97C \uC815\uC758\uD558\uB294 \uACF3 )\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. \uC544\uB798\uB294 \uAC01 \uD15C\uD50C\uB9BF \uBCC4\uB85C \uD30C\uC77C\uB9C8\uB2E4 \uC815\uC758\uB418\uC788\uB294 \uC18C\uC2A4\uCF54\uB4DC\uC57C.\n<%=model %> \uC774 \uBD80\uBD84\uC5D0 \uC6B0\uB9AC\uAC00 \uC785\uB825\uD55C \uBAA8\uB378\uC744 \uAE30\uBC18\uC73C\uB85C \uC0DD\uC131\uB418\uB294 \uAC70\uC9C0.\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.\nmodel.constant.ts\n```\nimport {{ BaseModel, Field, Full, Light, Model, baseQueries, baseSorts }} from \"@akanjs/constant\";\nimport {{ Int, Dayjs, dayjs }} from \"@akanjs/base\";\n\nexport const <%= model %>Statuses = [\"active\"] as const;\nexport type <%= Model %>Status = (typeof <%= 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(\"<%= Model %>Input\")\nexport class <%= 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(\"<%= Model %>Object\")\nexport class <%= Model %>Object extends BaseModel(<%= Model %>Input) {{\n @Field.Prop(() => String, {{ enum: <%= model %>Statuses, default: \"active\" }})\n status: <%= 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<%= Model %>\")\nexport class Light<%= Model %> extends Light(<%= Model %>Object, [\"field\", \"status\"] as const) {{}}\n\n//\uCD5C\uC885 \uB370\uC774\uD130\uC758 \uD0C0\uC785\uC774 \uC815\uC758\uB418\uB294 \uACF3\n@Model.Full(\"<%= Model %>\")\nexport class <%= Model %> extends Full(<%= Model %>Object, Light<%= 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(\"<%= Model %>Insight\")\nexport class <%= 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(\"<%= Model %>Summary\")\nexport class <%= Model %>Summary {{\n @Field.Prop(() => Int, {{ min: 0, default: 0, query: {{ status: {{}} }} }})\n total<%= Model %>: number;\n}}\n\n//\uB370\uC774\uD130\uB97C \uC870\uD68C\uD560 \uB54C \uD544\uC694\uD55C \uCFFC\uB9AC\uB97C \uC815\uC758\uD558\uB294 \uACF3\nexport const <%= model %>Query = {{\n ...baseQueries,\n}};\n//\uB370\uC774\uD130\uB97C \uC815\uB82C\uD560 \uB54C \uD544\uC694\uD55C \uC815\uB82C\uC744 \uC815\uC758\uD558\uB294 \uACF3\nexport const <%= model %>Sort = {{\n ...baseSorts,\n}};\n```\n\n\nmodel.dictonary.ts\n```\nimport {{ ModelDictionary, SignalDictionary, SummaryDictionary, baseTrans, getBaseSignalTrans }} from \"@akanjs/dictionary\";\nimport type {{ <%= Model %>, <%= Model %>Insight, <%= Model %>Summary, <%= model %>Sort }} from \"./<%= model %>.constant\";\nimport type {{ <%= Model %>Signal }} from \"./<%= model %>.signal\";\n\nconst modelDictionary = {{\n ...baseTrans,\n modelName: [\"<%= Model %>\", \"<%= Model %>\"],\n modelDesc: [\n \"<%= Model %> description\",\n \"<%= 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\": [\"<%= Model %> count in current query settting\", \"\uD604\uC7AC \uCFFC\uB9AC \uC124\uC815\uC5D0 \uB9DE\uB294 <%= 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<<%= Model %>, <%= Model %>Insight, typeof <%= model %>Sort>;\n\nexport const <%= model %>SummaryDictionary = {{\n // * ==================== Summary ==================== * //\n total<%= Model %>: [\"Total <%= Model %>\", \"\uCD1D <%= Model %> \uC218\"],\n \"desc-total<%= Model %>\": [\"Total <%= model %> count in the database\", \"\uB370\uC774\uD130\uBCA0\uC774\uC2A4\uC5D0 \uC800\uC7A5\uB41C \uCD1D <%= Model %> \uC218\"],\n // * ==================== Summary ==================== * //\n}} satisfies SummaryDictionary<<%= Model %>Summary>;\n\nconst signalDictionary = {{\n ...getBaseSignalTrans(\"<%= model %>\" as const),\n // * ==================== Endpoint ==================== * //\n \"api-<%= model %>ListInPublic\": [\"<%= Model %> List In Public\", \"\uACF5\uAC1C\uB41C <%= Model %> \uB9AC\uC2A4\uD2B8\"],\n \"apidesc-<%= model %>ListInPublic\": [\"Get a list of public <%= model %>\", \"\uACF5\uAC1C\uB41C <%= Model %>\uC758 \uB9AC\uC2A4\uD2B8\uB97C \uAC00\uC838\uC635\uB2C8\uB2E4\"],\n \"arg-<%= model %>ListInPublic-statuses\": [\"Statuses\", \"\uC0C1\uD0DC\"],\n \"argdesc-<%= model %>ListInPublic-statuses\": [\"Statuses to filter\", \"\uD544\uD130\uB9C1\uD560 \uC0C1\uD0DC\"],\n \"arg-<%= model %>ListInPublic-skip\": [\"Skip\", \"\uAC74\uB108\uB6F0\uAE30\"],\n \"argdesc-<%= model %>ListInPublic-skip\": [\"Number of items to skip\", \"\uAC74\uB108\uB6F8 \uC544\uC774\uD15C \uC218\"],\n \"arg-<%= model %>ListInPublic-limit\": [\"Limit\", \"\uC81C\uD55C\"],\n \"argdesc-<%= model %>ListInPublic-limit\": [\"Maximum number of items to return\", \"\uBC18\uD658\uD560 \uCD5C\uB300 \uC544\uC774\uD15C \uC218\"],\n \"arg-<%= model %>ListInPublic-sort\": [\"Sort\", \"\uC815\uB82C\"],\n \"argdesc-<%= model %>ListInPublic-sort\": [\"Sort order of the items\", \"\uC544\uC774\uD15C\uC758 \uC815\uB82C \uC21C\uC11C\"],\n\n \"api-<%= model %>InsightInPublic\": [\"<%= Model %> Insight In Public\", \"\uACF5\uAC1C\uB41C <%= Model %> \uC778\uC0AC\uC774\uD2B8\"],\n \"apidesc-<%= model %>InsightInPublic\": [\n \"Get insight data for public <%= model %>\",\n \"\uACF5\uAC1C\uB41C <%= Model %>\uC5D0 \uB300\uD55C \uC778\uC0AC\uC774\uD2B8 \uB370\uC774\uD130\uB97C \uAC00\uC838\uC635\uB2C8\uB2E4\",\n ],\n \"arg-<%= model %>InsightInPublic-statuses\": [\"Statuses\", \"\uC0C1\uD0DC\"],\n \"argdesc-<%= model %>InsightInPublic-statuses\": [\"Statuses to filter\", \"\uD544\uD130\uB9C1\uD560 \uC0C1\uD0DC\"],\n // * ==================== Endpoint ==================== * //\n}} satisfies SignalDictionary<<%= Model %>Signal, <%= Model %>>;\n```\nexport const <%= model %>Dictionary = {{ ...modelDictionary, ...signalDictionary }};\n\n\n\nmodel.document.ts\n```\nimport {{ Database, Document, Input, Middleware, Model, type SchemaOf }} from \"@akanjs/server\";\nimport {{ cnst }} from \"../cnst\";\n\n@Database.Input(() => cnst.<%= Model %>Input)\nexport class <%= Model %>Input extends Input(cnst.<%= Model %>Input) {{}}\n\n@Database.Document(() => cnst.<%= Model %>)\nexport class <%= Model %> extends Document(cnst.<%= Model %>) {{}}\n\n@Database.Model(() => cnst.<%= Model %>)\nexport class <%= Model %>Model extends Model(<%= Model %>, cnst.<%= model %>Cnst) {{\n async getSummary(): Promise<cnst.<%= Model %>Summary> {{\n return {{\n ...(await this.getDefaultSummary()),\n }};\n }}\n}}\n\n@Database.Middleware(() => cnst.<%= Model %>)\nexport class <%= Model %>Middleware extends Middleware(<%= Model %>Model, <%= Model %>) {{\n onSchema(schema: SchemaOf<<%= Model %>Model, <%= Model %>>) {{\n // schema.index({{ status: 1 }})\n }}\n}}\n\n\nmodel.signal.ts\n\nimport {{ Arg, DbSignal, Mutation, Query, Signal, resolve }} from \"@akanjs/signal\";\nimport {{ Int }} from \"@akanjs/base\";\nimport {{ Srvs, cnst }} from \"../cnst\";\n\n@Signal(() => cnst.<%= Model %>)\nexport class <%= Model %>Signal extends DbSignal(cnst.<%= model %>Cnst, Srvs, {{\n guards: {{ get: Query.Public, cru: Mutation.Every }},\n}}) {{\n // * /////////////////////////////////////\n // * Public Slice\n @Query.Public(() => [cnst.<%= Model %>])\n async <%= model %>ListInPublic(\n @Arg.Query(\"statuses\", () => [String], {{ nullable: true }}) statuses: cnst.<%= 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: keyof typeof cnst.<%= model %>Sort | null\n ) {{\n const <%= models %> = await this.<%= model %>Service.listByStatuses(statuses, {{ skip, limit, sort }});\n return resolve<cnst.<%= Model %>[]>(<%= models %>);\n }}\n @Query.Public(() => cnst.<%= Model %>Insight)\n async <%= model %>InsightInPublic(@Arg.Query(\"statuses\", () => [String], {{ nullable: true }}) statuses: cnst.<%= Model %>Status[] | null) {{\n const <%= model %>Insight = await this.<%= model %>Service.insightByStatuses(statuses);\n return resolve<cnst.<%= Model %>Insight>(<%= model %>Insight);\n }}\n // * Public Slice\n // * /////////////////////////////////////\n}}\n```\n\n\nmodel.service.ts\n```\nimport * as db from \"../db\";\nimport {{ DbService, Service }} from \"@akanjs/server\";\nimport {{ cnst }} from \"../cnst\";\n// import type * as srv from \"../srv\";\n\n@Service(\"<%= Model %>Service\")\nexport class <%= Model %>Service extends DbService(db.<%= model %>Db) {{\n // @Use() protected readonly injectedVar: string;\n // @Srv() protected readonly otherService: srv.OtherService;\n \n async summarize(): Promise<cnst.<%= Model %>Summary> {{\n return {{\n ...(await this.<%= model %>Model.getSummary()),\n }};\n }}\n}}\n```\n\n\nmodel.store.ts\n```\nimport {{ Store, stateOf }} from \"@akanjs/client\";\nimport {{ cnst }} from \"../cnst\";\nimport {{ fetch }} from \"../fetch\";\n\n@Store(() => cnst.<%= Model %>)\nexport class <%= Model %>Store extends stateOf(fetch.<%= 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, fetch, <%= Model %> }} from \"<%= clientPath %>\";\nimport {{ ClientInit, ClientView, DefaultOf }} from \"@akanjs/signal\";\nimport {{ getQueryMap }} from \"@akanjs/constant\";\n\nexport const Admin = ({{ sliceName = \"<%= model %>\", init, query }}: ModelsProps<cnst.<%= Model %>>) => {{\n return (\n <Data.ListContainer\n init={{init}}\n query={{query}}\n sliceName={{sliceName}}\n renderItem={{<%= Model %>.Unit.Card}}\n renderDashboard={{<%= Model %>.Util.Stat}}\n renderInsight={{<%= Model %>.Util.Insight}}\n renderTemplate={{<%= Model %>.Template.General}}\n renderTitle={{(<%= model %>: DefaultOf<cnst.<%= Model %>>) => `<%= Model %> - ${{<%= model %>.id ? <%= model %>.id : \"New\"}}`}}\n renderView={{(<%= model %>: cnst.<%= Model %>) => <<%= Model %>.View.General <%= model %>={{<%= model %>}} />}}\n queryMap={{getQueryMap(cnst.<%= Model %>Summary)}}\n columns={{[\n \"id\",\n \"status\",\n \"createdAt\",\n \"updatedAt\",\n ]}}\n actions={{(<%= model %>: cnst.Light<%= Model %>, idx) => [\"remove\", \"edit\", \"view\"]}}\n />\n );\n}};\n\ninterface CardProps {{\n className?: string;\n init: ClientInit<\"<%= model %>\", cnst.Light<%= Model %>>;\n}}\nexport const Card = ({{ className, init }}: CardProps) => {{\n return (\n <Load.Units\n className={{className}}\n init={{init}}\n renderItem={{(<%= model %>: cnst.Light<%= Model %>) => (\n <<%= Model %>.Unit.Card key={{<%= model %>.id}} href={{`/<%= model %>${{<%= model %>.id}}`}} <%= model %>={{<%= model %>}} />\n )}}\n />\n );\n}};\n\ninterface ViewProps {{\n className?: string;\n view: ClientView<\"<%= model %>\", cnst.<%= Model %>>;\n}}\nexport const View = ({{ view }}: ViewProps) => {{\n return <Load.View view={{view}} renderView={{(<%= model %>) => <<%= Model %>.View.General <%= model %>={{<%= model %>}} />}} />;\n}};\n```\n\nmodel.Templete.tsx\n```\n\"use client\";\nimport {{ Field }} from \"@shared.ui\";\nimport {{ Layout }} from \"@util.ui\";\nimport {{ cnst, st, usePage }} from \"<%= clientPath %>\";\n\ninterface <%= Model %>EditProps {{\n <%= model %>Id?: string | null;\n}}\n\nexport const General = ({{ <%= model %>Id = undefined }}: <%= Model %>EditProps) => {{\n const <%= model %>Form = st.use.<%= model %>Form();\n const {{ l }} = usePage();\n return (\n <Layout.Template>\n <Field.Text\n label={{l.field(\"<%= model %>\", \"id\")}}\n desc={{l.desc(\"<%= model %>\", \"id\")}}\n value={{<%= model %>Form.id}}\n onChange={{st.do.setIdOn<%= Model %>}}\n />\n </Layout.Template>\n );\n}};\n```\n\n\nmodel.Unit.tsx\n```\nimport {{ Link }} from \"@util.ui\";\nimport {{ cnst, <%= Model %> }} from \"<%= clientPath %>\";\nimport {{ ModelProps }} from \"@akanjs/client\";\n\nexport const Card = ({{ <%= model %>, href }}: ModelProps<\"<%= model %>\", cnst.Light<%= 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>{{<%= model %>.id}}</div>\n </Link>\n );\n}};\n```\n\n\nmodel.Util.tsx\n```\n\"use client\";\nimport {{ Data }} from \"@shared.ui\";\nimport {{ ModelDashboardProps, ModelInsightProps }} from \"@akanjs/client\";\nimport {{ cnst, fetch, st, usePage, <%= Model %> }} from \"<%= clientPath %>\";\nimport {{ getQueryMap }} from \"@akanjs/constant\";\n\nexport const Stat = ({{\n className,\n summary,\n sliceName = \"<%= model %>\",\n queryMap = getQueryMap(cnst.<%= 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<%= Model %>\"]}}\n hidePresents={{hidePresents}}\n />\n );\n}};\n\nexport const Insight = ({{\n className,\n insight,\n sliceName = \"<%= model %>\",\n}}: ModelInsightProps<cnst.<%= 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 {{ Image }} from \"@util.ui\";\nimport {{ cnst, <%= Model %> }} from \"<%= clientPath %>\";\nimport {{ clsx }} from \"@akanjs/client\";\n\ninterface <%= Model %>ViewProps {{\n className?: string;\n <%= model %>: cnst.<%= Model %>;\n self?: {{ id?: string }} | null;\n}}\n\nexport const General = ({{ className, <%= model %>, self }}: <%= Model %>ViewProps) => {{\n return (\n <div className={{clsx(className, `animate-fadeIn w-full`)}}>\n <div>{{<%= 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 requestModule: () => string;
|
|
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";
|
|
2
|
+
export declare const requestModule: (projectName: string, projectDesc: string) => string;
|
|
3
3
|
interface RequestConstantProps {
|
|
4
4
|
sysName: string;
|
|
5
5
|
modelName: string;
|
|
@@ -12,4 +12,15 @@ interface RequestConstantProps {
|
|
|
12
12
|
}[];
|
|
13
13
|
}
|
|
14
14
|
export declare const requestScalarConstant: ({ sysName, modelName, modelDesc, modelSchemaDesign, boilerplate, otherConstants, }: RequestConstantProps) => string;
|
|
15
|
+
interface RequestViewProps {
|
|
16
|
+
sysName: string;
|
|
17
|
+
modelName: string;
|
|
18
|
+
modelDesc: string;
|
|
19
|
+
modelSchemaDesign: string;
|
|
20
|
+
boilerplate: string;
|
|
21
|
+
paths: Map<string, {
|
|
22
|
+
filePath: string;
|
|
23
|
+
}>;
|
|
24
|
+
}
|
|
25
|
+
export declare const requestView: ({ sysName, modelName, modelDesc, modelSchemaDesign, boilerplate, paths, }: RequestViewProps) => string;
|
|
15
26
|
export {};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type App, type Lib, type Sys, Workspace } from "@akanjs/devkit";
|
|
2
2
|
export declare class ModuleRunner {
|
|
3
|
-
createModule(workspace: Workspace, moduleName: string): Promise<void>;
|
|
3
|
+
createModule(workspace: Workspace, sysType: "app" | "lib", sysName: string, moduleName: string, description: string): Promise<void>;
|
|
4
4
|
removeModule(workspace: Workspace, name: string): Promise<void>;
|
|
5
5
|
createScalarTemplate(sys: Sys, name: string): Promise<{
|
|
6
6
|
constant: {
|
|
@@ -12,6 +12,52 @@ export declare class ModuleRunner {
|
|
|
12
12
|
content: string;
|
|
13
13
|
};
|
|
14
14
|
}>;
|
|
15
|
+
createModuleTemplate(sys: Sys, name: string): Promise<{
|
|
16
|
+
constant: {
|
|
17
|
+
filename: string;
|
|
18
|
+
content: string;
|
|
19
|
+
};
|
|
20
|
+
dictionary: {
|
|
21
|
+
filename: string;
|
|
22
|
+
content: string;
|
|
23
|
+
};
|
|
24
|
+
service: {
|
|
25
|
+
filename: string;
|
|
26
|
+
content: string;
|
|
27
|
+
};
|
|
28
|
+
store: {
|
|
29
|
+
filename: string;
|
|
30
|
+
content: string;
|
|
31
|
+
};
|
|
32
|
+
signal: {
|
|
33
|
+
filename: string;
|
|
34
|
+
content: string;
|
|
35
|
+
};
|
|
36
|
+
test: {
|
|
37
|
+
filename: string;
|
|
38
|
+
content: string;
|
|
39
|
+
};
|
|
40
|
+
unit: {
|
|
41
|
+
filename: string;
|
|
42
|
+
content: string;
|
|
43
|
+
};
|
|
44
|
+
view: {
|
|
45
|
+
filename: string;
|
|
46
|
+
content: string;
|
|
47
|
+
};
|
|
48
|
+
template: {
|
|
49
|
+
filename: string;
|
|
50
|
+
content: string;
|
|
51
|
+
};
|
|
52
|
+
zone: {
|
|
53
|
+
filename: string;
|
|
54
|
+
content: string;
|
|
55
|
+
};
|
|
56
|
+
util: {
|
|
57
|
+
filename: string;
|
|
58
|
+
content: string;
|
|
59
|
+
};
|
|
60
|
+
}>;
|
|
15
61
|
createUnit(sys: App | Lib, modelName: string): Promise<void>;
|
|
16
62
|
createView(sys: App | Lib, modelName: string): Promise<void>;
|
|
17
63
|
}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { type Sys, Workspace } from "@akanjs/devkit";
|
|
2
2
|
export declare class ModuleScript {
|
|
3
3
|
#private;
|
|
4
|
-
createModule(
|
|
4
|
+
createModule(sys: Sys): Promise<void>;
|
|
5
5
|
removeModule(workspace: Workspace, name: string): Promise<void>;
|
|
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
9
|
createUnit(workspace: Workspace, type: "app" | "lib", appOrLibName: string, modelName: string): Promise<void>;
|
|
10
|
-
createView(
|
|
10
|
+
createView(sys: Sys): Promise<void>;
|
|
11
11
|
}
|
|
@@ -85,6 +85,7 @@ export declare class SysExecutor extends Executor {
|
|
|
85
85
|
getDatabaseModules(): Promise<string[]>;
|
|
86
86
|
getServiceModules(): Promise<string[]>;
|
|
87
87
|
getScalarModules(): Promise<string[]>;
|
|
88
|
+
getViewModules(): Promise<string[]>;
|
|
88
89
|
getScalarConstantFiles(): Promise<{
|
|
89
90
|
filepath: string;
|
|
90
91
|
content: string;
|