@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,294 +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 {
7
- printHeader,
8
- printSuccess,
9
- printWarning,
10
- printError,
11
- printInfo,
12
- printStep,
13
- createTimer,
14
- } from '../utils/format.js';
15
-
16
- // ─── Types ──────────────────────────────────────────────────────────
17
-
18
- interface DiffEntry {
19
- type: 'added' | 'removed' | 'modified';
20
- category: string;
21
- name: string;
22
- detail?: string;
23
- breaking: boolean;
24
- }
25
-
26
- // ─── Helpers ────────────────────────────────────────────────────────
27
-
28
- function getNames(items: any[] | undefined): Map<string, any> {
29
- const map = new Map<string, any>();
30
- if (!Array.isArray(items)) return map;
31
- for (const item of items) {
32
- if (item?.name) map.set(item.name, item);
33
- }
34
- return map;
35
- }
36
-
37
- function getFieldNames(obj: any): string[] {
38
- if (!obj?.fields || typeof obj.fields !== 'object') return [];
39
- return Object.keys(obj.fields);
40
- }
41
-
42
- function getFieldType(obj: any, fieldName: string): string | undefined {
43
- return obj?.fields?.[fieldName]?.type;
44
- }
45
-
46
- function isFieldRequired(obj: any, fieldName: string): boolean {
47
- return obj?.fields?.[fieldName]?.required === true;
48
- }
49
-
50
- function diffNamedArrays(
51
- beforeItems: any[] | undefined,
52
- afterItems: any[] | undefined,
53
- category: string,
54
- detectFieldChanges: boolean,
55
- ): DiffEntry[] {
56
- const entries: DiffEntry[] = [];
57
- const beforeMap = getNames(beforeItems);
58
- const afterMap = getNames(afterItems);
59
-
60
- // Removed items
61
- for (const [name] of beforeMap) {
62
- if (!afterMap.has(name)) {
63
- entries.push({
64
- type: 'removed',
65
- category,
66
- name,
67
- breaking: true,
68
- });
69
- }
70
- }
71
-
72
- // Added items
73
- for (const [name] of afterMap) {
74
- if (!beforeMap.has(name)) {
75
- entries.push({
76
- type: 'added',
77
- category,
78
- name,
79
- breaking: false,
80
- });
81
- }
82
- }
83
-
84
- // Modified items — field-level diff for objects
85
- if (detectFieldChanges) {
86
- for (const [name, beforeObj] of beforeMap) {
87
- const afterObj = afterMap.get(name);
88
- if (!afterObj) continue;
89
-
90
- const beforeFields = getFieldNames(beforeObj);
91
- const afterFields = getFieldNames(afterObj);
92
- const beforeSet = new Set(beforeFields);
93
- const afterSet = new Set(afterFields);
94
-
95
- // Removed fields
96
- for (const f of beforeFields) {
97
- if (!afterSet.has(f)) {
98
- entries.push({
99
- type: 'removed',
100
- category: `${category}.${name}.fields`,
101
- name: f,
102
- breaking: true,
103
- detail: 'field removed',
104
- });
105
- }
106
- }
107
-
108
- // Added fields
109
- for (const f of afterFields) {
110
- if (!beforeSet.has(f)) {
111
- const breaking = isFieldRequired(afterObj, f);
112
- entries.push({
113
- type: 'added',
114
- category: `${category}.${name}.fields`,
115
- name: f,
116
- breaking,
117
- detail: breaking ? 'required field added' : 'optional field added',
118
- });
119
- }
120
- }
121
-
122
- // Type changes
123
- for (const f of beforeFields) {
124
- if (!afterSet.has(f)) continue;
125
- const oldType = getFieldType(beforeObj, f);
126
- const newType = getFieldType(afterObj, f);
127
- if (oldType && newType && oldType !== newType) {
128
- entries.push({
129
- type: 'modified',
130
- category: `${category}.${name}.fields`,
131
- name: f,
132
- breaking: true,
133
- detail: `type changed: ${oldType} → ${newType}`,
134
- });
135
- }
136
- }
137
-
138
- // Label / ownership changes on the object itself
139
- if (beforeObj.label !== afterObj.label) {
140
- entries.push({
141
- type: 'modified',
142
- category,
143
- name,
144
- breaking: false,
145
- detail: `label changed: "${beforeObj.label ?? '(none)'}" → "${afterObj.label ?? '(none)'}"`,
146
- });
147
- }
148
- }
149
- }
150
-
151
- return entries;
152
- }
153
-
154
- // ─── Command ────────────────────────────────────────────────────────
155
-
156
- export default class Diff extends Command {
157
- static override description = 'Compare two ObjectStack configurations and detect breaking changes';
158
-
159
- static override args = {
160
- before: Args.string({ description: 'Path to the "before" config file', required: false }),
161
- after: Args.string({ description: 'Path to the "after" config file', required: false }),
162
- };
163
-
164
- static override flags = {
165
- before: Flags.string({ description: 'Path to the "before" config (alternative)' }),
166
- after: Flags.string({ description: 'Path to the "after" config (alternative)' }),
167
- json: Flags.boolean({ description: 'Output as JSON' }),
168
- 'breaking-only': Flags.boolean({ description: 'Show only breaking changes' }),
169
- };
170
-
171
- async run(): Promise<void> {
172
- const { args, flags } = await this.parse(Diff);
173
- const timer = createTimer();
174
-
175
- const beforePath: string | undefined = args.before || flags.before;
176
- const afterPath: string | undefined = args.after || flags.after;
177
-
178
- if (!beforePath || !afterPath) {
179
- printError('Two config file paths are required.');
180
- console.log('');
181
- console.log(chalk.dim(' Usage: objectstack diff <before> <after>'));
182
- console.log(chalk.dim(' or: objectstack diff --before path1 --after path2'));
183
- process.exit(1);
184
- }
185
-
186
- if (!flags.json) {
187
- printHeader('Diff');
188
- printStep('Loading configurations...');
189
- }
190
-
191
- try {
192
- const { config: beforeConfig } = await loadConfig(beforePath);
193
- const { config: afterConfig } = await loadConfig(afterPath);
194
-
195
- if (!flags.json) {
196
- printInfo(`Before: ${chalk.white(beforePath)}`);
197
- printInfo(`After: ${chalk.white(afterPath)}`);
198
- }
199
-
200
- // ── Diff all categories ──
201
- const allDiffs: DiffEntry[] = [];
202
-
203
- // Objects (with field-level diff)
204
- allDiffs.push(...diffNamedArrays(beforeConfig.objects, afterConfig.objects, 'objects', true));
205
-
206
- // Views, Flows, Agents, Apps (name-level diff)
207
- const simpleCats: Array<{ key: string; label: string }> = [
208
- { key: 'views', label: 'views' },
209
- { key: 'flows', label: 'flows' },
210
- { key: 'agents', label: 'agents' },
211
- { key: 'apps', label: 'apps' },
212
- { key: 'dashboards', label: 'dashboards' },
213
- { key: 'actions', label: 'actions' },
214
- { key: 'workflows', label: 'workflows' },
215
- { key: 'apis', label: 'apis' },
216
- { key: 'roles', label: 'roles' },
217
- ];
218
-
219
- for (const cat of simpleCats) {
220
- allDiffs.push(
221
- ...diffNamedArrays(beforeConfig[cat.key], afterConfig[cat.key], cat.label, false),
222
- );
223
- }
224
-
225
- // ── Filter ──
226
- const diffs = flags['breaking-only']
227
- ? allDiffs.filter((d) => d.breaking)
228
- : allDiffs;
229
-
230
- const breakingCount = allDiffs.filter((d) => d.breaking).length;
231
-
232
- // ── Output ──
233
- if (flags.json) {
234
- console.log(JSON.stringify({
235
- before: beforePath,
236
- after: afterPath,
237
- total: diffs.length,
238
- breaking: breakingCount,
239
- changes: diffs,
240
- duration: timer.elapsed(),
241
- }, null, 2));
242
- return;
243
- }
244
-
245
- console.log('');
246
-
247
- if (diffs.length === 0) {
248
- printSuccess(flags['breaking-only']
249
- ? 'No breaking changes detected.'
250
- : 'No changes detected.');
251
- console.log('');
252
- return;
253
- }
254
-
255
- // Group by category
256
- const grouped = new Map<string, DiffEntry[]>();
257
- for (const d of diffs) {
258
- const key = d.category;
259
- if (!grouped.has(key)) grouped.set(key, []);
260
- grouped.get(key)!.push(d);
261
- }
262
-
263
- for (const [category, items] of grouped) {
264
- console.log(` ${chalk.bold(category)}`);
265
- for (const item of items) {
266
- const icon = item.type === 'added' ? '+' : item.type === 'removed' ? '-' : '~';
267
- const color = item.type === 'added' ? chalk.green : item.type === 'removed' ? chalk.red : chalk.yellow;
268
- const breakingTag = item.breaking ? chalk.bgRed.white(' BREAKING ') + ' ' : '';
269
- const detail = item.detail ? chalk.dim(` (${item.detail})`) : '';
270
- console.log(` ${color(icon)} ${breakingTag}${color(item.name)}${detail}`);
271
- }
272
- console.log('');
273
- }
274
-
275
- // Summary
276
- if (breakingCount > 0) {
277
- printError(`${breakingCount} breaking change(s) detected`);
278
- } else {
279
- printSuccess('No breaking changes');
280
- }
281
- console.log(chalk.dim(` ${diffs.length} total change(s) in ${timer.display()}`));
282
- console.log('');
283
-
284
- } catch (error: any) {
285
- if (flags.json) {
286
- console.log(JSON.stringify({ error: error.message }));
287
- process.exit(1);
288
- }
289
- console.log('');
290
- printError(error.message || String(error));
291
- process.exit(1);
292
- }
293
- }
294
- }