@objectstack/cli 4.0.4 → 4.1.0

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 (269) hide show
  1. package/README.md +44 -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/cloud/login.d.ts +16 -0
  7. package/dist/commands/cloud/login.d.ts.map +1 -0
  8. package/dist/commands/cloud/login.js +166 -0
  9. package/dist/commands/cloud/login.js.map +1 -0
  10. package/dist/commands/cloud/logout.d.ts +15 -0
  11. package/dist/commands/cloud/logout.d.ts.map +1 -0
  12. package/dist/commands/cloud/logout.js +51 -0
  13. package/dist/commands/cloud/logout.js.map +1 -0
  14. package/dist/commands/cloud/whoami.d.ts +15 -0
  15. package/dist/commands/cloud/whoami.d.ts.map +1 -0
  16. package/dist/commands/cloud/whoami.js +81 -0
  17. package/dist/commands/cloud/whoami.js.map +1 -0
  18. package/dist/commands/compile.d.ts +3 -0
  19. package/dist/commands/compile.d.ts.map +1 -1
  20. package/dist/commands/compile.js +128 -6
  21. package/dist/commands/compile.js.map +1 -1
  22. package/dist/commands/create.js +1 -1
  23. package/dist/commands/data/create.js +2 -2
  24. package/dist/commands/data/create.js.map +1 -1
  25. package/dist/commands/data/delete.js +2 -2
  26. package/dist/commands/data/delete.js.map +1 -1
  27. package/dist/commands/data/get.js +2 -2
  28. package/dist/commands/data/get.js.map +1 -1
  29. package/dist/commands/data/query.js +2 -2
  30. package/dist/commands/data/query.js.map +1 -1
  31. package/dist/commands/data/update.js +2 -2
  32. package/dist/commands/data/update.js.map +1 -1
  33. package/dist/commands/dev.d.ts +9 -0
  34. package/dist/commands/dev.d.ts.map +1 -1
  35. package/dist/commands/dev.js +116 -22
  36. package/dist/commands/dev.js.map +1 -1
  37. package/dist/commands/generate.js +9 -9
  38. package/dist/commands/generate.js.map +1 -1
  39. package/dist/commands/i18n/check.d.ts +18 -0
  40. package/dist/commands/i18n/check.d.ts.map +1 -0
  41. package/dist/commands/i18n/check.js +153 -0
  42. package/dist/commands/i18n/check.js.map +1 -0
  43. package/dist/commands/init.js +2 -2
  44. package/dist/commands/lint.d.ts +3 -0
  45. package/dist/commands/lint.d.ts.map +1 -1
  46. package/dist/commands/lint.js +24 -0
  47. package/dist/commands/lint.js.map +1 -1
  48. package/dist/commands/login.d.ts +17 -0
  49. package/dist/commands/login.d.ts.map +1 -0
  50. package/dist/commands/login.js +313 -0
  51. package/dist/commands/login.js.map +1 -0
  52. package/dist/commands/logout.d.ts.map +1 -0
  53. package/dist/commands/{auth/logout.js → logout.js} +14 -2
  54. package/dist/commands/logout.js.map +1 -0
  55. package/dist/commands/meta/delete.js +2 -2
  56. package/dist/commands/meta/delete.js.map +1 -1
  57. package/dist/commands/meta/get.js +2 -2
  58. package/dist/commands/meta/get.js.map +1 -1
  59. package/dist/commands/meta/list.js +2 -2
  60. package/dist/commands/meta/list.js.map +1 -1
  61. package/dist/commands/meta/register.js +2 -2
  62. package/dist/commands/meta/register.js.map +1 -1
  63. package/dist/commands/package/publish.d.ts +32 -0
  64. package/dist/commands/package/publish.d.ts.map +1 -0
  65. package/dist/commands/package/publish.js +324 -0
  66. package/dist/commands/package/publish.js.map +1 -0
  67. package/dist/commands/projects/bind.d.ts +30 -0
  68. package/dist/commands/projects/bind.d.ts.map +1 -0
  69. package/dist/commands/projects/bind.js +132 -0
  70. package/dist/commands/projects/bind.js.map +1 -0
  71. package/dist/commands/projects/create.d.ts +28 -0
  72. package/dist/commands/projects/create.d.ts.map +1 -0
  73. package/dist/commands/projects/create.js +120 -0
  74. package/dist/commands/projects/create.js.map +1 -0
  75. package/dist/commands/projects/list.d.ts +21 -0
  76. package/dist/commands/projects/list.d.ts.map +1 -0
  77. package/dist/commands/projects/list.js +79 -0
  78. package/dist/commands/projects/list.js.map +1 -0
  79. package/dist/commands/projects/projects.test.d.ts +2 -0
  80. package/dist/commands/projects/projects.test.d.ts.map +1 -0
  81. package/dist/commands/projects/projects.test.js +56 -0
  82. package/dist/commands/projects/projects.test.js.map +1 -0
  83. package/dist/commands/projects/show.d.ts +21 -0
  84. package/dist/commands/projects/show.d.ts.map +1 -0
  85. package/dist/commands/projects/show.js +72 -0
  86. package/dist/commands/projects/show.js.map +1 -0
  87. package/dist/commands/projects/switch.d.ts +24 -0
  88. package/dist/commands/projects/switch.d.ts.map +1 -0
  89. package/dist/commands/projects/switch.js +64 -0
  90. package/dist/commands/projects/switch.js.map +1 -0
  91. package/dist/commands/publish.d.ts +17 -0
  92. package/dist/commands/publish.d.ts.map +1 -0
  93. package/dist/commands/publish.js +135 -0
  94. package/dist/commands/publish.js.map +1 -0
  95. package/dist/commands/{auth/login.d.ts → register.d.ts} +3 -2
  96. package/dist/commands/register.d.ts.map +1 -0
  97. package/dist/commands/{auth/login.js → register.js} +44 -61
  98. package/dist/commands/register.js.map +1 -0
  99. package/dist/commands/rollback.d.ts +13 -0
  100. package/dist/commands/rollback.d.ts.map +1 -0
  101. package/dist/commands/rollback.js +77 -0
  102. package/dist/commands/rollback.js.map +1 -0
  103. package/dist/commands/serve.d.ts +22 -0
  104. package/dist/commands/serve.d.ts.map +1 -1
  105. package/dist/commands/serve.js +1173 -58
  106. package/dist/commands/serve.js.map +1 -1
  107. package/dist/commands/start.d.ts +18 -0
  108. package/dist/commands/start.d.ts.map +1 -0
  109. package/dist/commands/start.js +112 -0
  110. package/dist/commands/start.js.map +1 -0
  111. package/dist/commands/whoami.d.ts.map +1 -0
  112. package/dist/commands/{auth/whoami.js → whoami.js} +5 -5
  113. package/dist/commands/whoami.js.map +1 -0
  114. package/dist/index.d.ts +11 -4
  115. package/dist/index.d.ts.map +1 -1
  116. package/dist/index.js +14 -5
  117. package/dist/index.js.map +1 -1
  118. package/dist/utils/account.d.ts +31 -0
  119. package/dist/utils/account.d.ts.map +1 -0
  120. package/dist/utils/account.js +154 -0
  121. package/dist/utils/account.js.map +1 -0
  122. package/dist/utils/api-client.d.ts +10 -4
  123. package/dist/utils/api-client.d.ts.map +1 -1
  124. package/dist/utils/api-client.js +13 -7
  125. package/dist/utils/api-client.js.map +1 -1
  126. package/dist/utils/auth-config.d.ts +6 -0
  127. package/dist/utils/auth-config.d.ts.map +1 -1
  128. package/dist/utils/auth-config.js.map +1 -1
  129. package/dist/utils/auth-flows.d.ts +31 -0
  130. package/dist/utils/auth-flows.d.ts.map +1 -0
  131. package/dist/utils/auth-flows.js +151 -0
  132. package/dist/utils/auth-flows.js.map +1 -0
  133. package/dist/utils/build-runtime.d.ts +45 -0
  134. package/dist/utils/build-runtime.d.ts.map +1 -0
  135. package/dist/utils/build-runtime.js +154 -0
  136. package/dist/utils/build-runtime.js.map +1 -0
  137. package/dist/utils/cloud-config.d.ts +24 -0
  138. package/dist/utils/cloud-config.d.ts.map +1 -0
  139. package/dist/utils/cloud-config.js +75 -0
  140. package/dist/utils/cloud-config.js.map +1 -0
  141. package/dist/utils/config.d.ts.map +1 -1
  142. package/dist/utils/config.js +17 -2
  143. package/dist/utils/config.js.map +1 -1
  144. package/dist/utils/console.d.ts +33 -0
  145. package/dist/utils/console.d.ts.map +1 -0
  146. package/dist/utils/console.js +172 -0
  147. package/dist/utils/console.js.map +1 -0
  148. package/dist/utils/extract-hook-body.d.ts +13 -0
  149. package/dist/utils/extract-hook-body.d.ts.map +1 -0
  150. package/dist/utils/extract-hook-body.js +175 -0
  151. package/dist/utils/extract-hook-body.js.map +1 -0
  152. package/dist/utils/format.d.ts +8 -0
  153. package/dist/utils/format.d.ts.map +1 -1
  154. package/dist/utils/format.js +15 -2
  155. package/dist/utils/format.js.map +1 -1
  156. package/dist/utils/i18n-coverage.d.ts +61 -0
  157. package/dist/utils/i18n-coverage.d.ts.map +1 -0
  158. package/dist/utils/i18n-coverage.js +176 -0
  159. package/dist/utils/i18n-coverage.js.map +1 -0
  160. package/dist/utils/lower-callables.d.ts +17 -0
  161. package/dist/utils/lower-callables.d.ts.map +1 -0
  162. package/dist/utils/lower-callables.js +181 -0
  163. package/dist/utils/lower-callables.js.map +1 -0
  164. package/dist/utils/plugin-detection.d.ts +1 -0
  165. package/dist/utils/plugin-detection.d.ts.map +1 -1
  166. package/dist/utils/plugin-detection.js +41 -0
  167. package/dist/utils/plugin-detection.js.map +1 -1
  168. package/dist/utils/studio.d.ts +1 -0
  169. package/dist/utils/studio.d.ts.map +1 -1
  170. package/dist/utils/studio.js +24 -9
  171. package/dist/utils/studio.js.map +1 -1
  172. package/package.json +60 -22
  173. package/.turbo/turbo-build.log +0 -4
  174. package/CHANGELOG.md +0 -821
  175. package/bin/run-dev.js +0 -5
  176. package/dist/commands/auth/login.d.ts.map +0 -1
  177. package/dist/commands/auth/login.js.map +0 -1
  178. package/dist/commands/auth/logout.d.ts.map +0 -1
  179. package/dist/commands/auth/logout.js.map +0 -1
  180. package/dist/commands/auth/whoami.d.ts.map +0 -1
  181. package/dist/commands/auth/whoami.js.map +0 -1
  182. package/dist/commands/codemod/v2-to-v3.d.ts +0 -10
  183. package/dist/commands/codemod/v2-to-v3.d.ts.map +0 -1
  184. package/dist/commands/codemod/v2-to-v3.js +0 -145
  185. package/dist/commands/codemod/v2-to-v3.js.map +0 -1
  186. package/dist/commands/plugin/add.d.ts +0 -22
  187. package/dist/commands/plugin/add.d.ts.map +0 -1
  188. package/dist/commands/plugin/add.js +0 -93
  189. package/dist/commands/plugin/add.js.map +0 -1
  190. package/dist/commands/plugin/build.d.ts +0 -29
  191. package/dist/commands/plugin/build.d.ts.map +0 -1
  192. package/dist/commands/plugin/build.js +0 -170
  193. package/dist/commands/plugin/build.js.map +0 -1
  194. package/dist/commands/plugin/info.d.ts +0 -10
  195. package/dist/commands/plugin/info.d.ts.map +0 -1
  196. package/dist/commands/plugin/info.js +0 -65
  197. package/dist/commands/plugin/info.js.map +0 -1
  198. package/dist/commands/plugin/list.d.ts +0 -13
  199. package/dist/commands/plugin/list.d.ts.map +0 -1
  200. package/dist/commands/plugin/list.js +0 -78
  201. package/dist/commands/plugin/list.js.map +0 -1
  202. package/dist/commands/plugin/publish.d.ts +0 -27
  203. package/dist/commands/plugin/publish.d.ts.map +0 -1
  204. package/dist/commands/plugin/publish.js +0 -152
  205. package/dist/commands/plugin/publish.js.map +0 -1
  206. package/dist/commands/plugin/remove.d.ts +0 -20
  207. package/dist/commands/plugin/remove.d.ts.map +0 -1
  208. package/dist/commands/plugin/remove.js +0 -79
  209. package/dist/commands/plugin/remove.js.map +0 -1
  210. package/dist/commands/plugin/validate.d.ts +0 -23
  211. package/dist/commands/plugin/validate.d.ts.map +0 -1
  212. package/dist/commands/plugin/validate.js +0 -251
  213. package/dist/commands/plugin/validate.js.map +0 -1
  214. package/src/bin.ts +0 -13
  215. package/src/commands/auth/login.ts +0 -188
  216. package/src/commands/auth/logout.ts +0 -51
  217. package/src/commands/auth/whoami.ts +0 -85
  218. package/src/commands/codemod/v2-to-v3.ts +0 -171
  219. package/src/commands/compile.ts +0 -114
  220. package/src/commands/create.ts +0 -281
  221. package/src/commands/data/create.ts +0 -110
  222. package/src/commands/data/delete.ts +0 -84
  223. package/src/commands/data/get.ts +0 -84
  224. package/src/commands/data/query.ts +0 -127
  225. package/src/commands/data/update.ts +0 -114
  226. package/src/commands/dev.ts +0 -83
  227. package/src/commands/diff.ts +0 -294
  228. package/src/commands/doctor.ts +0 -572
  229. package/src/commands/explain.ts +0 -412
  230. package/src/commands/generate.ts +0 -924
  231. package/src/commands/info.ts +0 -124
  232. package/src/commands/init.ts +0 -327
  233. package/src/commands/lint.ts +0 -315
  234. package/src/commands/meta/delete.ts +0 -79
  235. package/src/commands/meta/get.ts +0 -73
  236. package/src/commands/meta/list.ts +0 -105
  237. package/src/commands/meta/register.ts +0 -97
  238. package/src/commands/plugin/add.ts +0 -112
  239. package/src/commands/plugin/build.ts +0 -193
  240. package/src/commands/plugin/info.ts +0 -79
  241. package/src/commands/plugin/list.ts +0 -93
  242. package/src/commands/plugin/publish.ts +0 -176
  243. package/src/commands/plugin/remove.ts +0 -97
  244. package/src/commands/plugin/validate.ts +0 -268
  245. package/src/commands/serve.ts +0 -411
  246. package/src/commands/studio.ts +0 -52
  247. package/src/commands/test.ts +0 -135
  248. package/src/commands/validate.ts +0 -143
  249. package/src/index.ts +0 -22
  250. package/src/utils/api-client.ts +0 -88
  251. package/src/utils/auth-config.ts +0 -107
  252. package/src/utils/config.ts +0 -80
  253. package/src/utils/format.ts +0 -267
  254. package/src/utils/output-formatter.ts +0 -91
  255. package/src/utils/plugin-detection.ts +0 -16
  256. package/src/utils/plugin-helpers.ts +0 -37
  257. package/src/utils/studio.ts +0 -350
  258. package/test/commands.test.ts +0 -128
  259. package/test/create.test.ts +0 -25
  260. package/test/plugin-commands.test.ts +0 -44
  261. package/test/plugin.test.ts +0 -169
  262. package/test/remote-api-commands.test.ts +0 -188
  263. package/test/remote-api-utils.test.ts +0 -196
  264. package/test/serve-host-config.test.ts +0 -77
  265. package/tsconfig.build.json +0 -20
  266. package/tsconfig.json +0 -25
  267. package/tsup.config.ts +0 -23
  268. /package/dist/commands/{auth/logout.d.ts → logout.d.ts} +0 -0
  269. /package/dist/commands/{auth/whoami.d.ts → whoami.d.ts} +0 -0
@@ -1,171 +0,0 @@
1
- // Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.
2
-
3
- import { Command, Flags } from '@oclif/core';
4
- import chalk from 'chalk';
5
- import fs from 'fs';
6
- import path from 'path';
7
- import { printHeader, printSuccess, printError, printInfo, printStep, createTimer } from '../../utils/format.js';
8
-
9
- // ─── Transform Definitions ──────────────────────────────────────────
10
-
11
- interface Transform {
12
- pattern: RegExp;
13
- replacement: string;
14
- description: string;
15
- }
16
-
17
- const V2_TO_V3_TRANSFORMS: Transform[] = [
18
- {
19
- pattern: /\bEnhancedObjectKernel\b/g,
20
- replacement: 'ObjectKernel',
21
- description: 'EnhancedObjectKernel → ObjectKernel',
22
- },
23
- {
24
- pattern: /\bmax_length\b/g,
25
- replacement: 'maxLength',
26
- description: 'max_length → maxLength',
27
- },
28
- {
29
- pattern: /\breference_filters\b/g,
30
- replacement: 'referenceFilters',
31
- description: 'reference_filters → referenceFilters',
32
- },
33
- {
34
- pattern: /\bdefault_value\b/g,
35
- replacement: 'defaultValue',
36
- description: 'default_value → defaultValue',
37
- },
38
- {
39
- pattern: /\bmin_length\b/g,
40
- replacement: 'minLength',
41
- description: 'min_length → minLength',
42
- },
43
- {
44
- pattern: /\bunique_name\b/g,
45
- replacement: 'uniqueName',
46
- description: 'unique_name → uniqueName',
47
- },
48
- {
49
- pattern: /from\s+['"]@objectstack\/core\/enhanced['"]/g,
50
- replacement: "from '@objectstack/core'",
51
- description: 'Update import from @objectstack/core/enhanced',
52
- },
53
- {
54
- pattern: /from\s+['"]@objectstack\/spec\/dist\/[^'"]+['"]/g,
55
- replacement: "from '@objectstack/spec'",
56
- description: 'Update deep import from @objectstack/spec/dist/',
57
- },
58
- ];
59
-
60
- // ─── Helpers ────────────────────────────────────────────────────────
61
-
62
- function walkDir(dir: string, ext: string): string[] {
63
- const results: string[] = [];
64
- if (!fs.existsSync(dir)) return results;
65
-
66
- const entries = fs.readdirSync(dir, { withFileTypes: true });
67
- for (const entry of entries) {
68
- if (entry.name === 'node_modules') continue;
69
- const fullPath = path.join(dir, entry.name);
70
- if (entry.isDirectory()) {
71
- results.push(...walkDir(fullPath, ext));
72
- } else if (entry.name.endsWith(ext)) {
73
- results.push(fullPath);
74
- }
75
- }
76
- return results;
77
- }
78
-
79
- // ─── Command ────────────────────────────────────────────────────────
80
-
81
- export default class V2ToV3 extends Command {
82
- static override description = 'Migrate ObjectStack v2 config to v3 format';
83
-
84
- static override flags = {
85
- dir: Flags.string({ description: 'Directory to scan', default: 'src/' }),
86
- 'dry-run': Flags.boolean({ description: 'Show changes without writing files' }),
87
- };
88
-
89
- async run(): Promise<void> {
90
- const { flags } = await this.parse(V2ToV3);
91
-
92
- printHeader('Codemod: v2 → v3');
93
-
94
- const timer = createTimer();
95
- const dir = path.resolve(process.cwd(), flags.dir);
96
-
97
- if (!fs.existsSync(dir)) {
98
- printError(`Directory not found: ${dir}`);
99
- process.exit(1);
100
- }
101
-
102
- console.log(` ${chalk.dim('Directory:')} ${chalk.white(flags.dir)}`);
103
- console.log(` ${chalk.dim('Dry run:')} ${chalk.white(flags['dry-run'] ? 'yes' : 'no')}`);
104
- console.log('');
105
-
106
- printStep('Scanning TypeScript files...');
107
- const files = walkDir(dir, '.ts');
108
-
109
- if (files.length === 0) {
110
- printInfo('No .ts files found in directory');
111
- return;
112
- }
113
-
114
- printInfo(`Found ${files.length} TypeScript file(s)`);
115
- console.log('');
116
-
117
- let totalTransforms = 0;
118
- let filesModified = 0;
119
- const transformCounts: Record<string, number> = {};
120
-
121
- for (const file of files) {
122
- const original = fs.readFileSync(file, 'utf-8');
123
- let content = original;
124
- let fileTransforms = 0;
125
-
126
- for (const transform of V2_TO_V3_TRANSFORMS) {
127
- const matches = content.match(transform.pattern);
128
- if (matches) {
129
- const count = matches.length;
130
- content = content.replace(transform.pattern, transform.replacement);
131
- fileTransforms += count;
132
- transformCounts[transform.description] = (transformCounts[transform.description] || 0) + count;
133
- }
134
- }
135
-
136
- if (fileTransforms > 0) {
137
- const relPath = path.relative(process.cwd(), file);
138
- filesModified++;
139
- totalTransforms += fileTransforms;
140
-
141
- if (flags['dry-run']) {
142
- printInfo(`${relPath} — ${fileTransforms} change(s)`);
143
- } else {
144
- fs.writeFileSync(file, content);
145
- printSuccess(`${relPath} — ${fileTransforms} change(s)`);
146
- }
147
- }
148
- }
149
-
150
- console.log('');
151
-
152
- if (totalTransforms === 0) {
153
- printSuccess('No v2 patterns found — code is already v3 compatible');
154
- } else {
155
- console.log(chalk.bold(' Summary:'));
156
- for (const [desc, count] of Object.entries(transformCounts)) {
157
- console.log(` ${chalk.dim(desc)}: ${chalk.white(count)}`);
158
- }
159
- console.log('');
160
-
161
- if (flags['dry-run']) {
162
- printInfo(`Would modify ${filesModified} file(s) with ${totalTransforms} total change(s)`);
163
- console.log(chalk.dim(' Run without --dry-run to apply changes'));
164
- } else {
165
- printSuccess(`Modified ${filesModified} file(s) with ${totalTransforms} total change(s) (${timer.display()})`);
166
- }
167
- }
168
-
169
- console.log('');
170
- }
171
- }
@@ -1,114 +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 path from 'path';
5
- import fs from 'fs';
6
- import chalk from 'chalk';
7
- import { ZodError } from 'zod';
8
- import { ObjectStackDefinitionSchema, normalizeStackInput } from '@objectstack/spec';
9
- import { loadConfig } from '../utils/config.js';
10
- import {
11
- printHeader,
12
- printKV,
13
- printSuccess,
14
- printError,
15
- printStep,
16
- createTimer,
17
- formatZodErrors,
18
- collectMetadataStats,
19
- printMetadataStats,
20
- } from '../utils/format.js';
21
-
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);
36
- const timer = createTimer();
37
-
38
- if (!flags.json) {
39
- printHeader('Compile');
40
- }
41
-
42
- try {
43
- // 1. Load Configuration
44
- if (!flags.json) printStep('Loading configuration...');
45
- const { config, absolutePath, duration } = await loadConfig(args.config);
46
-
47
- if (!flags.json) {
48
- printKV('Config', path.relative(process.cwd(), absolutePath));
49
- printKV('Load time', `${duration}ms`);
50
- }
51
-
52
- // 2. Normalize map-formatted stack definition and validate against Protocol
53
- if (!flags.json) printStep('Validating protocol compliance...');
54
- const normalized = normalizeStackInput(config as Record<string, unknown>);
55
- const result = ObjectStackDefinitionSchema.safeParse(normalized);
56
-
57
- if (!result.success) {
58
- if (flags.json) {
59
- console.log(JSON.stringify({ success: false, errors: (result.error as unknown as ZodError).issues }));
60
- this.exit(1);
61
- }
62
- console.log('');
63
- printError('Validation failed');
64
- formatZodErrors(result.error as unknown as ZodError);
65
- this.exit(1);
66
- }
67
-
68
- // 3. Generate Artifact
69
- if (!flags.json) printStep('Writing artifact...');
70
- const output = flags.output!;
71
- const artifactPath = path.resolve(process.cwd(), output);
72
- const artifactDir = path.dirname(artifactPath);
73
-
74
- if (!fs.existsSync(artifactDir)) {
75
- fs.mkdirSync(artifactDir, { recursive: true });
76
- }
77
-
78
- const jsonContent = JSON.stringify(result.data, null, 2);
79
- fs.writeFileSync(artifactPath, jsonContent);
80
-
81
- const sizeKB = (jsonContent.length / 1024).toFixed(1);
82
- const stats = collectMetadataStats(config);
83
-
84
- if (flags.json) {
85
- console.log(JSON.stringify({
86
- success: true,
87
- output: artifactPath,
88
- size: jsonContent.length,
89
- stats,
90
- duration: timer.elapsed(),
91
- }));
92
- return;
93
- }
94
-
95
- // 4. Summary
96
- console.log('');
97
- printSuccess(`Build complete ${chalk.dim(`(${timer.display()})`)}`);
98
- console.log('');
99
- printMetadataStats(stats);
100
- console.log('');
101
- printKV('Artifact', `${output} ${chalk.dim(`(${sizeKB} KB`)})`);
102
- console.log('');
103
-
104
- } catch (error: any) {
105
- if (flags.json) {
106
- console.log(JSON.stringify({ success: false, error: error.message }));
107
- this.exit(1);
108
- }
109
- console.log('');
110
- printError(error.message || String(error));
111
- this.error(error.message || String(error));
112
- }
113
- }
114
- }
@@ -1,281 +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 fs from 'fs';
6
- import path from 'path';
7
- import { execSync } from 'child_process';
8
-
9
- export const templates = {
10
- plugin: {
11
- description: 'Create a new ObjectStack plugin',
12
- files: {
13
- 'package.json': (name: string) => ({
14
- name: `@objectstack/plugin-${name}`,
15
- version: '0.1.0',
16
- description: `ObjectStack Plugin: ${name}`,
17
- main: 'dist/index.js',
18
- types: 'dist/index.d.ts',
19
- scripts: {
20
- build: 'tsc',
21
- dev: 'tsc --watch',
22
- test: 'vitest',
23
- },
24
- keywords: ['objectstack', 'plugin', name],
25
- author: '',
26
- license: 'MIT',
27
- dependencies: {
28
- '@objectstack/spec': 'workspace:*',
29
- zod: '^4.3.6',
30
- },
31
- devDependencies: {
32
- '@types/node': '^22.0.0',
33
- typescript: '^5.8.0',
34
- vitest: '^4.0.0',
35
- },
36
- }),
37
- 'tsconfig.json': () => ({
38
- extends: '../../tsconfig.json',
39
- compilerOptions: {
40
- outDir: 'dist',
41
- rootDir: 'src',
42
- },
43
- include: ['src/**/*'],
44
- }),
45
- 'src/index.ts': (name: string) => `import type { Plugin } from '@objectstack/spec';
46
-
47
- /**
48
- * ${name} Plugin for ObjectStack
49
- */
50
- export const ${toCamelCase(name)}Plugin: Plugin = {
51
- name: '${name}',
52
- version: '0.1.0',
53
-
54
- async initialize(context) {
55
- console.log('Initializing ${name} plugin...');
56
- // Plugin initialization logic
57
- },
58
-
59
- async destroy() {
60
- console.log('Destroying ${name} plugin...');
61
- // Plugin cleanup logic
62
- },
63
- };
64
-
65
- export default ${toCamelCase(name)}Plugin;
66
- `,
67
- 'README.md': (name: string) => `# @objectstack/plugin-${name}
68
-
69
- ObjectStack Plugin: ${name}
70
-
71
- ## Installation
72
-
73
- \`\`\`bash
74
- pnpm add @objectstack/plugin-${name}
75
- \`\`\`
76
-
77
- ## Usage
78
-
79
- \`\`\`typescript
80
- import { ${toCamelCase(name)}Plugin } from '@objectstack/plugin-${name}';
81
-
82
- // Use the plugin in your ObjectStack configuration
83
- export default {
84
- plugins: [
85
- ${toCamelCase(name)}Plugin,
86
- ],
87
- };
88
- \`\`\`
89
-
90
- ## License
91
-
92
- MIT
93
- `,
94
- },
95
- },
96
-
97
- example: {
98
- description: 'Create a new ObjectStack example application',
99
- files: {
100
- 'package.json': (name: string) => ({
101
- name: `@example/${name}`,
102
- version: '0.1.0',
103
- private: true,
104
- description: `ObjectStack Example: ${name}`,
105
- scripts: {
106
- build: 'objectstack compile',
107
- dev: 'objectstack dev',
108
- test: 'vitest',
109
- },
110
- dependencies: {
111
- '@objectstack/spec': 'workspace:*',
112
- '@objectstack/cli': 'workspace:*',
113
- zod: '^4.3.6',
114
- },
115
- devDependencies: {
116
- '@types/node': '^22.0.0',
117
- tsx: '^4.21.0',
118
- typescript: '^5.8.0',
119
- vitest: '^4.0.0',
120
- },
121
- }),
122
- 'objectstack.config.ts': (name: string) => `import { defineStack } from '@objectstack/spec';
123
-
124
- // Barrel imports — add more as you create new type folders
125
- // import * as objects from './src/objects';
126
- // import * as actions from './src/actions';
127
- // import * as apps from './src/apps';
128
-
129
- export default defineStack({
130
- manifest: {
131
- name: '${name}',
132
- version: '0.1.0',
133
- description: '${name} example application',
134
- },
135
-
136
- objects: [
137
- // Object.values(objects), // Uncomment after creating src/objects/index.ts
138
- ],
139
-
140
- apps: [
141
- // Object.values(apps), // Uncomment after creating src/apps/index.ts
142
- ],
143
- });
144
- `,
145
- 'README.md': (name: string) => `# ${name} Example
146
-
147
- ObjectStack example application: ${name}
148
-
149
- ## Quick Start
150
-
151
- \`\`\`bash
152
- # Build the configuration
153
- pnpm build
154
-
155
- # Run in development mode
156
- pnpm dev
157
- \`\`\`
158
-
159
- ## Structure
160
-
161
- - \`objectstack.config.ts\` - Main configuration file
162
- - \`dist/objectstack.json\` - Compiled artifact
163
-
164
- ## Learn More
165
-
166
- - [ObjectStack Documentation](../../content/docs)
167
- - [Examples](../)
168
- `,
169
- 'tsconfig.json': () => ({
170
- extends: '../../tsconfig.json',
171
- compilerOptions: {
172
- outDir: 'dist',
173
- rootDir: '.',
174
- },
175
- include: ['*.ts', 'src/**/*'],
176
- }),
177
- },
178
- },
179
- };
180
-
181
- function toCamelCase(str: string): string {
182
- return str.replace(/-([a-z])/g, (g) => g[1].toUpperCase());
183
- }
184
-
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
-
200
- console.log(chalk.bold(`\n📦 ObjectStack Project Creator`));
201
- console.log(chalk.dim(`-------------------------------`));
202
-
203
- if (!templates[args.type as keyof typeof templates]) {
204
- console.error(chalk.red(`\n❌ Unknown type: ${args.type}`));
205
- console.log(chalk.dim('Available types: plugin, example'));
206
- process.exit(1);
207
- }
208
-
209
- if (!args.name) {
210
- console.error(chalk.red('\n❌ Project name is required'));
211
- console.log(chalk.dim(`Usage: objectstack create ${args.type} <name>`));
212
- process.exit(1);
213
- }
214
-
215
- const template = templates[args.type as keyof typeof templates];
216
- const cwd = process.cwd();
217
-
218
- // Determine target directory
219
- let targetDir: string;
220
- if (flags.dir) {
221
- targetDir = path.resolve(cwd, flags.dir);
222
- } else {
223
- const baseDir = args.type === 'plugin' ? 'packages/plugins' : 'examples';
224
- const projectName = args.type === 'plugin' ? `plugin-${args.name}` : args.name;
225
- targetDir = path.join(cwd, baseDir, projectName);
226
- }
227
-
228
- // Check if directory already exists
229
- if (fs.existsSync(targetDir)) {
230
- console.error(chalk.red(`\n❌ Directory already exists: ${targetDir}`));
231
- process.exit(1);
232
- }
233
-
234
- console.log(`📁 Creating ${args.type}: ${chalk.blue(args.name)}`);
235
- console.log(`📂 Location: ${chalk.dim(targetDir)}`);
236
- console.log('');
237
-
238
- try {
239
- // Create directory
240
- fs.mkdirSync(targetDir, { recursive: true });
241
-
242
- // Create files from template
243
- for (const [filePath, contentFn] of Object.entries(template.files)) {
244
- const fullPath = path.join(targetDir, filePath);
245
- const dir = path.dirname(fullPath);
246
-
247
- if (!fs.existsSync(dir)) {
248
- fs.mkdirSync(dir, { recursive: true });
249
- }
250
-
251
- const content = contentFn(args.name);
252
- const fileContent = typeof content === 'string'
253
- ? content
254
- : JSON.stringify(content, null, 2);
255
-
256
- fs.writeFileSync(fullPath, fileContent);
257
- console.log(chalk.green(`✓ Created ${filePath}`));
258
- }
259
-
260
- console.log('');
261
- console.log(chalk.green('✅ Project created successfully!'));
262
- console.log('');
263
- console.log(chalk.bold('Next steps:'));
264
- console.log(chalk.dim(` cd ${path.relative(cwd, targetDir)}`));
265
- console.log(chalk.dim(' pnpm install'));
266
- console.log(chalk.dim(' pnpm build'));
267
- console.log('');
268
-
269
- } catch (error: any) {
270
- console.error(chalk.red('\n❌ Failed to create project:'));
271
- console.error(error.message || error);
272
-
273
- // Clean up on error
274
- if (fs.existsSync(targetDir)) {
275
- fs.rmSync(targetDir, { recursive: true });
276
- }
277
-
278
- process.exit(1);
279
- }
280
- }
281
- }
@@ -1,110 +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 DataCreate extends Command {
9
- static override description = 'Create a new record';
10
-
11
- static override examples = [
12
- '$ os data create project_task \'{"name":"New Task","status":"open"}\'',
13
- '$ os data create project_task --data task-data.json',
14
- '$ os data create project_task --data task-data.json --format json',
15
- ];
16
-
17
- static override args = {
18
- object: Args.string({
19
- description: 'Object name (snake_case)',
20
- required: true,
21
- }),
22
- data: Args.string({
23
- description: 'Record data as JSON string (or use --data flag for file)',
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
- data: Flags.string({
39
- char: 'd',
40
- description: 'Path to JSON file containing record data',
41
- }),
42
- format: Flags.string({
43
- char: 'f',
44
- description: 'Output format',
45
- options: ['json', 'table', 'yaml'],
46
- default: 'table',
47
- }),
48
- };
49
-
50
- async run(): Promise<void> {
51
- const { args, flags } = await this.parse(DataCreate);
52
-
53
- try {
54
- const { client, token } = await createApiClient({
55
- url: flags.url,
56
- token: flags.token,
57
- });
58
-
59
- requireAuth(token);
60
-
61
- // Parse record data
62
- let recordData: any;
63
-
64
- if (flags.data) {
65
- // Read from file
66
- const { readFile } = await import('node:fs/promises');
67
- const fileContent = await readFile(flags.data, 'utf-8');
68
- try {
69
- recordData = JSON.parse(fileContent);
70
- } catch (e) {
71
- throw new Error(`Invalid JSON in file: ${(e as Error).message}`);
72
- }
73
- } else if (args.data) {
74
- // Parse from argument
75
- try {
76
- recordData = JSON.parse(args.data);
77
- } catch (e) {
78
- throw new Error(`Invalid JSON: ${(e as Error).message}`);
79
- }
80
- } else {
81
- throw new Error('Record data is required (provide JSON string or use --data flag)');
82
- }
83
-
84
- // Create the record
85
- const result = await client.data.create(args.object, recordData);
86
-
87
- if (flags.format === 'json') {
88
- formatOutput(result, 'json');
89
- } else if (flags.format === 'yaml') {
90
- formatOutput(result, 'yaml');
91
- } else {
92
- printSuccess(`Record created: ${result.id}`);
93
- if (result.record) {
94
- console.log('');
95
- formatOutput(result.record, 'table');
96
- }
97
- }
98
- } catch (error: any) {
99
- if (flags.format === 'json') {
100
- console.log(JSON.stringify({
101
- success: false,
102
- error: error.message,
103
- }, null, 2));
104
- this.exit(1);
105
- }
106
- printError(error.message || String(error));
107
- this.exit(1);
108
- }
109
- }
110
- }