@ldsg/cli 0.3.31 → 0.3.32

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 (70) hide show
  1. package/.rush/temp/package-deps_build.json +27 -27
  2. package/.rush/temp/shrinkwrap-deps.json +58 -3
  3. package/.tsbuildinfo +1 -1
  4. package/CHANGELOG.json +26 -0
  5. package/CHANGELOG.md +16 -2
  6. package/README.md +3 -0
  7. package/dist/__tests__/commands.test.js +104 -104
  8. package/dist/__tests__/formatter.test.js +66 -63
  9. package/dist/__tests__/formatter.test.js.map +1 -1
  10. package/dist/__tests__/json-file-mutator.test.js +48 -45
  11. package/dist/__tests__/json-file-mutator.test.js.map +1 -1
  12. package/dist/__tests__/source-resolver.test.js +39 -39
  13. package/dist/cli.js +89 -89
  14. package/dist/cli.js.map +1 -1
  15. package/dist/commands/resource/convert.d.ts +1 -1
  16. package/dist/commands/resource/convert.js +9 -7
  17. package/dist/commands/resource/convert.js.map +1 -1
  18. package/dist/commands/resource/create.d.ts +2 -2
  19. package/dist/commands/resource/create.js +5 -5
  20. package/dist/commands/resource/delete.d.ts +2 -2
  21. package/dist/commands/resource/delete.js.map +1 -1
  22. package/dist/commands/resource/diff.d.ts +2 -2
  23. package/dist/commands/resource/diff.js +8 -8
  24. package/dist/commands/resource/get.d.ts +1 -1
  25. package/dist/commands/resource/list.d.ts +2 -2
  26. package/dist/commands/resource/list.js +11 -11
  27. package/dist/commands/resource/list.js.map +1 -1
  28. package/dist/commands/resource/tree.d.ts +1 -1
  29. package/dist/commands/resource/update.d.ts +2 -2
  30. package/dist/commands/resource/update.js +1 -1
  31. package/dist/constants.js +2 -2
  32. package/dist/types/get-extend-app-data-params.d.ts +2 -2
  33. package/dist/types/resource-record.d.ts +2 -2
  34. package/dist/utils/formatter.d.ts +1 -1
  35. package/dist/utils/formatter.js +25 -25
  36. package/dist/utils/get-extend-app-data-params-using-npm-ldsg-module.d.ts +1 -1
  37. package/dist/utils/get-extend-app-data-params-using-npm-ldsg-module.js +12 -12
  38. package/dist/utils/get-extend-app-data-params-using-npm-ldsg-module.js.map +1 -1
  39. package/dist/utils/get-extend-app-data-params-using-workspace-ldsg-module/index.d.ts +1 -1
  40. package/dist/utils/get-extend-app-data-params-using-workspace-ldsg-module/index.js +20 -20
  41. package/dist/utils/get-extend-app-data-params-using-workspace-ldsg-module/index.js.map +1 -1
  42. package/dist/utils/json-file-mutator.d.ts +2 -2
  43. package/dist/utils/json-file-mutator.js +4 -4
  44. package/dist/utils/json-file-mutator.js.map +1 -1
  45. package/dist/utils/source-resolver.d.ts +1 -1
  46. package/dist/utils/source-resolver.js +15 -15
  47. package/dist/utils/source-resolver.js.map +1 -1
  48. package/jest.config.js +8 -8
  49. package/package.json +9 -6
  50. package/src/__tests__/commands.test.ts +116 -116
  51. package/src/__tests__/formatter.test.ts +68 -65
  52. package/src/__tests__/json-file-mutator.test.ts +57 -52
  53. package/src/__tests__/source-resolver.test.ts +43 -43
  54. package/src/cli.ts +132 -114
  55. package/src/commands/resource/convert.ts +13 -11
  56. package/src/commands/resource/create.ts +8 -8
  57. package/src/commands/resource/delete.ts +6 -4
  58. package/src/commands/resource/diff.ts +10 -10
  59. package/src/commands/resource/get.ts +2 -2
  60. package/src/commands/resource/list.ts +20 -18
  61. package/src/commands/resource/tree.ts +2 -2
  62. package/src/commands/resource/update.ts +4 -4
  63. package/src/constants.ts +2 -2
  64. package/src/types/get-extend-app-data-params.ts +5 -3
  65. package/src/types/resource-record.ts +2 -2
  66. package/src/utils/formatter.ts +27 -27
  67. package/src/utils/get-extend-app-data-params-using-npm-ldsg-module.ts +20 -16
  68. package/src/utils/get-extend-app-data-params-using-workspace-ldsg-module/index.ts +28 -26
  69. package/src/utils/json-file-mutator.ts +18 -12
  70. package/src/utils/source-resolver.ts +26 -21
package/jest.config.js CHANGED
@@ -1,12 +1,12 @@
1
1
  /** @type {import('ts-jest').JestConfigWithTsJest} */
2
2
  module.exports = {
3
- preset: 'ts-jest',
4
- testEnvironment: 'node',
5
- testMatch: ['**/__tests__/**/*.test.ts'],
3
+ preset: "ts-jest",
4
+ testEnvironment: "node",
5
+ testMatch: ["**/__tests__/**/*.test.ts"],
6
6
  moduleNameMapper: {
7
- '^@ldsg/types$': '<rootDir>/../types/src',
8
- '^@ldsg/constants$': '<rootDir>/../constants/src',
9
- '^@ldsg/apaas-to-runtime$': '<rootDir>/../apaas-to-runtime/src',
10
- '^@ldsg/utils$': '<rootDir>/../utils/src'
11
- }
7
+ "^@ldsg/types$": "<rootDir>/../types/src",
8
+ "^@ldsg/constants$": "<rootDir>/../constants/src",
9
+ "^@ldsg/apaas-to-runtime$": "<rootDir>/../apaas-to-runtime/src",
10
+ "^@ldsg/utils$": "<rootDir>/../utils/src",
11
+ },
12
12
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ldsg/cli",
3
- "version": "0.3.31",
3
+ "version": "0.3.32",
4
4
  "description": "",
5
5
  "keywords": [],
6
6
  "license": "ISC",
@@ -13,10 +13,9 @@
13
13
  "axios": "^1.7.9",
14
14
  "commander": "^12.0.0",
15
15
  "fs-extra": "^11.3.0",
16
- "jsonata": "^2.0.6",
17
- "@ldsg/constants": "0.3.31",
18
- "@ldsg/apaas-to-runtime": "0.3.31",
19
- "@ldsg/utils": "0.3.31"
16
+ "@ldsg/apaas-to-runtime": "0.3.32",
17
+ "@ldsg/constants": "0.3.32",
18
+ "@ldsg/utils": "0.3.32"
20
19
  },
21
20
  "devDependencies": {
22
21
  "@types/fs-extra": "^11.0.4",
@@ -27,12 +26,14 @@
27
26
  "dotenv-cli": "~11.0.0",
28
27
  "jest": "^29.5.0",
29
28
  "lodash": "^4.17.21",
29
+ "oxfmt": "latest",
30
+ "oxlint": "latest",
30
31
  "supertest": "^7.1.4",
31
32
  "ts-jest": "^29.4.1",
32
33
  "ts-node": "^10.9.2",
33
34
  "tslib": "^2.8.1",
34
35
  "typescript": "^5.3.3",
35
- "@ldsg/types": "0.3.31"
36
+ "@ldsg/types": "0.3.32"
36
37
  },
37
38
  "publishConfig": {
38
39
  "access": "public"
@@ -40,6 +41,8 @@
40
41
  "scripts": {
41
42
  "build": "tsc --project tsconfig.build.json",
42
43
  "cli": "ts-node src/cli.ts",
44
+ "format": "oxfmt --write src/",
45
+ "lint": "oxlint src/",
43
46
  "test": "jest",
44
47
  "test:watch": "jest --watch"
45
48
  }
@@ -1,257 +1,257 @@
1
- import { ResourceRecords } from '@ldsg/types';
2
- import { listResources, getResource, getTree } from '../commands/resource/list';
3
- import { createResource } from '../commands/resource/create';
4
- import { updateResource } from '../commands/resource/update';
5
- import { deleteResource } from '../commands/resource/delete';
6
- import { diffResource } from '../commands/resource/diff';
7
- import { SourceData } from '../types/resource-record';
8
- import fs from 'fs-extra';
1
+ import { ResourceRecords } from "@ldsg/types";
2
+ import { listResources, getResource, getTree } from "../commands/resource/list";
3
+ import { createResource } from "../commands/resource/create";
4
+ import { updateResource } from "../commands/resource/update";
5
+ import { deleteResource } from "../commands/resource/delete";
6
+ import { diffResource } from "../commands/resource/diff";
7
+ import { SourceData } from "../types/resource-record";
8
+ import fs from "fs-extra";
9
9
 
10
- jest.mock('fs-extra');
10
+ jest.mock("fs-extra");
11
11
 
12
12
  const mockedFs = fs as jest.Mocked<typeof fs>;
13
13
 
14
14
  const sampleRecords: ResourceRecords = [
15
- { id: 'app1', kind: 'application', parentId: null, settings: { title: 'My App' } },
16
- { id: 'form1', kind: 'form', parentId: 'app1', settings: { title: 'Login Form' } },
17
- { id: 'form2', kind: 'form', parentId: 'app1', settings: { title: 'Register Form' } },
18
- { id: 'table1', kind: 'table', parentId: 'app1', settings: { title: 'Users' } },
19
- { id: 'field1', kind: 'field', parentId: 'table1', settings: { title: 'Name' } },
20
- { id: 'field2', kind: 'field', parentId: 'table1', settings: { title: 'Email' } }
15
+ { id: "app1", kind: "application", parentId: null, settings: { title: "My App" } },
16
+ { id: "form1", kind: "form", parentId: "app1", settings: { title: "Login Form" } },
17
+ { id: "form2", kind: "form", parentId: "app1", settings: { title: "Register Form" } },
18
+ { id: "table1", kind: "table", parentId: "app1", settings: { title: "Users" } },
19
+ { id: "field1", kind: "field", parentId: "table1", settings: { title: "Name" } },
20
+ { id: "field2", kind: "field", parentId: "table1", settings: { title: "Email" } },
21
21
  ];
22
22
 
23
23
  const sourceData: SourceData = {
24
24
  resourceRecords: sampleRecords,
25
- format: 'array',
26
- filePath: '/test/data.json'
25
+ format: "array",
26
+ filePath: "/test/data.json",
27
27
  };
28
28
 
29
- describe('commands', () => {
29
+ describe("commands", () => {
30
30
  beforeEach(() => {
31
31
  jest.resetAllMocks();
32
32
  mockedFs.readJson.mockResolvedValue([...sampleRecords]);
33
33
  });
34
34
 
35
- describe('listResources', () => {
36
- it('should return all records without filter', async () => {
35
+ describe("listResources", () => {
36
+ it("should return all records without filter", async () => {
37
37
  const result = await listResources(sampleRecords, {});
38
38
  expect(result.total).toBe(6);
39
39
  expect(result.resources).toHaveLength(6);
40
40
  });
41
41
 
42
- it('should filter by kind', async () => {
43
- const result = await listResources(sampleRecords, { kind: 'form' });
42
+ it("should filter by kind", async () => {
43
+ const result = await listResources(sampleRecords, { kind: "form" });
44
44
  expect(result.total).toBe(2);
45
- expect(result.resources.every((r) => r.kind === 'form')).toBe(true);
45
+ expect(result.resources.every((r) => r.kind === "form")).toBe(true);
46
46
  });
47
47
 
48
- it('should filter by parentId', async () => {
49
- const result = await listResources(sampleRecords, { parentId: 'table1' });
48
+ it("should filter by parentId", async () => {
49
+ const result = await listResources(sampleRecords, { parentId: "table1" });
50
50
  expect(result.total).toBe(2);
51
- expect(result.resources.every((r) => r.parentId === 'table1')).toBe(true);
51
+ expect(result.resources.every((r) => r.parentId === "table1")).toBe(true);
52
52
  });
53
53
 
54
- it('should filter by rootId', async () => {
55
- const result = await listResources(sampleRecords, { rootId: 'table1' });
54
+ it("should filter by rootId", async () => {
55
+ const result = await listResources(sampleRecords, { rootId: "table1" });
56
56
  expect(result.total).toBe(3);
57
- expect(result.resources.map((r) => r.id)).toEqual(['table1', 'field1', 'field2']);
57
+ expect(result.resources.map((r) => r.id)).toEqual(["table1", "field1", "field2"]);
58
58
  });
59
59
 
60
- it('should combine filters', async () => {
61
- const result = await listResources(sampleRecords, { kind: 'field', rootId: 'table1' });
60
+ it("should combine filters", async () => {
61
+ const result = await listResources(sampleRecords, { kind: "field", rootId: "table1" });
62
62
  expect(result.total).toBe(2);
63
63
  });
64
64
  });
65
65
 
66
- describe('getResource', () => {
67
- it('should get a single resource by id', async () => {
68
- const result = await getResource(sampleRecords, 'app1', {});
66
+ describe("getResource", () => {
67
+ it("should get a single resource by id", async () => {
68
+ const result = await getResource(sampleRecords, "app1", {});
69
69
  expect(result).not.toBeNull();
70
- expect(result!.id).toBe('app1');
70
+ expect(result!.id).toBe("app1");
71
71
  });
72
72
 
73
- it('should return null for non-existent id', async () => {
74
- const result = await getResource(sampleRecords, 'nonexistent', {});
73
+ it("should return null for non-existent id", async () => {
74
+ const result = await getResource(sampleRecords, "nonexistent", {});
75
75
  expect(result).toBeNull();
76
76
  });
77
77
 
78
- it('should include children when requested', async () => {
79
- const result = (await getResource(sampleRecords, 'app1', { children: true })) as any;
78
+ it("should include children when requested", async () => {
79
+ const result = (await getResource(sampleRecords, "app1", { children: true })) as any;
80
80
  expect(result.children).toHaveLength(3);
81
- expect(result.children.map((c: any) => c.id)).toEqual(['form1', 'form2', 'table1']);
81
+ expect(result.children.map((c: any) => c.id)).toEqual(["form1", "form2", "table1"]);
82
82
  });
83
83
 
84
- it('should return null for non-existent id with tree option', async () => {
85
- const result = await getResource(sampleRecords, 'nonexistent', { tree: true });
84
+ it("should return null for non-existent id with tree option", async () => {
85
+ const result = await getResource(sampleRecords, "nonexistent", { tree: true });
86
86
  expect(result).toBeNull();
87
87
  });
88
88
  });
89
89
 
90
- describe('getTree', () => {
91
- it('should build tree for specified root', async () => {
92
- const result = await getTree(sampleRecords, 'table1');
93
- expect(result.rootId).toBe('table1');
94
- expect(result.tree.resource.id).toBe('table1');
90
+ describe("getTree", () => {
91
+ it("should build tree for specified root", async () => {
92
+ const result = await getTree(sampleRecords, "table1");
93
+ expect(result.rootId).toBe("table1");
94
+ expect(result.tree.resource.id).toBe("table1");
95
95
  expect(result.tree.children).toHaveLength(2);
96
96
  });
97
97
 
98
- it('should auto-detect root when only one', async () => {
98
+ it("should auto-detect root when only one", async () => {
99
99
  const singleRoot: ResourceRecords = [
100
- { id: 'app1', kind: 'application', parentId: null, settings: {} },
101
- { id: 'form1', kind: 'form', parentId: 'app1', settings: {} }
100
+ { id: "app1", kind: "application", parentId: null, settings: {} },
101
+ { id: "form1", kind: "form", parentId: "app1", settings: {} },
102
102
  ];
103
103
  const result = await getTree(singleRoot, undefined);
104
- expect(result.rootId).toBe('app1');
104
+ expect(result.rootId).toBe("app1");
105
105
  });
106
106
 
107
- it('should throw for non-existent root', async () => {
108
- await expect(getTree(sampleRecords, 'nonexistent')).rejects.toThrow('not found');
107
+ it("should throw for non-existent root", async () => {
108
+ await expect(getTree(sampleRecords, "nonexistent")).rejects.toThrow("not found");
109
109
  });
110
110
  });
111
111
 
112
- describe('createResource', () => {
113
- it('should create with explicit fields', async () => {
112
+ describe("createResource", () => {
113
+ it("should create with explicit fields", async () => {
114
114
  mockedFs.readJson.mockResolvedValue([...sampleRecords]);
115
115
 
116
116
  const result = await createResource({
117
117
  sourceData,
118
- kind: 'form',
119
- parentId: 'app1',
120
- settings: { title: 'New Form' }
118
+ kind: "form",
119
+ parentId: "app1",
120
+ settings: { title: "New Form" },
121
121
  });
122
122
 
123
- expect(result.record.kind).toBe('form');
124
- expect(result.record.parentId).toBe('app1');
125
- expect(result.record.settings).toEqual({ title: 'New Form' });
123
+ expect(result.record.kind).toBe("form");
124
+ expect(result.record.parentId).toBe("app1");
125
+ expect(result.record.settings).toEqual({ title: "New Form" });
126
126
  expect(mockedFs.writeJson).toHaveBeenCalled();
127
127
  });
128
128
 
129
- it('should throw without kind', async () => {
129
+ it("should throw without kind", async () => {
130
130
  await expect(
131
131
  createResource({
132
132
  sourceData,
133
- parentId: 'app1'
134
- } as any)
135
- ).rejects.toThrow('--kind');
133
+ parentId: "app1",
134
+ } as any),
135
+ ).rejects.toThrow("--kind");
136
136
  });
137
137
 
138
- it('should throw without parent-id', async () => {
138
+ it("should throw without parent-id", async () => {
139
139
  await expect(
140
140
  createResource({
141
141
  sourceData,
142
- kind: 'form'
143
- } as any)
144
- ).rejects.toThrow('--parent-id');
142
+ kind: "form",
143
+ } as any),
144
+ ).rejects.toThrow("--parent-id");
145
145
  });
146
146
  });
147
147
 
148
- describe('updateResource', () => {
149
- it('should update existing resource', async () => {
148
+ describe("updateResource", () => {
149
+ it("should update existing resource", async () => {
150
150
  mockedFs.readJson.mockResolvedValue([...sampleRecords]);
151
151
 
152
152
  const result = await updateResource({
153
153
  sourceData,
154
- id: 'form1',
155
- settings: { title: 'Updated Form' }
154
+ id: "form1",
155
+ settings: { title: "Updated Form" },
156
156
  });
157
157
 
158
- expect(result.record.id).toBe('form1');
159
- expect(result.record.settings).toEqual({ title: 'Updated Form' });
158
+ expect(result.record.id).toBe("form1");
159
+ expect(result.record.settings).toEqual({ title: "Updated Form" });
160
160
  expect(mockedFs.writeJson).toHaveBeenCalled();
161
161
  });
162
162
 
163
- it('should throw on non-existent id', async () => {
163
+ it("should throw on non-existent id", async () => {
164
164
  await expect(
165
165
  updateResource({
166
166
  sourceData,
167
- id: 'nonexistent',
168
- settings: { title: 'x' }
169
- })
170
- ).rejects.toThrow('not found');
167
+ id: "nonexistent",
168
+ settings: { title: "x" },
169
+ }),
170
+ ).rejects.toThrow("not found");
171
171
  });
172
172
  });
173
173
 
174
- describe('deleteResource', () => {
175
- it('should delete resource and children', async () => {
174
+ describe("deleteResource", () => {
175
+ it("should delete resource and children", async () => {
176
176
  mockedFs.readJson.mockResolvedValue([...sampleRecords]);
177
177
 
178
178
  const result = await deleteResource({
179
179
  sourceData,
180
- id: 'table1'
180
+ id: "table1",
181
181
  });
182
182
 
183
183
  expect(result.removed).toHaveLength(3);
184
- expect(result.removed.map((r) => r.id)).toEqual(['table1', 'field1', 'field2']);
184
+ expect(result.removed.map((r) => r.id)).toEqual(["table1", "field1", "field2"]);
185
185
  });
186
186
 
187
- it('should throw on non-existent id', async () => {
187
+ it("should throw on non-existent id", async () => {
188
188
  await expect(
189
189
  deleteResource({
190
190
  sourceData,
191
- id: 'nonexistent'
192
- })
193
- ).rejects.toThrow('not found');
191
+ id: "nonexistent",
192
+ }),
193
+ ).rejects.toThrow("not found");
194
194
  });
195
195
  });
196
196
 
197
- describe('diffResource', () => {
197
+ describe("diffResource", () => {
198
198
  const recordsA: ResourceRecords = [
199
- { id: '1', kind: 'application', parentId: null, settings: { title: 'App A', version: 1 } }
199
+ { id: "1", kind: "application", parentId: null, settings: { title: "App A", version: 1 } },
200
200
  ];
201
201
  const recordsB: ResourceRecords = [
202
202
  {
203
- id: '1',
204
- kind: 'application',
203
+ id: "1",
204
+ kind: "application",
205
205
  parentId: null,
206
- settings: { title: 'App B', version: 1, newField: 'new' }
207
- }
206
+ settings: { title: "App B", version: 1, newField: "new" },
207
+ },
208
208
  ];
209
209
 
210
- it('should detect changed fields', async () => {
210
+ it("should detect changed fields", async () => {
211
211
  const result = await diffResource({
212
- sourceA: 'a.json',
213
- sourceB: 'b.json',
214
- id: '1',
212
+ sourceA: "a.json",
213
+ sourceB: "b.json",
214
+ id: "1",
215
215
  recordsA,
216
- recordsB
216
+ recordsB,
217
217
  });
218
218
 
219
219
  expect(result.changed.length).toBeGreaterThan(0);
220
- expect(result.changed.some((c) => c.path === 'title')).toBe(true);
220
+ expect(result.changed.some((c) => c.path === "title")).toBe(true);
221
221
  });
222
222
 
223
- it('should detect added fields', async () => {
223
+ it("should detect added fields", async () => {
224
224
  const result = await diffResource({
225
- sourceA: 'a.json',
226
- sourceB: 'b.json',
227
- id: '1',
225
+ sourceA: "a.json",
226
+ sourceB: "b.json",
227
+ id: "1",
228
228
  recordsA,
229
- recordsB
229
+ recordsB,
230
230
  });
231
231
 
232
- expect(result.added.some((a) => a.path === 'newField')).toBe(true);
232
+ expect(result.added.some((a) => a.path === "newField")).toBe(true);
233
233
  });
234
234
 
235
- it('should handle resource only in one side', async () => {
235
+ it("should handle resource only in one side", async () => {
236
236
  const result = await diffResource({
237
- sourceA: 'a.json',
238
- sourceB: 'b.json',
239
- id: '2',
237
+ sourceA: "a.json",
238
+ sourceB: "b.json",
239
+ id: "2",
240
240
  recordsA: [],
241
- recordsB: [{ id: '2', kind: 'application', parentId: null, settings: {} }]
241
+ recordsB: [{ id: "2", kind: "application", parentId: null, settings: {} }],
242
242
  });
243
243
 
244
244
  expect(result.sideA).toBeNull();
245
245
  expect(result.sideB).not.toBeNull();
246
246
  });
247
247
 
248
- it('should report no differences for identical resources', async () => {
248
+ it("should report no differences for identical resources", async () => {
249
249
  const result = await diffResource({
250
- sourceA: 'a.json',
251
- sourceB: 'b.json',
252
- id: '1',
250
+ sourceA: "a.json",
251
+ sourceB: "b.json",
252
+ id: "1",
253
253
  recordsA,
254
- recordsB: recordsA
254
+ recordsB: recordsA,
255
255
  });
256
256
 
257
257
  expect(result.changed).toHaveLength(0);