@objectstack/cli 4.0.3 → 4.0.5

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 (241) hide show
  1. package/README.md +12 -25
  2. package/dist/commands/build.d.ts +5 -0
  3. package/dist/commands/build.d.ts.map +1 -0
  4. package/dist/commands/build.js +6 -0
  5. package/dist/commands/build.js.map +1 -0
  6. package/dist/commands/compile.d.ts +3 -0
  7. package/dist/commands/compile.d.ts.map +1 -1
  8. package/dist/commands/compile.js +128 -6
  9. package/dist/commands/compile.js.map +1 -1
  10. package/dist/commands/create.js +1 -1
  11. package/dist/commands/data/create.js +2 -2
  12. package/dist/commands/data/create.js.map +1 -1
  13. package/dist/commands/data/delete.js +2 -2
  14. package/dist/commands/data/delete.js.map +1 -1
  15. package/dist/commands/data/get.js +2 -2
  16. package/dist/commands/data/get.js.map +1 -1
  17. package/dist/commands/data/query.js +2 -2
  18. package/dist/commands/data/query.js.map +1 -1
  19. package/dist/commands/data/update.js +2 -2
  20. package/dist/commands/data/update.js.map +1 -1
  21. package/dist/commands/dev.d.ts +3 -0
  22. package/dist/commands/dev.d.ts.map +1 -1
  23. package/dist/commands/dev.js +48 -19
  24. package/dist/commands/dev.js.map +1 -1
  25. package/dist/commands/generate.js +9 -9
  26. package/dist/commands/generate.js.map +1 -1
  27. package/dist/commands/i18n/check.d.ts +18 -0
  28. package/dist/commands/i18n/check.d.ts.map +1 -0
  29. package/dist/commands/i18n/check.js +153 -0
  30. package/dist/commands/i18n/check.js.map +1 -0
  31. package/dist/commands/init.js +2 -2
  32. package/dist/commands/lint.d.ts +3 -0
  33. package/dist/commands/lint.d.ts.map +1 -1
  34. package/dist/commands/lint.js +24 -0
  35. package/dist/commands/lint.js.map +1 -1
  36. package/dist/commands/login.d.ts +17 -0
  37. package/dist/commands/login.d.ts.map +1 -0
  38. package/dist/commands/login.js +313 -0
  39. package/dist/commands/login.js.map +1 -0
  40. package/dist/commands/logout.d.ts.map +1 -0
  41. package/dist/commands/{auth/logout.js → logout.js} +14 -2
  42. package/dist/commands/logout.js.map +1 -0
  43. package/dist/commands/meta/delete.js +2 -2
  44. package/dist/commands/meta/delete.js.map +1 -1
  45. package/dist/commands/meta/get.js +2 -2
  46. package/dist/commands/meta/get.js.map +1 -1
  47. package/dist/commands/meta/list.js +2 -2
  48. package/dist/commands/meta/list.js.map +1 -1
  49. package/dist/commands/meta/register.js +2 -2
  50. package/dist/commands/meta/register.js.map +1 -1
  51. package/dist/commands/projects/bind.d.ts +30 -0
  52. package/dist/commands/projects/bind.d.ts.map +1 -0
  53. package/dist/commands/projects/bind.js +132 -0
  54. package/dist/commands/projects/bind.js.map +1 -0
  55. package/dist/commands/projects/create.d.ts +28 -0
  56. package/dist/commands/projects/create.d.ts.map +1 -0
  57. package/dist/commands/projects/create.js +120 -0
  58. package/dist/commands/projects/create.js.map +1 -0
  59. package/dist/commands/projects/list.d.ts +21 -0
  60. package/dist/commands/projects/list.d.ts.map +1 -0
  61. package/dist/commands/projects/list.js +79 -0
  62. package/dist/commands/projects/list.js.map +1 -0
  63. package/dist/commands/projects/projects.test.d.ts +2 -0
  64. package/dist/commands/projects/projects.test.d.ts.map +1 -0
  65. package/dist/commands/projects/projects.test.js +56 -0
  66. package/dist/commands/projects/projects.test.js.map +1 -0
  67. package/dist/commands/projects/show.d.ts +21 -0
  68. package/dist/commands/projects/show.d.ts.map +1 -0
  69. package/dist/commands/projects/show.js +72 -0
  70. package/dist/commands/projects/show.js.map +1 -0
  71. package/dist/commands/projects/switch.d.ts +24 -0
  72. package/dist/commands/projects/switch.d.ts.map +1 -0
  73. package/dist/commands/projects/switch.js +64 -0
  74. package/dist/commands/projects/switch.js.map +1 -0
  75. package/dist/commands/publish.d.ts +14 -0
  76. package/dist/commands/publish.d.ts.map +1 -0
  77. package/dist/commands/publish.js +91 -0
  78. package/dist/commands/publish.js.map +1 -0
  79. package/dist/commands/{auth/login.d.ts → register.d.ts} +3 -2
  80. package/dist/commands/register.d.ts.map +1 -0
  81. package/dist/commands/{auth/login.js → register.js} +44 -61
  82. package/dist/commands/register.js.map +1 -0
  83. package/dist/commands/serve.d.ts +8 -0
  84. package/dist/commands/serve.d.ts.map +1 -1
  85. package/dist/commands/serve.js +606 -44
  86. package/dist/commands/serve.js.map +1 -1
  87. package/dist/commands/start.d.ts +11 -0
  88. package/dist/commands/start.d.ts.map +1 -0
  89. package/dist/commands/start.js +43 -0
  90. package/dist/commands/start.js.map +1 -0
  91. package/dist/commands/whoami.d.ts.map +1 -0
  92. package/dist/commands/{auth/whoami.js → whoami.js} +5 -5
  93. package/dist/commands/whoami.js.map +1 -0
  94. package/dist/index.d.ts +7 -4
  95. package/dist/index.d.ts.map +1 -1
  96. package/dist/index.js +8 -5
  97. package/dist/index.js.map +1 -1
  98. package/dist/utils/account.d.ts +31 -0
  99. package/dist/utils/account.d.ts.map +1 -0
  100. package/dist/utils/account.js +154 -0
  101. package/dist/utils/account.js.map +1 -0
  102. package/dist/utils/api-client.d.ts +10 -4
  103. package/dist/utils/api-client.d.ts.map +1 -1
  104. package/dist/utils/api-client.js +13 -7
  105. package/dist/utils/api-client.js.map +1 -1
  106. package/dist/utils/auth-config.d.ts +6 -0
  107. package/dist/utils/auth-config.d.ts.map +1 -1
  108. package/dist/utils/auth-config.js.map +1 -1
  109. package/dist/utils/build-runtime.d.ts +45 -0
  110. package/dist/utils/build-runtime.d.ts.map +1 -0
  111. package/dist/utils/build-runtime.js +154 -0
  112. package/dist/utils/build-runtime.js.map +1 -0
  113. package/dist/utils/config.d.ts.map +1 -1
  114. package/dist/utils/config.js +17 -2
  115. package/dist/utils/config.js.map +1 -1
  116. package/dist/utils/console.d.ts +32 -0
  117. package/dist/utils/console.d.ts.map +1 -0
  118. package/dist/utils/console.js +169 -0
  119. package/dist/utils/console.js.map +1 -0
  120. package/dist/utils/extract-hook-body.d.ts +13 -0
  121. package/dist/utils/extract-hook-body.d.ts.map +1 -0
  122. package/dist/utils/extract-hook-body.js +175 -0
  123. package/dist/utils/extract-hook-body.js.map +1 -0
  124. package/dist/utils/format.d.ts +8 -0
  125. package/dist/utils/format.d.ts.map +1 -1
  126. package/dist/utils/format.js +15 -2
  127. package/dist/utils/format.js.map +1 -1
  128. package/dist/utils/i18n-coverage.d.ts +61 -0
  129. package/dist/utils/i18n-coverage.d.ts.map +1 -0
  130. package/dist/utils/i18n-coverage.js +176 -0
  131. package/dist/utils/i18n-coverage.js.map +1 -0
  132. package/dist/utils/lower-callables.d.ts +17 -0
  133. package/dist/utils/lower-callables.d.ts.map +1 -0
  134. package/dist/utils/lower-callables.js +181 -0
  135. package/dist/utils/lower-callables.js.map +1 -0
  136. package/dist/utils/plugin-detection.d.ts +1 -0
  137. package/dist/utils/plugin-detection.d.ts.map +1 -1
  138. package/dist/utils/plugin-detection.js +41 -0
  139. package/dist/utils/plugin-detection.js.map +1 -1
  140. package/dist/utils/studio.d.ts +1 -0
  141. package/dist/utils/studio.d.ts.map +1 -1
  142. package/dist/utils/studio.js +25 -9
  143. package/dist/utils/studio.js.map +1 -1
  144. package/package.json +55 -21
  145. package/.turbo/turbo-build.log +0 -4
  146. package/CHANGELOG.md +0 -805
  147. package/bin/run-dev.js +0 -5
  148. package/dist/commands/auth/login.d.ts.map +0 -1
  149. package/dist/commands/auth/login.js.map +0 -1
  150. package/dist/commands/auth/logout.d.ts.map +0 -1
  151. package/dist/commands/auth/logout.js.map +0 -1
  152. package/dist/commands/auth/whoami.d.ts.map +0 -1
  153. package/dist/commands/auth/whoami.js.map +0 -1
  154. package/dist/commands/codemod/v2-to-v3.d.ts +0 -10
  155. package/dist/commands/codemod/v2-to-v3.d.ts.map +0 -1
  156. package/dist/commands/codemod/v2-to-v3.js +0 -145
  157. package/dist/commands/codemod/v2-to-v3.js.map +0 -1
  158. package/dist/commands/plugin/add.d.ts +0 -22
  159. package/dist/commands/plugin/add.d.ts.map +0 -1
  160. package/dist/commands/plugin/add.js +0 -93
  161. package/dist/commands/plugin/add.js.map +0 -1
  162. package/dist/commands/plugin/build.d.ts +0 -29
  163. package/dist/commands/plugin/build.d.ts.map +0 -1
  164. package/dist/commands/plugin/build.js +0 -170
  165. package/dist/commands/plugin/build.js.map +0 -1
  166. package/dist/commands/plugin/info.d.ts +0 -10
  167. package/dist/commands/plugin/info.d.ts.map +0 -1
  168. package/dist/commands/plugin/info.js +0 -65
  169. package/dist/commands/plugin/info.js.map +0 -1
  170. package/dist/commands/plugin/list.d.ts +0 -13
  171. package/dist/commands/plugin/list.d.ts.map +0 -1
  172. package/dist/commands/plugin/list.js +0 -78
  173. package/dist/commands/plugin/list.js.map +0 -1
  174. package/dist/commands/plugin/publish.d.ts +0 -27
  175. package/dist/commands/plugin/publish.d.ts.map +0 -1
  176. package/dist/commands/plugin/publish.js +0 -152
  177. package/dist/commands/plugin/publish.js.map +0 -1
  178. package/dist/commands/plugin/remove.d.ts +0 -20
  179. package/dist/commands/plugin/remove.d.ts.map +0 -1
  180. package/dist/commands/plugin/remove.js +0 -79
  181. package/dist/commands/plugin/remove.js.map +0 -1
  182. package/dist/commands/plugin/validate.d.ts +0 -23
  183. package/dist/commands/plugin/validate.d.ts.map +0 -1
  184. package/dist/commands/plugin/validate.js +0 -251
  185. package/dist/commands/plugin/validate.js.map +0 -1
  186. package/src/bin.ts +0 -13
  187. package/src/commands/auth/login.ts +0 -188
  188. package/src/commands/auth/logout.ts +0 -51
  189. package/src/commands/auth/whoami.ts +0 -85
  190. package/src/commands/codemod/v2-to-v3.ts +0 -171
  191. package/src/commands/compile.ts +0 -114
  192. package/src/commands/create.ts +0 -281
  193. package/src/commands/data/create.ts +0 -110
  194. package/src/commands/data/delete.ts +0 -84
  195. package/src/commands/data/get.ts +0 -84
  196. package/src/commands/data/query.ts +0 -127
  197. package/src/commands/data/update.ts +0 -114
  198. package/src/commands/dev.ts +0 -83
  199. package/src/commands/diff.ts +0 -294
  200. package/src/commands/doctor.ts +0 -572
  201. package/src/commands/explain.ts +0 -412
  202. package/src/commands/generate.ts +0 -924
  203. package/src/commands/info.ts +0 -124
  204. package/src/commands/init.ts +0 -327
  205. package/src/commands/lint.ts +0 -315
  206. package/src/commands/meta/delete.ts +0 -79
  207. package/src/commands/meta/get.ts +0 -73
  208. package/src/commands/meta/list.ts +0 -105
  209. package/src/commands/meta/register.ts +0 -97
  210. package/src/commands/plugin/add.ts +0 -112
  211. package/src/commands/plugin/build.ts +0 -193
  212. package/src/commands/plugin/info.ts +0 -79
  213. package/src/commands/plugin/list.ts +0 -93
  214. package/src/commands/plugin/publish.ts +0 -176
  215. package/src/commands/plugin/remove.ts +0 -97
  216. package/src/commands/plugin/validate.ts +0 -268
  217. package/src/commands/serve.ts +0 -411
  218. package/src/commands/studio.ts +0 -52
  219. package/src/commands/test.ts +0 -135
  220. package/src/commands/validate.ts +0 -143
  221. package/src/index.ts +0 -22
  222. package/src/utils/api-client.ts +0 -88
  223. package/src/utils/auth-config.ts +0 -107
  224. package/src/utils/config.ts +0 -80
  225. package/src/utils/format.ts +0 -267
  226. package/src/utils/output-formatter.ts +0 -91
  227. package/src/utils/plugin-detection.ts +0 -16
  228. package/src/utils/plugin-helpers.ts +0 -37
  229. package/src/utils/studio.ts +0 -350
  230. package/test/commands.test.ts +0 -128
  231. package/test/create.test.ts +0 -25
  232. package/test/plugin-commands.test.ts +0 -44
  233. package/test/plugin.test.ts +0 -169
  234. package/test/remote-api-commands.test.ts +0 -188
  235. package/test/remote-api-utils.test.ts +0 -196
  236. package/test/serve-host-config.test.ts +0 -77
  237. package/tsconfig.build.json +0 -20
  238. package/tsconfig.json +0 -25
  239. package/tsup.config.ts +0 -23
  240. /package/dist/commands/{auth/logout.d.ts → logout.d.ts} +0 -0
  241. /package/dist/commands/{auth/whoami.d.ts → whoami.d.ts} +0 -0
@@ -1,315 +0,0 @@
1
- // Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.
2
-
3
- import { Args, Command, Flags } from '@oclif/core';
4
- import chalk from 'chalk';
5
- import { normalizeStackInput } from '@objectstack/spec';
6
- import { loadConfig } from '../utils/config.js';
7
- import {
8
- printHeader,
9
- printSuccess,
10
- printWarning,
11
- printError,
12
- printInfo,
13
- printStep,
14
- createTimer,
15
- } from '../utils/format.js';
16
-
17
- // ─── Types ──────────────────────────────────────────────────────────
18
-
19
- type Severity = 'error' | 'warning' | 'suggestion';
20
-
21
- interface LintIssue {
22
- severity: Severity;
23
- rule: string;
24
- message: string;
25
- path: string;
26
- fix?: string;
27
- }
28
-
29
- // ─── Rules ──────────────────────────────────────────────────────────
30
-
31
- const SNAKE_CASE_RE = /^[a-z][a-z0-9_]*$/;
32
-
33
- function checkSnakeCase(value: string, path: string, label: string): LintIssue | null {
34
- if (!SNAKE_CASE_RE.test(value)) {
35
- return {
36
- severity: 'error',
37
- rule: 'naming/snake-case',
38
- message: `${label} "${value}" must be snake_case`,
39
- path,
40
- fix: value.replace(/([A-Z]+)([A-Z][a-z])/g, '$1_$2').replace(/([a-z\d])([A-Z])/g, '$1_$2').toLowerCase().replace(/^_/, '').replace(/-/g, '_'),
41
- };
42
- }
43
- return null;
44
- }
45
-
46
- function checkLabelExists(item: any, path: string, kind: string): LintIssue | null {
47
- if (!item.label) {
48
- return {
49
- severity: 'error',
50
- rule: 'required/label',
51
- message: `${kind} "${item.name || '?'}" is missing a label`,
52
- path,
53
- };
54
- }
55
- return null;
56
- }
57
-
58
- function checkLabelCase(label: string, path: string): LintIssue | null {
59
- if (label && label[0] !== label[0].toUpperCase()) {
60
- return {
61
- severity: 'warning',
62
- rule: 'convention/label-case',
63
- message: `Label "${label}" should start with an uppercase letter`,
64
- path,
65
- fix: label.charAt(0).toUpperCase() + label.slice(1),
66
- };
67
- }
68
- return null;
69
- }
70
-
71
- // ─── Lint Engine ────────────────────────────────────────────────────
72
-
73
- function lintConfig(config: any): LintIssue[] {
74
- const issues: LintIssue[] = [];
75
-
76
- const push = (issue: LintIssue | null) => {
77
- if (issue) issues.push(issue);
78
- };
79
-
80
- // ── Objects ──
81
- const objects: any[] = Array.isArray(config.objects) ? config.objects : [];
82
-
83
- for (let i = 0; i < objects.length; i++) {
84
- const obj = objects[i];
85
- const objPath = `objects[${i}]`;
86
-
87
- // Object name must be snake_case
88
- if (obj.name) {
89
- push(checkSnakeCase(obj.name, `${objPath}.name`, 'Object name'));
90
- }
91
-
92
- // Object must have label
93
- push(checkLabelExists(obj, `${objPath}.label`, 'Object'));
94
-
95
- // Object label conventions
96
- if (obj.label) {
97
- push(checkLabelCase(obj.label, `${objPath}.label`));
98
- }
99
-
100
- // Fields
101
- if (obj.fields && typeof obj.fields === 'object') {
102
- const fieldNames = Object.keys(obj.fields);
103
-
104
- if (fieldNames.length === 0) {
105
- issues.push({
106
- severity: 'warning',
107
- rule: 'structure/empty-fields',
108
- message: `Object "${obj.name || '?'}" has an empty fields map`,
109
- path: `${objPath}.fields`,
110
- });
111
- }
112
-
113
- for (const fieldName of fieldNames) {
114
- const field = obj.fields[fieldName];
115
- const fieldPath = `${objPath}.fields.${fieldName}`;
116
-
117
- // Field key must be snake_case
118
- push(checkSnakeCase(fieldName, fieldPath, 'Field name'));
119
-
120
- // Field must have label
121
- if (field && typeof field === 'object') {
122
- push(checkLabelExists({ ...field, name: fieldName }, `${fieldPath}.label`, 'Field'));
123
- if (field.label) {
124
- push(checkLabelCase(field.label, `${fieldPath}.label`));
125
- }
126
- }
127
- }
128
- } else if (!obj.fields) {
129
- issues.push({
130
- severity: 'error',
131
- rule: 'structure/no-fields',
132
- message: `Object "${obj.name || '?'}" has no fields defined`,
133
- path: `${objPath}.fields`,
134
- });
135
- }
136
- }
137
-
138
- // ── Views ──
139
- const views: any[] = Array.isArray(config.views) ? config.views : [];
140
- for (let i = 0; i < views.length; i++) {
141
- const view = views[i];
142
- const viewPath = `views[${i}]`;
143
- if (view.name) {
144
- push(checkSnakeCase(view.name, `${viewPath}.name`, 'View name'));
145
- }
146
- push(checkLabelExists(view, `${viewPath}.label`, 'View'));
147
- if (view.label) {
148
- push(checkLabelCase(view.label, `${viewPath}.label`));
149
- }
150
- }
151
-
152
- // ── Apps ──
153
- const apps: any[] = Array.isArray(config.apps) ? config.apps : [];
154
- for (let i = 0; i < apps.length; i++) {
155
- const app = apps[i];
156
- const appPath = `apps[${i}]`;
157
- if (app.name) {
158
- push(checkSnakeCase(app.name, `${appPath}.name`, 'App name'));
159
- }
160
- push(checkLabelExists(app, `${appPath}.label`, 'App'));
161
- if (app.label) {
162
- push(checkLabelCase(app.label, `${appPath}.label`));
163
- }
164
- }
165
-
166
- // ── Flows ──
167
- const flows: any[] = Array.isArray(config.flows) ? config.flows : [];
168
- for (let i = 0; i < flows.length; i++) {
169
- const flow = flows[i];
170
- const flowPath = `flows[${i}]`;
171
- if (flow.name) {
172
- push(checkSnakeCase(flow.name, `${flowPath}.name`, 'Flow name'));
173
- }
174
- }
175
-
176
- // ── Agents ──
177
- const agents: any[] = Array.isArray(config.agents) ? config.agents : [];
178
- for (let i = 0; i < agents.length; i++) {
179
- const agent = agents[i];
180
- const agentPath = `agents[${i}]`;
181
- if (agent.name) {
182
- push(checkSnakeCase(agent.name, `${agentPath}.name`, 'Agent name'));
183
- }
184
- }
185
-
186
- return issues;
187
- }
188
-
189
- // ─── Command ────────────────────────────────────────────────────────
190
-
191
- export default class Lint extends Command {
192
- static override description = 'Check ObjectStack configuration for style and convention issues';
193
-
194
- static override args = {
195
- config: Args.string({ description: 'Configuration file path', required: false }),
196
- };
197
-
198
- static override flags = {
199
- json: Flags.boolean({ description: 'Output as JSON' }),
200
- fix: Flags.boolean({ description: 'Show what would be fixed (dry-run)' }),
201
- };
202
-
203
- async run(): Promise<void> {
204
- const { args, flags } = await this.parse(Lint);
205
- const configPath = args.config;
206
- const timer = createTimer();
207
-
208
- if (!flags.json) {
209
- printHeader('Lint');
210
- printStep('Loading configuration...');
211
- }
212
-
213
- try {
214
- const { config, absolutePath } = await loadConfig(configPath);
215
-
216
- if (!flags.json) {
217
- printInfo(`Config: ${chalk.white(absolutePath)}`);
218
- }
219
-
220
- const normalized = normalizeStackInput(config as Record<string, unknown>);
221
- const issues = lintConfig(normalized);
222
-
223
- // ── JSON output ──
224
- if (flags.json) {
225
- const errors = issues.filter((i) => i.severity === 'error');
226
- const warnings = issues.filter((i) => i.severity === 'warning');
227
- const suggestions = issues.filter((i) => i.severity === 'suggestion');
228
- console.log(JSON.stringify({
229
- passed: errors.length === 0,
230
- total: issues.length,
231
- errors: errors.length,
232
- warnings: warnings.length,
233
- suggestions: suggestions.length,
234
- issues,
235
- duration: timer.elapsed(),
236
- }, null, 2));
237
- if (errors.length > 0) process.exit(1);
238
- return;
239
- }
240
-
241
- console.log('');
242
-
243
- if (issues.length === 0) {
244
- printSuccess(`All checks passed ${chalk.dim(`(${timer.display()})`)}`);
245
- console.log('');
246
- return;
247
- }
248
-
249
- // Group by severity
250
- const errors = issues.filter((i) => i.severity === 'error');
251
- const warnings = issues.filter((i) => i.severity === 'warning');
252
- const suggestions = issues.filter((i) => i.severity === 'suggestion');
253
-
254
- const printIssue = (issue: LintIssue) => {
255
- const color =
256
- issue.severity === 'error' ? chalk.red :
257
- issue.severity === 'warning' ? chalk.yellow :
258
- chalk.blue;
259
- const icon =
260
- issue.severity === 'error' ? '✗' :
261
- issue.severity === 'warning' ? '⚠' :
262
- 'ℹ';
263
-
264
- console.log(` ${color(icon)} ${color(issue.message)}`);
265
- console.log(chalk.dim(` ${issue.rule} at ${issue.path}`));
266
- if (flags.fix && issue.fix) {
267
- console.log(chalk.green(` → fix: ${issue.fix}`));
268
- }
269
- };
270
-
271
- if (errors.length > 0) {
272
- console.log(chalk.bold.red(` Errors (${errors.length})`));
273
- errors.forEach(printIssue);
274
- console.log('');
275
- }
276
-
277
- if (warnings.length > 0) {
278
- console.log(chalk.bold.yellow(` Warnings (${warnings.length})`));
279
- warnings.forEach(printIssue);
280
- console.log('');
281
- }
282
-
283
- if (suggestions.length > 0) {
284
- console.log(chalk.bold.blue(` Suggestions (${suggestions.length})`));
285
- suggestions.forEach(printIssue);
286
- console.log('');
287
- }
288
-
289
- // Summary
290
- const parts: string[] = [];
291
- if (errors.length > 0) parts.push(chalk.red(`${errors.length} error(s)`));
292
- if (warnings.length > 0) parts.push(chalk.yellow(`${warnings.length} warning(s)`));
293
- if (suggestions.length > 0) parts.push(chalk.blue(`${suggestions.length} suggestion(s)`));
294
- console.log(` ${parts.join(', ')} ${chalk.dim(`(${timer.display()})`)}`);
295
-
296
- if (flags.fix) {
297
- console.log('');
298
- printInfo('Dry-run mode: no files were modified.');
299
- }
300
-
301
- console.log('');
302
-
303
- if (errors.length > 0) process.exit(1);
304
-
305
- } catch (error: any) {
306
- if (flags.json) {
307
- console.log(JSON.stringify({ error: error.message }));
308
- process.exit(1);
309
- }
310
- console.log('');
311
- printError(error.message || String(error));
312
- process.exit(1);
313
- }
314
- }
315
- }
@@ -1,79 +0,0 @@
1
- // Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.
2
-
3
- import { Args, Command, Flags } from '@oclif/core';
4
- import { printError, printSuccess } from '../../utils/format.js';
5
- import { createApiClient, requireAuth } from '../../utils/api-client.js';
6
- import { formatOutput } from '../../utils/output-formatter.js';
7
-
8
- export default class MetaDelete extends Command {
9
- static override description = 'Delete a metadata item';
10
-
11
- static override examples = [
12
- '$ os meta delete object my_custom_object',
13
- '$ os meta delete plugin my-plugin',
14
- '$ os meta delete object my_custom_object --format json',
15
- ];
16
-
17
- static override args = {
18
- type: Args.string({
19
- description: 'Metadata type',
20
- required: true,
21
- }),
22
- name: Args.string({
23
- description: 'Item name (snake_case)',
24
- required: true,
25
- }),
26
- };
27
-
28
- static override flags = {
29
- url: Flags.string({
30
- char: 'u',
31
- description: 'Server URL',
32
- env: 'OBJECTSTACK_URL',
33
- }),
34
- token: Flags.string({
35
- char: 't',
36
- description: 'Authentication token',
37
- env: 'OBJECTSTACK_TOKEN',
38
- }),
39
- format: Flags.string({
40
- char: 'f',
41
- description: 'Output format',
42
- options: ['json', 'table', 'yaml'],
43
- default: 'table',
44
- }),
45
- };
46
-
47
- async run(): Promise<void> {
48
- const { args, flags } = await this.parse(MetaDelete);
49
-
50
- try {
51
- const { client, token } = await createApiClient({
52
- url: flags.url,
53
- token: flags.token,
54
- });
55
-
56
- requireAuth(token);
57
-
58
- const result = await client.meta.deleteItem(args.type, args.name);
59
-
60
- if (flags.format === 'json') {
61
- formatOutput({ success: true, type: args.type, name: args.name, deleted: result.deleted }, 'json');
62
- } else if (flags.format === 'yaml') {
63
- formatOutput({ success: true, type: args.type, name: args.name, deleted: result.deleted }, 'yaml');
64
- } else {
65
- printSuccess(`Metadata deleted: ${args.type}/${args.name}`);
66
- }
67
- } catch (error: any) {
68
- if (flags.format === 'json') {
69
- console.log(JSON.stringify({
70
- success: false,
71
- error: error.message,
72
- }, null, 2));
73
- this.exit(1);
74
- }
75
- printError(error.message || String(error));
76
- this.exit(1);
77
- }
78
- }
79
- }
@@ -1,73 +0,0 @@
1
- // Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.
2
-
3
- import { Args, Command, Flags } from '@oclif/core';
4
- import { printError } from '../../utils/format.js';
5
- import { createApiClient, requireAuth } from '../../utils/api-client.js';
6
- import { formatOutput } from '../../utils/output-formatter.js';
7
-
8
- export default class MetaGet extends Command {
9
- static override description = 'Get a metadata item';
10
-
11
- static override examples = [
12
- '$ os meta get object project_task',
13
- '$ os meta get plugin my-plugin --format json',
14
- ];
15
-
16
- static override args = {
17
- type: Args.string({
18
- description: 'Metadata type',
19
- required: true,
20
- }),
21
- name: Args.string({
22
- description: 'Item name (snake_case)',
23
- required: true,
24
- }),
25
- };
26
-
27
- static override flags = {
28
- url: Flags.string({
29
- char: 'u',
30
- description: 'Server URL',
31
- env: 'OBJECTSTACK_URL',
32
- }),
33
- token: Flags.string({
34
- char: 't',
35
- description: 'Authentication token',
36
- env: 'OBJECTSTACK_TOKEN',
37
- }),
38
- format: Flags.string({
39
- char: 'f',
40
- description: 'Output format',
41
- options: ['json', 'table', 'yaml'],
42
- default: 'json',
43
- }),
44
- };
45
-
46
- async run(): Promise<void> {
47
- const { args, flags } = await this.parse(MetaGet);
48
-
49
- try {
50
- const { client, token } = await createApiClient({
51
- url: flags.url,
52
- token: flags.token,
53
- });
54
-
55
- requireAuth(token);
56
-
57
- // Get the metadata item
58
- const item = await client.meta.getItem(args.type, args.name);
59
-
60
- formatOutput(item, flags.format as any);
61
- } catch (error: any) {
62
- if (flags.format === 'json') {
63
- console.log(JSON.stringify({
64
- success: false,
65
- error: error.message,
66
- }, null, 2));
67
- this.exit(1);
68
- }
69
- printError(error.message || String(error));
70
- this.exit(1);
71
- }
72
- }
73
- }
@@ -1,105 +0,0 @@
1
- // Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.
2
-
3
- import { Args, Command, Flags } from '@oclif/core';
4
- import { printError } from '../../utils/format.js';
5
- import { createApiClient, requireAuth } from '../../utils/api-client.js';
6
- import { formatOutput } from '../../utils/output-formatter.js';
7
-
8
- export default class MetaList extends Command {
9
- static override description = 'List metadata types or items';
10
-
11
- static override examples = [
12
- '$ os meta list',
13
- '$ os meta list object',
14
- '$ os meta list plugin --format json',
15
- ];
16
-
17
- static override args = {
18
- type: Args.string({
19
- description: 'Metadata type (object, plugin, view, etc.)',
20
- }),
21
- };
22
-
23
- static override flags = {
24
- url: Flags.string({
25
- char: 'u',
26
- description: 'Server URL',
27
- env: 'OBJECTSTACK_URL',
28
- }),
29
- token: Flags.string({
30
- char: 't',
31
- description: 'Authentication token',
32
- env: 'OBJECTSTACK_TOKEN',
33
- }),
34
- format: Flags.string({
35
- char: 'f',
36
- description: 'Output format',
37
- options: ['json', 'table', 'yaml'],
38
- default: 'table',
39
- }),
40
- };
41
-
42
- async run(): Promise<void> {
43
- const { args, flags } = await this.parse(MetaList);
44
-
45
- try {
46
- const { client, token } = await createApiClient({
47
- url: flags.url,
48
- token: flags.token,
49
- });
50
-
51
- requireAuth(token);
52
-
53
- if (!args.type) {
54
- // List all metadata types
55
- const types = await client.meta.getTypes();
56
-
57
- if (flags.format === 'json') {
58
- formatOutput(types, 'json');
59
- } else if (flags.format === 'yaml') {
60
- formatOutput(types, 'yaml');
61
- } else {
62
- console.log('\nAvailable metadata types:\n');
63
- if (Array.isArray(types)) {
64
- types.forEach(type => console.log(` • ${type}`));
65
- } else {
66
- console.log('No types available');
67
- }
68
- console.log('');
69
- }
70
- } else {
71
- // List items of a specific type
72
- const items = await client.meta.getItems(args.type);
73
-
74
- if (flags.format === 'json') {
75
- formatOutput(items, 'json');
76
- } else if (flags.format === 'yaml') {
77
- formatOutput(items, 'yaml');
78
- } else {
79
- console.log(`\n${args.type} items:\n`);
80
- if (Array.isArray(items)) {
81
- if (items.length === 0) {
82
- console.log(' (no items)');
83
- } else {
84
- items.forEach(item => {
85
- const name = item.name || item.id || JSON.stringify(item);
86
- console.log(` • ${name}`);
87
- });
88
- }
89
- }
90
- console.log('');
91
- }
92
- }
93
- } catch (error: any) {
94
- if (flags.format === 'json') {
95
- console.log(JSON.stringify({
96
- success: false,
97
- error: error.message,
98
- }, null, 2));
99
- this.exit(1);
100
- }
101
- printError(error.message || String(error));
102
- this.exit(1);
103
- }
104
- }
105
- }
@@ -1,97 +0,0 @@
1
- // Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.
2
-
3
- import { Args, Command, Flags } from '@oclif/core';
4
- import { printError, printSuccess } from '../../utils/format.js';
5
- import { createApiClient, requireAuth } from '../../utils/api-client.js';
6
- import { formatOutput } from '../../utils/output-formatter.js';
7
-
8
- export default class MetaRegister extends Command {
9
- static override description = 'Register metadata (create or update)';
10
-
11
- static override examples = [
12
- '$ os meta register object --data object-def.json',
13
- '$ os meta register plugin --data plugin-manifest.json',
14
- ];
15
-
16
- static override args = {
17
- type: Args.string({
18
- description: 'Metadata type',
19
- required: true,
20
- }),
21
- };
22
-
23
- static override flags = {
24
- url: Flags.string({
25
- char: 'u',
26
- description: 'Server URL',
27
- env: 'OBJECTSTACK_URL',
28
- }),
29
- token: Flags.string({
30
- char: 't',
31
- description: 'Authentication token',
32
- env: 'OBJECTSTACK_TOKEN',
33
- }),
34
- data: Flags.string({
35
- char: 'd',
36
- description: 'Path to JSON file containing metadata definition',
37
- required: true,
38
- }),
39
- format: Flags.string({
40
- char: 'f',
41
- description: 'Output format',
42
- options: ['json', 'table', 'yaml'],
43
- default: 'table',
44
- }),
45
- };
46
-
47
- async run(): Promise<void> {
48
- const { args, flags } = await this.parse(MetaRegister);
49
-
50
- try {
51
- const { client, token } = await createApiClient({
52
- url: flags.url,
53
- token: flags.token,
54
- });
55
-
56
- requireAuth(token);
57
-
58
- // Read metadata from file
59
- const { readFile } = await import('node:fs/promises');
60
- const fileContent = await readFile(flags.data, 'utf-8');
61
- let metadata: any;
62
-
63
- try {
64
- metadata = JSON.parse(fileContent);
65
- } catch (e) {
66
- throw new Error(`Invalid JSON in file: ${(e as Error).message}`);
67
- }
68
-
69
- // Extract name from metadata
70
- const name = metadata.name;
71
- if (!name) {
72
- throw new Error('Metadata definition must include a "name" field');
73
- }
74
-
75
- // Register the metadata
76
- const result = await client.meta.saveItem(args.type, name, metadata);
77
-
78
- if (flags.format === 'json') {
79
- formatOutput(result, 'json');
80
- } else if (flags.format === 'yaml') {
81
- formatOutput(result, 'yaml');
82
- } else {
83
- printSuccess(`Metadata registered: ${args.type}/${name}`);
84
- }
85
- } catch (error: any) {
86
- if (flags.format === 'json') {
87
- console.log(JSON.stringify({
88
- success: false,
89
- error: error.message,
90
- }, null, 2));
91
- this.exit(1);
92
- }
93
- printError(error.message || String(error));
94
- this.exit(1);
95
- }
96
- }
97
- }