@kosdev-code/kos-ui-cli 0.1.0-dev.5053

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/README.md +7 -0
  2. package/package.json +30 -0
  3. package/src/index.d.ts +2 -0
  4. package/src/index.d.ts.map +1 -0
  5. package/src/index.js +1 -0
  6. package/src/index.js.map +1 -0
  7. package/src/lib/cli.mjs +803 -0
  8. package/src/lib/generators/cache/index.mjs +18 -0
  9. package/src/lib/generators/component/index.mjs +55 -0
  10. package/src/lib/generators/env/index.mjs +42 -0
  11. package/src/lib/generators/i18n/namespace.mjs +61 -0
  12. package/src/lib/generators/kab/index.mjs +82 -0
  13. package/src/lib/generators/metadata.json +341 -0
  14. package/src/lib/generators/model/add-future.mjs +96 -0
  15. package/src/lib/generators/model/companion.mjs +117 -0
  16. package/src/lib/generators/model/container.mjs +96 -0
  17. package/src/lib/generators/model/context.mjs +77 -0
  18. package/src/lib/generators/model/hook.mjs +77 -0
  19. package/src/lib/generators/model/model.mjs +79 -0
  20. package/src/lib/generators/plugin/index.mjs +195 -0
  21. package/src/lib/generators/project/app.mjs +39 -0
  22. package/src/lib/generators/project/content.mjs +41 -0
  23. package/src/lib/generators/project/i18n.mjs +38 -0
  24. package/src/lib/generators/project/plugin.mjs +38 -0
  25. package/src/lib/generators/project/splash.mjs +39 -0
  26. package/src/lib/generators/project/theme.mjs +38 -0
  27. package/src/lib/generators/serve/index.mjs +74 -0
  28. package/src/lib/generators/version/index.mjs +182 -0
  29. package/src/lib/generators/workspace/index.mjs +40 -0
  30. package/src/lib/generators/workspace/list-models.mjs +64 -0
  31. package/src/lib/generators/workspace/list-projects.mjs +167 -0
  32. package/src/lib/plopfile.mjs +67 -0
  33. package/src/lib/routing-plopfile.mjs +53 -0
  34. package/src/lib/scripts/generate-metadata.mjs +39 -0
  35. package/src/lib/utils/action-factory.mjs +9 -0
  36. package/src/lib/utils/cache.mjs +128 -0
  37. package/src/lib/utils/command-builder.mjs +94 -0
  38. package/src/lib/utils/exec.mjs +18 -0
  39. package/src/lib/utils/generator-loader.mjs +65 -0
  40. package/src/lib/utils/index.mjs +1 -0
  41. package/src/lib/utils/java-home.mjs +55 -0
  42. package/src/lib/utils/logger.mjs +0 -0
  43. package/src/lib/utils/nx-context.mjs +395 -0
  44. package/src/lib/utils/prompts.mjs +75 -0
  45. package/src/lib/utils/studio-home.mjs +12 -0
  46. package/src/lib/utils/utils.mjs +126 -0
  47. package/src/lib/utils/validators.mjs +10 -0
@@ -0,0 +1,117 @@
1
+ // generators/model/companion.mjs
2
+ import { actionFactory } from "../../utils/action-factory.mjs";
3
+ import { execute } from "../../utils/exec.mjs";
4
+ import {
5
+ getAllModels,
6
+ getModelProjectsWithFallback,
7
+ getProjectDetails,
8
+ } from "../../utils/nx-context.mjs";
9
+ import {
10
+ COMPANION_PROMPTS,
11
+ DEFAULT_PROMPTS,
12
+ MODEL_PROMPTS,
13
+ } from "../../utils/prompts.mjs";
14
+ import { required } from "../../utils/validators.mjs";
15
+
16
+ export const metadata = {
17
+ key: "model:companion",
18
+ name: "KOS Companion Model",
19
+ namedArguments: {
20
+ name: "modelName",
21
+ modelName: "modelName",
22
+ project: "modelProject",
23
+ modelProject: "modelProject",
24
+ companionParent: "companionParent",
25
+ companionPattern: "companionPattern",
26
+ container: "container",
27
+ parentAware: "parentAware",
28
+ singleton: "singleton",
29
+ dataServices: "dataServices",
30
+ autoRegister: "autoRegister",
31
+ dryRun: "dryRun",
32
+ interactive: "interactive",
33
+ },
34
+ };
35
+
36
+ export default async function (plop) {
37
+ const libraryProjects = await getModelProjectsWithFallback();
38
+
39
+ // Check if we're in interactive mode by looking at process args
40
+ const isInteractive = process.argv.includes('-i') || process.argv.includes('--interactive');
41
+
42
+ // For interactive mode, use lazy loading. For non-interactive, load immediately.
43
+ let modelChoices;
44
+ if (isInteractive) {
45
+ modelChoices = async () => {
46
+ const allModels = await getAllModels();
47
+ return allModels.map((m) => ({
48
+ name: `${m.model} (${m.project})`,
49
+ value: m.model,
50
+ }));
51
+ };
52
+ } else {
53
+ const allModels = await getAllModels();
54
+ modelChoices = allModels.map((m) => ({
55
+ name: `${m.model} (${m.project})`,
56
+ value: m.model,
57
+ }));
58
+ }
59
+
60
+ plop.setActionType("createCompanionModel", async function (answers) {
61
+ const modelProject = await getProjectDetails(answers.modelProject);
62
+ const allModels = await getAllModels();
63
+ const companionProject = allModels.find(
64
+ (m) => m.model === answers.companionParent
65
+ )?.project;
66
+
67
+ const command = `npx nx generate @kosdev-code/kos-nx-plugin:kos-model \
68
+ --name=${answers.modelName} \
69
+ --modelProject=${modelProject.name} \
70
+ --skipRegistration=true \
71
+ --container=${!!answers.container} \
72
+ --dataServices=${!!answers.dataServices} \
73
+ --singleton=${!!answers.singleton} \
74
+ --parentAware=${!!answers.parentAware} \
75
+ --autoRegister=${!!answers.autoRegister} \
76
+ --companion=true \
77
+ --companionModel=${answers.companionParent} \
78
+ --companionModelProject=${companionProject} \
79
+ --companionPattern=${answers.companionPattern} \
80
+ --no-interactive ${answers.dryRun ? "--dryRun" : ""} --verbose`;
81
+
82
+ try {
83
+ await execute(command);
84
+ } catch (error) {
85
+ throw new Error(error);
86
+ }
87
+ });
88
+
89
+ plop.setGenerator("model:companion", {
90
+ description: "Create a new KOS Companion Model",
91
+ prompts: [
92
+ ...DEFAULT_PROMPTS,
93
+ {
94
+ type: "input",
95
+ name: "modelName",
96
+ message: "Enter the name of the model",
97
+ validate: required,
98
+ },
99
+ {
100
+ type: "list",
101
+ name: "modelProject",
102
+ message: "Which model project to use?",
103
+ validate: required,
104
+ choices: libraryProjects,
105
+ },
106
+ {
107
+ type: "list",
108
+ name: "companionParent",
109
+ message: "Select the companion parent model",
110
+ choices: modelChoices,
111
+ },
112
+ ...COMPANION_PROMPTS,
113
+ ...MODEL_PROMPTS,
114
+ ],
115
+ actions: actionFactory("createCompanionModel", metadata),
116
+ });
117
+ }
@@ -0,0 +1,96 @@
1
+ // generators/model/container.mjs
2
+ import { actionFactory } from "../../utils/action-factory.mjs";
3
+ import { execute } from "../../utils/exec.mjs";
4
+ import {
5
+ getAllModels,
6
+ getAllProjects,
7
+ getProjectDetails,
8
+ } from "../../utils/nx-context.mjs";
9
+ import { DEFAULT_PROMPTS, MODEL_PROMPTS } from "../../utils/prompts.mjs";
10
+
11
+ export const metadata = {
12
+ key: "container",
13
+ name: "KOS Container Model",
14
+ namedArguments: {
15
+ modelName: "modelName",
16
+ registrationProject: "registrationProject",
17
+ container: "container",
18
+ parentAware: "parentAware",
19
+ singleton: "singleton",
20
+ dataServices: "dataServices",
21
+ autoRegister: "autoRegister",
22
+ dryRun: "dryRun",
23
+ interactive: "interactive",
24
+ },
25
+ };
26
+
27
+ export default async function (plop) {
28
+ const allProjects = await getAllProjects();
29
+
30
+ // Check if we're in interactive mode by looking at process args
31
+ const isInteractive = process.argv.includes('-i') || process.argv.includes('--interactive');
32
+
33
+ // For interactive mode, use lazy loading. For non-interactive, load immediately.
34
+ let modelChoices;
35
+ if (isInteractive) {
36
+ modelChoices = async () => {
37
+ const allModels = await getAllModels();
38
+ return allModels.map((m) => ({
39
+ name: `${m.model} (${m.project})`,
40
+ value: m.model,
41
+ }));
42
+ };
43
+ } else {
44
+ const allModels = await getAllModels();
45
+ modelChoices = allModels.map((m) => ({
46
+ name: `${m.model} (${m.project})`,
47
+ value: m.model,
48
+ }));
49
+ }
50
+
51
+ plop.setActionType("createContainer", async function (answers) {
52
+ const allModels = await getAllModels();
53
+ const modelProject = allModels.find(
54
+ (m) => m.model === answers.modelName
55
+ )?.project;
56
+ const projectDetails = await getProjectDetails(modelProject);
57
+
58
+ const command = `npx nx generate @kosdev-code/kos-nx-plugin:kos-container-model \
59
+ --modelName=${answers.modelName} \
60
+ --modelProject=${projectDetails.name} \
61
+ --skipRegistration=true \
62
+ --dataServices=${!!answers.dataServices} \
63
+ --singleton=${!!answers.singleton} \
64
+ --autoRegister=${!!answers.autoRegister} \
65
+ --no-interactive ${answers.dryRun ? "--dryRun" : ""} --verbose`;
66
+
67
+ try {
68
+ await execute(command);
69
+ } catch (error) {
70
+ throw new Error(error);
71
+ }
72
+
73
+ return `Container model created for ${answers.modelName}`;
74
+ });
75
+
76
+ plop.setGenerator("container", {
77
+ description: "Create a new KOS Container Model",
78
+ prompts: [
79
+ ...DEFAULT_PROMPTS,
80
+ {
81
+ type: "list",
82
+ name: "modelName",
83
+ message: "Which model to use?",
84
+ choices: modelChoices,
85
+ },
86
+ {
87
+ type: "list",
88
+ name: "registrationProject",
89
+ message: "Which project should the model be registered in?",
90
+ choices: allProjects,
91
+ },
92
+ ...MODEL_PROMPTS,
93
+ ],
94
+ actions: actionFactory("createContainer", metadata),
95
+ });
96
+ }
@@ -0,0 +1,77 @@
1
+ // generators/model/context.mjs
2
+ import { actionFactory } from "../../utils/action-factory.mjs";
3
+ import { execute } from "../../utils/exec.mjs";
4
+ import { getAllModels, getAllProjects } from "../../utils/nx-context.mjs";
5
+ export const metadata = {
6
+ key: "context",
7
+ name: "KOS Model React Context",
8
+ namedArguments: {
9
+ modelName: "modelName",
10
+ componentProject: "componentProject",
11
+ project: "componentProject",
12
+ },
13
+ };
14
+
15
+ export default async function (plop) {
16
+ const allProjects = await getAllProjects();
17
+
18
+ // Check if we're in interactive mode by looking at process args
19
+ const isInteractive = process.argv.includes('-i') || process.argv.includes('--interactive');
20
+
21
+ // For interactive mode, use lazy loading. For non-interactive, load immediately.
22
+ let modelChoices;
23
+ if (isInteractive) {
24
+ modelChoices = async () => {
25
+ const allModels = await getAllModels();
26
+ return allModels.map((m) => ({
27
+ name: `${m.model} (${m.project})`,
28
+ value: m.model,
29
+ }));
30
+ };
31
+ } else {
32
+ const allModels = await getAllModels();
33
+ modelChoices = allModels.map((m) => ({
34
+ name: `${m.model} (${m.project})`,
35
+ value: m.model,
36
+ }));
37
+ }
38
+
39
+ plop.setActionType("createContext", async function (answers) {
40
+ const allModels = await getAllModels();
41
+ const modelProject = allModels.find(
42
+ (m) => m.model === answers.modelName
43
+ )?.project;
44
+ const command = `npx nx generate @kosdev-code/kos-nx-plugin:kos-context \
45
+ --appProject=${answers.componentProject} \
46
+ --modelProject=${modelProject} \
47
+ --name=${answers.modelName} \
48
+ --no-interactive ${answers.dryRun ? "--dryRun" : ""}`;
49
+
50
+ try {
51
+ await execute(command);
52
+ } catch (error) {
53
+ throw new Error(error);
54
+ }
55
+
56
+ return `Context created for ${answers.modelName} in ${answers.componentProject}`;
57
+ });
58
+
59
+ plop.setGenerator("context", {
60
+ description: "Create a context for a KOS Model",
61
+ prompts: [
62
+ {
63
+ type: "list",
64
+ name: "modelName",
65
+ message: "Which model to use?",
66
+ choices: modelChoices,
67
+ },
68
+ {
69
+ type: "list",
70
+ name: "componentProject",
71
+ message: "Which project should the context be created in?",
72
+ choices: allProjects,
73
+ },
74
+ ],
75
+ actions: actionFactory("createContext", metadata),
76
+ });
77
+ }
@@ -0,0 +1,77 @@
1
+ // generators/model/hook.mjs
2
+ import { actionFactory } from "../../utils/action-factory.mjs";
3
+ import { execute } from "../../utils/exec.mjs";
4
+ import { getAllModels, getAllProjects } from "../../utils/nx-context.mjs";
5
+ export const metadata = {
6
+ key: "hook",
7
+ name: "KOS Model React Hook",
8
+ namedArguments: {
9
+ modelName: "modelName",
10
+ componentProject: "componentProject",
11
+ project: "componentProject"
12
+ }
13
+ };
14
+
15
+ export default async function (plop) {
16
+ const allProjects = await getAllProjects();
17
+
18
+ // Check if we're in interactive mode by looking at process args
19
+ const isInteractive = process.argv.includes('-i') || process.argv.includes('--interactive');
20
+
21
+ // For interactive mode, use lazy loading. For non-interactive, load immediately.
22
+ let modelChoices;
23
+ if (isInteractive) {
24
+ modelChoices = async () => {
25
+ const allModels = await getAllModels();
26
+ return allModels.map((m) => ({
27
+ name: `${m.model} (${m.project})`,
28
+ value: m.model,
29
+ }));
30
+ };
31
+ } else {
32
+ const allModels = await getAllModels();
33
+ modelChoices = allModels.map((m) => ({
34
+ name: `${m.model} (${m.project})`,
35
+ value: m.model,
36
+ }));
37
+ }
38
+
39
+ plop.setActionType("createHook", async function (answers) {
40
+ const allModels = await getAllModels();
41
+ const modelProject = allModels.find(
42
+ (m) => m.model === answers.modelName
43
+ )?.project;
44
+ const command = `npx nx generate @kosdev-code/kos-nx-plugin:kos-hook \
45
+ --appProject=${answers.componentProject} \
46
+ --modelProject=${modelProject} \
47
+ --name=${answers.modelName} \
48
+ --no-interactive ${answers.dryRun ? "--dryRun" : ""}`;
49
+
50
+ try {
51
+ await execute(command);
52
+ } catch (error) {
53
+ throw new Error(error);
54
+ }
55
+
56
+ return `Hook created for ${answers.modelName} in ${answers.componentProject}`;
57
+ });
58
+
59
+ plop.setGenerator("hook", {
60
+ description: "Create a hook for a KOS Model",
61
+ prompts: [
62
+ {
63
+ type: "list",
64
+ name: "modelName",
65
+ message: "Which model to use?",
66
+ choices: modelChoices,
67
+ },
68
+ {
69
+ type: "list",
70
+ name: "componentProject",
71
+ message: "Which project should the hook be created in?",
72
+ choices: allProjects,
73
+ },
74
+ ],
75
+ actions: actionFactory("createHook", metadata),
76
+ });
77
+ }
@@ -0,0 +1,79 @@
1
+ // generators/model/model.mjs
2
+ import { actionFactory } from "../../utils/action-factory.mjs";
3
+ import { execute } from "../../utils/exec.mjs";
4
+ import {
5
+ getModelProjectsWithFallback,
6
+ getProjectDetails,
7
+ } from "../../utils/nx-context.mjs";
8
+ import { DEFAULT_PROMPTS, MODEL_PROMPTS } from "../../utils/prompts.mjs";
9
+ import { required } from "../../utils/validators.mjs";
10
+
11
+ export const metadata = {
12
+ key: "model",
13
+ name: "KOS Model",
14
+ invalidateCache: true,
15
+ namedArguments: {
16
+ name: "modelName",
17
+ modelName: "modelName",
18
+ project: "modelProject",
19
+ modelProject: "modelProject",
20
+ container: "container",
21
+ parentAware: "parentAware",
22
+ singleton: "singleton",
23
+ dataServices: "dataServices",
24
+ futureAware: "futureAware",
25
+ autoRegister: "autoRegister",
26
+ dryRun: "dryRun",
27
+ interactive: "interactive"
28
+ }
29
+ };
30
+
31
+ export default async function (plop) {
32
+ const libraryProjects = await getModelProjectsWithFallback();
33
+
34
+ plop.setActionType("createModel", async function (answers) {
35
+ const modelProject = await getProjectDetails(answers.modelProject);
36
+ const command = `npx nx generate @kosdev-code/kos-nx-plugin:kos-model \
37
+ --name=${answers.modelName} \
38
+ --modelProject=${modelProject.name} \
39
+ --skipRegistration=true \
40
+ --container=${!!answers.container} \
41
+ --dataServices=${!!answers.dataServices} \
42
+ --singleton=${!!answers.singleton} \
43
+ --parentAware=${!!answers.parentAware} \
44
+ --futureAware=${answers.futureAware || 'none'} \
45
+ --autoRegister=${!!answers.autoRegister} \
46
+ --no-interactive ${answers.dryRun ? "--dryRun" : ""} --verbose`;
47
+
48
+ try {
49
+ await execute(command);
50
+ } catch (error) {
51
+ throw new Error(error);
52
+ }
53
+
54
+ return `Model ${answers.modelName} created in ${answers.modelProject}`;
55
+ });
56
+
57
+ plop.setGenerator("model", {
58
+ description: "Create a new KOS Model",
59
+ prompts: [
60
+ ...DEFAULT_PROMPTS,
61
+ {
62
+ type: "input",
63
+ name: "modelName",
64
+ message: "Enter the name of the model",
65
+ validate: required,
66
+ },
67
+ {
68
+ type: "list",
69
+ name: "modelProject",
70
+ message: "Which model project to use?",
71
+ validate: required,
72
+ choices: libraryProjects,
73
+ },
74
+ ...MODEL_PROMPTS,
75
+ ],
76
+
77
+ actions: actionFactory("createModel", metadata),
78
+ });
79
+ }
@@ -0,0 +1,195 @@
1
+ // generators/plugin/plugin.mjs
2
+
3
+ import { execute } from "../../utils/exec.mjs";
4
+ import { getPluginProjectsWithFallback } from "../../utils/nx-context.mjs";
5
+ import { required } from "../../utils/validators.mjs";
6
+ export const metadata = [
7
+ {
8
+ key: "pluginComponent",
9
+ name: "KOS UI Plugin Component",
10
+ namedArguments: {
11
+ name: "componentName",
12
+ componentName: "componentName",
13
+ project: "componentProject",
14
+ componentProject: "componentProject",
15
+ extensionPoint: "extensionPoint"
16
+ }
17
+ },
18
+ {
19
+ key: "plugin:cui",
20
+ name: "KOS UI Plugin CUI Configuration",
21
+ namedArguments: {
22
+ name: "componentName",
23
+ componentName: "componentName",
24
+ project: "componentProject",
25
+ componentProject: "componentProject"
26
+ }
27
+ },
28
+ {
29
+ key: "plugin:setup",
30
+ name: "KOS UI Plugin Setup Step",
31
+ namedArguments: {
32
+ name: "componentName",
33
+ componentName: "componentName",
34
+ project: "componentProject",
35
+ componentProject: "componentProject"
36
+ }
37
+ },
38
+ {
39
+ key: "plugin:utility",
40
+ name: "KOS UI Plugin Utility",
41
+ namedArguments: {
42
+ name: "componentName",
43
+ componentName: "componentName",
44
+ project: "componentProject",
45
+ componentProject: "componentProject"
46
+ }
47
+ },
48
+ {
49
+ key: "plugin:setting",
50
+ name: "KOS UI Plugin Setting",
51
+ namedArguments: {
52
+ name: "componentName",
53
+ componentName: "componentName",
54
+ project: "componentProject",
55
+ componentProject: "componentProject",
56
+ group: "group"
57
+ }
58
+ },
59
+ {
60
+ key: "plugin:nav",
61
+ name: "KOS UI Plugin Navigation View",
62
+ namedArguments: {
63
+ name: "componentName",
64
+ componentName: "componentName",
65
+ project: "componentProject",
66
+ componentProject: "componentProject"
67
+ }
68
+ },
69
+ {
70
+ key: "plugin:cp",
71
+ name: "KOS UI Plugin Control Pour",
72
+ namedArguments: {
73
+ name: "componentName",
74
+ componentName: "componentName",
75
+ project: "componentProject",
76
+ componentProject: "componentProject"
77
+ }
78
+ },
79
+ {
80
+ key: "plugin:custom",
81
+ name: "KOS UI Plugin Custom (User-Specified Contribution)",
82
+ namedArguments: {
83
+ name: "componentName",
84
+ componentName: "componentName",
85
+ project: "componentProject",
86
+ componentProject: "componentProject",
87
+ contributionKey: "contributionKey"
88
+ }
89
+ },
90
+ ];
91
+
92
+ export default async function (plop) {
93
+ const pluginProjects = await getPluginProjectsWithFallback();
94
+
95
+ plop.setActionType("createPluginComponent", async function (answers) {
96
+ const pluginType = answers.extensionPoint;
97
+
98
+ let command = `npx nx generate @kosdev-code/kos-nx-plugin:kos-component --name=${answers.componentName} --group=${answers.group} --appProject=${answers.componentProject} --pluginType=${pluginType} --type=components --no-interactive`;
99
+
100
+ // Add contributionKey for custom plugin types
101
+ if (pluginType === 'custom' && answers.contributionKey) {
102
+ command = `npx nx generate @kosdev-code/kos-nx-plugin:kos-component --name=${answers.componentName} --contributionKey=${answers.contributionKey} --appProject=${answers.componentProject} --pluginType=${pluginType} --type=components --no-interactive`;
103
+ }
104
+
105
+ try {
106
+ await execute(command);
107
+ } catch (error) {
108
+ throw new Error(error);
109
+ }
110
+
111
+ return `Component ${answers.componentName} created in ${answers.componentProject}`;
112
+ });
113
+ const pluginPrompts = [
114
+ {
115
+ type: "input",
116
+ name: "componentName",
117
+ message: "Enter the name of the component",
118
+ validate: required,
119
+ },
120
+ {
121
+ type: "list",
122
+ name: "componentProject",
123
+ message: "Which project should the component be created in?",
124
+ choices: pluginProjects,
125
+ },
126
+ ];
127
+
128
+ const pluginTypes = [
129
+ { key: "plugin:cui", name: "cui" },
130
+ { key: "plugin:setup", name: "setup" },
131
+ { key: "plugin:utility", name: "utility" },
132
+ { key: "plugin:setting", name: "setting" },
133
+ { key: "plugin:nav", name: "nav" },
134
+ { key: "plugin:cp", name: "controlPour" },
135
+ { key: "plugin:custom", name: "custom" },
136
+ ];
137
+
138
+ // Generic plugin component
139
+ plop.setGenerator("pluginComponent", {
140
+ description: "Create a new KOS Plugin Component",
141
+ prompts: [
142
+ ...pluginPrompts,
143
+ {
144
+ type: "list",
145
+ name: "extensionPoint",
146
+ message: "What type of extension point is the plugin supporting?",
147
+ choices: pluginTypes.map((pt) => pt.name),
148
+ },
149
+ ],
150
+ actions: [{ type: "createPluginComponent" }],
151
+ });
152
+
153
+ // Specific plugin type aliases
154
+ for (const { key, name } of pluginTypes) {
155
+ const prompts = [
156
+ ...pluginPrompts,
157
+ ...(name === "setting"
158
+ ? [
159
+ {
160
+ type: "input",
161
+ name: "group",
162
+ message: "Which settings group should the setting be located?",
163
+ },
164
+ ]
165
+ : []),
166
+ ...(name === "custom"
167
+ ? [
168
+ {
169
+ type: "input",
170
+ name: "contributionKey",
171
+ message: "What contribution key should be used in .kos.json? (e.g., 'menus', 'panels', 'commands', etc.)",
172
+ validate: required,
173
+ },
174
+ ]
175
+ : []),
176
+ {
177
+ type: "input",
178
+ name: "extensionPoint",
179
+ message: "Hidden extensionPoint",
180
+ default: name,
181
+ when: false, // hide from CLI
182
+ },
183
+ ];
184
+
185
+ plop.setGenerator(key, {
186
+ description: `Create a new KOS ${
187
+ name[0].toUpperCase() + name.slice(1)
188
+ } Plugin Component`,
189
+ prompts,
190
+ actions: [
191
+ { type: "createPluginComponent", data: { extensionPoint: name } },
192
+ ],
193
+ });
194
+ }
195
+ }
@@ -0,0 +1,39 @@
1
+ // generators/project/app.mjs
2
+ import { actionFactory } from "../../utils/action-factory.mjs";
3
+ import { execute } from "../../utils/exec.mjs";
4
+ import { required } from "../../utils/validators.mjs";
5
+
6
+ export const metadata = {
7
+ key: "project",
8
+ name: "KOS UI App Project",
9
+ invalidateCache: true,
10
+ namedArguments: { name: "name" },
11
+ };
12
+ export default async function (plop) {
13
+ plop.setActionType("createUiProject", async function (answers) {
14
+ const command = `npx nx generate @kosdev-code/kos-nx-plugin:kos-ui-project \
15
+ --name=${answers.name} \
16
+ --no-interactive`;
17
+
18
+ try {
19
+ await execute(command);
20
+ } catch (error) {
21
+ throw new Error(error);
22
+ }
23
+
24
+ return `UI project ${answers.name} created.`;
25
+ });
26
+
27
+ plop.setGenerator("project", {
28
+ description: "Create a new KOS UI App project",
29
+ prompts: [
30
+ {
31
+ type: "input",
32
+ name: "name",
33
+ message: "What is the name of the app project?",
34
+ validate: required,
35
+ },
36
+ ],
37
+ actions: actionFactory("createUiProject", metadata),
38
+ });
39
+ }