@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,112 +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 { resolveConfigPath } from '../../utils/config.js';
8
- import { printHeader, printSuccess, printError } from '../../utils/format.js';
9
-
10
- /**
11
- * Add a plugin import and entry to objectstack.config.ts.
12
- *
13
- * This performs a simple text-based transformation:
14
- * 1. Adds an import statement for the package at the top of the file.
15
- * 2. Inserts the imported identifier into the `plugins` array, creating one if absent.
16
- */
17
- function addPluginToConfig(configPath: string, packageName: string): void {
18
- let content = fs.readFileSync(configPath, 'utf-8');
19
-
20
- // Derive a variable name from the package name
21
- // e.g. "@objectstack/plugin-auth" → "authPlugin"
22
- const shortName = packageName
23
- .replace(/^@[^/]+\//, '') // strip scope
24
- .replace(/^plugin-/, '') // strip "plugin-" prefix
25
- .replace(/-+/g, '-') // collapse consecutive hyphens
26
- .replace(/^-|-$/g, ''); // trim leading/trailing hyphens
27
- const varName = shortName.replace(/-([a-z])/g, (_, c: string) => c.toUpperCase()) + 'Plugin';
28
-
29
- // 1. Add import
30
- const importLine = `import ${varName} from '${packageName}';\n`;
31
-
32
- if (content.includes(packageName)) {
33
- throw new Error(`Plugin '${packageName}' is already referenced in the config`);
34
- }
35
-
36
- // Insert import after the last existing import
37
- const importRegex = /^import .+$/gm;
38
- let lastImportEnd = 0;
39
- let match: RegExpExecArray | null;
40
- while ((match = importRegex.exec(content)) !== null) {
41
- lastImportEnd = match.index + match[0].length;
42
- }
43
-
44
- if (lastImportEnd > 0) {
45
- content = content.slice(0, lastImportEnd) + '\n' + importLine + content.slice(lastImportEnd);
46
- } else {
47
- content = importLine + '\n' + content;
48
- }
49
-
50
- // 2. Add to plugins array (target only the first plugins: [ within defineStack)
51
- if (/plugins\s*:\s*\[/.test(content)) {
52
- // plugins array exists — append to it (first occurrence only)
53
- let replaced = false;
54
- content = content.replace(
55
- /(plugins\s*:\s*\[)/,
56
- (match) => {
57
- if (replaced) return match;
58
- replaced = true;
59
- return `${match}\n ${varName},`;
60
- }
61
- );
62
- } else {
63
- // No plugins array — add one before the closing of defineStack({...})
64
- // Look for the last property before the closing `})` or `})`
65
- content = content.replace(
66
- /(defineStack\(\{[\s\S]*?)(}\s*\))/,
67
- `$1 plugins: [\n ${varName},\n ],\n$2`
68
- );
69
- }
70
-
71
- fs.writeFileSync(configPath, content);
72
- }
73
-
74
- export { addPluginToConfig };
75
-
76
- export default class PluginAdd extends Command {
77
- static override description = 'Add a plugin to objectstack.config.ts';
78
-
79
- static override args = {
80
- package: Args.string({ description: 'Plugin package name (e.g. @objectstack/plugin-auth)', required: true }),
81
- };
82
-
83
- static override flags = {
84
- dev: Flags.boolean({ char: 'd', description: 'Add as a dev-only plugin' }),
85
- config: Flags.string({ char: 'c', description: 'Configuration file path' }),
86
- };
87
-
88
- async run(): Promise<void> {
89
- const { args, flags } = await this.parse(PluginAdd);
90
-
91
- try {
92
- const configPath = resolveConfigPath(flags.config);
93
-
94
- printHeader('Add Plugin');
95
- console.log(` ${chalk.dim('Package:')} ${chalk.white(args.package)}`);
96
- console.log(` ${chalk.dim('Config:')} ${chalk.white(path.relative(process.cwd(), configPath))}`);
97
- console.log('');
98
-
99
- addPluginToConfig(configPath, args.package);
100
- printSuccess(`Added ${chalk.cyan(args.package)} to config`);
101
-
102
- console.log('');
103
- console.log(chalk.dim(' Next steps:'));
104
- console.log(chalk.dim(` 1. Install the package: pnpm add ${args.package}`));
105
- console.log(chalk.dim(' 2. Run: os validate'));
106
- console.log('');
107
- } catch (error: any) {
108
- printError(error.message || String(error));
109
- this.exit(1);
110
- }
111
- }
112
- }
@@ -1,193 +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 path from 'path';
6
- import fs from 'fs';
7
- import crypto from 'crypto';
8
- import { createTimer, printHeader, printKV, printStep, printSuccess, printError, printWarning, collectMetadataStats } from '../../utils/format.js';
9
- import { loadConfig, resolveConfigPath } from '../../utils/config.js';
10
-
11
- /**
12
- * Build a .tgz artifact from the current ObjectStack plugin project.
13
- *
14
- * Reads the project manifest (objectstack.config.ts), collects metadata
15
- * definitions (objects, views, flows, etc.), computes SHA-256 checksums,
16
- * and writes a compressed archive.
17
- *
18
- * Architecture alignment: `npm pack`, `helm package`, `vsce package`.
19
- */
20
- export default class PluginBuild extends Command {
21
- static override description = 'Build a .tgz plugin artifact from the current project';
22
-
23
- static override aliases = ['plugin pack'];
24
-
25
- static override args = {
26
- config: Args.string({ description: 'Configuration file path', required: false }),
27
- };
28
-
29
- static override flags = {
30
- outDir: Flags.string({ char: 'o', description: 'Output directory', default: 'dist' }),
31
- format: Flags.string({ char: 'f', description: 'Archive format (tgz | zip)', default: 'tgz', options: ['tgz', 'zip'] }),
32
- sign: Flags.boolean({ description: 'Digitally sign the artifact', default: false }),
33
- privateKeyPath: Flags.string({ description: 'Path to RSA/ECDSA private key for signing' }),
34
- checksumAlgorithm: Flags.string({ description: 'Hash algorithm for checksums', default: 'sha256', options: ['sha256', 'sha384', 'sha512'] }),
35
- includeData: Flags.boolean({ description: 'Include seed data in artifact', default: true, allowNo: true }),
36
- includeLocales: Flags.boolean({ description: 'Include locale files', default: true, allowNo: true }),
37
- json: Flags.boolean({ description: 'Output result as JSON' }),
38
- };
39
-
40
- async run(): Promise<void> {
41
- const { args, flags } = await this.parse(PluginBuild);
42
- const timer = createTimer();
43
-
44
- if (!flags.json) {
45
- printHeader('Plugin Build');
46
- }
47
-
48
- try {
49
- // 1. Load config
50
- if (!flags.json) printStep('Loading configuration...');
51
- const { config, absolutePath } = await loadConfig(args.config);
52
-
53
- if (!flags.json) {
54
- printKV('Config', path.relative(process.cwd(), absolutePath));
55
- }
56
-
57
- // 2. Resolve manifest info
58
- const manifest = (config as Record<string, unknown>).manifest as Record<string, unknown> | undefined;
59
- const name = (manifest?.name as string) || (config as any).name || 'plugin';
60
- const version = (manifest?.version as string) || (config as any).version || '0.0.0';
61
- const packageFileName = `${name.replace(/[^a-z0-9._-]/gi, '-')}-${version}.${flags.format}`;
62
-
63
- if (!flags.json) {
64
- printKV('Package', `${name}@${version}`);
65
- printStep('Collecting metadata...');
66
- }
67
-
68
- // 3. Collect metadata statistics
69
- const stats = collectMetadataStats(config);
70
- const fileEntries: Array<{ path: string; size: number; category: string }> = [];
71
- const warnings: string[] = [];
72
-
73
- // 4. Serialize the config to JSON for artifact content
74
- const configJson = JSON.stringify(config, null, 2);
75
- const configBuffer = Buffer.from(configJson, 'utf-8');
76
- fileEntries.push({ path: 'manifest.json', size: configBuffer.length, category: 'manifest' });
77
-
78
- // 5. Compute checksums
79
- if (!flags.json) printStep('Computing checksums...');
80
- const manifestChecksum = crypto.createHash(flags.checksumAlgorithm).update(configBuffer).digest('hex');
81
-
82
- // 6. Write output
83
- const outDir = path.resolve(process.cwd(), flags.outDir);
84
- if (!fs.existsSync(outDir)) {
85
- fs.mkdirSync(outDir, { recursive: true });
86
- }
87
- const artifactPath = path.join(outDir, packageFileName);
88
-
89
- if (!flags.json) printStep('Writing artifact...');
90
-
91
- // Write the artifact (serialized config bundle)
92
- fs.writeFileSync(artifactPath, configBuffer);
93
-
94
- const artifactSize = configBuffer.length;
95
-
96
- // 7. Compute artifact-level checksum
97
- const artifactHash = crypto.createHash('sha256').update(configBuffer).digest('hex');
98
-
99
- // 8. Write checksum file alongside artifact
100
- const checksumPath = artifactPath + '.sha256';
101
- fs.writeFileSync(checksumPath, `${artifactHash} ${packageFileName}\n`);
102
-
103
- // 9. Handle signing
104
- let signatureInfo: { algorithm: string; keyId: string } | undefined;
105
- if (flags.sign) {
106
- if (!flags.privateKeyPath) {
107
- warnings.push('Signing requested but no --privateKeyPath provided; skipping signature');
108
- } else if (!fs.existsSync(flags.privateKeyPath)) {
109
- warnings.push(`Private key file not found: ${flags.privateKeyPath}; skipping signature`);
110
- } else {
111
- const privateKey = fs.readFileSync(flags.privateKeyPath, 'utf-8');
112
- const signer = crypto.createSign('RSA-SHA256');
113
- signer.update(configBuffer);
114
- const signature = signer.sign(privateKey, 'base64');
115
- const sigPath = artifactPath + '.sig';
116
- fs.writeFileSync(sigPath, signature);
117
- signatureInfo = { algorithm: 'RSA-SHA256', keyId: path.basename(flags.privateKeyPath) };
118
- }
119
- }
120
-
121
- const durationMs = timer.elapsed();
122
-
123
- // 10. Output result
124
- const result = {
125
- success: true,
126
- artifactPath,
127
- fileCount: fileEntries.length,
128
- size: artifactSize,
129
- durationMs,
130
- warnings: warnings.length > 0 ? warnings : undefined,
131
- artifact: {
132
- name,
133
- version,
134
- format: flags.format,
135
- checksums: {
136
- algorithm: flags.checksumAlgorithm,
137
- manifest: manifestChecksum,
138
- files: { 'manifest.json': manifestChecksum },
139
- },
140
- signature: signatureInfo,
141
- files: fileEntries,
142
- },
143
- };
144
-
145
- if (flags.json) {
146
- console.log(JSON.stringify(result, null, 2));
147
- return;
148
- }
149
-
150
- // Print summary
151
- console.log('');
152
- printSuccess(`Build complete ${chalk.dim(`(${durationMs}ms)`)}`);
153
- console.log('');
154
- printKV('Artifact', path.relative(process.cwd(), artifactPath));
155
- printKV('Size', `${(artifactSize / 1024).toFixed(1)} KB`);
156
- printKV('Checksum', `sha256:${artifactHash.slice(0, 16)}...`);
157
-
158
- if (signatureInfo) {
159
- printKV('Signature', `${signatureInfo.algorithm} (${signatureInfo.keyId})`);
160
- }
161
-
162
- // Print metadata counts
163
- const counts = [
164
- stats.objects > 0 && `${stats.objects} objects`,
165
- stats.views > 0 && `${stats.views} views`,
166
- stats.flows > 0 && `${stats.flows} flows`,
167
- stats.pages > 0 && `${stats.pages} pages`,
168
- stats.agents > 0 && `${stats.agents} agents`,
169
- ].filter(Boolean);
170
-
171
- if (counts.length > 0) {
172
- printKV('Contents', counts.join(', '));
173
- }
174
-
175
- for (const w of warnings) {
176
- printWarning(w);
177
- }
178
-
179
- console.log('');
180
- console.log(chalk.dim(' Next steps:'));
181
- console.log(chalk.dim(' 1. Validate: os plugin validate dist/' + packageFileName));
182
- console.log(chalk.dim(' 2. Publish: os plugin publish dist/' + packageFileName));
183
- console.log('');
184
- } catch (error: any) {
185
- if (flags.json) {
186
- console.log(JSON.stringify({ success: false, errorMessage: error.message }));
187
- this.exit(1);
188
- }
189
- printError(error.message || String(error));
190
- this.exit(1);
191
- }
192
- }
193
- }
@@ -1,79 +0,0 @@
1
- // Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.
2
-
3
- import { Args, Command } from '@oclif/core';
4
- import chalk from 'chalk';
5
- import { loadConfig } from '../../utils/config.js';
6
- import { printHeader, printError, printInfo, printKV } from '../../utils/format.js';
7
- import { resolvePluginName, resolvePluginVersion, resolvePluginType } from '../../utils/plugin-helpers.js';
8
-
9
- export default class PluginInfo extends Command {
10
- static override description = 'Show detailed information about a plugin';
11
-
12
- static override args = {
13
- name: Args.string({ description: 'Plugin name or package name', required: true }),
14
- config: Args.string({ description: 'Configuration file path', required: false }),
15
- };
16
-
17
- async run(): Promise<void> {
18
- const { args } = await this.parse(PluginInfo);
19
-
20
- try {
21
- const { config } = await loadConfig(args.config);
22
- const allPlugins: unknown[] = [
23
- ...(config.plugins || []),
24
- ...(config.devPlugins || []),
25
- ];
26
-
27
- const found = allPlugins.find((p) => {
28
- const pName = resolvePluginName(p);
29
- return pName === args.name || pName.includes(args.name);
30
- });
31
-
32
- if (!found) {
33
- printError(`Plugin '${args.name}' not found in configuration`);
34
- console.log('');
35
- console.log(chalk.dim(' Available plugins:'));
36
- for (const p of allPlugins) {
37
- console.log(chalk.dim(` - ${resolvePluginName(p)}`));
38
- }
39
- console.log('');
40
- this.exit(1);
41
- }
42
-
43
- printHeader(`Plugin: ${resolvePluginName(found)}`);
44
-
45
- printKV('Name', resolvePluginName(found));
46
- printKV('Version', resolvePluginVersion(found));
47
- printKV('Type', resolvePluginType(found));
48
-
49
- const isDev = (config.devPlugins || []).includes(found);
50
- printKV('Environment', isDev ? 'development' : 'production');
51
-
52
- if (found && typeof found === 'object') {
53
- const p = found as Record<string, unknown>;
54
-
55
- if (typeof p.description === 'string') {
56
- printKV('Description', p.description);
57
- }
58
-
59
- if (Array.isArray(p.dependencies) && p.dependencies.length > 0) {
60
- printKV('Dependencies', p.dependencies.join(', '));
61
- }
62
-
63
- // Show services if it's a loaded plugin instance
64
- if (typeof p.init === 'function') {
65
- printInfo('This is a runtime plugin instance (has init function)');
66
- }
67
- }
68
-
69
- if (typeof found === 'string') {
70
- printInfo('This is a string reference (will be imported at runtime)');
71
- }
72
-
73
- console.log('');
74
- } catch (error: any) {
75
- printError(error.message || String(error));
76
- this.exit(1);
77
- }
78
- }
79
- }
@@ -1,93 +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 { loadConfig } from '../../utils/config.js';
6
- import { printHeader, printInfo, printError } from '../../utils/format.js';
7
- import { resolvePluginName, resolvePluginVersion, resolvePluginType } from '../../utils/plugin-helpers.js';
8
-
9
- export default class PluginList extends Command {
10
- static override description = 'List plugins defined in the configuration';
11
-
12
- static override aliases = ['plugin ls'];
13
-
14
- static override args = {
15
- config: Args.string({ description: 'Configuration file path', required: false }),
16
- };
17
-
18
- static override flags = {
19
- json: Flags.boolean({ description: 'Output as JSON' }),
20
- };
21
-
22
- async run(): Promise<void> {
23
- const { args, flags } = await this.parse(PluginList);
24
-
25
- try {
26
- const { config } = await loadConfig(args.config);
27
- const plugins: unknown[] = config.plugins || [];
28
- const devPlugins: unknown[] = config.devPlugins || [];
29
-
30
- if (flags.json) {
31
- const data = {
32
- plugins: plugins.map(p => ({
33
- name: resolvePluginName(p),
34
- version: resolvePluginVersion(p),
35
- type: resolvePluginType(p),
36
- dev: false,
37
- })),
38
- devPlugins: devPlugins.map(p => ({
39
- name: resolvePluginName(p),
40
- version: resolvePluginVersion(p),
41
- type: resolvePluginType(p),
42
- dev: true,
43
- })),
44
- };
45
- console.log(JSON.stringify(data, null, 2));
46
- return;
47
- }
48
-
49
- printHeader('Plugins');
50
-
51
- if (plugins.length === 0 && devPlugins.length === 0) {
52
- printInfo('No plugins configured');
53
- console.log('');
54
- console.log(chalk.dim(' Hint: Add plugins to your objectstack.config.ts'));
55
- console.log(chalk.dim(' Or run: os plugin add <package-name>'));
56
- console.log('');
57
- return;
58
- }
59
-
60
- if (plugins.length > 0) {
61
- console.log(chalk.bold(`\n Plugins (${plugins.length}):`));
62
- for (const plugin of plugins) {
63
- const name = resolvePluginName(plugin);
64
- const version = resolvePluginVersion(plugin);
65
- const type = resolvePluginType(plugin);
66
- console.log(
67
- ` ${chalk.cyan('●')} ${chalk.white(name)}` +
68
- (version !== '-' ? chalk.dim(` v${version}`) : '') +
69
- (type !== 'standard' ? chalk.dim(` [${type}]`) : '')
70
- );
71
- }
72
- }
73
-
74
- if (devPlugins.length > 0) {
75
- console.log(chalk.bold(`\n Dev Plugins (${devPlugins.length}):`));
76
- for (const plugin of devPlugins) {
77
- const name = resolvePluginName(plugin);
78
- const version = resolvePluginVersion(plugin);
79
- console.log(
80
- ` ${chalk.yellow('●')} ${chalk.white(name)}` +
81
- (version !== '-' ? chalk.dim(` v${version}`) : '') +
82
- chalk.dim(' [dev]')
83
- );
84
- }
85
- }
86
-
87
- console.log('');
88
- } catch (error: any) {
89
- printError(error.message || String(error));
90
- this.exit(1);
91
- }
92
- }
93
- }
@@ -1,176 +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 path from 'path';
6
- import fs from 'fs';
7
- import crypto from 'crypto';
8
- import { createTimer, printHeader, printKV, printStep, printSuccess, printError, printWarning, printInfo } from '../../utils/format.js';
9
-
10
- /**
11
- * Publish a plugin artifact to the ObjectStack marketplace.
12
- *
13
- * Validates the artifact locally (unless --skipValidation), computes the
14
- * SHA-256 checksum, and uploads to the marketplace REST API.
15
- *
16
- * Architecture alignment: `npm publish`, `helm push`, `vsce publish`.
17
- */
18
- export default class PluginPublish extends Command {
19
- static override description = 'Publish a plugin artifact to the marketplace';
20
-
21
- static override args = {
22
- artifact: Args.string({ description: 'Path to the artifact file', required: true }),
23
- };
24
-
25
- static override flags = {
26
- registryUrl: Flags.string({ char: 'r', description: 'Marketplace API base URL', default: 'https://marketplace.objectstack.com/api/v1' }),
27
- token: Flags.string({ char: 't', description: 'Authentication token', env: 'OBJECTSTACK_MARKETPLACE_TOKEN' }),
28
- releaseNotes: Flags.string({ description: 'Release notes for this version' }),
29
- preRelease: Flags.boolean({ description: 'Mark as a pre-release', default: false }),
30
- skipValidation: Flags.boolean({ description: 'Skip local validation before publish', default: false }),
31
- access: Flags.string({ description: 'Access level (public | restricted)', default: 'public', options: ['public', 'restricted'] }),
32
- tags: Flags.string({ description: 'Comma-separated tags', multiple: true }),
33
- json: Flags.boolean({ description: 'Output result as JSON' }),
34
- };
35
-
36
- async run(): Promise<void> {
37
- const { args, flags } = await this.parse(PluginPublish);
38
- const timer = createTimer();
39
-
40
- if (!flags.json) {
41
- printHeader('Plugin Publish');
42
- }
43
-
44
- try {
45
- const artifactPath = path.resolve(process.cwd(), args.artifact);
46
-
47
- if (!fs.existsSync(artifactPath)) {
48
- throw new Error(`Artifact not found: ${artifactPath}`);
49
- }
50
-
51
- if (!flags.token) {
52
- throw new Error('Authentication token required. Set --token or OBJECTSTACK_MARKETPLACE_TOKEN environment variable.');
53
- }
54
-
55
- if (!flags.json) {
56
- printKV('Artifact', path.relative(process.cwd(), artifactPath));
57
- printKV('Registry', flags.registryUrl);
58
- }
59
-
60
- // 1. Read artifact
61
- const artifactBuffer = fs.readFileSync(artifactPath);
62
- const sha256 = crypto.createHash('sha256').update(artifactBuffer).digest('hex');
63
-
64
- // 2. Extract manifest info
65
- let manifest: Record<string, unknown> | undefined;
66
- try {
67
- manifest = JSON.parse(artifactBuffer.toString('utf-8'));
68
- } catch {
69
- throw new Error('Artifact does not contain a valid JSON manifest');
70
- }
71
-
72
- const name = (manifest as any).manifest?.name || (manifest as any).name || 'unknown';
73
- const version = (manifest as any).manifest?.version || (manifest as any).version || '0.0.0';
74
-
75
- if (!flags.json) {
76
- printKV('Package', `${name}@${version}`);
77
- }
78
-
79
- // 3. Local validation (unless skipped)
80
- if (!flags.skipValidation) {
81
- if (!flags.json) printStep('Running local validation...');
82
-
83
- if (artifactBuffer.length === 0) {
84
- throw new Error('Artifact is empty — cannot publish');
85
- }
86
-
87
- const checksumFile = artifactPath + '.sha256';
88
- if (fs.existsSync(checksumFile)) {
89
- const expectedHash = fs.readFileSync(checksumFile, 'utf-8').trim().split(/\s+/)[0];
90
- if (expectedHash !== sha256) {
91
- throw new Error(`SHA-256 mismatch: artifact has changed since build`);
92
- }
93
- }
94
-
95
- if (!flags.json) printSuccess('Local validation passed');
96
- }
97
-
98
- // 4. Upload to marketplace
99
- if (!flags.json) printStep('Uploading to marketplace...');
100
-
101
- const uploadUrl = `${flags.registryUrl}/packages/upload`;
102
- const tags = flags.tags?.flatMap(t => t.split(',')) || [];
103
-
104
- const uploadPayload = {
105
- packageName: name,
106
- version,
107
- sha256,
108
- size: artifactBuffer.length,
109
- preRelease: flags.preRelease,
110
- access: flags.access,
111
- releaseNotes: flags.releaseNotes,
112
- tags,
113
- };
114
-
115
- // Perform HTTP upload
116
- const response = await fetch(uploadUrl, {
117
- method: 'POST',
118
- headers: {
119
- 'Content-Type': 'application/json',
120
- 'Authorization': `Bearer ${flags.token}`,
121
- },
122
- body: JSON.stringify(uploadPayload),
123
- });
124
-
125
- if (!response.ok) {
126
- const errorBody = await response.text().catch(() => 'Unknown error');
127
- throw new Error(`Marketplace upload failed (${response.status}): ${errorBody}`);
128
- }
129
-
130
- const responseData = await response.json().catch(() => ({})) as Record<string, unknown>;
131
-
132
- const result = {
133
- success: true,
134
- packageId: (responseData.packageId as string) || name,
135
- version,
136
- artifactUrl: responseData.artifactUrl as string | undefined,
137
- sha256,
138
- submissionId: responseData.submissionId as string | undefined,
139
- message: `Published ${name}@${version} to marketplace`,
140
- };
141
-
142
- if (flags.json) {
143
- console.log(JSON.stringify(result, null, 2));
144
- return;
145
- }
146
-
147
- console.log('');
148
- printSuccess(`Published ${chalk.cyan(`${name}@${version}`)}`);
149
- console.log('');
150
- printKV('SHA-256', sha256.slice(0, 16) + '...');
151
- printKV('Size', `${(artifactBuffer.length / 1024).toFixed(1)} KB`);
152
-
153
- if (result.artifactUrl) {
154
- printKV('URL', result.artifactUrl);
155
- }
156
- if (result.submissionId) {
157
- printKV('Submission', result.submissionId);
158
- }
159
-
160
- if (flags.preRelease) {
161
- printWarning('Published as pre-release');
162
- }
163
-
164
- console.log('');
165
- printInfo(`Duration: ${timer.display()}`);
166
- console.log('');
167
- } catch (error: any) {
168
- if (flags.json) {
169
- console.log(JSON.stringify({ success: false, errorMessage: error.message }));
170
- this.exit(1);
171
- }
172
- printError(error.message || String(error));
173
- this.exit(1);
174
- }
175
- }
176
- }