@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,124 +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
- printKV,
10
- printSuccess,
11
- printError,
12
- printStep,
13
- createTimer,
14
- collectMetadataStats,
15
- printMetadataStats,
16
- } from '../utils/format.js';
17
-
18
- export default class Info extends Command {
19
- static override description = 'Display metadata summary of an ObjectStack configuration';
20
-
21
- static override args = {
22
- config: Args.string({ description: 'Configuration file path', required: false }),
23
- };
24
-
25
- static override flags = {
26
- json: Flags.boolean({ description: 'Output as JSON' }),
27
- };
28
-
29
- async run(): Promise<void> {
30
- const { args, flags } = await this.parse(Info);
31
- const timer = createTimer();
32
-
33
- if (!flags.json) {
34
- printHeader('Info');
35
- }
36
-
37
- try {
38
- const { config: rawConfig, absolutePath, duration } = await loadConfig(args.config);
39
- const config: any = normalizeStackInput(rawConfig as Record<string, unknown>);
40
- const stats = collectMetadataStats(config);
41
-
42
- if (flags.json) {
43
- console.log(JSON.stringify({
44
- config: absolutePath,
45
- manifest: config.manifest || null,
46
- stats,
47
- objects: (config.objects || []).map((o: any) => ({
48
- name: o.name,
49
- label: o.label,
50
- fields: o.fields ? Object.keys(o.fields).length : 0,
51
- })),
52
- loadTime: duration,
53
- }, null, 2));
54
- return;
55
- }
56
-
57
- // Manifest
58
- if (config.manifest) {
59
- const m = config.manifest;
60
- console.log('');
61
- console.log(` ${chalk.bold(m.name || m.id || 'Unnamed')} ${chalk.dim(`v${m.version || '0.0.0'}`)}`);
62
- if (m.id) console.log(chalk.dim(` ${m.id}`));
63
- if (m.description) console.log(chalk.dim(` ${m.description}`));
64
- if (m.namespace) printKV(' Namespace', m.namespace);
65
- if (m.type) printKV(' Type', m.type);
66
- }
67
-
68
- console.log('');
69
- printMetadataStats(stats);
70
-
71
- // Object details
72
- if (config.objects && config.objects.length > 0) {
73
- console.log('');
74
- console.log(chalk.bold(' Objects:'));
75
- for (const obj of config.objects) {
76
- const fieldCount = obj.fields ? Object.keys(obj.fields).length : 0;
77
- const ownership = obj.ownership || 'own';
78
- console.log(
79
- ` ${chalk.cyan(obj.name || '?')}` +
80
- chalk.dim(` (${fieldCount} fields, ${ownership})`) +
81
- (obj.label ? chalk.dim(` — ${obj.label}`) : '')
82
- );
83
- }
84
- }
85
-
86
- // Agent details
87
- if (config.agents && config.agents.length > 0) {
88
- console.log('');
89
- console.log(chalk.bold(' Agents:'));
90
- for (const agent of config.agents) {
91
- console.log(
92
- ` ${chalk.magenta(agent.name || '?')}` +
93
- (agent.role ? chalk.dim(` — ${agent.role}`) : '')
94
- );
95
- }
96
- }
97
-
98
- // App details
99
- if (config.apps && config.apps.length > 0) {
100
- console.log('');
101
- console.log(chalk.bold(' Apps:'));
102
- for (const app of config.apps) {
103
- console.log(
104
- ` ${chalk.green(app.name || '?')}` +
105
- (app.label ? chalk.dim(` — ${app.label}`) : '')
106
- );
107
- }
108
- }
109
-
110
- console.log('');
111
- console.log(chalk.dim(` Loaded in ${duration}ms`));
112
- console.log('');
113
-
114
- } catch (error: any) {
115
- if (flags.json) {
116
- console.log(JSON.stringify({ error: error.message }));
117
- process.exit(1);
118
- }
119
- console.log('');
120
- printError(error.message || String(error));
121
- process.exit(1);
122
- }
123
- }
124
- }
@@ -1,327 +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 { printHeader, printSuccess, printError, printStep, printKV, printInfo } from '../utils/format.js';
8
-
9
- export const TEMPLATES: Record<string, {
10
- description: string;
11
- dependencies: Record<string, string>;
12
- devDependencies: Record<string, string>;
13
- scripts: Record<string, string>;
14
- configContent: (name: string) => string;
15
- srcFiles: Record<string, (name: string) => string>;
16
- }> = {
17
- app: {
18
- description: 'Full application with objects, views, and actions',
19
- dependencies: {
20
- '@objectstack/spec': 'workspace:*',
21
- '@objectstack/runtime': 'workspace:^',
22
- '@objectstack/objectql': 'workspace:^',
23
- '@objectstack/driver-memory': 'workspace:^',
24
- },
25
- devDependencies: {
26
- '@objectstack/cli': 'workspace:*',
27
- 'typescript': '^5.3.0',
28
- },
29
- scripts: {
30
- dev: 'objectstack dev',
31
- start: 'objectstack serve',
32
- build: 'objectstack compile',
33
- validate: 'objectstack validate',
34
- typecheck: 'tsc --noEmit',
35
- },
36
- configContent: (name: string) => `import { defineStack } from '@objectstack/spec';
37
- import * as objects from './src/objects';
38
-
39
- export default defineStack({
40
- manifest: {
41
- id: 'com.example.${name}',
42
- namespace: '${name}',
43
- version: '0.1.0',
44
- type: 'app',
45
- name: '${toTitleCase(name)}',
46
- description: '${toTitleCase(name)} application built with ObjectStack',
47
- },
48
-
49
- objects: Object.values(objects),
50
- });
51
- `,
52
- srcFiles: {
53
- 'src/objects/index.ts': (name) => `export { default as ${toCamelCase(name)} } from './${name}';
54
- `,
55
- 'src/objects/__name__.ts': (name) => `import { Data } from '@objectstack/spec';
56
-
57
- const ${toCamelCase(name)}: Data.Object = {
58
- name: '${name}',
59
- label: '${toTitleCase(name)}',
60
- ownership: 'own',
61
- fields: {
62
- name: {
63
- type: 'text',
64
- label: 'Name',
65
- required: true,
66
- },
67
- description: {
68
- type: 'textarea',
69
- label: 'Description',
70
- },
71
- status: {
72
- type: 'select',
73
- label: 'Status',
74
- options: [
75
- { label: 'Draft', value: 'draft' },
76
- { label: 'Active', value: 'active' },
77
- { label: 'Archived', value: 'archived' },
78
- ],
79
- defaultValue: 'draft',
80
- },
81
- },
82
- };
83
-
84
- export default ${toCamelCase(name)};
85
- `,
86
- },
87
- },
88
-
89
- plugin: {
90
- description: 'Reusable plugin with objects and extensions',
91
- dependencies: {
92
- '@objectstack/spec': 'workspace:*',
93
- },
94
- devDependencies: {
95
- 'typescript': '^5.3.0',
96
- 'vitest': '^4.0.18',
97
- },
98
- scripts: {
99
- build: 'objectstack compile',
100
- validate: 'objectstack validate',
101
- test: 'vitest run',
102
- typecheck: 'tsc --noEmit',
103
- },
104
- configContent: (name: string) => `import { defineStack } from '@objectstack/spec';
105
- import * as objects from './src/objects';
106
-
107
- export default defineStack({
108
- manifest: {
109
- id: 'com.objectstack.plugin-${name}',
110
- namespace: 'plugin_${name}',
111
- version: '0.1.0',
112
- type: 'plugin',
113
- name: '${toTitleCase(name)} Plugin',
114
- description: 'ObjectStack Plugin: ${toTitleCase(name)}',
115
- },
116
-
117
- objects: Object.values(objects),
118
- });
119
- `,
120
- srcFiles: {
121
- 'src/objects/index.ts': (name) => `export { default as ${toCamelCase(name)} } from './${name}';
122
- `,
123
- 'src/objects/__name__.ts': (name) => `import { Data } from '@objectstack/spec';
124
-
125
- const ${toCamelCase(name)}: Data.Object = {
126
- name: '${name}',
127
- label: '${toTitleCase(name)}',
128
- ownership: 'own',
129
- fields: {
130
- name: {
131
- type: 'text',
132
- label: 'Name',
133
- required: true,
134
- },
135
- },
136
- };
137
-
138
- export default ${toCamelCase(name)};
139
- `,
140
- },
141
- },
142
-
143
- empty: {
144
- description: 'Minimal project with just a config file',
145
- dependencies: {
146
- '@objectstack/spec': 'workspace:*',
147
- },
148
- devDependencies: {
149
- '@objectstack/cli': 'workspace:*',
150
- 'typescript': '^5.3.0',
151
- },
152
- scripts: {
153
- build: 'objectstack compile',
154
- validate: 'objectstack validate',
155
- typecheck: 'tsc --noEmit',
156
- },
157
- configContent: (name: string) => `import { defineStack } from '@objectstack/spec';
158
-
159
- export default defineStack({
160
- manifest: {
161
- id: 'com.example.${name}',
162
- namespace: '${name}',
163
- version: '0.1.0',
164
- type: 'app',
165
- name: '${toTitleCase(name)}',
166
- description: '',
167
- },
168
- });
169
- `,
170
- srcFiles: {},
171
- },
172
- };
173
-
174
- function toCamelCase(str: string): string {
175
- return str.replace(/[-_]([a-z])/g, (_, c) => c.toUpperCase());
176
- }
177
-
178
- function toTitleCase(str: string): string {
179
- return str.replace(/[-_]/g, ' ').replace(/\b\w/g, c => c.toUpperCase());
180
- }
181
-
182
- function printWarning(msg: string) {
183
- console.log(chalk.yellow(` ⚠ ${msg}`));
184
- }
185
-
186
- export default class Init extends Command {
187
- static override id = 'init';
188
-
189
- static override description = 'Initialize a new ObjectStack project in the current directory';
190
-
191
- static override args = {
192
- name: Args.string({ description: 'Project name (defaults to directory name)', required: false }),
193
- };
194
-
195
- static override flags = {
196
- template: Flags.string({ char: 't', description: 'Template: app, plugin, empty', default: 'app' }),
197
- install: Flags.boolean({ description: 'Install dependencies', default: true, allowNo: true }),
198
- };
199
-
200
- async run(): Promise<void> {
201
- const { args, flags } = await this.parse(Init);
202
-
203
- printHeader('Init');
204
-
205
- const cwd = process.cwd();
206
- const projectName = args.name || path.basename(cwd);
207
- const template = TEMPLATES[flags.template];
208
-
209
- if (!template) {
210
- printError(`Unknown template: ${flags.template}`);
211
- console.log(chalk.dim(` Available: ${Object.keys(TEMPLATES).join(', ')}`));
212
- this.error(`Unknown template: ${flags.template}`);
213
- }
214
-
215
- // Check for existing config
216
- if (fs.existsSync(path.join(cwd, 'objectstack.config.ts'))) {
217
- printError('objectstack.config.ts already exists in this directory');
218
- console.log(chalk.dim(' Use `objectstack generate` to add metadata to an existing project'));
219
- this.error('objectstack.config.ts already exists in this directory');
220
- }
221
-
222
- printKV('Project', projectName);
223
- printKV('Template', `${flags.template} — ${template.description}`);
224
- printKV('Directory', cwd);
225
- console.log('');
226
-
227
- const createdFiles: string[] = [];
228
-
229
- try {
230
- // 1. Create package.json if missing
231
- const pkgPath = path.join(cwd, 'package.json');
232
- if (!fs.existsSync(pkgPath)) {
233
- const pkg = {
234
- name: projectName,
235
- version: '0.1.0',
236
- private: true,
237
- type: 'module',
238
- scripts: template.scripts,
239
- dependencies: template.dependencies,
240
- devDependencies: template.devDependencies,
241
- };
242
- fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + '\n');
243
- createdFiles.push('package.json');
244
- } else {
245
- printInfo('package.json already exists, skipping');
246
- }
247
-
248
- // 2. Create objectstack.config.ts
249
- const configContent = template.configContent(projectName);
250
- fs.writeFileSync(path.join(cwd, 'objectstack.config.ts'), configContent);
251
- createdFiles.push('objectstack.config.ts');
252
-
253
- // 3. Create tsconfig.json if missing
254
- const tsconfigPath = path.join(cwd, 'tsconfig.json');
255
- if (!fs.existsSync(tsconfigPath)) {
256
- const tsconfig = {
257
- compilerOptions: {
258
- target: 'ES2022',
259
- module: 'ESNext',
260
- moduleResolution: 'bundler',
261
- strict: true,
262
- esModuleInterop: true,
263
- skipLibCheck: true,
264
- outDir: 'dist',
265
- rootDir: '.',
266
- declaration: true,
267
- },
268
- include: ['*.ts', 'src/**/*'],
269
- exclude: ['dist', 'node_modules'],
270
- };
271
- fs.writeFileSync(tsconfigPath, JSON.stringify(tsconfig, null, 2) + '\n');
272
- createdFiles.push('tsconfig.json');
273
- }
274
-
275
- // 4. Create src files
276
- for (const [filePath, contentFn] of Object.entries(template.srcFiles)) {
277
- const resolvedPath = filePath.replace('__name__', projectName);
278
- const fullPath = path.join(cwd, resolvedPath);
279
- const dir = path.dirname(fullPath);
280
-
281
- if (!fs.existsSync(dir)) {
282
- fs.mkdirSync(dir, { recursive: true });
283
- }
284
-
285
- fs.writeFileSync(fullPath, contentFn(projectName));
286
- createdFiles.push(resolvedPath);
287
- }
288
-
289
- // 5. Create .gitignore if missing
290
- const gitignorePath = path.join(cwd, '.gitignore');
291
- if (!fs.existsSync(gitignorePath)) {
292
- fs.writeFileSync(gitignorePath, `node_modules/\ndist/\n*.tsbuildinfo\n`);
293
- createdFiles.push('.gitignore');
294
- }
295
-
296
- // Summary
297
- console.log(chalk.bold(' Created files:'));
298
- for (const f of createdFiles) {
299
- console.log(chalk.green(` + ${f}`));
300
- }
301
- console.log('');
302
-
303
- // Install dependencies
304
- if (flags.install) {
305
- printStep('Installing dependencies...');
306
- const { execSync } = await import('child_process');
307
- try {
308
- execSync('pnpm install', { stdio: 'inherit', cwd });
309
- } catch {
310
- printWarning('Dependency installation failed. Run `pnpm install` manually.');
311
- }
312
- }
313
-
314
- printSuccess('Project initialized!');
315
- console.log('');
316
- console.log(chalk.bold(' Next steps:'));
317
- console.log(chalk.dim(' objectstack validate # Check configuration'));
318
- console.log(chalk.dim(' objectstack dev # Start development server'));
319
- console.log(chalk.dim(' objectstack generate # Add objects, views, etc.'));
320
- console.log('');
321
-
322
- } catch (error: any) {
323
- printError(error.message || String(error));
324
- this.error(error.message || String(error));
325
- }
326
- }
327
- }