@researchdatabox/redbox-dev-tools 0.0.1-beta.8936
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 +255 -0
- package/bin/cli.js +3 -0
- package/bin/run-hook-mocha.js +3 -0
- package/bin/run-hook-tsc.js +3 -0
- package/bin/wrapper-webpack.js +145 -0
- package/config/tsconfig.base.json +16 -0
- package/dist/bin/run-hook-mocha.d.ts +1 -0
- package/dist/bin/run-hook-mocha.js +49 -0
- package/dist/bin/run-hook-tsc.d.ts +1 -0
- package/dist/bin/run-hook-tsc.js +19 -0
- package/dist/cli-parsers.d.ts +9 -0
- package/dist/cli-parsers.js +131 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +464 -0
- package/dist/commands/form-config.d.ts +5 -0
- package/dist/commands/form-config.js +194 -0
- package/dist/completion/index.d.ts +1 -0
- package/dist/completion/index.js +217 -0
- package/dist/generators/add-method.d.ts +27 -0
- package/dist/generators/add-method.js +235 -0
- package/dist/generators/angular-app.d.ts +24 -0
- package/dist/generators/angular-app.js +342 -0
- package/dist/generators/angular-service.d.ts +21 -0
- package/dist/generators/angular-service.js +154 -0
- package/dist/generators/controller.d.ts +40 -0
- package/dist/generators/controller.js +195 -0
- package/dist/generators/form-component.d.ts +46 -0
- package/dist/generators/form-component.js +906 -0
- package/dist/generators/form-field.d.ts +15 -0
- package/dist/generators/form-field.js +160 -0
- package/dist/generators/model.d.ts +42 -0
- package/dist/generators/model.js +206 -0
- package/dist/generators/service.d.ts +16 -0
- package/dist/generators/service.js +111 -0
- package/dist/runtime-resolver.d.ts +3 -0
- package/dist/runtime-resolver.js +27 -0
- package/dist/templates/hook-archetype.d.ts +12 -0
- package/dist/templates/hook-archetype.js +143 -0
- package/dist/testing.d.ts +7 -0
- package/dist/testing.js +53 -0
- package/dist/utils/config-helper.d.ts +71 -0
- package/dist/utils/config-helper.js +574 -0
- package/dist/utils/generator.d.ts +10 -0
- package/dist/utils/generator.js +68 -0
- package/dist/utils/hook-tsconfig.d.ts +9 -0
- package/dist/utils/hook-tsconfig.js +104 -0
- package/dist/utils/paths.d.ts +10 -0
- package/dist/utils/paths.js +60 -0
- package/index.js +4 -0
- package/package.json +85 -0
- package/runtime-resolver.d.ts +1 -0
- package/runtime-resolver.js +3 -0
- package/skills/redbox-angular-apps/SKILL.md +42 -0
- package/skills/redbox-angular-services/SKILL.md +29 -0
- package/skills/redbox-controllers/SKILL.md +65 -0
- package/skills/redbox-feature-design-planner/SKILL.md +169 -0
- package/skills/redbox-feature-implementation-review/SKILL.md +117 -0
- package/skills/redbox-form-components/SKILL.md +114 -0
- package/skills/redbox-form-config/SKILL.md +34 -0
- package/skills/redbox-hook-development/SKILL.md +66 -0
- package/skills/redbox-services/SKILL.md +54 -0
- package/skills/redbox-test-verification/SKILL.md +38 -0
- package/skills/redbox-testing/SKILL.md +64 -0
- package/skills/redbox-web-verification/SKILL.md +71 -0
- package/skills/redbox-web-verification/redbox-angular-apps/SKILL.md +48 -0
- package/skills/redbox-web-verification/redbox-angular-services/SKILL.md +30 -0
- package/skills/redbox-web-verification/redbox-controllers/SKILL.md +56 -0
- package/skills/redbox-web-verification/redbox-form-config/SKILL.md +29 -0
- package/skills/redbox-web-verification/redbox-hook-development/SKILL.md +61 -0
- package/skills/redbox-web-verification/redbox-services/SKILL.md +45 -0
- package/skills/redbox-web-verification/redbox-testing/SKILL.md +53 -0
- package/skills/redbox-web-verification/redbox-web-verification/SKILL.md +47 -0
- package/templates/hook-archetype/standard/.gitignore.hbs +4 -0
- package/templates/hook-archetype/standard/.npmignore.hbs +3 -0
- package/templates/hook-archetype/standard/.npmrc.hbs +6 -0
- package/templates/hook-archetype/standard/.nvmrc.hbs +1 -0
- package/templates/hook-archetype/standard/AGENTS.md.hbs +34 -0
- package/templates/hook-archetype/standard/Dockerfile.hbs +28 -0
- package/templates/hook-archetype/standard/README.md.hbs +39 -0
- package/templates/hook-archetype/standard/assets/fonts/.gitkeep +1 -0
- package/templates/hook-archetype/standard/language-defaults/.gitkeep +1 -0
- package/templates/hook-archetype/standard/package.json.hbs +40 -0
- package/templates/hook-archetype/standard/src/api/controllers/ExampleController.ts.hbs +21 -0
- package/templates/hook-archetype/standard/src/api/controllers/index.ts.hbs +23 -0
- package/templates/hook-archetype/standard/src/api/services/ExampleService.ts.hbs +22 -0
- package/templates/hook-archetype/standard/src/api/services/index.ts.hbs +23 -0
- package/templates/hook-archetype/standard/src/config/brandingConfigurationDefaults.ts.hbs +9 -0
- package/templates/hook-archetype/standard/src/config/reusableFormDefinitions.ts.hbs +6 -0
- package/templates/hook-archetype/standard/src/form-config/default-1.0-draft.ts.hbs +20 -0
- package/templates/hook-archetype/standard/src/form-config/index.ts.hbs +8 -0
- package/templates/hook-archetype/standard/src/index.ts.hbs +55 -0
- package/templates/hook-archetype/standard/support/bootstrap-data/.gitkeep +1 -0
- package/templates/hook-archetype/standard/support/development/docker-compose.yml.hbs +75 -0
- package/templates/hook-archetype/standard/support/integration-testing/docker-compose.mocha.yml.hbs +84 -0
- package/templates/hook-archetype/standard/support/integration-testing/run-mocha-hook.sh.hbs +9 -0
- package/templates/hook-archetype/standard/test/integration/hook-registration.test.ts.hbs +13 -0
- package/templates/hook-archetype/standard/test/support/globals.ts.hbs +40 -0
- package/templates/hook-archetype/standard/test/tsconfig.json.hbs +8 -0
- package/templates/hook-archetype/standard/test/unit/.mocharc.cjs.hbs +9 -0
- package/templates/hook-archetype/standard/test/unit/index.test.ts.hbs +40 -0
- package/templates/hook-archetype/standard/tsconfig.json.hbs +15 -0
- package/templates/hook-archetype/standard/views/.gitkeep +1 -0
- package/testing.d.ts +1 -0
- package/testing.js +3 -0
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.generateCompletionScript = generateCompletionScript;
|
|
4
|
+
function getCompletionSpec() {
|
|
5
|
+
const globalOptions = ['--root', '--core-types-root', '--angular-root', '--dry-run', '-h', '--help', '-V', '--version'];
|
|
6
|
+
const topLevelCommands = ['init', 'check', 'migrate-hook-dependencies', 'generate', 'g', 'install-skills', 'skills', 'migrate-form-config', 'completion', 'help'];
|
|
7
|
+
const generateCommands = ['controller', 'service', 'method', 'angular-app', 'angular-service', 'form-component', 'form-field', 'model'];
|
|
8
|
+
const commandOptions = {
|
|
9
|
+
'migrate-form-config': ['-i', '--input', '-o', '--output'],
|
|
10
|
+
'check': [],
|
|
11
|
+
'completion': [],
|
|
12
|
+
'init': [],
|
|
13
|
+
'install-skills': [],
|
|
14
|
+
'migrate-hook-dependencies': [],
|
|
15
|
+
'skills': [],
|
|
16
|
+
'generate controller': ['--actions', '--webservice', '--class-name', '--route', '--routes', '--nav', '--lang', '--auth'],
|
|
17
|
+
'generate service': ['--methods'],
|
|
18
|
+
'generate method': ['--file', '--method', '--route', '--http', '--auth', '--nav', '--lang'],
|
|
19
|
+
'generate angular-app': ['--ejs-view', '--auth'],
|
|
20
|
+
'generate angular-service': ['--app', '--methods'],
|
|
21
|
+
'generate form-component': ['--app', '--with-service'],
|
|
22
|
+
'generate form-field': ['--type'],
|
|
23
|
+
'generate model': ['--identity', '--attrs', '--belongs-to', '--has-many']
|
|
24
|
+
};
|
|
25
|
+
const fileValueOptions = ['--root', '--core-types-root', '--angular-root', '--input', '--output', '--file'];
|
|
26
|
+
return { globalOptions, topLevelCommands, generateCommands, commandOptions, fileValueOptions };
|
|
27
|
+
}
|
|
28
|
+
function generateBashCompletion() {
|
|
29
|
+
const spec = getCompletionSpec();
|
|
30
|
+
const top = spec.topLevelCommands.join(' ');
|
|
31
|
+
const generateSubs = spec.generateCommands.join(' ');
|
|
32
|
+
const globalOpts = spec.globalOptions.join(' ');
|
|
33
|
+
const fileOpts = spec.fileValueOptions.join(' ');
|
|
34
|
+
const commandOptionEntries = Object.entries(spec.commandOptions)
|
|
35
|
+
.map(([key, value]) => `"${key}") opts="${value.join(' ')}";;`)
|
|
36
|
+
.join('\n ');
|
|
37
|
+
return `# bash completion for redbox-dev-tools
|
|
38
|
+
_redbox_dev_tools_completion() {
|
|
39
|
+
local cur prev words cword
|
|
40
|
+
_init_completion || return
|
|
41
|
+
|
|
42
|
+
local top_commands="${top}"
|
|
43
|
+
local generate_subcommands="${generateSubs}"
|
|
44
|
+
local global_opts="${globalOpts}"
|
|
45
|
+
local file_value_opts="${fileOpts}"
|
|
46
|
+
|
|
47
|
+
case "$prev" in
|
|
48
|
+
$file_value_opts)
|
|
49
|
+
COMPREPLY=($(compgen -f -- "$cur"))
|
|
50
|
+
return
|
|
51
|
+
;;
|
|
52
|
+
esac
|
|
53
|
+
|
|
54
|
+
if [[ $cword -le 1 ]]; then
|
|
55
|
+
COMPREPLY=($(compgen -W "$top_commands $global_opts" -- "$cur"))
|
|
56
|
+
return
|
|
57
|
+
fi
|
|
58
|
+
|
|
59
|
+
if [[ "\${words[1]}" == "generate" || "\${words[1]}" == "g" ]]; then
|
|
60
|
+
if [[ $cword -eq 2 ]]; then
|
|
61
|
+
COMPREPLY=($(compgen -W "$generate_subcommands" -- "$cur"))
|
|
62
|
+
return
|
|
63
|
+
fi
|
|
64
|
+
local key="generate \${words[2]}"
|
|
65
|
+
local opts=""
|
|
66
|
+
case "$key" in
|
|
67
|
+
${commandOptionEntries}
|
|
68
|
+
*) opts="";;
|
|
69
|
+
esac
|
|
70
|
+
COMPREPLY=($(compgen -W "$opts $global_opts" -- "$cur"))
|
|
71
|
+
return
|
|
72
|
+
fi
|
|
73
|
+
|
|
74
|
+
local opts=""
|
|
75
|
+
case "\${words[1]}" in
|
|
76
|
+
"migrate-form-config") opts="-i --input -o --output" ;;
|
|
77
|
+
"check") opts="" ;;
|
|
78
|
+
"completion") opts="" ;;
|
|
79
|
+
"init") opts="" ;;
|
|
80
|
+
"install-skills") opts="" ;;
|
|
81
|
+
"migrate-hook-dependencies") opts="" ;;
|
|
82
|
+
"skills") opts="" ;;
|
|
83
|
+
*) opts="" ;;
|
|
84
|
+
esac
|
|
85
|
+
|
|
86
|
+
COMPREPLY=($(compgen -W "$opts $global_opts" -- "$cur"))
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
complete -F _redbox_dev_tools_completion redbox-dev-tools
|
|
90
|
+
`;
|
|
91
|
+
}
|
|
92
|
+
function generateZshCompletion() {
|
|
93
|
+
const bashScript = generateBashCompletion();
|
|
94
|
+
return `#compdef redbox-dev-tools
|
|
95
|
+
autoload -U +X bashcompinit && bashcompinit
|
|
96
|
+
${bashScript}`;
|
|
97
|
+
}
|
|
98
|
+
function generateFishCompletion() {
|
|
99
|
+
const spec = getCompletionSpec();
|
|
100
|
+
const lines = [
|
|
101
|
+
'# fish completion for redbox-dev-tools',
|
|
102
|
+
'set -l __rbhk_cmd redbox-dev-tools',
|
|
103
|
+
'complete -c $__rbhk_cmd -f'
|
|
104
|
+
];
|
|
105
|
+
for (const cmd of spec.topLevelCommands) {
|
|
106
|
+
lines.push(`complete -c $__rbhk_cmd -n "__fish_use_subcommand" -a "${cmd}"`);
|
|
107
|
+
}
|
|
108
|
+
for (const option of spec.globalOptions) {
|
|
109
|
+
if (option.startsWith('--')) {
|
|
110
|
+
const name = option.replace(/^--/, '');
|
|
111
|
+
const requiresValue = ['root', 'core-types-root', 'angular-root'].includes(name);
|
|
112
|
+
lines.push(`complete -c $__rbhk_cmd -l ${name}${requiresValue ? ' -r' : ''}`);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
for (const sub of spec.generateCommands) {
|
|
116
|
+
lines.push(`complete -c $__rbhk_cmd -n "__fish_seen_subcommand_from generate g; and __fish_use_subcommand" -a "${sub}"`);
|
|
117
|
+
}
|
|
118
|
+
lines.push('complete -c $__rbhk_cmd -n "__fish_seen_subcommand_from migrate-form-config" -s i -l input -r');
|
|
119
|
+
lines.push('complete -c $__rbhk_cmd -n "__fish_seen_subcommand_from migrate-form-config" -s o -l output -r');
|
|
120
|
+
lines.push('complete -c $__rbhk_cmd -n "__fish_seen_subcommand_from completion" -a "bash zsh fish powershell pwsh"');
|
|
121
|
+
lines.push('complete -c $__rbhk_cmd -n "__fish_seen_subcommand_from generate; and __fish_seen_subcommand_from controller" -l actions -r');
|
|
122
|
+
lines.push('complete -c $__rbhk_cmd -n "__fish_seen_subcommand_from generate; and __fish_seen_subcommand_from controller" -l webservice');
|
|
123
|
+
lines.push('complete -c $__rbhk_cmd -n "__fish_seen_subcommand_from generate; and __fish_seen_subcommand_from controller" -l class-name -r');
|
|
124
|
+
lines.push('complete -c $__rbhk_cmd -n "__fish_seen_subcommand_from generate; and __fish_seen_subcommand_from controller" -l route -r');
|
|
125
|
+
lines.push('complete -c $__rbhk_cmd -n "__fish_seen_subcommand_from generate; and __fish_seen_subcommand_from controller" -l routes -r');
|
|
126
|
+
lines.push('complete -c $__rbhk_cmd -n "__fish_seen_subcommand_from generate; and __fish_seen_subcommand_from controller" -l nav -r');
|
|
127
|
+
lines.push('complete -c $__rbhk_cmd -n "__fish_seen_subcommand_from generate; and __fish_seen_subcommand_from controller" -l lang -r');
|
|
128
|
+
lines.push('complete -c $__rbhk_cmd -n "__fish_seen_subcommand_from generate; and __fish_seen_subcommand_from controller" -l auth -r');
|
|
129
|
+
lines.push('complete -c $__rbhk_cmd -n "__fish_seen_subcommand_from generate; and __fish_seen_subcommand_from service" -l methods -r');
|
|
130
|
+
lines.push('complete -c $__rbhk_cmd -n "__fish_seen_subcommand_from generate; and __fish_seen_subcommand_from method" -l file -r');
|
|
131
|
+
lines.push('complete -c $__rbhk_cmd -n "__fish_seen_subcommand_from generate; and __fish_seen_subcommand_from method" -l method -r');
|
|
132
|
+
lines.push('complete -c $__rbhk_cmd -n "__fish_seen_subcommand_from generate; and __fish_seen_subcommand_from method" -l route -r');
|
|
133
|
+
lines.push('complete -c $__rbhk_cmd -n "__fish_seen_subcommand_from generate; and __fish_seen_subcommand_from method" -l http -r');
|
|
134
|
+
lines.push('complete -c $__rbhk_cmd -n "__fish_seen_subcommand_from generate; and __fish_seen_subcommand_from method" -l auth -r');
|
|
135
|
+
lines.push('complete -c $__rbhk_cmd -n "__fish_seen_subcommand_from generate; and __fish_seen_subcommand_from method" -l nav -r');
|
|
136
|
+
lines.push('complete -c $__rbhk_cmd -n "__fish_seen_subcommand_from generate; and __fish_seen_subcommand_from method" -l lang -r');
|
|
137
|
+
lines.push('complete -c $__rbhk_cmd -n "__fish_seen_subcommand_from generate; and __fish_seen_subcommand_from angular-app" -l ejs-view -r');
|
|
138
|
+
lines.push('complete -c $__rbhk_cmd -n "__fish_seen_subcommand_from generate; and __fish_seen_subcommand_from angular-app" -l auth -r');
|
|
139
|
+
lines.push('complete -c $__rbhk_cmd -n "__fish_seen_subcommand_from generate; and __fish_seen_subcommand_from angular-service" -l app -r');
|
|
140
|
+
lines.push('complete -c $__rbhk_cmd -n "__fish_seen_subcommand_from generate; and __fish_seen_subcommand_from angular-service" -l methods -r');
|
|
141
|
+
lines.push('complete -c $__rbhk_cmd -n "__fish_seen_subcommand_from generate; and __fish_seen_subcommand_from form-component" -l app -r');
|
|
142
|
+
lines.push('complete -c $__rbhk_cmd -n "__fish_seen_subcommand_from generate; and __fish_seen_subcommand_from form-component" -l with-service');
|
|
143
|
+
lines.push('complete -c $__rbhk_cmd -n "__fish_seen_subcommand_from generate; and __fish_seen_subcommand_from form-field" -l type -r');
|
|
144
|
+
lines.push('complete -c $__rbhk_cmd -n "__fish_seen_subcommand_from generate; and __fish_seen_subcommand_from model" -l identity -r');
|
|
145
|
+
lines.push('complete -c $__rbhk_cmd -n "__fish_seen_subcommand_from generate; and __fish_seen_subcommand_from model" -l attrs -r');
|
|
146
|
+
lines.push('complete -c $__rbhk_cmd -n "__fish_seen_subcommand_from generate; and __fish_seen_subcommand_from model" -l belongs-to -r');
|
|
147
|
+
lines.push('complete -c $__rbhk_cmd -n "__fish_seen_subcommand_from generate; and __fish_seen_subcommand_from model" -l has-many -r');
|
|
148
|
+
return `${lines.join('\n')}\n`;
|
|
149
|
+
}
|
|
150
|
+
function generatePowerShellCompletion() {
|
|
151
|
+
return `# PowerShell completion for redbox-dev-tools
|
|
152
|
+
Register-ArgumentCompleter -Native -CommandName redbox-dev-tools -ScriptBlock {
|
|
153
|
+
param($wordToComplete, $commandAst, $cursorPosition)
|
|
154
|
+
$tokens = $commandAst.CommandElements | ForEach-Object { $_.Extent.Text }
|
|
155
|
+
$global = @('--root','--core-types-root','--angular-root','--dry-run','-h','--help','-V','--version')
|
|
156
|
+
$top = @('init','check','migrate-hook-dependencies','generate','g','install-skills','skills','migrate-form-config','completion','help')
|
|
157
|
+
$generateSub = @('controller','service','method','angular-app','angular-service','form-component','form-field','model')
|
|
158
|
+
|
|
159
|
+
if ($tokens.Count -le 2) {
|
|
160
|
+
@($top + $global) | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
|
|
161
|
+
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_)
|
|
162
|
+
}
|
|
163
|
+
return
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
if ($tokens[1] -eq 'generate' -or $tokens[1] -eq 'g') {
|
|
167
|
+
if ($tokens.Count -le 3) {
|
|
168
|
+
$generateSub | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
|
|
169
|
+
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_)
|
|
170
|
+
}
|
|
171
|
+
return
|
|
172
|
+
}
|
|
173
|
+
$sub = $tokens[2]
|
|
174
|
+
$opts = switch ($sub) {
|
|
175
|
+
'controller' { @('--actions','--webservice','--class-name','--route','--routes','--nav','--lang','--auth') }
|
|
176
|
+
'service' { @('--methods') }
|
|
177
|
+
'method' { @('--file','--method','--route','--http','--auth','--nav','--lang') }
|
|
178
|
+
'angular-app' { @('--ejs-view','--auth') }
|
|
179
|
+
'angular-service' { @('--app','--methods') }
|
|
180
|
+
'form-component' { @('--app','--with-service') }
|
|
181
|
+
'form-field' { @('--type') }
|
|
182
|
+
'model' { @('--identity','--attrs','--belongs-to','--has-many') }
|
|
183
|
+
default { @() }
|
|
184
|
+
}
|
|
185
|
+
@($opts + $global) | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
|
|
186
|
+
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterName', $_)
|
|
187
|
+
}
|
|
188
|
+
return
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
$opts = switch ($tokens[1]) {
|
|
192
|
+
'migrate-form-config' { @('-i','--input','-o','--output') }
|
|
193
|
+
'completion' { @('bash','zsh','fish','powershell','pwsh') }
|
|
194
|
+
default { @() }
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
@($opts + $global) | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
|
|
198
|
+
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterName', $_)
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
`;
|
|
202
|
+
}
|
|
203
|
+
function generateCompletionScript(shell) {
|
|
204
|
+
switch (shell) {
|
|
205
|
+
case 'bash':
|
|
206
|
+
return generateBashCompletion();
|
|
207
|
+
case 'zsh':
|
|
208
|
+
return generateZshCompletion();
|
|
209
|
+
case 'fish':
|
|
210
|
+
return generateFishCompletion();
|
|
211
|
+
case 'powershell':
|
|
212
|
+
case 'pwsh':
|
|
213
|
+
return generatePowerShellCompletion();
|
|
214
|
+
default:
|
|
215
|
+
throw new Error(`Unsupported shell '${shell}'. Expected one of: bash, zsh, fish, powershell`);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { Generator, GeneratorOptions } from '../utils/generator';
|
|
2
|
+
import { RedboxPaths } from '../utils/paths';
|
|
3
|
+
import { NavigationMapping, LanguageDefaultEntry } from '../utils/config-helper';
|
|
4
|
+
export interface AddMethodGeneratorOptions extends GeneratorOptions {
|
|
5
|
+
file: string;
|
|
6
|
+
method: string;
|
|
7
|
+
route?: string;
|
|
8
|
+
http?: string;
|
|
9
|
+
auth?: string[];
|
|
10
|
+
navigation?: NavigationMapping[];
|
|
11
|
+
languageDefaults?: LanguageDefaultEntry[];
|
|
12
|
+
paths: RedboxPaths;
|
|
13
|
+
}
|
|
14
|
+
export declare class AddMethodGenerator extends Generator {
|
|
15
|
+
private filePath;
|
|
16
|
+
private method;
|
|
17
|
+
private route?;
|
|
18
|
+
private http?;
|
|
19
|
+
private auth?;
|
|
20
|
+
private navigation;
|
|
21
|
+
private languageDefaults;
|
|
22
|
+
private paths;
|
|
23
|
+
private project;
|
|
24
|
+
constructor(options: AddMethodGeneratorOptions);
|
|
25
|
+
generate(): Promise<void>;
|
|
26
|
+
private updateClass;
|
|
27
|
+
}
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.AddMethodGenerator = void 0;
|
|
37
|
+
const path = __importStar(require("path"));
|
|
38
|
+
const fs = __importStar(require("fs"));
|
|
39
|
+
const ts_morph_1 = require("ts-morph");
|
|
40
|
+
const generator_1 = require("../utils/generator");
|
|
41
|
+
const config_helper_1 = require("../utils/config-helper");
|
|
42
|
+
class AddMethodGenerator extends generator_1.Generator {
|
|
43
|
+
filePath;
|
|
44
|
+
method;
|
|
45
|
+
route;
|
|
46
|
+
http;
|
|
47
|
+
auth;
|
|
48
|
+
navigation;
|
|
49
|
+
languageDefaults;
|
|
50
|
+
paths;
|
|
51
|
+
project;
|
|
52
|
+
constructor(options) {
|
|
53
|
+
super(options);
|
|
54
|
+
this.filePath = path.isAbsolute(options.file) ? options.file : path.resolve(this.root, options.file);
|
|
55
|
+
this.method = options.method;
|
|
56
|
+
this.route = options.route;
|
|
57
|
+
this.http = options.http || 'GET';
|
|
58
|
+
this.auth = options.auth;
|
|
59
|
+
this.navigation = options.navigation || [];
|
|
60
|
+
this.languageDefaults = options.languageDefaults || [];
|
|
61
|
+
this.paths = options.paths;
|
|
62
|
+
this.project = new ts_morph_1.Project({
|
|
63
|
+
manipulationSettings: {
|
|
64
|
+
quoteKind: ts_morph_1.QuoteKind.Single,
|
|
65
|
+
},
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
async generate() {
|
|
69
|
+
if (!fs.existsSync(this.filePath)) {
|
|
70
|
+
throw new Error(`File not found: ${this.filePath}`);
|
|
71
|
+
}
|
|
72
|
+
const sourceFile = this.project.addSourceFileAtPath(this.filePath);
|
|
73
|
+
const relativePath = path.relative(this.root, this.filePath);
|
|
74
|
+
// 1. Identify if it's a Controller or Service
|
|
75
|
+
const isController = this.filePath.endsWith('Controller.ts');
|
|
76
|
+
const isService = this.filePath.endsWith('Service.ts');
|
|
77
|
+
if (!isController && !isService) {
|
|
78
|
+
throw new Error('Target file must be a Controller or Service (.ts)');
|
|
79
|
+
}
|
|
80
|
+
// 2. Find the class
|
|
81
|
+
const targetClass = sourceFile.getFirstDescendantByKind(ts_morph_1.SyntaxKind.ClassDeclaration);
|
|
82
|
+
if (!targetClass) {
|
|
83
|
+
throw new Error('Could not find a class in the target file');
|
|
84
|
+
}
|
|
85
|
+
this.updateClass(targetClass, isController);
|
|
86
|
+
sourceFile.formatText();
|
|
87
|
+
if (this.dryRun) {
|
|
88
|
+
console.log(` [UPDATE] ${relativePath} (dry run)`);
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
await sourceFile.save();
|
|
92
|
+
console.log(` [UPDATE] ${relativePath}`);
|
|
93
|
+
}
|
|
94
|
+
const fileName = path.basename(this.filePath, '.ts');
|
|
95
|
+
const className = isController ? fileName.replace('Controller', '') : fileName.replace('Service', '');
|
|
96
|
+
if (!this.dryRun) {
|
|
97
|
+
if (isController) {
|
|
98
|
+
await (0, config_helper_1.updateControllerIndex)({
|
|
99
|
+
project: this.project,
|
|
100
|
+
paths: this.paths,
|
|
101
|
+
root: this.root,
|
|
102
|
+
controllerName: fileName,
|
|
103
|
+
className: className,
|
|
104
|
+
webservice: this.filePath.includes(path.join('controllers', 'webservice')),
|
|
105
|
+
dryRun: this.dryRun
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
await (0, config_helper_1.updateServiceIndex)({
|
|
110
|
+
project: this.project,
|
|
111
|
+
paths: this.paths,
|
|
112
|
+
root: this.root,
|
|
113
|
+
serviceName: fileName,
|
|
114
|
+
className: className,
|
|
115
|
+
dryRun: this.dryRun
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
// 3. Update routes and auth if it's a controller and route is provided
|
|
120
|
+
if (isController && this.route) {
|
|
121
|
+
const trimmedRoute = this.route.trim();
|
|
122
|
+
if (!trimmedRoute) {
|
|
123
|
+
throw new Error('Route cannot be empty or whitespace.');
|
|
124
|
+
}
|
|
125
|
+
const controllerName = fileName;
|
|
126
|
+
const webservice = this.filePath.includes(path.join('controllers', 'webservice'));
|
|
127
|
+
await (0, config_helper_1.updateRoutes)({
|
|
128
|
+
project: this.project,
|
|
129
|
+
paths: this.paths,
|
|
130
|
+
root: this.root,
|
|
131
|
+
route: trimmedRoute,
|
|
132
|
+
controllerName: controllerName,
|
|
133
|
+
action: this.method,
|
|
134
|
+
webservice: webservice,
|
|
135
|
+
dryRun: this.dryRun
|
|
136
|
+
});
|
|
137
|
+
if (this.auth && this.auth.length > 0) {
|
|
138
|
+
await (0, config_helper_1.updateAuth)({
|
|
139
|
+
project: this.project,
|
|
140
|
+
paths: this.paths,
|
|
141
|
+
root: this.root,
|
|
142
|
+
route: trimmedRoute,
|
|
143
|
+
auth: this.auth,
|
|
144
|
+
dryRun: this.dryRun
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
if (this.navigation.length > 0) {
|
|
148
|
+
const routePath = trimmedRoute.split(' ').pop();
|
|
149
|
+
if (!routePath) {
|
|
150
|
+
throw new Error(`Route is missing a path segment: '${trimmedRoute}'.`);
|
|
151
|
+
}
|
|
152
|
+
for (const nav of this.navigation) {
|
|
153
|
+
const actionName = nav.action || this.method;
|
|
154
|
+
if (actionName !== this.method) {
|
|
155
|
+
console.warn(` [NAV] Navigation mapping action '${actionName}' does not match method '${this.method}'. Skipping.`);
|
|
156
|
+
continue;
|
|
157
|
+
}
|
|
158
|
+
await (0, config_helper_1.updateNavigationConfig)({
|
|
159
|
+
project: this.project,
|
|
160
|
+
paths: this.paths,
|
|
161
|
+
root: this.root,
|
|
162
|
+
mapping: {
|
|
163
|
+
...nav,
|
|
164
|
+
href: routePath
|
|
165
|
+
},
|
|
166
|
+
dryRun: this.dryRun
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
if (this.languageDefaults.length > 0) {
|
|
172
|
+
await (0, config_helper_1.updateLanguageDefaults)({
|
|
173
|
+
root: this.root,
|
|
174
|
+
entries: this.languageDefaults,
|
|
175
|
+
dryRun: this.dryRun
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
updateClass(klass, isController) {
|
|
180
|
+
// 1. Add method stub if it doesn't exist
|
|
181
|
+
if (!klass.getMethod(this.method)) {
|
|
182
|
+
if (isController) {
|
|
183
|
+
klass.addMethod({
|
|
184
|
+
name: this.method,
|
|
185
|
+
scope: ts_morph_1.Scope.Public,
|
|
186
|
+
isAsync: true,
|
|
187
|
+
returnType: 'Promise<unknown>',
|
|
188
|
+
parameters: [
|
|
189
|
+
{ name: 'req', type: 'Sails.Req' },
|
|
190
|
+
{ name: 'res', type: 'Sails.Res' }
|
|
191
|
+
],
|
|
192
|
+
statements: `return this.sendResp(req, res, { data: { message: 'Action ${this.method} in ${klass.getName()}' } });`
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
else {
|
|
196
|
+
klass.addMethod({
|
|
197
|
+
name: this.method,
|
|
198
|
+
scope: ts_morph_1.Scope.Public,
|
|
199
|
+
isAsync: true,
|
|
200
|
+
returnType: 'Promise<Record<string, unknown>>',
|
|
201
|
+
parameters: [
|
|
202
|
+
{ name: '..._args', type: 'unknown[]' }
|
|
203
|
+
],
|
|
204
|
+
statements: [
|
|
205
|
+
`sails.log.verbose(\`\${this.logHeader} ${this.method} called\`);`,
|
|
206
|
+
`return { message: 'Method ${this.method} in ${klass.getName()}' };`
|
|
207
|
+
]
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
// 2. Update _exportedMethods
|
|
212
|
+
const exportedMethodsProp = klass.getProperty('_exportedMethods');
|
|
213
|
+
if (exportedMethodsProp) {
|
|
214
|
+
const initializer = exportedMethodsProp.getInitializerIfKind(ts_morph_1.SyntaxKind.ArrayLiteralExpression);
|
|
215
|
+
if (initializer) {
|
|
216
|
+
if (!initializer.getElements().some((e) => e.getText().replace(/['"]/g, '') === this.method)) {
|
|
217
|
+
initializer.addElement(`'${this.method}'`);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
else {
|
|
222
|
+
// Create _exportedMethods if missing
|
|
223
|
+
const hasInit = !!klass.getMethod('init');
|
|
224
|
+
const methods = hasInit ? ['init', this.method] : [this.method];
|
|
225
|
+
klass.addProperty({
|
|
226
|
+
name: '_exportedMethods',
|
|
227
|
+
scope: ts_morph_1.Scope.Protected,
|
|
228
|
+
hasOverrideKeyword: true,
|
|
229
|
+
type: 'string[]',
|
|
230
|
+
initializer: `[${methods.map(m => `'${m}'`).join(', ')}]`
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
exports.AddMethodGenerator = AddMethodGenerator;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { Generator, GeneratorOptions } from '../utils/generator';
|
|
2
|
+
import { RedboxPaths } from '../utils/paths';
|
|
3
|
+
export interface AngularAppGeneratorOptions extends GeneratorOptions {
|
|
4
|
+
name: string;
|
|
5
|
+
ejsView: string;
|
|
6
|
+
auth?: string[];
|
|
7
|
+
paths: RedboxPaths;
|
|
8
|
+
}
|
|
9
|
+
export declare class AngularAppGenerator extends Generator {
|
|
10
|
+
private name;
|
|
11
|
+
private ejsView;
|
|
12
|
+
private auth?;
|
|
13
|
+
private paths;
|
|
14
|
+
private project;
|
|
15
|
+
constructor(options: AngularAppGeneratorOptions);
|
|
16
|
+
generate(): Promise<void>;
|
|
17
|
+
private scaffoldAngularApp;
|
|
18
|
+
private updateAngularJson;
|
|
19
|
+
private generateEjsView;
|
|
20
|
+
private updateRouteConfig;
|
|
21
|
+
private updateAuthConfig;
|
|
22
|
+
private toClassName;
|
|
23
|
+
private getSafeEjsViewName;
|
|
24
|
+
}
|