@objectstack/cli 3.0.6 → 3.0.7
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/.turbo/turbo-build.log +2 -26
- package/CHANGELOG.md +14 -0
- package/README.md +98 -54
- package/bin/run-dev.js +5 -0
- package/bin/run.js +5 -0
- package/dist/bin.d.ts +11 -0
- package/dist/bin.d.ts.map +1 -0
- package/dist/bin.js +12 -3767
- package/dist/bin.js.map +1 -0
- package/dist/commands/codemod/v2-to-v3.d.ts +10 -0
- package/dist/commands/codemod/v2-to-v3.d.ts.map +1 -0
- package/dist/commands/codemod/v2-to-v3.js +145 -0
- package/dist/commands/codemod/v2-to-v3.js.map +1 -0
- package/dist/commands/compile.d.ts +13 -0
- package/dist/commands/compile.d.ts.map +1 -0
- package/dist/commands/compile.js +91 -0
- package/dist/commands/compile.js.map +1 -0
- package/dist/commands/create.d.ts +91 -0
- package/dist/commands/create.d.ts.map +1 -0
- package/dist/commands/create.js +259 -0
- package/dist/commands/create.js.map +1 -0
- package/dist/commands/dev.d.ts +14 -0
- package/dist/commands/dev.d.ts.map +1 -0
- package/dist/commands/dev.js +67 -0
- package/dist/commands/dev.js.map +1 -0
- package/dist/commands/diff.d.ts +16 -0
- package/dist/commands/diff.d.ts.map +1 -0
- package/dist/commands/diff.js +239 -0
- package/dist/commands/diff.js.map +1 -0
- package/dist/commands/doctor.d.ts +10 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +532 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/explain.d.ts +12 -0
- package/dist/commands/explain.d.ts.map +1 -0
- package/dist/commands/explain.js +368 -0
- package/dist/commands/explain.js.map +1 -0
- package/dist/commands/generate.d.ts +17 -0
- package/dist/commands/generate.d.ts.map +1 -0
- package/dist/commands/generate.js +833 -0
- package/dist/commands/generate.js.map +1 -0
- package/dist/commands/info.d.ts +12 -0
- package/dist/commands/info.d.ts.map +1 -0
- package/dist/commands/info.js +100 -0
- package/dist/commands/info.js.map +1 -0
- package/dist/commands/init.d.ts +22 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +295 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/lint.d.ts +13 -0
- package/dist/commands/lint.d.ts.map +1 -0
- package/dist/commands/lint.js +255 -0
- package/dist/commands/lint.js.map +1 -0
- package/dist/commands/plugin/add.d.ts +22 -0
- package/dist/commands/plugin/add.d.ts.map +1 -0
- package/dist/commands/plugin/add.js +93 -0
- package/dist/commands/plugin/add.js.map +1 -0
- package/dist/commands/plugin/info.d.ts +10 -0
- package/dist/commands/plugin/info.d.ts.map +1 -0
- package/dist/commands/plugin/info.js +65 -0
- package/dist/commands/plugin/info.js.map +1 -0
- package/dist/commands/plugin/list.d.ts +13 -0
- package/dist/commands/plugin/list.d.ts.map +1 -0
- package/dist/commands/plugin/list.js +78 -0
- package/dist/commands/plugin/list.js.map +1 -0
- package/dist/commands/plugin/remove.d.ts +20 -0
- package/dist/commands/plugin/remove.d.ts.map +1 -0
- package/dist/commands/plugin/remove.js +79 -0
- package/dist/commands/plugin/remove.js.map +1 -0
- package/dist/commands/serve.d.ts +15 -0
- package/dist/commands/serve.d.ts.map +1 -0
- package/dist/commands/serve.js +286 -0
- package/dist/commands/serve.js.map +1 -0
- package/dist/commands/studio.d.ts +19 -0
- package/dist/commands/studio.d.ts.map +1 -0
- package/dist/commands/studio.js +43 -0
- package/dist/commands/studio.js.map +1 -0
- package/dist/commands/test.d.ts +13 -0
- package/dist/commands/test.d.ts.map +1 -0
- package/dist/commands/test.js +120 -0
- package/dist/commands/test.js.map +1 -0
- package/dist/commands/validate.d.ts +13 -0
- package/dist/commands/validate.d.ts.map +1 -0
- package/dist/commands/validate.js +115 -0
- package/dist/commands/validate.js.map +1 -0
- package/dist/index.d.ts +15 -114
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +20 -2805
- package/dist/index.js.map +1 -0
- package/dist/utils/config.d.ts +21 -0
- package/dist/utils/config.d.ts.map +1 -0
- package/dist/utils/config.js +66 -0
- package/dist/utils/config.js.map +1 -0
- package/dist/utils/format.d.ts +52 -0
- package/dist/utils/format.d.ts.map +1 -0
- package/dist/utils/format.js +202 -0
- package/dist/utils/format.js.map +1 -0
- package/dist/utils/plugin-helpers.d.ts +14 -0
- package/dist/utils/plugin-helpers.d.ts.map +1 -0
- package/dist/utils/plugin-helpers.js +40 -0
- package/dist/utils/plugin-helpers.js.map +1 -0
- package/dist/utils/studio.d.ts +58 -0
- package/dist/utils/studio.d.ts.map +1 -0
- package/dist/utils/studio.js +288 -0
- package/dist/utils/studio.js.map +1 -0
- package/package.json +33 -15
- package/src/bin.ts +11 -104
- package/src/commands/{codemod.ts → codemod/v2-to-v3.ts} +21 -28
- package/src/commands/compile.ts +31 -22
- package/src/commands/create.ts +29 -19
- package/src/commands/dev.ts +21 -10
- package/src/commands/diff.ts +28 -19
- package/src/commands/doctor.ts +17 -10
- package/src/commands/explain.ts +20 -10
- package/src/commands/generate.ts +81 -90
- package/src/commands/info.ts +20 -11
- package/src/commands/init.ts +32 -20
- package/src/commands/lint.ts +24 -14
- package/src/commands/plugin/add.ts +112 -0
- package/src/commands/plugin/info.ts +79 -0
- package/src/commands/plugin/list.ts +93 -0
- package/src/commands/plugin/remove.ts +97 -0
- package/src/commands/serve.ts +30 -20
- package/src/commands/studio.ts +21 -11
- package/src/commands/test.ts +21 -10
- package/src/commands/validate.ts +32 -22
- package/src/index.ts +20 -12
- package/src/utils/plugin-helpers.ts +37 -0
- package/src/utils/studio.ts +0 -1
- package/test/commands.test.ts +76 -37
- package/test/plugin-commands.test.ts +42 -160
- package/test/plugin.test.ts +19 -23
- package/tsconfig.build.json +18 -0
- package/bin/objectstack.js +0 -2
- package/dist/chunk-T2YN4AB7.js +0 -249
- package/dist/chunk-XNACYTC5.js +0 -251
- package/dist/config-FOXDQ5F7.js +0 -10
- package/dist/config-GBR54FKL.js +0 -11
- package/src/commands/plugin.ts +0 -372
- package/src/utils/plugin-commands.ts +0 -163
package/src/commands/compile.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.
|
|
2
2
|
|
|
3
|
-
import { Command } from '
|
|
3
|
+
import { Args, Command, Flags } from '@oclif/core';
|
|
4
4
|
import path from 'path';
|
|
5
5
|
import fs from 'fs';
|
|
6
6
|
import chalk from 'chalk';
|
|
@@ -19,47 +19,55 @@ import {
|
|
|
19
19
|
printMetadataStats,
|
|
20
20
|
} from '../utils/format.js';
|
|
21
21
|
|
|
22
|
-
export
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
22
|
+
export default class Compile extends Command {
|
|
23
|
+
static override description = 'Compile ObjectStack configuration to JSON artifact';
|
|
24
|
+
|
|
25
|
+
static override args = {
|
|
26
|
+
config: Args.string({ description: 'Source configuration file', required: false }),
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
static override flags = {
|
|
30
|
+
output: Flags.string({ char: 'o', description: 'Output JSON file', default: 'dist/objectstack.json' }),
|
|
31
|
+
json: Flags.boolean({ description: 'Output compile result as JSON (for CI)' }),
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
async run(): Promise<void> {
|
|
35
|
+
const { args, flags } = await this.parse(Compile);
|
|
28
36
|
const timer = createTimer();
|
|
29
37
|
|
|
30
|
-
if (!
|
|
38
|
+
if (!flags.json) {
|
|
31
39
|
printHeader('Compile');
|
|
32
40
|
}
|
|
33
41
|
|
|
34
42
|
try {
|
|
35
43
|
// 1. Load Configuration
|
|
36
|
-
if (!
|
|
37
|
-
const { config, absolutePath, duration } = await loadConfig(
|
|
44
|
+
if (!flags.json) printStep('Loading configuration...');
|
|
45
|
+
const { config, absolutePath, duration } = await loadConfig(args.config);
|
|
38
46
|
|
|
39
|
-
if (!
|
|
47
|
+
if (!flags.json) {
|
|
40
48
|
printKV('Config', path.relative(process.cwd(), absolutePath));
|
|
41
49
|
printKV('Load time', `${duration}ms`);
|
|
42
50
|
}
|
|
43
51
|
|
|
44
52
|
// 2. Normalize map-formatted stack definition and validate against Protocol
|
|
45
|
-
if (!
|
|
53
|
+
if (!flags.json) printStep('Validating protocol compliance...');
|
|
46
54
|
const normalized = normalizeStackInput(config as Record<string, unknown>);
|
|
47
55
|
const result = ObjectStackDefinitionSchema.safeParse(normalized);
|
|
48
56
|
|
|
49
57
|
if (!result.success) {
|
|
50
|
-
if (
|
|
58
|
+
if (flags.json) {
|
|
51
59
|
console.log(JSON.stringify({ success: false, errors: (result.error as unknown as ZodError).issues }));
|
|
52
|
-
|
|
60
|
+
this.exit(1);
|
|
53
61
|
}
|
|
54
62
|
console.log('');
|
|
55
63
|
printError('Validation failed');
|
|
56
64
|
formatZodErrors(result.error as unknown as ZodError);
|
|
57
|
-
|
|
65
|
+
this.exit(1);
|
|
58
66
|
}
|
|
59
67
|
|
|
60
68
|
// 3. Generate Artifact
|
|
61
|
-
if (!
|
|
62
|
-
const output =
|
|
69
|
+
if (!flags.json) printStep('Writing artifact...');
|
|
70
|
+
const output = flags.output!;
|
|
63
71
|
const artifactPath = path.resolve(process.cwd(), output);
|
|
64
72
|
const artifactDir = path.dirname(artifactPath);
|
|
65
73
|
|
|
@@ -73,7 +81,7 @@ export const compileCommand = new Command('compile')
|
|
|
73
81
|
const sizeKB = (jsonContent.length / 1024).toFixed(1);
|
|
74
82
|
const stats = collectMetadataStats(config);
|
|
75
83
|
|
|
76
|
-
if (
|
|
84
|
+
if (flags.json) {
|
|
77
85
|
console.log(JSON.stringify({
|
|
78
86
|
success: true,
|
|
79
87
|
output: artifactPath,
|
|
@@ -94,12 +102,13 @@ export const compileCommand = new Command('compile')
|
|
|
94
102
|
console.log('');
|
|
95
103
|
|
|
96
104
|
} catch (error: any) {
|
|
97
|
-
if (
|
|
105
|
+
if (flags.json) {
|
|
98
106
|
console.log(JSON.stringify({ success: false, error: error.message }));
|
|
99
|
-
|
|
107
|
+
this.exit(1);
|
|
100
108
|
}
|
|
101
109
|
console.log('');
|
|
102
110
|
printError(error.message || String(error));
|
|
103
|
-
|
|
111
|
+
this.error(error.message || String(error));
|
|
104
112
|
}
|
|
105
|
-
}
|
|
113
|
+
}
|
|
114
|
+
}
|
package/src/commands/create.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.
|
|
2
2
|
|
|
3
|
-
import { Command } from '
|
|
3
|
+
import { Args, Command, Flags } from '@oclif/core';
|
|
4
4
|
import chalk from 'chalk';
|
|
5
5
|
import fs from 'fs';
|
|
6
6
|
import path from 'path';
|
|
@@ -182,37 +182,46 @@ function toCamelCase(str: string): string {
|
|
|
182
182
|
return str.replace(/-([a-z])/g, (g) => g[1].toUpperCase());
|
|
183
183
|
}
|
|
184
184
|
|
|
185
|
-
export
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
185
|
+
export default class Create extends Command {
|
|
186
|
+
static override description = 'Create a new package, plugin, or example from template';
|
|
187
|
+
|
|
188
|
+
static override args = {
|
|
189
|
+
type: Args.string({ description: 'Type of project to create (plugin, example)', required: true }),
|
|
190
|
+
name: Args.string({ description: 'Name of the project', required: false }),
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
static override flags = {
|
|
194
|
+
dir: Flags.string({ char: 'd', description: 'Target directory' }),
|
|
195
|
+
};
|
|
196
|
+
|
|
197
|
+
async run(): Promise<void> {
|
|
198
|
+
const { args, flags } = await this.parse(Create);
|
|
199
|
+
|
|
191
200
|
console.log(chalk.bold(`\n📦 ObjectStack Project Creator`));
|
|
192
201
|
console.log(chalk.dim(`-------------------------------`));
|
|
193
202
|
|
|
194
|
-
if (!templates[type as keyof typeof templates]) {
|
|
195
|
-
console.error(chalk.red(`\n❌ Unknown type: ${type}`));
|
|
203
|
+
if (!templates[args.type as keyof typeof templates]) {
|
|
204
|
+
console.error(chalk.red(`\n❌ Unknown type: ${args.type}`));
|
|
196
205
|
console.log(chalk.dim('Available types: plugin, example'));
|
|
197
206
|
process.exit(1);
|
|
198
207
|
}
|
|
199
208
|
|
|
200
|
-
if (!name) {
|
|
209
|
+
if (!args.name) {
|
|
201
210
|
console.error(chalk.red('\n❌ Project name is required'));
|
|
202
|
-
console.log(chalk.dim(`Usage: objectstack create ${type} <name>`));
|
|
211
|
+
console.log(chalk.dim(`Usage: objectstack create ${args.type} <name>`));
|
|
203
212
|
process.exit(1);
|
|
204
213
|
}
|
|
205
214
|
|
|
206
|
-
const template = templates[type as keyof typeof templates];
|
|
215
|
+
const template = templates[args.type as keyof typeof templates];
|
|
207
216
|
const cwd = process.cwd();
|
|
208
217
|
|
|
209
218
|
// Determine target directory
|
|
210
219
|
let targetDir: string;
|
|
211
|
-
if (
|
|
212
|
-
targetDir = path.resolve(cwd,
|
|
220
|
+
if (flags.dir) {
|
|
221
|
+
targetDir = path.resolve(cwd, flags.dir);
|
|
213
222
|
} else {
|
|
214
|
-
const baseDir = type === 'plugin' ? 'packages/plugins' : 'examples';
|
|
215
|
-
const projectName = type === 'plugin' ? `plugin-${name}` : name;
|
|
223
|
+
const baseDir = args.type === 'plugin' ? 'packages/plugins' : 'examples';
|
|
224
|
+
const projectName = args.type === 'plugin' ? `plugin-${args.name}` : args.name;
|
|
216
225
|
targetDir = path.join(cwd, baseDir, projectName);
|
|
217
226
|
}
|
|
218
227
|
|
|
@@ -222,7 +231,7 @@ export const createCommand = new Command('create')
|
|
|
222
231
|
process.exit(1);
|
|
223
232
|
}
|
|
224
233
|
|
|
225
|
-
console.log(`📁 Creating ${type}: ${chalk.blue(name)}`);
|
|
234
|
+
console.log(`📁 Creating ${args.type}: ${chalk.blue(args.name)}`);
|
|
226
235
|
console.log(`📂 Location: ${chalk.dim(targetDir)}`);
|
|
227
236
|
console.log('');
|
|
228
237
|
|
|
@@ -239,7 +248,7 @@ export const createCommand = new Command('create')
|
|
|
239
248
|
fs.mkdirSync(dir, { recursive: true });
|
|
240
249
|
}
|
|
241
250
|
|
|
242
|
-
const content = contentFn(name);
|
|
251
|
+
const content = contentFn(args.name);
|
|
243
252
|
const fileContent = typeof content === 'string'
|
|
244
253
|
? content
|
|
245
254
|
: JSON.stringify(content, null, 2);
|
|
@@ -268,4 +277,5 @@ export const createCommand = new Command('create')
|
|
|
268
277
|
|
|
269
278
|
process.exit(1);
|
|
270
279
|
}
|
|
271
|
-
}
|
|
280
|
+
}
|
|
281
|
+
}
|
package/src/commands/dev.ts
CHANGED
|
@@ -1,19 +1,29 @@
|
|
|
1
1
|
// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.
|
|
2
2
|
|
|
3
|
-
import { Command } from '
|
|
3
|
+
import { Args, Command, Flags } from '@oclif/core';
|
|
4
4
|
import chalk from 'chalk';
|
|
5
5
|
import { execSync, spawn } from 'child_process';
|
|
6
6
|
import fs from 'fs';
|
|
7
7
|
import path from 'path';
|
|
8
8
|
import { printHeader, printKV, printStep, printError } from '../utils/format.js';
|
|
9
9
|
|
|
10
|
-
export
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
10
|
+
export default class Dev extends Command {
|
|
11
|
+
static override description = 'Start development mode with hot-reload';
|
|
12
|
+
|
|
13
|
+
static override args = {
|
|
14
|
+
package: Args.string({ description: 'Package name or filter pattern', default: 'all', required: false }),
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
static override flags = {
|
|
18
|
+
watch: Flags.boolean({ char: 'w', description: 'Enable watch mode (default)', default: true }),
|
|
19
|
+
ui: Flags.boolean({ description: 'Enable Studio UI at /_studio/' }),
|
|
20
|
+
verbose: Flags.boolean({ char: 'v', description: 'Verbose output' }),
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
async run(): Promise<void> {
|
|
24
|
+
const { args, flags } = await this.parse(Dev);
|
|
25
|
+
const packageName = args.package;
|
|
26
|
+
|
|
17
27
|
printHeader('Development Mode');
|
|
18
28
|
|
|
19
29
|
// Check if we are running inside a package (Single Package Mode)
|
|
@@ -28,7 +38,7 @@ export const devCommand = new Command('dev')
|
|
|
28
38
|
// usage: objectstack serve --dev
|
|
29
39
|
const binPath = process.argv[1]; // path to objectstack bin
|
|
30
40
|
|
|
31
|
-
const child = spawn(process.execPath, [binPath, 'serve', '--dev', ...(
|
|
41
|
+
const child = spawn(process.execPath, [binPath, 'serve', '--dev', ...(flags.ui ? ['--ui'] : []), ...(flags.verbose ? ['--verbose'] : [])], {
|
|
32
42
|
stdio: 'inherit',
|
|
33
43
|
env: { ...process.env, NODE_ENV: 'development' }
|
|
34
44
|
});
|
|
@@ -69,4 +79,5 @@ export const devCommand = new Command('dev')
|
|
|
69
79
|
printError(`Development mode failed: ${error.message || error}`);
|
|
70
80
|
process.exit(1);
|
|
71
81
|
}
|
|
72
|
-
}
|
|
82
|
+
}
|
|
83
|
+
}
|
package/src/commands/diff.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.
|
|
2
2
|
|
|
3
|
-
import { Command } from '
|
|
3
|
+
import { Args, Command, Flags } from '@oclif/core';
|
|
4
4
|
import chalk from 'chalk';
|
|
5
5
|
import { loadConfig } from '../utils/config.js';
|
|
6
6
|
import {
|
|
@@ -153,19 +153,27 @@ function diffNamedArrays(
|
|
|
153
153
|
|
|
154
154
|
// ─── Command ────────────────────────────────────────────────────────
|
|
155
155
|
|
|
156
|
-
export
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
156
|
+
export default class Diff extends Command {
|
|
157
|
+
static override description = 'Compare two ObjectStack configurations and detect breaking changes';
|
|
158
|
+
|
|
159
|
+
static override args = {
|
|
160
|
+
before: Args.string({ description: 'Path to the "before" config file', required: false }),
|
|
161
|
+
after: Args.string({ description: 'Path to the "after" config file', required: false }),
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
static override flags = {
|
|
165
|
+
before: Flags.string({ description: 'Path to the "before" config (alternative)' }),
|
|
166
|
+
after: Flags.string({ description: 'Path to the "after" config (alternative)' }),
|
|
167
|
+
json: Flags.boolean({ description: 'Output as JSON' }),
|
|
168
|
+
'breaking-only': Flags.boolean({ description: 'Show only breaking changes' }),
|
|
169
|
+
};
|
|
170
|
+
|
|
171
|
+
async run(): Promise<void> {
|
|
172
|
+
const { args, flags } = await this.parse(Diff);
|
|
165
173
|
const timer = createTimer();
|
|
166
174
|
|
|
167
|
-
const beforePath: string | undefined =
|
|
168
|
-
const afterPath: string | undefined =
|
|
175
|
+
const beforePath: string | undefined = args.before || flags.before;
|
|
176
|
+
const afterPath: string | undefined = args.after || flags.after;
|
|
169
177
|
|
|
170
178
|
if (!beforePath || !afterPath) {
|
|
171
179
|
printError('Two config file paths are required.');
|
|
@@ -175,7 +183,7 @@ export const diffCommand = new Command('diff')
|
|
|
175
183
|
process.exit(1);
|
|
176
184
|
}
|
|
177
185
|
|
|
178
|
-
if (!
|
|
186
|
+
if (!flags.json) {
|
|
179
187
|
printHeader('Diff');
|
|
180
188
|
printStep('Loading configurations...');
|
|
181
189
|
}
|
|
@@ -184,7 +192,7 @@ export const diffCommand = new Command('diff')
|
|
|
184
192
|
const { config: beforeConfig } = await loadConfig(beforePath);
|
|
185
193
|
const { config: afterConfig } = await loadConfig(afterPath);
|
|
186
194
|
|
|
187
|
-
if (!
|
|
195
|
+
if (!flags.json) {
|
|
188
196
|
printInfo(`Before: ${chalk.white(beforePath)}`);
|
|
189
197
|
printInfo(`After: ${chalk.white(afterPath)}`);
|
|
190
198
|
}
|
|
@@ -215,14 +223,14 @@ export const diffCommand = new Command('diff')
|
|
|
215
223
|
}
|
|
216
224
|
|
|
217
225
|
// ── Filter ──
|
|
218
|
-
const diffs =
|
|
226
|
+
const diffs = flags['breaking-only']
|
|
219
227
|
? allDiffs.filter((d) => d.breaking)
|
|
220
228
|
: allDiffs;
|
|
221
229
|
|
|
222
230
|
const breakingCount = allDiffs.filter((d) => d.breaking).length;
|
|
223
231
|
|
|
224
232
|
// ── Output ──
|
|
225
|
-
if (
|
|
233
|
+
if (flags.json) {
|
|
226
234
|
console.log(JSON.stringify({
|
|
227
235
|
before: beforePath,
|
|
228
236
|
after: afterPath,
|
|
@@ -237,7 +245,7 @@ export const diffCommand = new Command('diff')
|
|
|
237
245
|
console.log('');
|
|
238
246
|
|
|
239
247
|
if (diffs.length === 0) {
|
|
240
|
-
printSuccess(
|
|
248
|
+
printSuccess(flags['breaking-only']
|
|
241
249
|
? 'No breaking changes detected.'
|
|
242
250
|
: 'No changes detected.');
|
|
243
251
|
console.log('');
|
|
@@ -274,7 +282,7 @@ export const diffCommand = new Command('diff')
|
|
|
274
282
|
console.log('');
|
|
275
283
|
|
|
276
284
|
} catch (error: any) {
|
|
277
|
-
if (
|
|
285
|
+
if (flags.json) {
|
|
278
286
|
console.log(JSON.stringify({ error: error.message }));
|
|
279
287
|
process.exit(1);
|
|
280
288
|
}
|
|
@@ -282,4 +290,5 @@ export const diffCommand = new Command('diff')
|
|
|
282
290
|
printError(error.message || String(error));
|
|
283
291
|
process.exit(1);
|
|
284
292
|
}
|
|
285
|
-
}
|
|
293
|
+
}
|
|
294
|
+
}
|
package/src/commands/doctor.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.
|
|
2
2
|
|
|
3
|
-
import { Command } from '
|
|
3
|
+
import { Command, Flags } from '@oclif/core';
|
|
4
4
|
import chalk from 'chalk';
|
|
5
5
|
import { execSync } from 'child_process';
|
|
6
6
|
import fs from 'fs';
|
|
@@ -299,11 +299,17 @@ function scanDeprecatedPatterns(dir: string): Array<{ file: string; line: number
|
|
|
299
299
|
|
|
300
300
|
// ─── Command ────────────────────────────────────────────────────────
|
|
301
301
|
|
|
302
|
-
export
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
302
|
+
export default class Doctor extends Command {
|
|
303
|
+
static override description = 'Check development environment and configuration health';
|
|
304
|
+
|
|
305
|
+
static override flags = {
|
|
306
|
+
verbose: Flags.boolean({ char: 'v', description: 'Show detailed information' }),
|
|
307
|
+
'scan-deprecations': Flags.boolean({ description: 'Scan for deprecated ObjectStack patterns' }),
|
|
308
|
+
};
|
|
309
|
+
|
|
310
|
+
async run(): Promise<void> {
|
|
311
|
+
const { flags } = await this.parse(Doctor);
|
|
312
|
+
|
|
307
313
|
printHeader('Environment Health Check');
|
|
308
314
|
|
|
309
315
|
const results: HealthCheckResult[] = [];
|
|
@@ -439,7 +445,7 @@ export const doctorCommand = new Command('doctor')
|
|
|
439
445
|
printError(`${padded} ${result.message}`);
|
|
440
446
|
}
|
|
441
447
|
|
|
442
|
-
if (result.fix && (
|
|
448
|
+
if (result.fix && (flags.verbose || result.status === 'error')) {
|
|
443
449
|
console.log(chalk.dim(` → ${result.fix}`));
|
|
444
450
|
}
|
|
445
451
|
|
|
@@ -526,7 +532,7 @@ export const doctorCommand = new Command('doctor')
|
|
|
526
532
|
}
|
|
527
533
|
|
|
528
534
|
// ── Deprecation Pattern Scan ─────────────────────────────────────
|
|
529
|
-
if (
|
|
535
|
+
if (flags['scan-deprecations']) {
|
|
530
536
|
printStep('Scanning for deprecated ObjectStack patterns...');
|
|
531
537
|
const scanDir = path.join(cwd, 'src');
|
|
532
538
|
const deprecations = scanDeprecatedPatterns(scanDir);
|
|
@@ -534,7 +540,7 @@ export const doctorCommand = new Command('doctor')
|
|
|
534
540
|
hasWarnings = true;
|
|
535
541
|
for (const dep of deprecations) {
|
|
536
542
|
printWarning(`${dep.file}:${dep.line} — ${dep.description}`);
|
|
537
|
-
if (
|
|
543
|
+
if (flags.verbose) {
|
|
538
544
|
console.log(chalk.dim(` → ${dep.replacement}`));
|
|
539
545
|
}
|
|
540
546
|
}
|
|
@@ -562,4 +568,5 @@ export const doctorCommand = new Command('doctor')
|
|
|
562
568
|
}
|
|
563
569
|
|
|
564
570
|
console.log('');
|
|
565
|
-
}
|
|
571
|
+
}
|
|
572
|
+
}
|
package/src/commands/explain.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.
|
|
2
2
|
|
|
3
|
-
import { Command } from '
|
|
3
|
+
import { Args, Command, Flags } from '@oclif/core';
|
|
4
4
|
import chalk from 'chalk';
|
|
5
5
|
import {
|
|
6
6
|
printHeader,
|
|
@@ -314,15 +314,24 @@ const SCHEMAS: Record<string, SchemaInfo> = {
|
|
|
314
314
|
|
|
315
315
|
// ─── Command ────────────────────────────────────────────────────────
|
|
316
316
|
|
|
317
|
-
export
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
317
|
+
export default class Explain extends Command {
|
|
318
|
+
static override description = 'Display human-readable explanation of an ObjectStack schema';
|
|
319
|
+
|
|
320
|
+
static override args = {
|
|
321
|
+
schema: Args.string({ description: 'Schema name (e.g., object, field, view, flow, agent, app)', required: false }),
|
|
322
|
+
};
|
|
323
|
+
|
|
324
|
+
static override flags = {
|
|
325
|
+
json: Flags.boolean({ description: 'Output as JSON' }),
|
|
326
|
+
};
|
|
327
|
+
|
|
328
|
+
async run(): Promise<void> {
|
|
329
|
+
const { args, flags } = await this.parse(Explain);
|
|
330
|
+
const schemaName = args.schema;
|
|
322
331
|
|
|
323
332
|
// ── No argument: list all schemas ──
|
|
324
333
|
if (!schemaName) {
|
|
325
|
-
if (
|
|
334
|
+
if (flags.json) {
|
|
326
335
|
console.log(JSON.stringify({
|
|
327
336
|
schemas: Object.entries(SCHEMAS).map(([key, s]) => ({
|
|
328
337
|
name: key,
|
|
@@ -347,7 +356,7 @@ export const explainCommand = new Command('explain')
|
|
|
347
356
|
// ── Lookup schema ──
|
|
348
357
|
const schema = SCHEMAS[schemaName.toLowerCase()];
|
|
349
358
|
if (!schema) {
|
|
350
|
-
if (
|
|
359
|
+
if (flags.json) {
|
|
351
360
|
console.log(JSON.stringify({ error: `Unknown schema: ${schemaName}` }));
|
|
352
361
|
process.exit(1);
|
|
353
362
|
}
|
|
@@ -359,7 +368,7 @@ export const explainCommand = new Command('explain')
|
|
|
359
368
|
}
|
|
360
369
|
|
|
361
370
|
// ── JSON output ──
|
|
362
|
-
if (
|
|
371
|
+
if (flags.json) {
|
|
363
372
|
console.log(JSON.stringify(schema, null, 2));
|
|
364
373
|
return;
|
|
365
374
|
}
|
|
@@ -399,4 +408,5 @@ export const explainCommand = new Command('explain')
|
|
|
399
408
|
// Documentation link
|
|
400
409
|
printKV(' Docs', `https://objectstack.dev/docs/${schema.docsPath}`);
|
|
401
410
|
console.log('');
|
|
402
|
-
}
|
|
411
|
+
}
|
|
412
|
+
}
|