@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,588 @@
|
|
|
1
|
+
# Model Signal Implementation Guide for Akan.js
|
|
2
|
+
|
|
3
|
+
## Purpose and Role of Model Signal Files
|
|
4
|
+
|
|
5
|
+
`model.signal.ts` files serve as the communication bridge between client and server in Akan.js applications. They implement a declarative pattern that simplifies and standardizes data flow throughout your application, while providing strong typing and automatic code generation.
|
|
6
|
+
|
|
7
|
+
Signals provide five key functionalities:
|
|
8
|
+
|
|
9
|
+
1. **Data Queries** (`@Query`) - Fetch data with typed parameters and responses
|
|
10
|
+
2. **Data Mutations** (`@Mutation`) - Modify data with transactional safety
|
|
11
|
+
3. **Real-time Messaging** (`@Message`) - Handle WebSocket communication
|
|
12
|
+
4. **Background Processing** (`@Process`) - Execute long-running jobs
|
|
13
|
+
5. **Publish/Subscribe** (`@Pubsub`) - Manage real-time data subscriptions
|
|
14
|
+
|
|
15
|
+
The Signal system abstracts away the underlying transport mechanisms (GraphQL, REST, WebSockets) while maintaining type safety across client and server.
|
|
16
|
+
|
|
17
|
+
## Signal Class Structure
|
|
18
|
+
|
|
19
|
+
A typical model.signal.ts file follows this structure:
|
|
20
|
+
|
|
21
|
+
```typescript
|
|
22
|
+
import { ID, Int } from "@akanjs/base";
|
|
23
|
+
import { SortOf } from "@akanjs/constant";
|
|
24
|
+
import { Arg, DbSignal, Mutation, Query, resolve, Self, Signal } from "@akanjs/signal";
|
|
25
|
+
|
|
26
|
+
import { cnst, Srvs } from "../cnst";
|
|
27
|
+
import type * as db from "../db";
|
|
28
|
+
|
|
29
|
+
@Signal(() => cnst.ModelName)
|
|
30
|
+
export class ModelNameSignal extends DbSignal(cnst.modelNameCnst, Srvs, {
|
|
31
|
+
guards: { get: Query.Public, cru: Mutation.User },
|
|
32
|
+
}) {
|
|
33
|
+
// Signal methods here...
|
|
34
|
+
}
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Key components:
|
|
38
|
+
|
|
39
|
+
- `@Signal()` decorator defines this class as a signal provider
|
|
40
|
+
- `DbSignal()` higher-order function provides standard CRUD operations
|
|
41
|
+
- `guards` option configures default access control for CRUD operations
|
|
42
|
+
- Service references are injected from `Srvs` imported from cnst.ts
|
|
43
|
+
|
|
44
|
+
## Decorator Reference
|
|
45
|
+
|
|
46
|
+
### 1. @Query Decorator
|
|
47
|
+
|
|
48
|
+
Used for read-only operations with access control levels:
|
|
49
|
+
|
|
50
|
+
```typescript
|
|
51
|
+
@Query.Public(() => [cnst.Product]) // Public access, returns array of Products
|
|
52
|
+
async productListInFeatured(
|
|
53
|
+
@Arg.Query("skip", () => Int, { nullable: true }) skip: number | null,
|
|
54
|
+
@Arg.Query("limit", () => Int, { nullable: true }) limit: number | null,
|
|
55
|
+
@Arg.Query("sort", () => String, { nullable: true }) sort: SortOf<cnst.ProductFilter> | null
|
|
56
|
+
) {
|
|
57
|
+
const products = await this.productService.listFeatured({ skip, limit, sort });
|
|
58
|
+
return resolve<cnst.Product[]>(products); // Type-safe resolution
|
|
59
|
+
}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Access control levels:
|
|
63
|
+
|
|
64
|
+
- `Query.Public` - Available to unauthenticated users
|
|
65
|
+
- `Query.User` - Requires user authentication
|
|
66
|
+
- `Query.Admin` - Requires admin access
|
|
67
|
+
- `Query.SuperAdmin` - Requires super admin access
|
|
68
|
+
- `Query.Every` - Available to all authenticated users (any role)
|
|
69
|
+
|
|
70
|
+
### 2. @Mutation Decorator
|
|
71
|
+
|
|
72
|
+
Used for operations that modify data, with similar access control:
|
|
73
|
+
|
|
74
|
+
```typescript
|
|
75
|
+
@Mutation.User(() => cnst.ChatRoom) // User-level access, returns ChatRoom
|
|
76
|
+
async openChatRoom(
|
|
77
|
+
@Arg.Param("root", () => ID) root: string,
|
|
78
|
+
@Arg.Param("targetId", () => ID) targetId: string,
|
|
79
|
+
@Self() self: Self // Gets current user automatically
|
|
80
|
+
) {
|
|
81
|
+
const chatRoom = await this.chatRoomService.open({
|
|
82
|
+
targetId,
|
|
83
|
+
userId: self.id,
|
|
84
|
+
root,
|
|
85
|
+
});
|
|
86
|
+
return resolve<cnst.ChatRoom>(chatRoom);
|
|
87
|
+
}
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### 3. @Message Decorator
|
|
91
|
+
|
|
92
|
+
Handles real-time socket messages for instant communication:
|
|
93
|
+
|
|
94
|
+
```typescript
|
|
95
|
+
@Message.User(() => Boolean) // User-level access, returns Boolean
|
|
96
|
+
async readChat(
|
|
97
|
+
@Arg.Msg("root", () => ID) root: string,
|
|
98
|
+
@Arg.Msg("userId", () => ID) userId: string
|
|
99
|
+
) {
|
|
100
|
+
const chat = await this.chatRoomService.readChat(root, userId);
|
|
101
|
+
return resolve<boolean>(!!chat);
|
|
102
|
+
}
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### 4. @Process Decorator
|
|
106
|
+
|
|
107
|
+
For background processing on the server:
|
|
108
|
+
|
|
109
|
+
```typescript
|
|
110
|
+
@Process.Federation(() => Boolean) // Federation scope, returns Boolean
|
|
111
|
+
async archiveDbBackup(
|
|
112
|
+
@Arg.Msg("dbBackupId", () => String) dbBackupId: string
|
|
113
|
+
) {
|
|
114
|
+
await this.dbBackupService.archiveDbBackup(dbBackupId);
|
|
115
|
+
return done(true); // Use done() for process completion
|
|
116
|
+
}
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
Process scopes:
|
|
120
|
+
|
|
121
|
+
- `Process.Federation` - Run on federation servers
|
|
122
|
+
- `Process.Batch` - Run on batch processing servers
|
|
123
|
+
- `Process.All` - Run on all server types
|
|
124
|
+
|
|
125
|
+
### 5. @Pubsub Decorator
|
|
126
|
+
|
|
127
|
+
Manages real-time subscriptions:
|
|
128
|
+
|
|
129
|
+
```typescript
|
|
130
|
+
@Pubsub.Public(() => cnst.Chat) // Public subscription, emits Chat objects
|
|
131
|
+
chatAdded(
|
|
132
|
+
@Arg.Room("root", () => ID) root: string, // Room parameter for subscription
|
|
133
|
+
@Ws() ws: Ws // WebSocket context
|
|
134
|
+
) {
|
|
135
|
+
return subscribe<cnst.Chat>(); // Subscribe to this type
|
|
136
|
+
}
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
## Parameter Decorators
|
|
140
|
+
|
|
141
|
+
Signals use parameter decorators to define how data is passed:
|
|
142
|
+
|
|
143
|
+
1. **HTTP/GraphQL Parameters**
|
|
144
|
+
|
|
145
|
+
- `@Arg.Query()` - URL query parameters
|
|
146
|
+
- `@Arg.Param()` - URL path parameters
|
|
147
|
+
- `@Arg.Body()` - Request body data
|
|
148
|
+
- `@Arg.Upload()` - File uploads
|
|
149
|
+
|
|
150
|
+
2. **WebSocket Parameters**
|
|
151
|
+
|
|
152
|
+
- `@Arg.Msg()` - Message data
|
|
153
|
+
- `@Arg.Room()` - Room for subscription
|
|
154
|
+
|
|
155
|
+
3. **Context Parameters**
|
|
156
|
+
- `@Self()` - Current authenticated user
|
|
157
|
+
- `@Account()` - User account information
|
|
158
|
+
- `@UserIp()` - Client IP address
|
|
159
|
+
- `@Ws()` - WebSocket context
|
|
160
|
+
|
|
161
|
+
## Slice Pattern for Data Access
|
|
162
|
+
|
|
163
|
+
The slice pattern standardizes data access with consistent naming and pagination:
|
|
164
|
+
|
|
165
|
+
```typescript
|
|
166
|
+
// * /////////////////////////////////////
|
|
167
|
+
// * Self Slice
|
|
168
|
+
@Query.User(() => [cnst.ChatRoom])
|
|
169
|
+
async chatRoomListInSelf( // listIn<SliceName> pattern
|
|
170
|
+
@Arg.Query("skip", () => Int, { nullable: true }) skip: number | null,
|
|
171
|
+
@Arg.Query("limit", () => Int, { nullable: true }) limit: number | null,
|
|
172
|
+
@Arg.Query("sort", () => String, { nullable: true }) sort: SortOf<cnst.ChatRoomFilter> | null,
|
|
173
|
+
@Self() self: Self
|
|
174
|
+
) {
|
|
175
|
+
const chatRooms = await this.chatRoomService.listInUser(self.id, { skip, limit, sort });
|
|
176
|
+
return resolve<cnst.ChatRoom[]>(chatRooms);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
@Query.User(() => cnst.ChatRoomInsight)
|
|
180
|
+
async chatRoomInsightInSelf( // insightIn<SliceName> pattern
|
|
181
|
+
@Self() self: Self
|
|
182
|
+
) {
|
|
183
|
+
const chatRoomInsight = await this.chatRoomService.insightInUser(self.id);
|
|
184
|
+
return resolve<cnst.ChatRoomInsight>(chatRoomInsight);
|
|
185
|
+
}
|
|
186
|
+
// * Self Slice
|
|
187
|
+
// * /////////////////////////////////////
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
Common slices:
|
|
191
|
+
|
|
192
|
+
- `Self` - Data related to the current user
|
|
193
|
+
- `Public` - Publicly accessible data
|
|
194
|
+
- `Featured` - Highlighted items
|
|
195
|
+
- `Root/Parent` - Items within a parent container
|
|
196
|
+
- Custom domain slices (e.g., `DevApp`, `Init`)
|
|
197
|
+
|
|
198
|
+
## Client-Side Signal Usage
|
|
199
|
+
|
|
200
|
+
### 1. Direct API Calls
|
|
201
|
+
|
|
202
|
+
```typescript
|
|
203
|
+
import { productGet, productListInFeatured } from "./product.signal";
|
|
204
|
+
|
|
205
|
+
// Fetch a single product
|
|
206
|
+
const product = await productGet("product-123");
|
|
207
|
+
|
|
208
|
+
// Fetch a list with parameters
|
|
209
|
+
const featuredProducts = await productListInFeatured(0, 10, "price-asc");
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
### 2. Store Integration
|
|
213
|
+
|
|
214
|
+
```typescript
|
|
215
|
+
// product.store.ts
|
|
216
|
+
import { create } from "zustand";
|
|
217
|
+
import { productListInFeatured, productInsightInFeatured } from "./product.signal";
|
|
218
|
+
|
|
219
|
+
export const useProductStore = create<ProductStore>((set) => ({
|
|
220
|
+
featured: [],
|
|
221
|
+
insight: undefined,
|
|
222
|
+
|
|
223
|
+
loadFeatured: async (page = 1, limit = 10) => {
|
|
224
|
+
const [products, insight] = await Promise.all([
|
|
225
|
+
productListInFeatured((page - 1) * limit, limit, "popular"),
|
|
226
|
+
productInsightInFeatured(),
|
|
227
|
+
]);
|
|
228
|
+
|
|
229
|
+
set({ featured: products, insight });
|
|
230
|
+
},
|
|
231
|
+
}));
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
### 3. React Component Integration
|
|
235
|
+
|
|
236
|
+
```tsx
|
|
237
|
+
import { useEffect } from "react";
|
|
238
|
+
import { useProductStore } from "./product.store";
|
|
239
|
+
|
|
240
|
+
function FeaturedProducts() {
|
|
241
|
+
const { featured, insight, loadFeatured } = useProductStore();
|
|
242
|
+
|
|
243
|
+
useEffect(() => {
|
|
244
|
+
loadFeatured();
|
|
245
|
+
}, []);
|
|
246
|
+
|
|
247
|
+
return (
|
|
248
|
+
<div>
|
|
249
|
+
<h3>Featured Products ({insight?.count})</h3>
|
|
250
|
+
{featured.map((product) => (
|
|
251
|
+
<ProductCard key={product.id} product={product} />
|
|
252
|
+
))}
|
|
253
|
+
</div>
|
|
254
|
+
);
|
|
255
|
+
}
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
### 4. Real-Time Subscriptions
|
|
259
|
+
|
|
260
|
+
```tsx
|
|
261
|
+
import { useEffect } from "react";
|
|
262
|
+
import { subscribeChatAdded } from "./chatRoom.signal";
|
|
263
|
+
import { useChatStore } from "./chat.store";
|
|
264
|
+
|
|
265
|
+
function ChatRoom({ roomId }) {
|
|
266
|
+
const { addChat } = useChatStore();
|
|
267
|
+
|
|
268
|
+
useEffect(() => {
|
|
269
|
+
// Subscribe to real-time updates
|
|
270
|
+
const unsubscribe = subscribeChatAdded(roomId, (chat) => {
|
|
271
|
+
addChat(chat);
|
|
272
|
+
});
|
|
273
|
+
|
|
274
|
+
return () => {
|
|
275
|
+
// Cleanup subscription
|
|
276
|
+
unsubscribe();
|
|
277
|
+
};
|
|
278
|
+
}, [roomId]);
|
|
279
|
+
|
|
280
|
+
// Component JSX...
|
|
281
|
+
}
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
## Advanced Patterns
|
|
285
|
+
|
|
286
|
+
### 1. DbSignal for Standard CRUD
|
|
287
|
+
|
|
288
|
+
DbSignal creates standard operations that you don't need to implement:
|
|
289
|
+
|
|
290
|
+
```typescript
|
|
291
|
+
@Signal(() => cnst.Board)
|
|
292
|
+
export class BoardSignal extends DbSignal(cnst.boardCnst, Srvs, {
|
|
293
|
+
guards: { get: Query.Public, cru: Mutation.Admin },
|
|
294
|
+
}) {
|
|
295
|
+
// Custom methods beyond CRUD go here
|
|
296
|
+
}
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
This automatically provides:
|
|
300
|
+
|
|
301
|
+
- `getBoard(id)` - Get by ID
|
|
302
|
+
- `lightBoard(id)` - Get lightweight version
|
|
303
|
+
- `boardList(filter, options)` - List with pagination
|
|
304
|
+
- `boardInsight(filter)` - Get counts/statistics
|
|
305
|
+
- `boardExists(filter)` - Check existence
|
|
306
|
+
- `createBoard(data)` - Create new record
|
|
307
|
+
- `updateBoard(id, data)` - Update existing record
|
|
308
|
+
- `removeBoard(id)` - Soft-delete record
|
|
309
|
+
|
|
310
|
+
### 2. Combined Queries
|
|
311
|
+
|
|
312
|
+
```typescript
|
|
313
|
+
@Query.Public(() => cnst.DashboardData)
|
|
314
|
+
async getDashboard(@Self() self: Self) {
|
|
315
|
+
// Parallel data fetching
|
|
316
|
+
const [stats, notifications, activities] = await Promise.all([
|
|
317
|
+
this.statsService.getUserStats(self.id),
|
|
318
|
+
this.notificationService.getRecent(self.id, { limit: 5 }),
|
|
319
|
+
this.activityService.getRecent(self.id, { limit: 10 })
|
|
320
|
+
]);
|
|
321
|
+
|
|
322
|
+
// Return combined result
|
|
323
|
+
return resolve<cnst.DashboardData>({
|
|
324
|
+
stats,
|
|
325
|
+
notifications,
|
|
326
|
+
activities
|
|
327
|
+
});
|
|
328
|
+
}
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
### 3. Batch Operations
|
|
332
|
+
|
|
333
|
+
```typescript
|
|
334
|
+
@Mutation.Admin(() => [cnst.User])
|
|
335
|
+
async bulkUpdateUserStatus(
|
|
336
|
+
@Arg.Body("userIds", () => [ID]) userIds: string[],
|
|
337
|
+
@Arg.Body("status", () => String) status: cnst.UserStatus
|
|
338
|
+
) {
|
|
339
|
+
const users = await this.userService.bulkUpdateStatus(userIds, status);
|
|
340
|
+
return resolve<cnst.User[]>(users);
|
|
341
|
+
}
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
### 4. Filtered Access Control
|
|
345
|
+
|
|
346
|
+
```typescript
|
|
347
|
+
@Query.User(() => cnst.ProjectDetails)
|
|
348
|
+
async getProjectDetails(
|
|
349
|
+
@Arg.Param("projectId", () => ID) projectId: string,
|
|
350
|
+
@Self() self: Self
|
|
351
|
+
) {
|
|
352
|
+
// Check permissions within the method
|
|
353
|
+
const hasAccess = await this.projectService.checkUserAccess(projectId, self.id);
|
|
354
|
+
if (!hasAccess) {
|
|
355
|
+
throw new Error("Access denied");
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
const project = await this.projectService.getDetails(projectId);
|
|
359
|
+
return resolve<cnst.ProjectDetails>(project);
|
|
360
|
+
}
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
## Best Practices
|
|
364
|
+
|
|
365
|
+
### 1. Naming Conventions
|
|
366
|
+
|
|
367
|
+
- **Method Names**:
|
|
368
|
+
|
|
369
|
+
- Use `modelListIn<Slice>` for list queries
|
|
370
|
+
- Use `modelInsightIn<Slice>` for insight queries
|
|
371
|
+
- Prefix mutations with verbs (`createUser`, `updateProfile`)
|
|
372
|
+
- Use descriptive names that indicate functionality
|
|
373
|
+
|
|
374
|
+
- **Parameter Names**:
|
|
375
|
+
- Use consistent names across similar methods
|
|
376
|
+
- Match service method parameter names where possible
|
|
377
|
+
|
|
378
|
+
### 2. Type Safety
|
|
379
|
+
|
|
380
|
+
- Always specify return types in decorators: `@Query.Public(() => ModelType)`
|
|
381
|
+
- Always use `resolve<Type>()` with explicit type
|
|
382
|
+
- Define parameter types with GraphQL scalar types: `() => ID`, `() => Int`
|
|
383
|
+
- Use nullability consistently: `{ nullable: true }`
|
|
384
|
+
|
|
385
|
+
### 3. Performance
|
|
386
|
+
|
|
387
|
+
- Use pagination parameters consistently (`skip`/`limit` or `page`/`pageSize`)
|
|
388
|
+
- Implement slices for focused data retrieval
|
|
389
|
+
- Use parallel requests with `Promise.all` for combined data
|
|
390
|
+
- Consider implementing cursor-based pagination for large datasets
|
|
391
|
+
|
|
392
|
+
### 4. Security
|
|
393
|
+
|
|
394
|
+
- Apply appropriate access control decorators
|
|
395
|
+
- Validate input data in signals or services
|
|
396
|
+
- Use the `@Self()` decorator to ensure user-scoped operations
|
|
397
|
+
- Implement rate limiting for public endpoints
|
|
398
|
+
|
|
399
|
+
### 5. Error Handling
|
|
400
|
+
|
|
401
|
+
- Use try/catch blocks for operations that might fail
|
|
402
|
+
- Return standardized error formats
|
|
403
|
+
- Add logging for debugging purposes
|
|
404
|
+
- Handle database errors gracefully
|
|
405
|
+
|
|
406
|
+
## Implementation Examples
|
|
407
|
+
|
|
408
|
+
### Basic CRUD Signal with DbSignal
|
|
409
|
+
|
|
410
|
+
```typescript
|
|
411
|
+
@Signal(() => cnst.Product)
|
|
412
|
+
export class ProductSignal extends DbSignal(cnst.productCnst, Srvs, {
|
|
413
|
+
guards: { get: Query.Public, cru: Mutation.Admin },
|
|
414
|
+
}) {
|
|
415
|
+
// Custom methods beyond auto-generated CRUD
|
|
416
|
+
@Query.Public(() => [cnst.Product])
|
|
417
|
+
async productListInFeatured(
|
|
418
|
+
@Arg.Query("skip", () => Int, { nullable: true }) skip: number | null,
|
|
419
|
+
@Arg.Query("limit", () => Int, { nullable: true }) limit: number | null
|
|
420
|
+
) {
|
|
421
|
+
const products = await this.productService.listFeatured({ skip, limit });
|
|
422
|
+
return resolve<cnst.Product[]>(products);
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
@Mutation.Admin(() => Boolean)
|
|
426
|
+
async toggleProductFeatured(
|
|
427
|
+
@Arg.Param("productId", () => ID) productId: string,
|
|
428
|
+
@Arg.Body("featured", () => Boolean) featured: boolean
|
|
429
|
+
) {
|
|
430
|
+
await this.productService.setFeatured(productId, featured);
|
|
431
|
+
return resolve<boolean>(true);
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
```
|
|
435
|
+
|
|
436
|
+
### Real-Time Chat Signal
|
|
437
|
+
|
|
438
|
+
```typescript
|
|
439
|
+
@Signal(() => cnst.Chat)
|
|
440
|
+
export class ChatSignal {
|
|
441
|
+
@Mutation.User(() => cnst.Chat)
|
|
442
|
+
async sendChat(
|
|
443
|
+
@Arg.Body("roomId", () => ID) roomId: string,
|
|
444
|
+
@Arg.Body("message", () => String) message: string,
|
|
445
|
+
@Self() self: Self
|
|
446
|
+
) {
|
|
447
|
+
const chat = await this.chatService.create(roomId, self.id, message);
|
|
448
|
+
return resolve<cnst.Chat>(chat);
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
@Message.User(() => Boolean)
|
|
452
|
+
async markAsRead(@Arg.Msg("chatId", () => ID) chatId: string, @Self() self: Self) {
|
|
453
|
+
await this.chatService.markAsRead(chatId, self.id);
|
|
454
|
+
return resolve<boolean>(true);
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
@Pubsub.User(() => cnst.Chat)
|
|
458
|
+
chatReceived(@Arg.Room("roomId", () => ID) roomId: string, @Ws() ws: Ws) {
|
|
459
|
+
return subscribe<cnst.Chat>();
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
```
|
|
463
|
+
|
|
464
|
+
### Background Processing Signal
|
|
465
|
+
|
|
466
|
+
```typescript
|
|
467
|
+
@Signal(() => cnst.Report)
|
|
468
|
+
export class ReportSignal {
|
|
469
|
+
@Mutation.Admin(() => cnst.Report)
|
|
470
|
+
async generateReport(
|
|
471
|
+
@Arg.Body("type", () => String) type: cnst.ReportType,
|
|
472
|
+
@Arg.Body("parameters", () => cnst.ReportParameters) parameters: cnst.ReportParameters,
|
|
473
|
+
@Self() self: Self
|
|
474
|
+
) {
|
|
475
|
+
// Create report record
|
|
476
|
+
const report = await this.reportService.initReport(type, parameters, self.id);
|
|
477
|
+
|
|
478
|
+
// Queue background process
|
|
479
|
+
await this.reportService.queueReportGeneration(report.id);
|
|
480
|
+
|
|
481
|
+
return resolve<cnst.Report>(report);
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
@Process.Batch(() => Boolean)
|
|
485
|
+
async processReport(@Arg.Msg("reportId", () => ID) reportId: string) {
|
|
486
|
+
await this.reportService.generateReport(reportId);
|
|
487
|
+
return done(true);
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
```
|
|
491
|
+
|
|
492
|
+
## Troubleshooting
|
|
493
|
+
|
|
494
|
+
### Common Issues
|
|
495
|
+
|
|
496
|
+
1. **Type Mismatch Errors**
|
|
497
|
+
|
|
498
|
+
- Ensure GraphQL types match TypeScript types
|
|
499
|
+
- Check nullable parameters and provide default values
|
|
500
|
+
- Verify service method return types match signal return types
|
|
501
|
+
|
|
502
|
+
2. **Authentication Errors**
|
|
503
|
+
|
|
504
|
+
- Verify guard levels match your security requirements
|
|
505
|
+
- Check that @Self() is used in user-scoped operations
|
|
506
|
+
- Test with different user roles to verify access control
|
|
507
|
+
|
|
508
|
+
3. **Real-Time Communication Issues**
|
|
509
|
+
|
|
510
|
+
- Ensure room names are consistent between subscriptions and messages
|
|
511
|
+
- Verify WebSocket connection is established
|
|
512
|
+
- Check that subscription events are being triggered correctly
|
|
513
|
+
|
|
514
|
+
4. **Missing Data in Client**
|
|
515
|
+
- Verify signal method parameters match client call parameters
|
|
516
|
+
- Check that resolve<Type>() is being used correctly
|
|
517
|
+
- Ensure proper error handling on the client side
|
|
518
|
+
|
|
519
|
+
### Debugging Tips
|
|
520
|
+
|
|
521
|
+
1. Enable verbose logging in development
|
|
522
|
+
2. Use network inspection tools to examine requests/responses
|
|
523
|
+
3. Add temporary logging in signal methods
|
|
524
|
+
4. Test signals directly in a backend-only environment
|
|
525
|
+
5. Use GraphQL playground to test queries/mutations
|
|
526
|
+
|
|
527
|
+
## Advanced Topics
|
|
528
|
+
|
|
529
|
+
### Custom Signal Decorators
|
|
530
|
+
|
|
531
|
+
You can create custom decorators for reusable patterns:
|
|
532
|
+
|
|
533
|
+
```typescript
|
|
534
|
+
// Create a custom slice decorator
|
|
535
|
+
export function SelfSlice<T>(returnType: () => T) {
|
|
536
|
+
return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
|
|
537
|
+
Query.User(returnType)(target, propertyKey, descriptor);
|
|
538
|
+
// Add additional metadata or behavior
|
|
539
|
+
};
|
|
540
|
+
}
|
|
541
|
+
```
|
|
542
|
+
|
|
543
|
+
### Signal Integration with External APIs
|
|
544
|
+
|
|
545
|
+
```typescript
|
|
546
|
+
@Signal(() => cnst.ExternalData)
|
|
547
|
+
export class ExternalApiSignal {
|
|
548
|
+
@Query.Public(() => cnst.WeatherData)
|
|
549
|
+
async getWeatherData(@Arg.Query("location", () => String) location: string) {
|
|
550
|
+
// Call external API with proper error handling
|
|
551
|
+
try {
|
|
552
|
+
const data = await this.externalApiService.fetchWeather(location);
|
|
553
|
+
return resolve<cnst.WeatherData>(data);
|
|
554
|
+
} catch (error) {
|
|
555
|
+
// Handle and transform errors from external API
|
|
556
|
+
throw new Error(`Weather API error: ${error.message}`);
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
```
|
|
561
|
+
|
|
562
|
+
### Caching Strategies
|
|
563
|
+
|
|
564
|
+
Signals can implement caching for performance:
|
|
565
|
+
|
|
566
|
+
```typescript
|
|
567
|
+
@Signal(() => cnst.Product)
|
|
568
|
+
export class ProductSignal extends DbSignal(cnst.productCnst, Srvs) {
|
|
569
|
+
@Query.Public(() => cnst.Product)
|
|
570
|
+
async getProduct(@Arg.Param("productId", () => ID) productId: string) {
|
|
571
|
+
// Check cache first
|
|
572
|
+
const cached = await this.cacheService.get(`product:${productId}`);
|
|
573
|
+
if (cached) {
|
|
574
|
+
return resolve<cnst.Product>(cached);
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
// Fetch from database if not cached
|
|
578
|
+
const product = await this.productService.get(productId);
|
|
579
|
+
|
|
580
|
+
// Cache for future requests
|
|
581
|
+
await this.cacheService.set(`product:${productId}`, product, 3600);
|
|
582
|
+
|
|
583
|
+
return resolve<cnst.Product>(product);
|
|
584
|
+
}
|
|
585
|
+
}
|
|
586
|
+
```
|
|
587
|
+
|
|
588
|
+
Remember that signals should be pure TypeScript with no framework-specific code, as they're used by both client and server. The Akan.js framework handles the conversion to the appropriate transport mechanism.
|