@kosdev-code/kos-ui-cli 2.0.44 → 2.0.45
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 +481 -4
- package/package.json +5 -3
- package/src/lib/cli.mjs +59 -467
- package/src/lib/generators/api/compare.mjs +139 -0
- package/src/lib/generators/api/generate.mjs +105 -0
- package/src/lib/generators/api/lib/compare-api.mjs +748 -0
- package/src/lib/generators/api/lib/generate-api.mjs +452 -0
- package/src/lib/generators/dev/index.mjs +437 -0
- package/src/lib/generators/env/index.mjs +1 -0
- package/src/lib/generators/kab/index.mjs +82 -0
- package/src/lib/generators/metadata.json +71 -2
- package/src/lib/generators/model/add-future.mjs +21 -5
- package/src/lib/generators/model/companion.mjs +24 -5
- package/src/lib/generators/model/container.mjs +24 -5
- package/src/lib/generators/model/context.mjs +22 -5
- package/src/lib/generators/model/hook.mjs +22 -5
- package/src/lib/generators/model/model.mjs +3 -1
- package/src/lib/generators/plugin/index.mjs +30 -3
- package/src/lib/generators/serve/index.mjs +74 -0
- package/src/lib/generators/version/index.mjs +182 -0
- package/src/lib/generators/workspace/index.mjs +13 -3
- package/src/lib/plopfile.mjs +12 -0
- package/src/lib/utils/cli-help-display.mjs +84 -0
- package/src/lib/utils/cli-help-utils.mjs +261 -0
- package/src/lib/utils/command-builder.mjs +94 -0
- package/src/lib/utils/dev-config.mjs +150 -0
|
@@ -27,21 +27,39 @@ export const metadata = {
|
|
|
27
27
|
parentAware: "parentAware",
|
|
28
28
|
singleton: "singleton",
|
|
29
29
|
dataServices: "dataServices",
|
|
30
|
+
autoRegister: "autoRegister",
|
|
30
31
|
dryRun: "dryRun",
|
|
31
32
|
interactive: "interactive",
|
|
32
33
|
},
|
|
33
34
|
};
|
|
34
35
|
|
|
35
36
|
export default async function (plop) {
|
|
36
|
-
const allModels = await getAllModels();
|
|
37
37
|
const libraryProjects = await getModelProjectsWithFallback();
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
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
|
+
}
|
|
42
59
|
|
|
43
60
|
plop.setActionType("createCompanionModel", async function (answers) {
|
|
44
61
|
const modelProject = await getProjectDetails(answers.modelProject);
|
|
62
|
+
const allModels = await getAllModels();
|
|
45
63
|
const companionProject = allModels.find(
|
|
46
64
|
(m) => m.model === answers.companionParent
|
|
47
65
|
)?.project;
|
|
@@ -54,6 +72,7 @@ export default async function (plop) {
|
|
|
54
72
|
--dataServices=${!!answers.dataServices} \
|
|
55
73
|
--singleton=${!!answers.singleton} \
|
|
56
74
|
--parentAware=${!!answers.parentAware} \
|
|
75
|
+
--autoRegister=${!!answers.autoRegister} \
|
|
57
76
|
--companion=true \
|
|
58
77
|
--companionModel=${answers.companionParent} \
|
|
59
78
|
--companionModelProject=${companionProject} \
|
|
@@ -18,20 +18,38 @@ export const metadata = {
|
|
|
18
18
|
parentAware: "parentAware",
|
|
19
19
|
singleton: "singleton",
|
|
20
20
|
dataServices: "dataServices",
|
|
21
|
+
autoRegister: "autoRegister",
|
|
21
22
|
dryRun: "dryRun",
|
|
22
23
|
interactive: "interactive",
|
|
23
24
|
},
|
|
24
25
|
};
|
|
25
26
|
|
|
26
27
|
export default async function (plop) {
|
|
27
|
-
const allModels = await getAllModels();
|
|
28
28
|
const allProjects = await getAllProjects();
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
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
|
+
}
|
|
33
50
|
|
|
34
51
|
plop.setActionType("createContainer", async function (answers) {
|
|
52
|
+
const allModels = await getAllModels();
|
|
35
53
|
const modelProject = allModels.find(
|
|
36
54
|
(m) => m.model === answers.modelName
|
|
37
55
|
)?.project;
|
|
@@ -43,6 +61,7 @@ export default async function (plop) {
|
|
|
43
61
|
--skipRegistration=true \
|
|
44
62
|
--dataServices=${!!answers.dataServices} \
|
|
45
63
|
--singleton=${!!answers.singleton} \
|
|
64
|
+
--autoRegister=${!!answers.autoRegister} \
|
|
46
65
|
--no-interactive ${answers.dryRun ? "--dryRun" : ""} --verbose`;
|
|
47
66
|
|
|
48
67
|
try {
|
|
@@ -14,13 +14,30 @@ export const metadata = {
|
|
|
14
14
|
|
|
15
15
|
export default async function (plop) {
|
|
16
16
|
const allProjects = await getAllProjects();
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
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
|
+
}
|
|
22
38
|
|
|
23
39
|
plop.setActionType("createContext", async function (answers) {
|
|
40
|
+
const allModels = await getAllModels();
|
|
24
41
|
const modelProject = allModels.find(
|
|
25
42
|
(m) => m.model === answers.modelName
|
|
26
43
|
)?.project;
|
|
@@ -14,13 +14,30 @@ export const metadata = {
|
|
|
14
14
|
|
|
15
15
|
export default async function (plop) {
|
|
16
16
|
const allProjects = await getAllProjects();
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
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
|
+
}
|
|
22
38
|
|
|
23
39
|
plop.setActionType("createHook", async function (answers) {
|
|
40
|
+
const allModels = await getAllModels();
|
|
24
41
|
const modelProject = allModels.find(
|
|
25
42
|
(m) => m.model === answers.modelName
|
|
26
43
|
)?.project;
|
|
@@ -15,13 +15,14 @@ export const metadata = {
|
|
|
15
15
|
namedArguments: {
|
|
16
16
|
name: "modelName",
|
|
17
17
|
modelName: "modelName",
|
|
18
|
-
project: "modelProject",
|
|
18
|
+
project: "modelProject",
|
|
19
19
|
modelProject: "modelProject",
|
|
20
20
|
container: "container",
|
|
21
21
|
parentAware: "parentAware",
|
|
22
22
|
singleton: "singleton",
|
|
23
23
|
dataServices: "dataServices",
|
|
24
24
|
futureAware: "futureAware",
|
|
25
|
+
autoRegister: "autoRegister",
|
|
25
26
|
dryRun: "dryRun",
|
|
26
27
|
interactive: "interactive"
|
|
27
28
|
}
|
|
@@ -41,6 +42,7 @@ export default async function (plop) {
|
|
|
41
42
|
--singleton=${!!answers.singleton} \
|
|
42
43
|
--parentAware=${!!answers.parentAware} \
|
|
43
44
|
--futureAware=${answers.futureAware || 'none'} \
|
|
45
|
+
--autoRegister=${!!answers.autoRegister} \
|
|
44
46
|
--no-interactive ${answers.dryRun ? "--dryRun" : ""} --verbose`;
|
|
45
47
|
|
|
46
48
|
try {
|
|
@@ -66,8 +66,8 @@ export const metadata = [
|
|
|
66
66
|
componentProject: "componentProject"
|
|
67
67
|
}
|
|
68
68
|
},
|
|
69
|
-
{
|
|
70
|
-
key: "plugin:cp",
|
|
69
|
+
{
|
|
70
|
+
key: "plugin:cp",
|
|
71
71
|
name: "KOS UI Plugin Control Pour",
|
|
72
72
|
namedArguments: {
|
|
73
73
|
name: "componentName",
|
|
@@ -76,6 +76,17 @@ export const metadata = [
|
|
|
76
76
|
componentProject: "componentProject"
|
|
77
77
|
}
|
|
78
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
|
+
},
|
|
79
90
|
];
|
|
80
91
|
|
|
81
92
|
export default async function (plop) {
|
|
@@ -84,7 +95,12 @@ export default async function (plop) {
|
|
|
84
95
|
plop.setActionType("createPluginComponent", async function (answers) {
|
|
85
96
|
const pluginType = answers.extensionPoint;
|
|
86
97
|
|
|
87
|
-
|
|
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
|
+
}
|
|
88
104
|
|
|
89
105
|
try {
|
|
90
106
|
await execute(command);
|
|
@@ -116,6 +132,7 @@ export default async function (plop) {
|
|
|
116
132
|
{ key: "plugin:setting", name: "setting" },
|
|
117
133
|
{ key: "plugin:nav", name: "nav" },
|
|
118
134
|
{ key: "plugin:cp", name: "controlPour" },
|
|
135
|
+
{ key: "plugin:custom", name: "custom" },
|
|
119
136
|
];
|
|
120
137
|
|
|
121
138
|
// Generic plugin component
|
|
@@ -146,6 +163,16 @@ export default async function (plop) {
|
|
|
146
163
|
},
|
|
147
164
|
]
|
|
148
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
|
+
: []),
|
|
149
176
|
{
|
|
150
177
|
type: "input",
|
|
151
178
|
name: "extensionPoint",
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
// generators/serve/index.mjs
|
|
2
|
+
import { execSync } from "child_process";
|
|
3
|
+
import { detectWorkspace } from "../../utils/nx-context.mjs";
|
|
4
|
+
|
|
5
|
+
export const metadata = {
|
|
6
|
+
key: "serve",
|
|
7
|
+
name: "Run Serve Target",
|
|
8
|
+
namedArguments: {
|
|
9
|
+
project: "project",
|
|
10
|
+
interactive: "interactive"
|
|
11
|
+
},
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
async function getProjectsWithTarget(target) {
|
|
15
|
+
try {
|
|
16
|
+
const output = execSync(`npx nx show projects --with-target ${target} --json`, {
|
|
17
|
+
encoding: "utf-8",
|
|
18
|
+
stdio: ["pipe", "pipe", "ignore"]
|
|
19
|
+
});
|
|
20
|
+
return JSON.parse(output);
|
|
21
|
+
} catch (error) {
|
|
22
|
+
return [];
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export default async function (plop) {
|
|
27
|
+
const projects = await getProjectsWithTarget("serve");
|
|
28
|
+
|
|
29
|
+
if (projects.length === 0) {
|
|
30
|
+
console.warn("[kos-cli] No projects found with serve target");
|
|
31
|
+
// Still register the generator but it will fail gracefully
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
plop.setActionType("runServe", async function (answers) {
|
|
35
|
+
const isWorkspace = await detectWorkspace();
|
|
36
|
+
|
|
37
|
+
if (!isWorkspace) {
|
|
38
|
+
console.warn(
|
|
39
|
+
"[kos-cli] Not inside an Nx workspace. Cannot run serve target."
|
|
40
|
+
);
|
|
41
|
+
return "Skipped: Not a workspace";
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const { project } = answers;
|
|
45
|
+
|
|
46
|
+
console.log(`[kos-cli] Running serve on ${project}...`);
|
|
47
|
+
try {
|
|
48
|
+
// Run serve in foreground with stdio inherited so it stays alive
|
|
49
|
+
execSync(`npx nx run ${project}:serve`, {
|
|
50
|
+
stdio: "inherit",
|
|
51
|
+
});
|
|
52
|
+
return `Serve completed for ${project}`;
|
|
53
|
+
} catch (error) {
|
|
54
|
+
// Don't throw error for Ctrl+C or normal termination
|
|
55
|
+
if (error.signal === "SIGINT") {
|
|
56
|
+
return `Serve terminated for ${project}`;
|
|
57
|
+
}
|
|
58
|
+
throw new Error(`Failed to run serve on ${project}: ${error.message}`);
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
plop.setGenerator("serve", {
|
|
63
|
+
description: "Run the serve target on a project",
|
|
64
|
+
prompts: [
|
|
65
|
+
{
|
|
66
|
+
type: "list",
|
|
67
|
+
name: "project",
|
|
68
|
+
message: "Select a project to serve:",
|
|
69
|
+
choices: projects,
|
|
70
|
+
},
|
|
71
|
+
],
|
|
72
|
+
actions: () => [{ type: "runServe" }],
|
|
73
|
+
});
|
|
74
|
+
}
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
// generators/version/index.mjs
|
|
2
|
+
import { execSync } from "child_process";
|
|
3
|
+
import { existsSync, readFileSync } from "fs";
|
|
4
|
+
import path from "path";
|
|
5
|
+
import { detectWorkspace } from "../../utils/nx-context.mjs";
|
|
6
|
+
|
|
7
|
+
export const metadata = {
|
|
8
|
+
key: "version",
|
|
9
|
+
name: "Display CLI and SDK Version Information",
|
|
10
|
+
namedArguments: { interactive: "interactive" },
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
function getPackageVersion(packagePath) {
|
|
14
|
+
try {
|
|
15
|
+
const packageJsonPath = path.join(packagePath, "package.json");
|
|
16
|
+
if (existsSync(packageJsonPath)) {
|
|
17
|
+
const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf8"));
|
|
18
|
+
return packageJson.version || "unknown";
|
|
19
|
+
}
|
|
20
|
+
} catch (error) {
|
|
21
|
+
// Package not found
|
|
22
|
+
}
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function findWorkspaceRoot(startDir = process.cwd()) {
|
|
27
|
+
let dir = startDir;
|
|
28
|
+
while (dir !== path.dirname(dir)) {
|
|
29
|
+
if (existsSync(path.join(dir, "nx.json"))) {
|
|
30
|
+
return dir;
|
|
31
|
+
}
|
|
32
|
+
dir = path.dirname(dir);
|
|
33
|
+
}
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function getCliVersion() {
|
|
38
|
+
let version = null;
|
|
39
|
+
|
|
40
|
+
// Option 1: Check workspace root package.json for installed CLI
|
|
41
|
+
const workspaceRoot = findWorkspaceRoot();
|
|
42
|
+
if (workspaceRoot) {
|
|
43
|
+
try {
|
|
44
|
+
const output = execSync(
|
|
45
|
+
"npm list @kosdev-code/kos-ui-cli --depth=0 --json",
|
|
46
|
+
{
|
|
47
|
+
cwd: workspaceRoot,
|
|
48
|
+
encoding: "utf-8",
|
|
49
|
+
stdio: ["pipe", "pipe", "ignore"],
|
|
50
|
+
}
|
|
51
|
+
);
|
|
52
|
+
const data = JSON.parse(output);
|
|
53
|
+
version = data?.dependencies?.["@kosdev-code/kos-ui-cli"]?.version;
|
|
54
|
+
} catch (error) {
|
|
55
|
+
// Not in workspace dependencies
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Option 2: Check global installation
|
|
60
|
+
if (!version) {
|
|
61
|
+
try {
|
|
62
|
+
const output = execSync(
|
|
63
|
+
"npm list -g @kosdev-code/kos-ui-cli --depth=0 --json",
|
|
64
|
+
{
|
|
65
|
+
encoding: "utf-8",
|
|
66
|
+
stdio: ["pipe", "pipe", "ignore"],
|
|
67
|
+
}
|
|
68
|
+
);
|
|
69
|
+
const data = JSON.parse(output);
|
|
70
|
+
version = data?.dependencies?.["@kosdev-code/kos-ui-cli"]?.version;
|
|
71
|
+
} catch (error) {
|
|
72
|
+
// Not installed globally
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return version || "unknown";
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export default async function (plop) {
|
|
80
|
+
plop.setActionType("showVersions", async function () {
|
|
81
|
+
console.log("[kos-cli] Discovering version information...\n");
|
|
82
|
+
|
|
83
|
+
const isWorkspace = await detectWorkspace();
|
|
84
|
+
const workspaceRoot = findWorkspaceRoot();
|
|
85
|
+
|
|
86
|
+
const versions = {};
|
|
87
|
+
|
|
88
|
+
// Get CLI version
|
|
89
|
+
versions.cli = getCliVersion();
|
|
90
|
+
|
|
91
|
+
if (isWorkspace && workspaceRoot) {
|
|
92
|
+
// Get SDK versions from workspace dependencies
|
|
93
|
+
const sdkPackages = {
|
|
94
|
+
sdk: ["@kosdev-code/kos-ui-sdk", "@kosdev-code/kos-dispense-sdk"],
|
|
95
|
+
ddk: [
|
|
96
|
+
"@kosdev-code/kos-ddk-components",
|
|
97
|
+
"@kosdev-code/kos-ddk-model-components",
|
|
98
|
+
],
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
for (const [type, packages] of Object.entries(sdkPackages)) {
|
|
102
|
+
for (const pkgName of packages) {
|
|
103
|
+
try {
|
|
104
|
+
const output = execSync(`npm list ${pkgName} --depth=0 --json`, {
|
|
105
|
+
cwd: workspaceRoot,
|
|
106
|
+
encoding: "utf-8",
|
|
107
|
+
stdio: ["pipe", "pipe", "ignore"],
|
|
108
|
+
});
|
|
109
|
+
const data = JSON.parse(output);
|
|
110
|
+
const version = data?.dependencies?.[pkgName]?.version;
|
|
111
|
+
if (version) {
|
|
112
|
+
// Store with short name (without @kosdev-code/ prefix)
|
|
113
|
+
const shortName = pkgName.replace("@kosdev-code/", "");
|
|
114
|
+
versions[shortName] = version;
|
|
115
|
+
}
|
|
116
|
+
} catch (error) {
|
|
117
|
+
// Package not installed in workspace
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// Display results
|
|
124
|
+
console.log("Version Information:");
|
|
125
|
+
console.log("===================\n");
|
|
126
|
+
|
|
127
|
+
if (versions.cli) {
|
|
128
|
+
console.log(`kos-ui-cli: ${versions.cli}`);
|
|
129
|
+
} else {
|
|
130
|
+
console.log("kos-ui-cli: unknown");
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
if (isWorkspace) {
|
|
134
|
+
console.log("");
|
|
135
|
+
console.log("SDK Packages:");
|
|
136
|
+
console.log("-------------");
|
|
137
|
+
|
|
138
|
+
if (versions["kos-ui-sdk"]) {
|
|
139
|
+
console.log(`kos-ui-sdk: ${versions["kos-ui-sdk"]}`);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
if (versions["kos-dispense-sdk"]) {
|
|
143
|
+
console.log(`kos-dispense-sdk: ${versions["kos-dispense-sdk"]}`);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
console.log("");
|
|
147
|
+
console.log("DDK Packages:");
|
|
148
|
+
console.log("-------------");
|
|
149
|
+
|
|
150
|
+
if (versions["kos-ddk-components"]) {
|
|
151
|
+
console.log(`kos-ddk-components: ${versions["kos-ddk-components"]}`);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
if (versions["kos-ddk-model-components"]) {
|
|
155
|
+
console.log(
|
|
156
|
+
`kos-ddk-model-components: ${versions["kos-ddk-model-components"]}`
|
|
157
|
+
);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
if (!versions["kos-ui-sdk"] && !versions["kos-dispense-sdk"]) {
|
|
161
|
+
console.log("(No SDK packages found in workspace)");
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
if (
|
|
165
|
+
!versions["kos-ddk-components"] &&
|
|
166
|
+
!versions["kos-ddk-model-components"]
|
|
167
|
+
) {
|
|
168
|
+
console.log("(No DDK packages found in workspace)");
|
|
169
|
+
}
|
|
170
|
+
} else {
|
|
171
|
+
console.log("\n(Not in workspace - SDK versions unavailable)");
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
return "\n";
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
plop.setGenerator("version", {
|
|
178
|
+
description: "Display CLI and SDK version information",
|
|
179
|
+
prompts: [],
|
|
180
|
+
actions: () => [{ type: "showVersions" }],
|
|
181
|
+
});
|
|
182
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// generators/workspace/index.mjs
|
|
2
|
-
|
|
2
|
+
// Note: create-nx-workspace is imported lazily to avoid dependency errors
|
|
3
3
|
import { required } from "../../utils/validators.mjs";
|
|
4
4
|
import registerListModels from "./list-models.mjs";
|
|
5
5
|
import registerListProjects from "./list-projects.mjs";
|
|
@@ -9,14 +9,18 @@ export const metadata = {
|
|
|
9
9
|
name: "Create a new KOS UI Workspace",
|
|
10
10
|
namedArguments: {
|
|
11
11
|
name: "workspaceName",
|
|
12
|
-
workspaceName: "workspaceName"
|
|
12
|
+
workspaceName: "workspaceName",
|
|
13
|
+
enablePlugins: "enablePlugins"
|
|
13
14
|
}
|
|
14
15
|
};
|
|
15
16
|
export default async function (plop) {
|
|
16
17
|
plop.setActionType("createWorkspace", async function (answers) {
|
|
18
|
+
// Lazy import to avoid dependency errors when not using workspace generator
|
|
19
|
+
const { createWorkspace } = await import("create-nx-workspace");
|
|
17
20
|
await createWorkspace("@kosdev-code/kos-nx-plugin", {
|
|
18
21
|
nxCloud: "skip",
|
|
19
22
|
name: answers.workspaceName,
|
|
23
|
+
enablePlugins: answers.enablePlugins,
|
|
20
24
|
});
|
|
21
25
|
return `Workspace ${answers.workspaceName} created.`;
|
|
22
26
|
});
|
|
@@ -30,10 +34,16 @@ export default async function (plop) {
|
|
|
30
34
|
message: "Enter the workspace name",
|
|
31
35
|
validate: required,
|
|
32
36
|
},
|
|
37
|
+
{
|
|
38
|
+
type: "confirm",
|
|
39
|
+
name: "enablePlugins",
|
|
40
|
+
message: "Do you want to enable plugin support?",
|
|
41
|
+
default: true,
|
|
42
|
+
},
|
|
33
43
|
],
|
|
34
44
|
actions: () => [{ type: "createWorkspace" }],
|
|
35
45
|
});
|
|
36
|
-
|
|
46
|
+
|
|
37
47
|
// Register additional workspace generators
|
|
38
48
|
await registerListModels(plop);
|
|
39
49
|
await registerListProjects(plop);
|
package/src/lib/plopfile.mjs
CHANGED
|
@@ -12,8 +12,14 @@ import registerKosModel from "./generators/model/model.mjs";
|
|
|
12
12
|
import registerComponent from "./generators/component/index.mjs";
|
|
13
13
|
import registerPluginComponent from "./generators/plugin/index.mjs";
|
|
14
14
|
|
|
15
|
+
import registerApiGenerate from "./generators/api/generate.mjs";
|
|
16
|
+
import registerApiCompare from "./generators/api/compare.mjs";
|
|
15
17
|
import registerCacheGenerators from "./generators/cache/index.mjs";
|
|
18
|
+
import registerDev from "./generators/dev/index.mjs";
|
|
16
19
|
import registerEnv from "./generators/env/index.mjs";
|
|
20
|
+
import registerKab from "./generators/kab/index.mjs";
|
|
21
|
+
import registerServe from "./generators/serve/index.mjs";
|
|
22
|
+
import registerVersion from "./generators/version/index.mjs";
|
|
17
23
|
import registerI18nNamespace from "./generators/i18n/namespace.mjs";
|
|
18
24
|
import registerUiProject from "./generators/project/app.mjs";
|
|
19
25
|
import registerContentProject from "./generators/project/content.mjs";
|
|
@@ -56,6 +62,12 @@ export default async function (plop) {
|
|
|
56
62
|
await registerSplashProject(plop);
|
|
57
63
|
await registerI18n(plop);
|
|
58
64
|
await registerI18nNamespace(plop);
|
|
65
|
+
await registerApiGenerate(plop);
|
|
66
|
+
await registerApiCompare(plop);
|
|
67
|
+
await registerDev(plop);
|
|
59
68
|
await registerEnv(plop);
|
|
69
|
+
await registerKab(plop);
|
|
70
|
+
await registerServe(plop);
|
|
71
|
+
await registerVersion(plop);
|
|
60
72
|
await registerCacheGenerators(plop);
|
|
61
73
|
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI help display utilities
|
|
3
|
+
*
|
|
4
|
+
* High-level help display functions for the KOS CLI. Coordinates the display
|
|
5
|
+
* of generator-specific help and general CLI help using utilities from
|
|
6
|
+
* cli-help-utils.mjs.
|
|
7
|
+
*
|
|
8
|
+
* @module cli-help-display
|
|
9
|
+
*/
|
|
10
|
+
import { displayExamples, displayNamedArguments } from "./cli-help-utils.mjs";
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Display comprehensive help information for a specific generator.
|
|
14
|
+
*
|
|
15
|
+
* Shows the generator's name, description, named arguments mapping, and
|
|
16
|
+
* usage examples. This provides users with all the information needed to
|
|
17
|
+
* use a specific CLI command effectively.
|
|
18
|
+
*
|
|
19
|
+
* @param {string} command - The command name (e.g., 'model', 'api:generate')
|
|
20
|
+
* @param {Object} meta - Generator metadata from the generator's export
|
|
21
|
+
* @param {string} meta.name - Display name for the generator
|
|
22
|
+
* @param {string} meta.description - Brief description of what the generator does
|
|
23
|
+
* @param {Object} meta.namedArguments - Mapping of CLI args to prompt names
|
|
24
|
+
* @param {Object} [generator=null] - Optional plop generator object (fallback for metadata)
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* displayGeneratorHelp('api:generate', {
|
|
28
|
+
* name: 'Generate OpenAPI service types',
|
|
29
|
+
* description: 'Generate typed service helpers from OpenAPI specifications',
|
|
30
|
+
* namedArguments: { project: 'project', host: 'host' }
|
|
31
|
+
* })
|
|
32
|
+
*/
|
|
33
|
+
export function displayGeneratorHelp(command, meta, generator = null) {
|
|
34
|
+
console.log(`--- ${meta?.name || command} Help ---`);
|
|
35
|
+
console.log(
|
|
36
|
+
meta?.description || generator?.description || "No description available"
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
displayNamedArguments(meta?.namedArguments);
|
|
40
|
+
displayExamples(command, meta?.namedArguments);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Display general CLI help showing all available generators and global options.
|
|
45
|
+
*
|
|
46
|
+
* Outputs a comprehensive overview of the KOS CLI including:
|
|
47
|
+
* - List of all available generators with descriptions
|
|
48
|
+
* - General usage pattern
|
|
49
|
+
* - Global options that apply to all commands
|
|
50
|
+
* - Help invocation instructions
|
|
51
|
+
*
|
|
52
|
+
* This is displayed when users run `kosui --help` or `kosui` with no command.
|
|
53
|
+
*
|
|
54
|
+
* @param {Object} plop - The plop instance containing registered generators
|
|
55
|
+
*
|
|
56
|
+
* @example
|
|
57
|
+
* displayGeneralHelp(plopInstance)
|
|
58
|
+
* // Outputs:
|
|
59
|
+
* // --- KOS CLI Help ---
|
|
60
|
+
* //
|
|
61
|
+
* // Available Generators:
|
|
62
|
+
* // - model: Generate KOS models
|
|
63
|
+
* // - api:generate: Generate OpenAPI service types
|
|
64
|
+
* // ...
|
|
65
|
+
*/
|
|
66
|
+
export function displayGeneralHelp(plop) {
|
|
67
|
+
console.warn("--- KOS CLI Help ---");
|
|
68
|
+
console.log("\nAvailable Generators:");
|
|
69
|
+
plop.getGeneratorList().forEach((g) => {
|
|
70
|
+
console.log(`- ${g.name}: ${g.description}`);
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
console.log("\nUsage:");
|
|
74
|
+
console.log(" kosui <generator> [options]");
|
|
75
|
+
console.log(" kosui <generator> --help # Show generator-specific help");
|
|
76
|
+
console.log("\nGlobal Options:");
|
|
77
|
+
console.log(" --no-cache Disable cache");
|
|
78
|
+
console.log(" --refresh Clear cache and refresh");
|
|
79
|
+
console.log(" --quiet Suppress banner and debug output");
|
|
80
|
+
console.log(
|
|
81
|
+
" --interactive, -i Force interactive mode (ignore provided arguments)"
|
|
82
|
+
);
|
|
83
|
+
console.log(" --help Show this help");
|
|
84
|
+
}
|