@akanjs/cli 0.0.142 → 0.0.144
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/README.md +8 -0
- package/cjs/index.js +2437 -3204
- package/cjs/src/guidelines/___library/sharedUiStructureDescription.en.md +786 -0
- package/cjs/src/guidelines/___library/utilUiStructureDescription.en.md +395 -0
- package/cjs/src/guidelines/___lint/lintRuleDescription.en.md +64 -0
- package/cjs/src/guidelines/___module/moduleStructureDescription.en.md +80 -0
- package/cjs/src/guidelines/componentRule/componentRule.instruction.md +732 -0
- package/cjs/src/guidelines/databaseModule/databaseModule.instruction.md +691 -0
- package/cjs/src/guidelines/enumConstant/enumConstant.instruction.md +232 -0
- package/cjs/src/guidelines/fieldDecorator/fieldDecorator.instruction.md +611 -0
- package/cjs/src/guidelines/framework/framework.instruction.md +1112 -0
- package/cjs/src/guidelines/modelConstant/modelConstant.instruction.md +958 -0
- package/cjs/src/guidelines/modelDictionary/modelDictionary.instruction.md +583 -0
- package/cjs/src/guidelines/modelDocument/modelDocument.instruction.md +683 -0
- package/cjs/src/guidelines/modelService/modelService.instruction.md +935 -0
- package/cjs/src/guidelines/modelSignal/modelSignal.instruction.md +588 -0
- package/cjs/src/guidelines/modelStore/modelStore.instruction.md +591 -0
- package/cjs/src/guidelines/modelTemplate/modelTemplate.instruction.md +577 -0
- package/cjs/src/guidelines/modelUnit/modelUnit.instruction.md +833 -0
- package/cjs/src/guidelines/modelUtil/modelUtil.instruction.md +752 -0
- package/cjs/src/guidelines/modelView/modelView.instruction.md +1005 -0
- package/cjs/src/guidelines/modelZone/modelZone.instruction.md +528 -0
- package/cjs/src/guidelines/scalarConstant/scalarConstant.instruction.md +489 -0
- package/cjs/src/guidelines/scalarDictionary/scalarDictionary.instruction.md +347 -0
- package/cjs/src/guidelines/sharedUiUsage/sharedUiUsage.instruction.md +318 -0
- package/cjs/src/guidelines/utilUiUsage/utilUiUsage.instruction.md +339 -0
- package/cjs/src/templates/module/__model__.dictionary.js +4 -5
- package/esm/index.js +2524 -3286
- package/esm/src/guidelines/___library/sharedUiStructureDescription.en.md +786 -0
- package/esm/src/guidelines/___library/utilUiStructureDescription.en.md +395 -0
- package/esm/src/guidelines/___lint/lintRuleDescription.en.md +64 -0
- package/esm/src/guidelines/___module/moduleStructureDescription.en.md +80 -0
- package/esm/src/guidelines/componentRule/componentRule.instruction.md +732 -0
- package/esm/src/guidelines/databaseModule/databaseModule.instruction.md +691 -0
- package/esm/src/guidelines/enumConstant/enumConstant.instruction.md +232 -0
- package/esm/src/guidelines/fieldDecorator/fieldDecorator.instruction.md +611 -0
- package/esm/src/guidelines/framework/framework.instruction.md +1112 -0
- package/esm/src/guidelines/modelConstant/modelConstant.instruction.md +958 -0
- package/esm/src/guidelines/modelDictionary/modelDictionary.instruction.md +583 -0
- package/esm/src/guidelines/modelDocument/modelDocument.instruction.md +683 -0
- package/esm/src/guidelines/modelService/modelService.instruction.md +935 -0
- package/esm/src/guidelines/modelSignal/modelSignal.instruction.md +588 -0
- package/esm/src/guidelines/modelStore/modelStore.instruction.md +591 -0
- package/esm/src/guidelines/modelTemplate/modelTemplate.instruction.md +577 -0
- package/esm/src/guidelines/modelUnit/modelUnit.instruction.md +833 -0
- package/esm/src/guidelines/modelUtil/modelUtil.instruction.md +752 -0
- package/esm/src/guidelines/modelView/modelView.instruction.md +1005 -0
- package/esm/src/guidelines/modelZone/modelZone.instruction.md +528 -0
- package/esm/src/guidelines/scalarConstant/scalarConstant.instruction.md +489 -0
- package/esm/src/guidelines/scalarDictionary/scalarDictionary.instruction.md +347 -0
- package/esm/src/guidelines/sharedUiUsage/sharedUiUsage.instruction.md +318 -0
- package/esm/src/guidelines/utilUiUsage/utilUiUsage.instruction.md +339 -0
- package/esm/src/templates/module/__model__.dictionary.js +4 -5
- package/package.json +3 -1
- package/src/guideline/guideline.command.d.ts +7 -0
- package/src/guideline/guideline.prompt.d.ts +15 -0
- package/src/guideline/guideline.runner.d.ts +5 -0
- package/src/guideline/guideline.script.d.ts +6 -0
- package/src/guidelines/___library/sharedUiStructureDescription.en.md +786 -0
- package/src/guidelines/___library/utilUiStructureDescription.en.md +395 -0
- package/src/guidelines/___lint/lintRuleDescription.en.md +64 -0
- package/src/guidelines/___module/moduleStructureDescription.en.md +80 -0
- package/src/guidelines/componentRule/componentRule.instruction.md +732 -0
- package/src/guidelines/databaseModule/databaseModule.instruction.md +691 -0
- package/src/guidelines/enumConstant/enumConstant.instruction.md +232 -0
- package/src/guidelines/fieldDecorator/fieldDecorator.instruction.md +611 -0
- package/src/guidelines/framework/framework.instruction.md +1112 -0
- package/src/guidelines/modelConstant/modelConstant.instruction.md +958 -0
- package/src/guidelines/modelDictionary/modelDictionary.instruction.md +583 -0
- package/src/guidelines/modelDocument/modelDocument.instruction.md +683 -0
- package/src/guidelines/modelService/modelService.instruction.md +935 -0
- package/src/guidelines/modelSignal/modelSignal.instruction.md +588 -0
- package/src/guidelines/modelStore/modelStore.instruction.md +591 -0
- package/src/guidelines/modelTemplate/modelTemplate.instruction.md +577 -0
- package/src/guidelines/modelUnit/modelUnit.instruction.md +833 -0
- package/src/guidelines/modelUtil/modelUtil.instruction.md +752 -0
- package/src/guidelines/modelView/modelView.instruction.md +1005 -0
- package/src/guidelines/modelZone/modelZone.instruction.md +528 -0
- package/src/guidelines/scalarConstant/scalarConstant.instruction.md +489 -0
- package/src/guidelines/scalarDictionary/scalarDictionary.instruction.md +347 -0
- package/src/guidelines/sharedUiUsage/sharedUiUsage.instruction.md +318 -0
- package/src/guidelines/utilUiUsage/utilUiUsage.instruction.md +339 -0
- package/src/module/module.command.d.ts +6 -8
- package/src/module/module.prompt.d.ts +2 -15
- package/src/module/module.request.d.ts +22 -18
- package/src/module/module.runner.d.ts +4 -20
- package/src/module/module.script.d.ts +6 -7
- package/src/scalar/scalar.command.d.ts +7 -0
- package/src/scalar/scalar.prompt.d.ts +23 -0
- package/src/scalar/scalar.runner.d.ts +13 -0
- package/src/scalar/scalar.script.d.ts +6 -0
- package/cjs/src/templates/app/app/[lang]/(__appName__)/(public)/forgotpassword/page.js +0 -47
- package/cjs/src/templates/app/app/[lang]/(__appName__)/(public)/page.js +0 -128
- package/cjs/src/templates/app/app/[lang]/(__appName__)/(public)/privacy/page.js +0 -42
- package/cjs/src/templates/app/app/[lang]/(__appName__)/(public)/signin/page.js +0 -50
- package/cjs/src/templates/app/app/[lang]/(__appName__)/(public)/termsofservice/page.js +0 -41
- package/cjs/src/templates/app/app/[lang]/(__appName__)/(public)/unknown/page.js +0 -51
- package/cjs/src/templates/app/app/[lang]/(__appName__)/(user)/layout.js +0 -43
- package/cjs/src/templates/app/app/[lang]/(__appName__)/(user)/self/page.js +0 -60
- package/cjs/src/templates/app/app/[lang]/(__appName__)/layout.js +0 -54
- package/cjs/src/templates/app/app/[lang]/(__appName__)/styles.css.template +0 -19
- package/cjs/src/templates/app/app/[lang]/admin/layout.js +0 -54
- package/cjs/src/templates/app/app/[lang]/admin/page.js +0 -63
- package/cjs/src/templates/app/app/csr.js +0 -34
- package/cjs/src/templates/app/app/index.html.template +0 -13
- package/cjs/src/templates/app/app/layout.js +0 -38
- package/cjs/src/templates/app/capacitor.config.ts.template +0 -8
- package/cjs/src/templates/app/env/env.client.debug.ts.template +0 -7
- package/cjs/src/templates/app/env/env.client.develop.ts.template +0 -7
- package/cjs/src/templates/app/env/env.client.local.ts.template +0 -7
- package/cjs/src/templates/app/env/env.client.main.ts.template +0 -7
- package/cjs/src/templates/app/env/env.client.testing.ts.template +0 -7
- package/cjs/src/templates/app/env/env.server.debug.ts.template +0 -15
- package/cjs/src/templates/app/env/env.server.develop.ts.template +0 -15
- package/cjs/src/templates/app/env/env.server.local.ts.template +0 -15
- package/cjs/src/templates/app/env/env.server.main.ts.template +0 -15
- package/cjs/src/templates/app/env/env.server.testing.ts.template +0 -7
- package/cjs/src/templates/app/lib/setting/Setting.Template.js +0 -57
- package/cjs/src/templates/app/lib/setting/Setting.Unit.js +0 -38
- package/cjs/src/templates/app/lib/setting/Setting.Util.js +0 -34
- package/cjs/src/templates/app/lib/setting/Setting.View.js +0 -51
- package/cjs/src/templates/app/lib/setting/Setting.Zone.js +0 -80
- package/cjs/src/templates/app/lib/setting/index.js +0 -61
- package/cjs/src/templates/app/lib/summary/Summary.Template.js +0 -43
- package/cjs/src/templates/app/lib/summary/Summary.Unit.js +0 -38
- package/cjs/src/templates/app/lib/summary/Summary.Util.js +0 -33
- package/cjs/src/templates/app/lib/summary/Summary.View.js +0 -51
- package/cjs/src/templates/app/lib/summary/Summary.Zone.js +0 -62
- package/cjs/src/templates/app/lib/summary/index.js +0 -67
- package/cjs/src/templates/app/lib/user/User.Template.js +0 -65
- package/cjs/src/templates/app/lib/user/User.Unit.js +0 -38
- package/cjs/src/templates/app/lib/user/User.Util.js +0 -94
- package/cjs/src/templates/app/lib/user/User.View.js +0 -66
- package/cjs/src/templates/app/lib/user/User.Zone.js +0 -74
- package/cjs/src/templates/app/lib/user/index.js +0 -61
- package/cjs/src/templates/app/page.test.ts.template +0 -10
- package/cjs/src/templates/app/playwright.config.ts.template +0 -6
- package/cjs/src/templates/app/postcss.config.js.template +0 -10
- package/cjs/src/templates/app/public/manifest.json.template +0 -67
- package/cjs/src/templates/app/tsconfig.json.template +0 -22
- package/cjs/src/templates/app/tsconfig.spec.json.template +0 -7
- package/cjs/src/templates/app/ui/Footer.js +0 -67
- package/cjs/src/templates/app/ui/MainHeader.js +0 -131
- package/cjs/src/templates/crudPages/[__model__Id]/edit/page.js +0 -73
- package/cjs/src/templates/crudPages/[__model__Id]/page.js +0 -83
- package/cjs/src/templates/crudPages/new/page.js +0 -70
- package/cjs/src/templates/crudPages/page.js +0 -71
- package/cjs/src/templates/libRoot/.gitignore.template +0 -15
- package/cjs/src/templates/libRoot/env/env.server.example.ts.template +0 -7
- package/cjs/src/templates/libRoot/env/env.server.testing.ts.template +0 -7
- package/cjs/src/templates/libRoot/lib/setting/Setting.Template.js +0 -57
- package/cjs/src/templates/libRoot/lib/setting/Setting.Unit.js +0 -38
- package/cjs/src/templates/libRoot/lib/setting/Setting.Util.js +0 -34
- package/cjs/src/templates/libRoot/lib/setting/Setting.View.js +0 -51
- package/cjs/src/templates/libRoot/lib/setting/Setting.Zone.js +0 -80
- package/cjs/src/templates/libRoot/lib/setting/index.js +0 -61
- package/cjs/src/templates/libRoot/lib/summary/Summary.Template.js +0 -43
- package/cjs/src/templates/libRoot/lib/summary/Summary.Unit.js +0 -38
- package/cjs/src/templates/libRoot/lib/summary/Summary.Util.js +0 -33
- package/cjs/src/templates/libRoot/lib/summary/Summary.View.js +0 -51
- package/cjs/src/templates/libRoot/lib/summary/Summary.Zone.js +0 -62
- package/cjs/src/templates/libRoot/lib/summary/index.js +0 -67
- package/cjs/src/templates/libRoot/lib/user/User.Template.js +0 -65
- package/cjs/src/templates/libRoot/lib/user/User.Unit.js +0 -38
- package/cjs/src/templates/libRoot/lib/user/User.Util.js +0 -94
- package/cjs/src/templates/libRoot/lib/user/User.View.js +0 -66
- package/cjs/src/templates/libRoot/lib/user/User.Zone.js +0 -74
- package/cjs/src/templates/libRoot/lib/user/index.js +0 -61
- package/cjs/src/templates/libRoot/package.json.template +0 -4
- package/cjs/src/templates/libRoot/tsconfig.json.template +0 -13
- package/cjs/src/templates/libRoot/tsconfig.spec.json.template +0 -7
- package/cjs/src/templates/localDev/docker-compose.yaml.template +0 -36
- package/cjs/src/templates/module/__Model__.Template.js +0 -54
- package/cjs/src/templates/module/__Model__.Unit.js +0 -42
- package/cjs/src/templates/module/__Model__.Util.js +0 -70
- package/cjs/src/templates/module/__Model__.View.js +0 -48
- package/cjs/src/templates/module/__Model__.Zone.js +0 -83
- package/cjs/src/templates/module/index.js +0 -61
- package/cjs/src/templates/pkgRoot/tsconfig.json.template +0 -15
- package/cjs/src/templates/workspaceRoot/.env.template +0 -20
- package/cjs/src/templates/workspaceRoot/.gitignore.template +0 -118
- package/cjs/src/templates/workspaceRoot/.prettierignore.template +0 -10
- package/cjs/src/templates/workspaceRoot/.prettierrc.json.template +0 -6
- package/cjs/src/templates/workspaceRoot/.swcrc.template +0 -9
- package/cjs/src/templates/workspaceRoot/.vscode/settings.json.template +0 -13
- package/cjs/src/templates/workspaceRoot/README.md.template +0 -37
- package/cjs/src/templates/workspaceRoot/eslint.config.ts.template +0 -3
- package/cjs/src/templates/workspaceRoot/package.json.template +0 -43
- package/cjs/src/templates/workspaceRoot/tsconfig.json.template +0 -29
- package/esm/src/templates/app/app/[lang]/(__appName__)/(public)/forgotpassword/page.js +0 -27
- package/esm/src/templates/app/app/[lang]/(__appName__)/(public)/page.js +0 -108
- package/esm/src/templates/app/app/[lang]/(__appName__)/(public)/privacy/page.js +0 -22
- package/esm/src/templates/app/app/[lang]/(__appName__)/(public)/signin/page.js +0 -30
- package/esm/src/templates/app/app/[lang]/(__appName__)/(public)/termsofservice/page.js +0 -21
- package/esm/src/templates/app/app/[lang]/(__appName__)/(public)/unknown/page.js +0 -31
- package/esm/src/templates/app/app/[lang]/(__appName__)/(user)/layout.js +0 -23
- package/esm/src/templates/app/app/[lang]/(__appName__)/(user)/self/page.js +0 -40
- package/esm/src/templates/app/app/[lang]/(__appName__)/layout.js +0 -34
- package/esm/src/templates/app/app/[lang]/(__appName__)/styles.css.template +0 -19
- package/esm/src/templates/app/app/[lang]/admin/layout.js +0 -34
- package/esm/src/templates/app/app/[lang]/admin/page.js +0 -43
- package/esm/src/templates/app/app/csr.js +0 -14
- package/esm/src/templates/app/app/index.html.template +0 -13
- package/esm/src/templates/app/app/layout.js +0 -18
- package/esm/src/templates/app/capacitor.config.ts.template +0 -8
- package/esm/src/templates/app/env/env.client.debug.ts.template +0 -7
- package/esm/src/templates/app/env/env.client.develop.ts.template +0 -7
- package/esm/src/templates/app/env/env.client.local.ts.template +0 -7
- package/esm/src/templates/app/env/env.client.main.ts.template +0 -7
- package/esm/src/templates/app/env/env.client.testing.ts.template +0 -7
- package/esm/src/templates/app/env/env.server.debug.ts.template +0 -15
- package/esm/src/templates/app/env/env.server.develop.ts.template +0 -15
- package/esm/src/templates/app/env/env.server.local.ts.template +0 -15
- package/esm/src/templates/app/env/env.server.main.ts.template +0 -15
- package/esm/src/templates/app/env/env.server.testing.ts.template +0 -7
- package/esm/src/templates/app/lib/setting/Setting.Template.js +0 -37
- package/esm/src/templates/app/lib/setting/Setting.Unit.js +0 -18
- package/esm/src/templates/app/lib/setting/Setting.Util.js +0 -14
- package/esm/src/templates/app/lib/setting/Setting.View.js +0 -31
- package/esm/src/templates/app/lib/setting/Setting.Zone.js +0 -60
- package/esm/src/templates/app/lib/setting/index.js +0 -41
- package/esm/src/templates/app/lib/summary/Summary.Template.js +0 -23
- package/esm/src/templates/app/lib/summary/Summary.Unit.js +0 -18
- package/esm/src/templates/app/lib/summary/Summary.Util.js +0 -13
- package/esm/src/templates/app/lib/summary/Summary.View.js +0 -31
- package/esm/src/templates/app/lib/summary/Summary.Zone.js +0 -42
- package/esm/src/templates/app/lib/summary/index.js +0 -47
- package/esm/src/templates/app/lib/user/User.Template.js +0 -45
- package/esm/src/templates/app/lib/user/User.Unit.js +0 -18
- package/esm/src/templates/app/lib/user/User.Util.js +0 -74
- package/esm/src/templates/app/lib/user/User.View.js +0 -46
- package/esm/src/templates/app/lib/user/User.Zone.js +0 -54
- package/esm/src/templates/app/lib/user/index.js +0 -41
- package/esm/src/templates/app/page.test.ts.template +0 -10
- package/esm/src/templates/app/playwright.config.ts.template +0 -6
- package/esm/src/templates/app/postcss.config.js.template +0 -10
- package/esm/src/templates/app/public/manifest.json.template +0 -67
- package/esm/src/templates/app/tsconfig.json.template +0 -22
- package/esm/src/templates/app/tsconfig.spec.json.template +0 -7
- package/esm/src/templates/app/ui/Footer.js +0 -47
- package/esm/src/templates/app/ui/MainHeader.js +0 -111
- package/esm/src/templates/crudPages/[__model__Id]/edit/page.js +0 -53
- package/esm/src/templates/crudPages/[__model__Id]/page.js +0 -63
- package/esm/src/templates/crudPages/new/page.js +0 -50
- package/esm/src/templates/crudPages/page.js +0 -51
- package/esm/src/templates/libRoot/.gitignore.template +0 -15
- package/esm/src/templates/libRoot/env/env.server.example.ts.template +0 -7
- package/esm/src/templates/libRoot/env/env.server.testing.ts.template +0 -7
- package/esm/src/templates/libRoot/lib/setting/Setting.Template.js +0 -37
- package/esm/src/templates/libRoot/lib/setting/Setting.Unit.js +0 -18
- package/esm/src/templates/libRoot/lib/setting/Setting.Util.js +0 -14
- package/esm/src/templates/libRoot/lib/setting/Setting.View.js +0 -31
- package/esm/src/templates/libRoot/lib/setting/Setting.Zone.js +0 -60
- package/esm/src/templates/libRoot/lib/setting/index.js +0 -41
- package/esm/src/templates/libRoot/lib/summary/Summary.Template.js +0 -23
- package/esm/src/templates/libRoot/lib/summary/Summary.Unit.js +0 -18
- package/esm/src/templates/libRoot/lib/summary/Summary.Util.js +0 -13
- package/esm/src/templates/libRoot/lib/summary/Summary.View.js +0 -31
- package/esm/src/templates/libRoot/lib/summary/Summary.Zone.js +0 -42
- package/esm/src/templates/libRoot/lib/summary/index.js +0 -47
- package/esm/src/templates/libRoot/lib/user/User.Template.js +0 -45
- package/esm/src/templates/libRoot/lib/user/User.Unit.js +0 -18
- package/esm/src/templates/libRoot/lib/user/User.Util.js +0 -74
- package/esm/src/templates/libRoot/lib/user/User.View.js +0 -46
- package/esm/src/templates/libRoot/lib/user/User.Zone.js +0 -54
- package/esm/src/templates/libRoot/lib/user/index.js +0 -41
- package/esm/src/templates/libRoot/package.json.template +0 -4
- package/esm/src/templates/libRoot/tsconfig.json.template +0 -13
- package/esm/src/templates/libRoot/tsconfig.spec.json.template +0 -7
- package/esm/src/templates/localDev/docker-compose.yaml.template +0 -36
- package/esm/src/templates/module/__Model__.Template.js +0 -34
- package/esm/src/templates/module/__Model__.Unit.js +0 -22
- package/esm/src/templates/module/__Model__.Util.js +0 -50
- package/esm/src/templates/module/__Model__.View.js +0 -28
- package/esm/src/templates/module/__Model__.Zone.js +0 -63
- package/esm/src/templates/module/index.js +0 -41
- package/esm/src/templates/pkgRoot/tsconfig.json.template +0 -15
- package/esm/src/templates/workspaceRoot/.env.template +0 -20
- package/esm/src/templates/workspaceRoot/.gitignore.template +0 -118
- package/esm/src/templates/workspaceRoot/.prettierignore.template +0 -10
- package/esm/src/templates/workspaceRoot/.prettierrc.json.template +0 -6
- package/esm/src/templates/workspaceRoot/.swcrc.template +0 -9
- package/esm/src/templates/workspaceRoot/.vscode/settings.json.template +0 -13
- package/esm/src/templates/workspaceRoot/README.md.template +0 -37
- package/esm/src/templates/workspaceRoot/eslint.config.ts.template +0 -3
- package/esm/src/templates/workspaceRoot/package.json.template +0 -43
- package/esm/src/templates/workspaceRoot/tsconfig.json.template +0 -29
- package/src/application/application.prompt.d.ts +0 -2
- package/src/templates/app/app/[lang]/(__appName__)/(public)/forgotpassword/page.d.ts +0 -9
- package/src/templates/app/app/[lang]/(__appName__)/(public)/page.d.ts +0 -9
- package/src/templates/app/app/[lang]/(__appName__)/(public)/privacy/page.d.ts +0 -9
- package/src/templates/app/app/[lang]/(__appName__)/(public)/signin/page.d.ts +0 -9
- package/src/templates/app/app/[lang]/(__appName__)/(public)/termsofservice/page.d.ts +0 -10
- package/src/templates/app/app/[lang]/(__appName__)/(public)/unknown/page.d.ts +0 -9
- package/src/templates/app/app/[lang]/(__appName__)/(user)/layout.d.ts +0 -9
- package/src/templates/app/app/[lang]/(__appName__)/(user)/self/page.d.ts +0 -9
- package/src/templates/app/app/[lang]/(__appName__)/layout.d.ts +0 -9
- package/src/templates/app/app/[lang]/admin/layout.d.ts +0 -9
- package/src/templates/app/app/[lang]/admin/page.d.ts +0 -9
- package/src/templates/app/app/csr.d.ts +0 -9
- package/src/templates/app/app/layout.d.ts +0 -9
- package/src/templates/app/lib/setting/Setting.Template.d.ts +0 -9
- package/src/templates/app/lib/setting/Setting.Unit.d.ts +0 -9
- package/src/templates/app/lib/setting/Setting.Util.d.ts +0 -9
- package/src/templates/app/lib/setting/Setting.View.d.ts +0 -9
- package/src/templates/app/lib/setting/Setting.Zone.d.ts +0 -9
- package/src/templates/app/lib/setting/index.d.ts +0 -9
- package/src/templates/app/lib/summary/Summary.Template.d.ts +0 -9
- package/src/templates/app/lib/summary/Summary.Unit.d.ts +0 -9
- package/src/templates/app/lib/summary/Summary.Util.d.ts +0 -9
- package/src/templates/app/lib/summary/Summary.View.d.ts +0 -9
- package/src/templates/app/lib/summary/Summary.Zone.d.ts +0 -9
- package/src/templates/app/lib/summary/index.d.ts +0 -9
- package/src/templates/app/lib/user/User.Template.d.ts +0 -9
- package/src/templates/app/lib/user/User.Unit.d.ts +0 -9
- package/src/templates/app/lib/user/User.Util.d.ts +0 -9
- package/src/templates/app/lib/user/User.View.d.ts +0 -9
- package/src/templates/app/lib/user/User.Zone.d.ts +0 -9
- package/src/templates/app/lib/user/index.d.ts +0 -9
- package/src/templates/app/ui/Footer.d.ts +0 -9
- package/src/templates/app/ui/MainHeader.d.ts +0 -10
- package/src/templates/crudPages/[__model__Id]/edit/page.d.ts +0 -11
- package/src/templates/crudPages/[__model__Id]/page.d.ts +0 -11
- package/src/templates/crudPages/new/page.d.ts +0 -11
- package/src/templates/crudPages/page.d.ts +0 -11
- package/src/templates/libRoot/lib/setting/Setting.Template.d.ts +0 -9
- package/src/templates/libRoot/lib/setting/Setting.Unit.d.ts +0 -9
- package/src/templates/libRoot/lib/setting/Setting.Util.d.ts +0 -9
- package/src/templates/libRoot/lib/setting/Setting.View.d.ts +0 -9
- package/src/templates/libRoot/lib/setting/Setting.Zone.d.ts +0 -9
- package/src/templates/libRoot/lib/setting/index.d.ts +0 -9
- package/src/templates/libRoot/lib/summary/Summary.Template.d.ts +0 -9
- package/src/templates/libRoot/lib/summary/Summary.Unit.d.ts +0 -9
- package/src/templates/libRoot/lib/summary/Summary.Util.d.ts +0 -9
- package/src/templates/libRoot/lib/summary/Summary.View.d.ts +0 -9
- package/src/templates/libRoot/lib/summary/Summary.Zone.d.ts +0 -9
- package/src/templates/libRoot/lib/summary/index.d.ts +0 -9
- package/src/templates/libRoot/lib/user/User.Template.d.ts +0 -9
- package/src/templates/libRoot/lib/user/User.Unit.d.ts +0 -9
- package/src/templates/libRoot/lib/user/User.Util.d.ts +0 -9
- package/src/templates/libRoot/lib/user/User.View.d.ts +0 -9
- package/src/templates/libRoot/lib/user/User.Zone.d.ts +0 -9
- package/src/templates/libRoot/lib/user/index.d.ts +0 -9
- package/src/templates/module/__Model__.Template.d.ts +0 -11
- package/src/templates/module/__Model__.Unit.d.ts +0 -11
- package/src/templates/module/__Model__.Util.d.ts +0 -11
- package/src/templates/module/__Model__.View.d.ts +0 -11
- package/src/templates/module/__Model__.Zone.d.ts +0 -11
- package/src/templates/module/index.d.ts +0 -11
|
@@ -0,0 +1,958 @@
|
|
|
1
|
+
# Akan.js Model Constant Implementation Guide
|
|
2
|
+
|
|
3
|
+
## Purpose and Role of Model Constant Files
|
|
4
|
+
|
|
5
|
+
Model constant files (`model.constant.ts`) serve as the foundation of the Akan.js framework by:
|
|
6
|
+
|
|
7
|
+
- Defining data structures for database schemas
|
|
8
|
+
- Generating GraphQL types for API interfaces
|
|
9
|
+
- Configuring validation rules for input data
|
|
10
|
+
- Establishing relationships between entities
|
|
11
|
+
- Supporting search indexing and optimization
|
|
12
|
+
- Enabling type-safe data manipulation
|
|
13
|
+
- Creating a single source of truth for the data model
|
|
14
|
+
|
|
15
|
+
## Model Class Hierarchy and Relationships
|
|
16
|
+
|
|
17
|
+
Akan.js uses a multi-tiered model architecture with clear inheritance patterns:
|
|
18
|
+
|
|
19
|
+
```
|
|
20
|
+
┌───────────────┐
|
|
21
|
+
│ ModelInput │
|
|
22
|
+
└───────┬───────┘
|
|
23
|
+
│
|
|
24
|
+
▼
|
|
25
|
+
┌───────────────┐
|
|
26
|
+
│ ModelObject │
|
|
27
|
+
└───┬───────────┘
|
|
28
|
+
│
|
|
29
|
+
┌─────────────────┬─┴───┬─────────────────┐
|
|
30
|
+
│ │ │ │
|
|
31
|
+
▼ ▼ ▼ ▼
|
|
32
|
+
┌───────────────────┐ ┌─────────┐ ┌─────────┐ ┌─────────────┐
|
|
33
|
+
│ ModelFilter │ │ Model │ │LightMod.│ │ModelInsight │
|
|
34
|
+
└───────────────────┘ └─────────┘ └─────────┘ └─────────────┘
|
|
35
|
+
│
|
|
36
|
+
▼
|
|
37
|
+
┌───────────────┐
|
|
38
|
+
│ModelSummary │
|
|
39
|
+
└───────────────┘
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Each model type serves a specific purpose in the data lifecycle:
|
|
43
|
+
|
|
44
|
+
1. **Input Model**: User-provided data for create/update operations
|
|
45
|
+
2. **Object Model**: Input + system-managed fields
|
|
46
|
+
3. **Light Model**: Subset of Object for listings/references
|
|
47
|
+
4. **Full Model**: Complete model for database schema
|
|
48
|
+
5. **Filter Model**: Query methods and sorting options
|
|
49
|
+
6. **Insight Model**: Aggregation fields for analytics
|
|
50
|
+
7. **Summary Model**: Dashboard statistics and counters
|
|
51
|
+
|
|
52
|
+
## File Structure and Organization
|
|
53
|
+
|
|
54
|
+
```typescript
|
|
55
|
+
// 1. Imports
|
|
56
|
+
import { enumOf, ID, Int } from "@akanjs/base";
|
|
57
|
+
import { Field, Filter, Model, sortOf, via } from "@akanjs/constant";
|
|
58
|
+
import { LightRelatedModel } from "../related/related.constant";
|
|
59
|
+
|
|
60
|
+
// 2. Enums
|
|
61
|
+
export const StatusEnum = enumOf(["active", "inactive"] as const);
|
|
62
|
+
export type StatusEnum = enumOf<typeof StatusEnum>;
|
|
63
|
+
|
|
64
|
+
// 3. Input Model
|
|
65
|
+
@Model.Input("ProductInput")
|
|
66
|
+
export class ProductInput {
|
|
67
|
+
// User-editable fields
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// 4. Object Model
|
|
71
|
+
@Model.Object("ProductObject")
|
|
72
|
+
export class ProductObject extends via(ProductInput) {
|
|
73
|
+
// System fields
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// 5. Light Model
|
|
77
|
+
@Model.Light("LightProduct")
|
|
78
|
+
export class LightProduct extends via(ProductObject, ["id", "name", "price"] as const) {}
|
|
79
|
+
|
|
80
|
+
// 6. Full Model
|
|
81
|
+
@Model.Full("Product")
|
|
82
|
+
export class Product extends via(ProductObject, LightProduct) {}
|
|
83
|
+
|
|
84
|
+
// 7. Insight Model (optional)
|
|
85
|
+
@Model.Insight("ProductInsight")
|
|
86
|
+
export class ProductInsight {
|
|
87
|
+
// Aggregation fields
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// 8. Summary Model (optional)
|
|
91
|
+
@Model.Summary("ProductSummary")
|
|
92
|
+
export class ProductSummary {
|
|
93
|
+
// Summary statistics
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// 9. Filter Model
|
|
97
|
+
@Model.Filter("ProductFilter")
|
|
98
|
+
export class ProductFilter extends sortOf(Product, {
|
|
99
|
+
newest: { createdAt: -1 },
|
|
100
|
+
}) {
|
|
101
|
+
// Query methods
|
|
102
|
+
}
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
## Required Imports
|
|
106
|
+
|
|
107
|
+
```typescript
|
|
108
|
+
// Base types
|
|
109
|
+
import { enumOf, ID, Int, Float, String, Boolean, Date, type Dayjs, dayjs, JSON } from "@akanjs/base";
|
|
110
|
+
|
|
111
|
+
// Model decorators
|
|
112
|
+
import { Field, Filter, Model, sortOf, via } from "@akanjs/constant";
|
|
113
|
+
|
|
114
|
+
// Related models (use Light models to prevent circular dependencies)
|
|
115
|
+
import { LightCategory } from "../category/category.constant";
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## Enum Definition Patterns
|
|
119
|
+
|
|
120
|
+
Enums should be defined with `enumOf()` and exported as both const and type:
|
|
121
|
+
|
|
122
|
+
```typescript
|
|
123
|
+
// Define enum with camelCase values (preferred)
|
|
124
|
+
export const StatusEnum = enumOf([
|
|
125
|
+
"active",
|
|
126
|
+
"inactive",
|
|
127
|
+
"pending"
|
|
128
|
+
] as const);
|
|
129
|
+
|
|
130
|
+
// Export as type for TypeScript
|
|
131
|
+
export type StatusEnum = enumOf<typeof StatusEnum>;
|
|
132
|
+
|
|
133
|
+
// Usage in fields
|
|
134
|
+
@Field.Prop(() => String, {
|
|
135
|
+
enum: StatusEnum,
|
|
136
|
+
default: "active"
|
|
137
|
+
})
|
|
138
|
+
status: StatusEnum;
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
## ModelInput Implementation
|
|
142
|
+
|
|
143
|
+
The Input model defines fields that users can create or update:
|
|
144
|
+
|
|
145
|
+
```typescript
|
|
146
|
+
@Model.Input("ProductInput")
|
|
147
|
+
export class ProductInput {
|
|
148
|
+
@Field.Prop(() => String, {
|
|
149
|
+
minlength: 3,
|
|
150
|
+
maxlength: 100,
|
|
151
|
+
})
|
|
152
|
+
name: string;
|
|
153
|
+
|
|
154
|
+
@Field.Prop(() => Int, {
|
|
155
|
+
min: 0,
|
|
156
|
+
default: 0,
|
|
157
|
+
})
|
|
158
|
+
price: number;
|
|
159
|
+
|
|
160
|
+
@Field.Prop(() => String, {
|
|
161
|
+
nullable: true,
|
|
162
|
+
maxlength: 1000,
|
|
163
|
+
})
|
|
164
|
+
description: string | null;
|
|
165
|
+
|
|
166
|
+
@Field.Prop(() => LightCategory, {
|
|
167
|
+
ref: "Category",
|
|
168
|
+
})
|
|
169
|
+
category: LightCategory;
|
|
170
|
+
}
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
Key characteristics:
|
|
174
|
+
|
|
175
|
+
- Contains only user-editable fields
|
|
176
|
+
- Includes validation rules (min, max, etc.)
|
|
177
|
+
- Uses nullable fields for optional data
|
|
178
|
+
- References other models with Light variants
|
|
179
|
+
- No system-generated fields (id, timestamps)
|
|
180
|
+
|
|
181
|
+
## ModelObject Implementation
|
|
182
|
+
|
|
183
|
+
The Object model extends Input with system-managed fields:
|
|
184
|
+
|
|
185
|
+
```typescript
|
|
186
|
+
@Model.Object("ProductObject")
|
|
187
|
+
export class ProductObject extends via(ProductInput) {
|
|
188
|
+
@Field.Prop(() => String, {
|
|
189
|
+
enum: StatusEnum,
|
|
190
|
+
default: "active",
|
|
191
|
+
})
|
|
192
|
+
status: StatusEnum;
|
|
193
|
+
|
|
194
|
+
@Field.Prop(() => Int, {
|
|
195
|
+
default: 0,
|
|
196
|
+
min: 0,
|
|
197
|
+
})
|
|
198
|
+
viewCount: number;
|
|
199
|
+
|
|
200
|
+
@Field.Hidden(() => String, {
|
|
201
|
+
nullable: true,
|
|
202
|
+
})
|
|
203
|
+
internalNotes: string | null;
|
|
204
|
+
|
|
205
|
+
@Field.Secret(() => String, {
|
|
206
|
+
nullable: true,
|
|
207
|
+
})
|
|
208
|
+
apiKey: string | null;
|
|
209
|
+
}
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
Key characteristics:
|
|
213
|
+
|
|
214
|
+
- Inherits all Input model fields via `via()`
|
|
215
|
+
- Adds system-managed fields like status
|
|
216
|
+
- Can include counters and metrics
|
|
217
|
+
- May include hidden fields with `Field.Hidden`
|
|
218
|
+
- May include sensitive data with `Field.Secret`
|
|
219
|
+
|
|
220
|
+
## LightModel Implementation
|
|
221
|
+
|
|
222
|
+
The Light model defines a subset of fields for listings and references:
|
|
223
|
+
|
|
224
|
+
```typescript
|
|
225
|
+
@Model.Light("LightProduct")
|
|
226
|
+
export class LightProduct extends via(ProductObject, ["id", "name", "price", "status", "category"] as const) {}
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
Key characteristics:
|
|
230
|
+
|
|
231
|
+
- Selects essential fields from Object model
|
|
232
|
+
- Uses `as const` assertion for type safety
|
|
233
|
+
- Always includes `id` field
|
|
234
|
+
- Optimized for listings and relationships
|
|
235
|
+
- No additional fields, only selection
|
|
236
|
+
|
|
237
|
+
## Full Model Implementation
|
|
238
|
+
|
|
239
|
+
The Full model combines Object and Light models for database schema:
|
|
240
|
+
|
|
241
|
+
```typescript
|
|
242
|
+
@Model.Full("Product")
|
|
243
|
+
export class Product extends via(ProductObject, LightProduct) {}
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
Key characteristics:
|
|
247
|
+
|
|
248
|
+
- Usually empty implementation
|
|
249
|
+
- Combines Object and Light models
|
|
250
|
+
- Used for database schema generation
|
|
251
|
+
- Primary model for CRUD operations
|
|
252
|
+
- Name should match the base entity (no suffix)
|
|
253
|
+
|
|
254
|
+
## Insight Model Implementation
|
|
255
|
+
|
|
256
|
+
The Insight model defines fields for analytics and aggregation:
|
|
257
|
+
|
|
258
|
+
```typescript
|
|
259
|
+
@Model.Insight("ProductInsight")
|
|
260
|
+
export class ProductInsight {
|
|
261
|
+
@Field.Prop(() => Int, {
|
|
262
|
+
default: 0,
|
|
263
|
+
accumulate: { $sum: 1 },
|
|
264
|
+
})
|
|
265
|
+
count: number;
|
|
266
|
+
|
|
267
|
+
@Field.Prop(() => Int, {
|
|
268
|
+
default: 0,
|
|
269
|
+
accumulate: { $sum: "$price" },
|
|
270
|
+
})
|
|
271
|
+
totalSales: number;
|
|
272
|
+
|
|
273
|
+
@Field.Prop(() => Float, {
|
|
274
|
+
default: 0,
|
|
275
|
+
accumulate: { $avg: "$price" },
|
|
276
|
+
})
|
|
277
|
+
averagePrice: number;
|
|
278
|
+
}
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
Key characteristics:
|
|
282
|
+
|
|
283
|
+
- Uses MongoDB accumulator operators
|
|
284
|
+
- Defines metrics and KPIs
|
|
285
|
+
- Supports data analytics
|
|
286
|
+
- Fields typically have numeric types
|
|
287
|
+
- Often has count, sum, avg operations
|
|
288
|
+
|
|
289
|
+
## Summary Model Implementation
|
|
290
|
+
|
|
291
|
+
The Summary model defines dashboard statistics:
|
|
292
|
+
|
|
293
|
+
```typescript
|
|
294
|
+
@Model.Summary("ProductSummary")
|
|
295
|
+
export class ProductSummary {
|
|
296
|
+
@Field.Prop(() => Int, {
|
|
297
|
+
min: 0,
|
|
298
|
+
default: 0,
|
|
299
|
+
query: {},
|
|
300
|
+
})
|
|
301
|
+
totalProducts: number;
|
|
302
|
+
|
|
303
|
+
@Field.Prop(() => Int, {
|
|
304
|
+
min: 0,
|
|
305
|
+
default: 0,
|
|
306
|
+
query: { status: "active" },
|
|
307
|
+
})
|
|
308
|
+
activeProducts: number;
|
|
309
|
+
|
|
310
|
+
@Field.Prop(() => Float, {
|
|
311
|
+
default: 0,
|
|
312
|
+
query: { price: { $gt: 0 } },
|
|
313
|
+
})
|
|
314
|
+
averagePrice: number;
|
|
315
|
+
}
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
Key characteristics:
|
|
319
|
+
|
|
320
|
+
- Defines summary statistics for dashboards
|
|
321
|
+
- Uses `query` option to filter records
|
|
322
|
+
- Provides high-level metrics
|
|
323
|
+
- May combine data from multiple models
|
|
324
|
+
- Often uses queries to filter record sets
|
|
325
|
+
|
|
326
|
+
## Filter Model Implementation
|
|
327
|
+
|
|
328
|
+
The Filter model defines query operations and sorting options:
|
|
329
|
+
|
|
330
|
+
```typescript
|
|
331
|
+
@Model.Filter("ProductFilter")
|
|
332
|
+
export class ProductFilter extends sortOf(Product, {
|
|
333
|
+
newest: { createdAt: -1 },
|
|
334
|
+
oldest: { createdAt: 1 },
|
|
335
|
+
cheapest: { price: 1 },
|
|
336
|
+
expensive: { price: -1 },
|
|
337
|
+
}) {
|
|
338
|
+
@Filter.Mongo()
|
|
339
|
+
byStatus(
|
|
340
|
+
@Filter.Arg("status", () => String, {
|
|
341
|
+
enum: StatusEnum,
|
|
342
|
+
default: "active",
|
|
343
|
+
})
|
|
344
|
+
status: StatusEnum
|
|
345
|
+
) {
|
|
346
|
+
return { status };
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
@Filter.Mongo()
|
|
350
|
+
inCategory(
|
|
351
|
+
@Filter.Arg("categoryId", () => ID, {
|
|
352
|
+
ref: "Category",
|
|
353
|
+
renderOption: (cat: LightCategory) => cat.name,
|
|
354
|
+
})
|
|
355
|
+
categoryId: string
|
|
356
|
+
) {
|
|
357
|
+
return { category: categoryId };
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
@Filter.Mongo()
|
|
361
|
+
priceRange(
|
|
362
|
+
@Filter.Arg("min", () => Int, { min: 0, default: 0 })
|
|
363
|
+
min: number,
|
|
364
|
+
|
|
365
|
+
@Filter.Arg("max", () => Int, { min: 0, nullable: true })
|
|
366
|
+
max: number | null
|
|
367
|
+
) {
|
|
368
|
+
const query: Record<string, any> = { price: { $gte: min } };
|
|
369
|
+
if (max !== null) {
|
|
370
|
+
query.price.$lte = max;
|
|
371
|
+
}
|
|
372
|
+
return query;
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
Key characteristics:
|
|
378
|
+
|
|
379
|
+
- Extends with `sortOf()` to define sorting options
|
|
380
|
+
- Uses `@Filter.Mongo()` for query methods
|
|
381
|
+
- Defines parameters with `@Filter.Arg()`
|
|
382
|
+
- Returns MongoDB query objects
|
|
383
|
+
- Can have complex query logic
|
|
384
|
+
- Supports references with `ref` option
|
|
385
|
+
|
|
386
|
+
## Field Decorators and Options
|
|
387
|
+
|
|
388
|
+
Field decorators configure property behavior:
|
|
389
|
+
|
|
390
|
+
```typescript
|
|
391
|
+
// Standard field (visible in API and DB)
|
|
392
|
+
@Field.Prop(() => String, { options })
|
|
393
|
+
name: string;
|
|
394
|
+
|
|
395
|
+
// Hidden field (DB only, not in API)
|
|
396
|
+
@Field.Hidden(() => JSON, { options })
|
|
397
|
+
metadata: Record<string, any>;
|
|
398
|
+
|
|
399
|
+
// Sensitive field (not selected by default)
|
|
400
|
+
@Field.Secret(() => String, { options })
|
|
401
|
+
apiKey: string;
|
|
402
|
+
|
|
403
|
+
// Computed field (not stored in DB)
|
|
404
|
+
@Field.Resolve(() => Int)
|
|
405
|
+
get total(): number {
|
|
406
|
+
return this.quantity * this.price;
|
|
407
|
+
}
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
Common field options:
|
|
411
|
+
|
|
412
|
+
| Option | Type | Description | Example |
|
|
413
|
+
| ----------- | ---------- | ------------------------ | -------------------------- |
|
|
414
|
+
| `default` | `any` | Default value | `{ default: 0 }` |
|
|
415
|
+
| `nullable` | `boolean` | Allows null | `{ nullable: true }` |
|
|
416
|
+
| `enum` | `Enum` | Restricts to enum values | `{ enum: StatusEnum }` |
|
|
417
|
+
| `min` | `number` | Minimum value | `{ min: 0 }` |
|
|
418
|
+
| `max` | `number` | Maximum value | `{ max: 100 }` |
|
|
419
|
+
| `minlength` | `number` | Minimum string length | `{ minlength: 3 }` |
|
|
420
|
+
| `maxlength` | `number` | Maximum string length | `{ maxlength: 255 }` |
|
|
421
|
+
| `ref` | `string` | Reference to model | `{ ref: "Category" }` |
|
|
422
|
+
| `refPath` | `string` | Dynamic reference path | `{ refPath: "modelType" }` |
|
|
423
|
+
| `immutable` | `boolean` | Cannot be changed | `{ immutable: true }` |
|
|
424
|
+
| `validate` | `function` | Custom validation | `{ validate: isEmail }` |
|
|
425
|
+
| `text` | `string` | Search configuration | `{ text: "search" }` |
|
|
426
|
+
|
|
427
|
+
## Filter Decorators and Arguments
|
|
428
|
+
|
|
429
|
+
Filter decorators define query methods:
|
|
430
|
+
|
|
431
|
+
```typescript
|
|
432
|
+
// MongoDB query
|
|
433
|
+
@Filter.Mongo()
|
|
434
|
+
byStatus(
|
|
435
|
+
@Filter.Arg("status", () => String, {
|
|
436
|
+
enum: StatusEnum,
|
|
437
|
+
default: "active"
|
|
438
|
+
})
|
|
439
|
+
status: StatusEnum
|
|
440
|
+
) {
|
|
441
|
+
return { status };
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
// Meilisearch query
|
|
445
|
+
@Filter.Meili()
|
|
446
|
+
searchText(
|
|
447
|
+
@Filter.Arg("query", () => String)
|
|
448
|
+
query: string
|
|
449
|
+
) {
|
|
450
|
+
return { q: query };
|
|
451
|
+
}
|
|
452
|
+
```
|
|
453
|
+
|
|
454
|
+
Filter argument options:
|
|
455
|
+
|
|
456
|
+
| Option | Description | Example |
|
|
457
|
+
| -------------- | ------------------------ | --------------------------------- |
|
|
458
|
+
| `enum` | Restricts to enum values | `{ enum: StatusEnum }` |
|
|
459
|
+
| `default` | Default value | `{ default: "active" }` |
|
|
460
|
+
| `nullable` | Allows null | `{ nullable: true }` |
|
|
461
|
+
| `ref` | Reference to model | `{ ref: "Category" }` |
|
|
462
|
+
| `renderOption` | Display function | `{ renderOption: (x) => x.name }` |
|
|
463
|
+
|
|
464
|
+
## Inheritance with via() and sortOf()
|
|
465
|
+
|
|
466
|
+
Akan.js uses utility functions for model inheritance:
|
|
467
|
+
|
|
468
|
+
```typescript
|
|
469
|
+
// Inherit all fields from Input model
|
|
470
|
+
extends via(ProductInput)
|
|
471
|
+
|
|
472
|
+
// Inherit specific fields from Object model
|
|
473
|
+
extends via(ProductObject, [
|
|
474
|
+
"id", "name", "price"
|
|
475
|
+
] as const)
|
|
476
|
+
|
|
477
|
+
// Inherit both Object and Light models
|
|
478
|
+
extends via(ProductObject, LightProduct)
|
|
479
|
+
|
|
480
|
+
// Define sorting options
|
|
481
|
+
extends sortOf(Product, {
|
|
482
|
+
newest: { createdAt: -1 },
|
|
483
|
+
cheapest: { price: 1 }
|
|
484
|
+
})
|
|
485
|
+
```
|
|
486
|
+
|
|
487
|
+
Key points:
|
|
488
|
+
|
|
489
|
+
- `via()` handles field inheritance
|
|
490
|
+
- Field selection uses `as const` for type safety
|
|
491
|
+
- `sortOf()` configures sorting options for filters
|
|
492
|
+
- Sort order: 1 for ascending, -1 for descending
|
|
493
|
+
|
|
494
|
+
## Working with References to Other Models
|
|
495
|
+
|
|
496
|
+
Models can reference other models in several ways:
|
|
497
|
+
|
|
498
|
+
```typescript
|
|
499
|
+
// Basic reference
|
|
500
|
+
@Field.Prop(() => LightCategory, { ref: "Category" })
|
|
501
|
+
category: LightCategory;
|
|
502
|
+
|
|
503
|
+
// Array of references
|
|
504
|
+
@Field.Prop(() => [LightTag], { ref: "Tag" })
|
|
505
|
+
tags: LightTag[];
|
|
506
|
+
|
|
507
|
+
// Optional reference
|
|
508
|
+
@Field.Prop(() => LightUser, {
|
|
509
|
+
ref: "User",
|
|
510
|
+
nullable: true
|
|
511
|
+
})
|
|
512
|
+
assignedTo: LightUser | null;
|
|
513
|
+
|
|
514
|
+
// Dynamic reference (polymorphic)
|
|
515
|
+
@Field.Prop(() => String, { enum: ModelType })
|
|
516
|
+
modelType: ModelType;
|
|
517
|
+
|
|
518
|
+
@Field.Prop(() => LightModel, { refPath: "modelType" })
|
|
519
|
+
model: LightModel;
|
|
520
|
+
|
|
521
|
+
// Parent-child relationship
|
|
522
|
+
@Field.Prop(() => LightProject, {
|
|
523
|
+
ref: "Project",
|
|
524
|
+
refType: "parent"
|
|
525
|
+
})
|
|
526
|
+
project: LightProject;
|
|
527
|
+
```
|
|
528
|
+
|
|
529
|
+
Key points:
|
|
530
|
+
|
|
531
|
+
- Always use Light models for references
|
|
532
|
+
- Set `ref` to the model name string
|
|
533
|
+
- Use arrays for one-to-many relationships
|
|
534
|
+
- Use `refPath` for polymorphic relationships
|
|
535
|
+
- Set `refType` for relationship semantics
|
|
536
|
+
|
|
537
|
+
## Validation Rules and Constraints
|
|
538
|
+
|
|
539
|
+
Add validation to ensure data integrity:
|
|
540
|
+
|
|
541
|
+
```typescript
|
|
542
|
+
// Numeric range validation
|
|
543
|
+
@Field.Prop(() => Int, { min: 0, max: 100 })
|
|
544
|
+
score: number;
|
|
545
|
+
|
|
546
|
+
// String length validation
|
|
547
|
+
@Field.Prop(() => String, { minlength: 3, maxlength: 50 })
|
|
548
|
+
username: string;
|
|
549
|
+
|
|
550
|
+
// Format validation
|
|
551
|
+
@Field.Prop(() => String, { type: "email" })
|
|
552
|
+
email: string;
|
|
553
|
+
|
|
554
|
+
// Custom validation function
|
|
555
|
+
@Field.Prop(() => String, {
|
|
556
|
+
validate: (value, model) => {
|
|
557
|
+
return /^[A-Z][a-z]+$/.test(value);
|
|
558
|
+
}
|
|
559
|
+
})
|
|
560
|
+
properName: string;
|
|
561
|
+
```
|
|
562
|
+
|
|
563
|
+
## Type Safety Considerations
|
|
564
|
+
|
|
565
|
+
Ensure type safety across the model:
|
|
566
|
+
|
|
567
|
+
```typescript
|
|
568
|
+
// 1. Use proper types for fields
|
|
569
|
+
@Field.Prop(() => Int)
|
|
570
|
+
count: number; // TypeScript type matches decorator type
|
|
571
|
+
|
|
572
|
+
// 2. Mark arrays as const for Light models
|
|
573
|
+
extends via(ProductObject, [
|
|
574
|
+
"id", "name"
|
|
575
|
+
] as const) // Type-safe field selection
|
|
576
|
+
|
|
577
|
+
// 3. Handle nullable fields correctly
|
|
578
|
+
@Field.Prop(() => String, { nullable: true })
|
|
579
|
+
description: string | null; // Include union with null
|
|
580
|
+
|
|
581
|
+
// 4. Export enum types
|
|
582
|
+
export type StatusEnum = enumOf<typeof StatusEnum>;
|
|
583
|
+
|
|
584
|
+
// 5. Use precise array types
|
|
585
|
+
@Field.Prop(() => [Int])
|
|
586
|
+
scores: number[]; // Array of integers
|
|
587
|
+
```
|
|
588
|
+
|
|
589
|
+
## Common Mistakes and Solutions
|
|
590
|
+
|
|
591
|
+
### 1. Missing Field Type
|
|
592
|
+
|
|
593
|
+
```typescript
|
|
594
|
+
// ❌ Wrong (missing type function)
|
|
595
|
+
@Field.Prop(String)
|
|
596
|
+
name: string;
|
|
597
|
+
|
|
598
|
+
// ✅ Correct
|
|
599
|
+
@Field.Prop(() => String)
|
|
600
|
+
name: string;
|
|
601
|
+
```
|
|
602
|
+
|
|
603
|
+
### 2. Incorrect Array Type
|
|
604
|
+
|
|
605
|
+
```typescript
|
|
606
|
+
// ❌ Wrong (using Array<T> syntax)
|
|
607
|
+
@Field.Prop(() => Array<String>)
|
|
608
|
+
tags: string[];
|
|
609
|
+
|
|
610
|
+
// ✅ Correct
|
|
611
|
+
@Field.Prop(() => [String])
|
|
612
|
+
tags: string[];
|
|
613
|
+
```
|
|
614
|
+
|
|
615
|
+
### 3. Missing Const Assertion
|
|
616
|
+
|
|
617
|
+
```typescript
|
|
618
|
+
// ❌ Wrong (missing as const)
|
|
619
|
+
extends via(ProductObject, ["id", "name"])
|
|
620
|
+
|
|
621
|
+
// ✅ Correct
|
|
622
|
+
extends via(ProductObject, ["id", "name"] as const)
|
|
623
|
+
```
|
|
624
|
+
|
|
625
|
+
### 4. Missing Nullable Type
|
|
626
|
+
|
|
627
|
+
```typescript
|
|
628
|
+
// ❌ Wrong (missing null in type)
|
|
629
|
+
@Field.Prop(() => String, { nullable: true })
|
|
630
|
+
description: string;
|
|
631
|
+
|
|
632
|
+
// ✅ Correct
|
|
633
|
+
@Field.Prop(() => String, { nullable: true })
|
|
634
|
+
description: string | null;
|
|
635
|
+
```
|
|
636
|
+
|
|
637
|
+
### 5. Circular Dependencies
|
|
638
|
+
|
|
639
|
+
```typescript
|
|
640
|
+
// ❌ Wrong (circular dependency)
|
|
641
|
+
import { Product } from "../product/product.constant";
|
|
642
|
+
|
|
643
|
+
// ✅ Correct
|
|
644
|
+
import { LightProduct } from "../product/product.constant";
|
|
645
|
+
```
|
|
646
|
+
|
|
647
|
+
### 6. Missing Default for Arrays
|
|
648
|
+
|
|
649
|
+
```typescript
|
|
650
|
+
// ❌ Wrong (no default for array)
|
|
651
|
+
@Field.Prop(() => [String])
|
|
652
|
+
tags: string[];
|
|
653
|
+
|
|
654
|
+
// ✅ Correct
|
|
655
|
+
@Field.Prop(() => [String], { default: [] })
|
|
656
|
+
tags: string[];
|
|
657
|
+
```
|
|
658
|
+
|
|
659
|
+
## Best Practices for Maintainable Models
|
|
660
|
+
|
|
661
|
+
1. **Follow the standard model hierarchy**
|
|
662
|
+
|
|
663
|
+
- Create all model types in the recommended order
|
|
664
|
+
- Use inheritance properly with `via()` and `sortOf()`
|
|
665
|
+
|
|
666
|
+
2. **Keep models focused**
|
|
667
|
+
|
|
668
|
+
- Each model should represent a single entity
|
|
669
|
+
- Split complex models into related entities
|
|
670
|
+
|
|
671
|
+
3. **Use proper naming conventions**
|
|
672
|
+
|
|
673
|
+
- File: `camelCase.constant.ts`
|
|
674
|
+
- Classes: `PascalCase` with type suffix
|
|
675
|
+
- Fields: `camelCase`
|
|
676
|
+
- Enums: `PascalCase` with `Enum` suffix
|
|
677
|
+
|
|
678
|
+
4. **Add appropriate defaults**
|
|
679
|
+
|
|
680
|
+
- Set reasonable defaults for required fields
|
|
681
|
+
- Use empty arrays for array fields: `{ default: [] }`
|
|
682
|
+
- Use function defaults for dates: `{ default: () => dayjs() }`
|
|
683
|
+
|
|
684
|
+
5. **Implement proper validation**
|
|
685
|
+
|
|
686
|
+
- Add min/max for numbers
|
|
687
|
+
- Add minlength/maxlength for strings
|
|
688
|
+
- Use custom validation for complex rules
|
|
689
|
+
|
|
690
|
+
6. **Optimize Light models**
|
|
691
|
+
|
|
692
|
+
- Include only essential fields
|
|
693
|
+
- Always include `id` field
|
|
694
|
+
- Keep them small for efficient API responses
|
|
695
|
+
|
|
696
|
+
7. **Document complex fields**
|
|
697
|
+
|
|
698
|
+
- Add comments for non-obvious fields
|
|
699
|
+
- Explain validation rules when complex
|
|
700
|
+
|
|
701
|
+
8. **Use appropriate Field decorators**
|
|
702
|
+
|
|
703
|
+
- `Field.Prop` for standard fields
|
|
704
|
+
- `Field.Hidden` for internal data
|
|
705
|
+
- `Field.Secret` for sensitive data
|
|
706
|
+
- `Field.Resolve` for computed properties
|
|
707
|
+
|
|
708
|
+
9. **Handle references correctly**
|
|
709
|
+
|
|
710
|
+
- Always use Light models for references
|
|
711
|
+
- Set proper `ref` option to model name
|
|
712
|
+
- Use `refPath` for polymorphic references
|
|
713
|
+
|
|
714
|
+
10. **Export everything needed**
|
|
715
|
+
- Export all models and enums
|
|
716
|
+
- Export type definitions for enums
|
|
717
|
+
|
|
718
|
+
## Complete Example with All Model Types
|
|
719
|
+
|
|
720
|
+
```typescript
|
|
721
|
+
// File: apps/ecommerce/lib/product/product.constant.ts
|
|
722
|
+
import { enumOf, ID, Int, Float, type Dayjs, dayjs } from "@akanjs/base";
|
|
723
|
+
import { Field, Filter, Model, sortOf, via } from "@akanjs/constant";
|
|
724
|
+
|
|
725
|
+
import { LightCategory } from "../category/category.constant";
|
|
726
|
+
import { LightUser } from "../user/user.constant";
|
|
727
|
+
|
|
728
|
+
// Enums
|
|
729
|
+
export const ProductStatus = enumOf(["draft", "active", "outOfStock", "discontinued"] as const);
|
|
730
|
+
export type ProductStatus = enumOf<typeof ProductStatus>;
|
|
731
|
+
|
|
732
|
+
// Input Model
|
|
733
|
+
@Model.Input("ProductInput")
|
|
734
|
+
export class ProductInput {
|
|
735
|
+
@Field.Prop(() => String, {
|
|
736
|
+
minlength: 3,
|
|
737
|
+
maxlength: 100,
|
|
738
|
+
})
|
|
739
|
+
name: string;
|
|
740
|
+
|
|
741
|
+
@Field.Prop(() => String, {
|
|
742
|
+
nullable: true,
|
|
743
|
+
maxlength: 1000,
|
|
744
|
+
})
|
|
745
|
+
description: string | null;
|
|
746
|
+
|
|
747
|
+
@Field.Prop(() => Float, {
|
|
748
|
+
min: 0,
|
|
749
|
+
default: 0,
|
|
750
|
+
})
|
|
751
|
+
price: number;
|
|
752
|
+
|
|
753
|
+
@Field.Prop(() => Int, {
|
|
754
|
+
min: 0,
|
|
755
|
+
default: 0,
|
|
756
|
+
})
|
|
757
|
+
stock: number;
|
|
758
|
+
|
|
759
|
+
@Field.Prop(() => LightCategory, {
|
|
760
|
+
ref: "Category",
|
|
761
|
+
})
|
|
762
|
+
category: LightCategory;
|
|
763
|
+
|
|
764
|
+
@Field.Prop(() => [String], {
|
|
765
|
+
default: [],
|
|
766
|
+
})
|
|
767
|
+
tags: string[];
|
|
768
|
+
|
|
769
|
+
@Field.Prop(() => String, {
|
|
770
|
+
nullable: true,
|
|
771
|
+
})
|
|
772
|
+
imageUrl: string | null;
|
|
773
|
+
}
|
|
774
|
+
|
|
775
|
+
// Object Model
|
|
776
|
+
@Model.Object("ProductObject")
|
|
777
|
+
export class ProductObject extends via(ProductInput) {
|
|
778
|
+
@Field.Prop(() => String, {
|
|
779
|
+
enum: ProductStatus,
|
|
780
|
+
default: "draft",
|
|
781
|
+
})
|
|
782
|
+
status: ProductStatus;
|
|
783
|
+
|
|
784
|
+
@Field.Prop(() => LightUser, {
|
|
785
|
+
ref: "User",
|
|
786
|
+
})
|
|
787
|
+
createdBy: LightUser;
|
|
788
|
+
|
|
789
|
+
@Field.Prop(() => Int, {
|
|
790
|
+
default: 0,
|
|
791
|
+
min: 0,
|
|
792
|
+
})
|
|
793
|
+
viewCount: number;
|
|
794
|
+
|
|
795
|
+
@Field.Prop(() => Date, {
|
|
796
|
+
default: () => dayjs(),
|
|
797
|
+
immutable: true,
|
|
798
|
+
})
|
|
799
|
+
launchDate: Dayjs;
|
|
800
|
+
|
|
801
|
+
@Field.Hidden(() => String, {
|
|
802
|
+
nullable: true,
|
|
803
|
+
})
|
|
804
|
+
internalNotes: string | null;
|
|
805
|
+
}
|
|
806
|
+
|
|
807
|
+
// Light Model
|
|
808
|
+
@Model.Light("LightProduct")
|
|
809
|
+
export class LightProduct extends via(ProductObject, [
|
|
810
|
+
"id",
|
|
811
|
+
"name",
|
|
812
|
+
"price",
|
|
813
|
+
"imageUrl",
|
|
814
|
+
"status",
|
|
815
|
+
"category",
|
|
816
|
+
] as const) {}
|
|
817
|
+
|
|
818
|
+
// Full Model
|
|
819
|
+
@Model.Full("Product")
|
|
820
|
+
export class Product extends via(ProductObject, LightProduct) {}
|
|
821
|
+
|
|
822
|
+
// Insight Model
|
|
823
|
+
@Model.Insight("ProductInsight")
|
|
824
|
+
export class ProductInsight {
|
|
825
|
+
@Field.Prop(() => Int, {
|
|
826
|
+
default: 0,
|
|
827
|
+
accumulate: { $sum: 1 },
|
|
828
|
+
})
|
|
829
|
+
count: number;
|
|
830
|
+
|
|
831
|
+
@Field.Prop(() => Float, {
|
|
832
|
+
default: 0,
|
|
833
|
+
accumulate: { $sum: "$price" },
|
|
834
|
+
})
|
|
835
|
+
totalValue: number;
|
|
836
|
+
|
|
837
|
+
@Field.Prop(() => Int, {
|
|
838
|
+
default: 0,
|
|
839
|
+
accumulate: { $sum: "$viewCount" },
|
|
840
|
+
})
|
|
841
|
+
totalViews: number;
|
|
842
|
+
}
|
|
843
|
+
|
|
844
|
+
// Summary Model
|
|
845
|
+
@Model.Summary("ProductSummary")
|
|
846
|
+
export class ProductSummary {
|
|
847
|
+
@Field.Prop(() => Int, {
|
|
848
|
+
min: 0,
|
|
849
|
+
default: 0,
|
|
850
|
+
query: {},
|
|
851
|
+
})
|
|
852
|
+
totalProducts: number;
|
|
853
|
+
|
|
854
|
+
@Field.Prop(() => Int, {
|
|
855
|
+
min: 0,
|
|
856
|
+
default: 0,
|
|
857
|
+
query: { status: "active" },
|
|
858
|
+
})
|
|
859
|
+
activeProducts: number;
|
|
860
|
+
|
|
861
|
+
@Field.Prop(() => Int, {
|
|
862
|
+
min: 0,
|
|
863
|
+
default: 0,
|
|
864
|
+
query: { stock: { $lte: 0 } },
|
|
865
|
+
})
|
|
866
|
+
outOfStockProducts: number;
|
|
867
|
+
}
|
|
868
|
+
|
|
869
|
+
// Filter Model
|
|
870
|
+
@Model.Filter("ProductFilter")
|
|
871
|
+
export class ProductFilter extends sortOf(Product, {
|
|
872
|
+
newest: { createdAt: -1 },
|
|
873
|
+
oldest: { createdAt: 1 },
|
|
874
|
+
cheapest: { price: 1 },
|
|
875
|
+
expensive: { price: -1 },
|
|
876
|
+
popular: { viewCount: -1 },
|
|
877
|
+
}) {
|
|
878
|
+
@Filter.Mongo()
|
|
879
|
+
byStatus(
|
|
880
|
+
@Filter.Arg("status", () => String, {
|
|
881
|
+
enum: ProductStatus,
|
|
882
|
+
default: "active",
|
|
883
|
+
})
|
|
884
|
+
status: ProductStatus
|
|
885
|
+
) {
|
|
886
|
+
return { status };
|
|
887
|
+
}
|
|
888
|
+
|
|
889
|
+
@Filter.Mongo()
|
|
890
|
+
inCategory(
|
|
891
|
+
@Filter.Arg("categoryId", () => ID, {
|
|
892
|
+
ref: "Category",
|
|
893
|
+
renderOption: (cat: LightCategory) => cat.name,
|
|
894
|
+
})
|
|
895
|
+
categoryId: string
|
|
896
|
+
) {
|
|
897
|
+
return { category: categoryId };
|
|
898
|
+
}
|
|
899
|
+
|
|
900
|
+
@Filter.Mongo()
|
|
901
|
+
hasTag(
|
|
902
|
+
@Filter.Arg("tag", () => String)
|
|
903
|
+
tag: string
|
|
904
|
+
) {
|
|
905
|
+
return { tags: tag };
|
|
906
|
+
}
|
|
907
|
+
|
|
908
|
+
@Filter.Mongo()
|
|
909
|
+
priceRange(
|
|
910
|
+
@Filter.Arg("min", () => Float, {
|
|
911
|
+
min: 0,
|
|
912
|
+
default: 0,
|
|
913
|
+
})
|
|
914
|
+
min: number,
|
|
915
|
+
|
|
916
|
+
@Filter.Arg("max", () => Float, {
|
|
917
|
+
min: 0,
|
|
918
|
+
nullable: true,
|
|
919
|
+
})
|
|
920
|
+
max: number | null
|
|
921
|
+
) {
|
|
922
|
+
const query: Record<string, any> = { price: { $gte: min } };
|
|
923
|
+
if (max !== null) {
|
|
924
|
+
query.price.$lte = max;
|
|
925
|
+
}
|
|
926
|
+
return query;
|
|
927
|
+
}
|
|
928
|
+
|
|
929
|
+
@Filter.Mongo()
|
|
930
|
+
inStock() {
|
|
931
|
+
return { stock: { $gt: 0 } };
|
|
932
|
+
}
|
|
933
|
+
|
|
934
|
+
@Filter.Meili()
|
|
935
|
+
searchText(
|
|
936
|
+
@Filter.Arg("query", () => String)
|
|
937
|
+
query: string
|
|
938
|
+
) {
|
|
939
|
+
return { q: query };
|
|
940
|
+
}
|
|
941
|
+
}
|
|
942
|
+
```
|
|
943
|
+
|
|
944
|
+
## Summary Checklist
|
|
945
|
+
|
|
946
|
+
1. **Structure**: Follow the model hierarchy (Input → Object → Light/Full → Filter/Summary/Insight)
|
|
947
|
+
2. **Naming**: Use consistent class naming (ModelInput, ModelObject, LightModel, Model)
|
|
948
|
+
3. **Enums**: Define with `enumOf()` and export both const and type
|
|
949
|
+
4. **Fields**: Use `Field.Prop` with appropriate options
|
|
950
|
+
5. **Validation**: Add constraints (min, max, minlength, maxlength)
|
|
951
|
+
6. **Defaults**: Set appropriate defaults, especially for arrays
|
|
952
|
+
7. **References**: Use Light models with proper `ref` option
|
|
953
|
+
8. **Light Models**: Select essential fields with `as const` assertion
|
|
954
|
+
9. **Full Models**: Combine Object and Light models
|
|
955
|
+
10. **Filter Models**: Define sort options and query methods
|
|
956
|
+
11. **Insight/Summary**: Add aggregation and summary fields
|
|
957
|
+
12. **Type Safety**: Ensure TypeScript types match field definitions
|
|
958
|
+
13. **Exports**: Export all models and enums
|