@t4h.framework/cli 0.0.0-experimental-c0d4325

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 (81) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +1 -0
  3. package/dist/bin/bin.js +57 -0
  4. package/dist/bin/bin.js.map +1 -0
  5. package/dist/commands/build/build.js +49 -0
  6. package/dist/commands/build/build.js.map +1 -0
  7. package/dist/commands/dev/dev.js +109 -0
  8. package/dist/commands/dev/dev.js.map +1 -0
  9. package/dist/commands/dev-server-up-app-process.js +84 -0
  10. package/dist/commands/dev-server-up-app-process.js.map +1 -0
  11. package/dist/commands/publish/publish.js +149 -0
  12. package/dist/commands/publish/publish.js.map +1 -0
  13. package/dist/models/CliFileSystemClaim.js +30 -0
  14. package/dist/models/CliFileSystemClaim.js.map +1 -0
  15. package/dist/models/CliHttpClientRequestClaim.js +21 -0
  16. package/dist/models/CliHttpClientRequestClaim.js.map +1 -0
  17. package/dist/models/CliORMClaim.js +37 -0
  18. package/dist/models/CliORMClaim.js.map +1 -0
  19. package/dist/models/DevServer.js +77 -0
  20. package/dist/models/DevServer.js.map +1 -0
  21. package/dist/models/DevServerFileBinary.js +27 -0
  22. package/dist/models/DevServerFileBinary.js.map +1 -0
  23. package/dist/models/DevServerFileSystemClaim.js +30 -0
  24. package/dist/models/DevServerFileSystemClaim.js.map +1 -0
  25. package/dist/models/DevServerHttpClientRequestClaim.js +21 -0
  26. package/dist/models/DevServerHttpClientRequestClaim.js.map +1 -0
  27. package/dist/models/DevServerORMClaim.js +37 -0
  28. package/dist/models/DevServerORMClaim.js.map +1 -0
  29. package/dist/models/DevServerSmtpSendEmailClaim.js +32 -0
  30. package/dist/models/DevServerSmtpSendEmailClaim.js.map +1 -0
  31. package/dist/models/FileBinary.js +28 -0
  32. package/dist/models/FileBinary.js.map +1 -0
  33. package/dist/models/InMemoryDatabase.js +86 -0
  34. package/dist/models/InMemoryDatabase.js.map +1 -0
  35. package/dist/models/JSONCodec.js +110 -0
  36. package/dist/models/JSONCodec.js.map +1 -0
  37. package/dist/models/JSONCodecKindFrameworkSerializableClass.js +7 -0
  38. package/dist/models/JSONCodecKindFrameworkSerializableClass.js.map +1 -0
  39. package/dist/models/JSONRPCClient.js +50 -0
  40. package/dist/models/JSONRPCClient.js.map +1 -0
  41. package/dist/models/JSONRPCServer.js +61 -0
  42. package/dist/models/JSONRPCServer.js.map +1 -0
  43. package/dist/models/__tests__/DevServerFileBinary.spec.js +44 -0
  44. package/dist/models/__tests__/DevServerFileBinary.spec.js.map +1 -0
  45. package/dist/models/__tests__/InMemoryDatabase.spec.js +189 -0
  46. package/dist/models/__tests__/InMemoryDatabase.spec.js.map +1 -0
  47. package/dist/models/__tests__/JSONCodec.spec.js +135 -0
  48. package/dist/models/__tests__/JSONCodec.spec.js.map +1 -0
  49. package/dist/models/__tests__/JSONCodecKindFrameworkSerializableClass.spec.js +51 -0
  50. package/dist/models/__tests__/JSONCodecKindFrameworkSerializableClass.spec.js.map +1 -0
  51. package/dist/models/__tests__/JSONRPCClient.spec.js +133 -0
  52. package/dist/models/__tests__/JSONRPCClient.spec.js.map +1 -0
  53. package/dist/models/__tests__/JSONRPCServer.spec.js +160 -0
  54. package/dist/models/__tests__/JSONRPCServer.spec.js.map +1 -0
  55. package/dist/tools/__tests__/up-app.spec.js +24 -0
  56. package/dist/tools/__tests__/up-app.spec.js.map +1 -0
  57. package/dist/tools/a.js +53 -0
  58. package/dist/tools/a.js.map +1 -0
  59. package/dist/tools/extract-workflow-jsx.js +206 -0
  60. package/dist/tools/extract-workflow-jsx.js.map +1 -0
  61. package/dist/tools/generate-rsc-entries.js +105 -0
  62. package/dist/tools/generate-rsc-entries.js.map +1 -0
  63. package/dist/tools/json-codec.js +17 -0
  64. package/dist/tools/json-codec.js.map +1 -0
  65. package/dist/tools/json-schema-to-inquirer-question.js +33 -0
  66. package/dist/tools/json-schema-to-inquirer-question.js.map +1 -0
  67. package/dist/tools/mkdir-out-dir-project-from-ts-config-path-and-json-package-path.js +11 -0
  68. package/dist/tools/mkdir-out-dir-project-from-ts-config-path-and-json-package-path.js.map +1 -0
  69. package/dist/tools/resolve-package-json-path.js +21 -0
  70. package/dist/tools/resolve-package-json-path.js.map +1 -0
  71. package/dist/tools/resolve-tsconfig-path-from-package-json-path.js +14 -0
  72. package/dist/tools/resolve-tsconfig-path-from-package-json-path.js.map +1 -0
  73. package/dist/tools/test.js +32 -0
  74. package/dist/tools/test.js.map +1 -0
  75. package/dist/tools/ts-build-watch.js +46 -0
  76. package/dist/tools/ts-build-watch.js.map +1 -0
  77. package/dist/tools/ts-build.js +37 -0
  78. package/dist/tools/ts-build.js.map +1 -0
  79. package/dist/tools/up-app.js +10 -0
  80. package/dist/tools/up-app.js.map +1 -0
  81. package/package.json +67 -0
@@ -0,0 +1,44 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { DevServerFileBinary } from '../DevServerFileBinary.js';
3
+ describe('DevServerFileBinary', () => {
4
+ describe('from', () => {
5
+ it('creates an instance from a plain object', () => {
6
+ const binary = DevServerFileBinary.from({
7
+ path: '/tmp/test.txt',
8
+ contentType: 'text/plain',
9
+ contentLength: 100,
10
+ });
11
+ expect(binary.path).toBe('/tmp/test.txt');
12
+ expect(binary.contentType).toBe('text/plain');
13
+ expect(binary.contentLength).toBe(100);
14
+ });
15
+ });
16
+ describe('toJSON', () => {
17
+ it('returns a plain object with path, contentType, and contentLength', () => {
18
+ const binary = DevServerFileBinary.from({
19
+ path: '/tmp/file.pdf',
20
+ contentType: 'application/pdf',
21
+ contentLength: 2048,
22
+ });
23
+ expect(binary.toJSON()).toEqual({
24
+ path: '/tmp/file.pdf',
25
+ contentType: 'application/pdf',
26
+ contentLength: 2048,
27
+ });
28
+ });
29
+ });
30
+ describe('round-trip', () => {
31
+ it('from(toJSON()) produces an equivalent instance', () => {
32
+ const original = DevServerFileBinary.from({
33
+ path: '/tmp/img.png',
34
+ contentType: 'image/png',
35
+ contentLength: 512,
36
+ });
37
+ const restored = DevServerFileBinary.from(original.toJSON());
38
+ expect(restored.path).toBe(original.path);
39
+ expect(restored.contentType).toBe(original.contentType);
40
+ expect(restored.contentLength).toBe(original.contentLength);
41
+ });
42
+ });
43
+ });
44
+ //# sourceMappingURL=DevServerFileBinary.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DevServerFileBinary.spec.js","sourceRoot":"","sources":["../../../src/models/__tests__/DevServerFileBinary.spec.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAA;AAE7C,OAAO,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAA;AAE/D,QAAQ,CAAC,qBAAqB,EAAE,GAAG,EAAE;IACnC,QAAQ,CAAC,MAAM,EAAE,GAAG,EAAE;QACpB,EAAE,CAAC,yCAAyC,EAAE,GAAG,EAAE;YACjD,MAAM,MAAM,GAAG,mBAAmB,CAAC,IAAI,CAAC;gBACtC,IAAI,EAAE,eAAe;gBACrB,WAAW,EAAE,YAAY;gBACzB,aAAa,EAAE,GAAG;aACnB,CAAC,CAAA;YAEF,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,CAAA;YACzC,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAA;YAC7C,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;QACxC,CAAC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,QAAQ,CAAC,QAAQ,EAAE,GAAG,EAAE;QACtB,EAAE,CAAC,kEAAkE,EAAE,GAAG,EAAE;YAC1E,MAAM,MAAM,GAAG,mBAAmB,CAAC,IAAI,CAAC;gBACtC,IAAI,EAAE,eAAe;gBACrB,WAAW,EAAE,iBAAiB;gBAC9B,aAAa,EAAE,IAAI;aACpB,CAAC,CAAA;YAEF,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC;gBAC9B,IAAI,EAAE,eAAe;gBACrB,WAAW,EAAE,iBAAiB;gBAC9B,aAAa,EAAE,IAAI;aACpB,CAAC,CAAA;QACJ,CAAC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,QAAQ,CAAC,YAAY,EAAE,GAAG,EAAE;QAC1B,EAAE,CAAC,gDAAgD,EAAE,GAAG,EAAE;YACxD,MAAM,QAAQ,GAAG,mBAAmB,CAAC,IAAI,CAAC;gBACxC,IAAI,EAAE,cAAc;gBACpB,WAAW,EAAE,WAAW;gBACxB,aAAa,EAAE,GAAG;aACnB,CAAC,CAAA;YAEF,MAAM,QAAQ,GAAG,mBAAmB,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAA;YAE5D,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAA;YACzC,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAA;YACvD,MAAM,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAA;QAC7D,CAAC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"}
@@ -0,0 +1,189 @@
1
+ import { describe, expect, it, vi } from 'vitest';
2
+ import { InMemoryDatabase, InMemoryDatabaseTable } from '../InMemoryDatabase.js';
3
+ describe('InMemoryDatabaseTable', () => {
4
+ describe('insert', () => {
5
+ it('inserts rows and returns generated ids', () => {
6
+ const table = new InMemoryDatabaseTable();
7
+ const ids = table.insert([{ name: 'Alice' }, { name: 'Bob' }]);
8
+ expect(ids).toHaveLength(2);
9
+ expect(typeof ids[0]).toBe('string');
10
+ expect(typeof ids[1]).toBe('string');
11
+ expect(ids[0]).not.toBe(ids[1]);
12
+ });
13
+ it('emits change event on insert', () => {
14
+ const table = new InMemoryDatabaseTable();
15
+ const listener = vi.fn();
16
+ table.on('change', listener);
17
+ table.insert([{ name: 'Alice' }]);
18
+ expect(listener).toHaveBeenCalledOnce();
19
+ });
20
+ });
21
+ describe('find', () => {
22
+ it('returns all rows matching the where clause', () => {
23
+ const table = new InMemoryDatabaseTable();
24
+ table.insert([{ name: 'Alice', age: 30 }, { name: 'Bob', age: 25 }, { name: 'Carol', age: 30 }]);
25
+ const rows = table.find({ where: { age: 30 } });
26
+ expect(rows).toHaveLength(2);
27
+ expect(rows.map(r => r.name)).toEqual(['Alice', 'Carol']);
28
+ });
29
+ it('returns empty array when no rows match', () => {
30
+ const table = new InMemoryDatabaseTable();
31
+ table.insert([{ name: 'Alice' }]);
32
+ const rows = table.find({ where: { name: 'Nobody' } });
33
+ expect(rows).toHaveLength(0);
34
+ });
35
+ it('applies limit', () => {
36
+ const table = new InMemoryDatabaseTable();
37
+ table.insert([{ n: 1 }, { n: 2 }, { n: 3 }]);
38
+ const rows = table.find({ where: {}, limit: 2 });
39
+ expect(rows).toHaveLength(2);
40
+ });
41
+ it('applies offset', () => {
42
+ const table = new InMemoryDatabaseTable();
43
+ table.insert([{ n: 1 }, { n: 2 }, { n: 3 }]);
44
+ const rows = table.find({ where: {}, offset: 1 });
45
+ expect(rows).toHaveLength(2);
46
+ expect(rows[0].n).toBe(2);
47
+ });
48
+ it('applies offset and limit together', () => {
49
+ const table = new InMemoryDatabaseTable();
50
+ table.insert([{ n: 1 }, { n: 2 }, { n: 3 }, { n: 4 }]);
51
+ const rows = table.find({ where: {}, offset: 1, limit: 2 });
52
+ expect(rows).toHaveLength(2);
53
+ expect(rows.map(r => r.n)).toEqual([2, 3]);
54
+ });
55
+ it('sorts rows ascending', () => {
56
+ const table = new InMemoryDatabaseTable();
57
+ table.insert([{ name: 'Charlie' }, { name: 'Alice' }, { name: 'Bob' }]);
58
+ const rows = table.find({ where: {}, orderBy: { name: 'asc' } });
59
+ expect(rows.map(r => r.name)).toEqual(['Alice', 'Bob', 'Charlie']);
60
+ });
61
+ it('sorts rows descending', () => {
62
+ const table = new InMemoryDatabaseTable();
63
+ table.insert([{ name: 'Alice' }, { name: 'Charlie' }, { name: 'Bob' }]);
64
+ const rows = table.find({ where: {}, orderBy: { name: 'desc' } });
65
+ expect(rows.map(r => r.name)).toEqual(['Charlie', 'Bob', 'Alice']);
66
+ });
67
+ it('sorts null values to the beginning for asc', () => {
68
+ const table = new InMemoryDatabaseTable();
69
+ table.insert([{ name: 'Bob' }, { name: null }, { name: 'Alice' }]);
70
+ const rows = table.find({ where: {}, orderBy: { name: 'asc' } });
71
+ expect(rows[0].name).toBeNull();
72
+ });
73
+ it('sorts null values to the beginning for desc', () => {
74
+ const table = new InMemoryDatabaseTable();
75
+ table.insert([{ name: 'Bob' }, { name: null }, { name: 'Alice' }]);
76
+ const rows = table.find({ where: {}, orderBy: { name: 'desc' } });
77
+ expect(rows[0].name).toBe('Bob');
78
+ });
79
+ it('returns 0 for equal rows in sort', () => {
80
+ const table = new InMemoryDatabaseTable();
81
+ table.insert([{ name: 'Alice', age: 30 }, { name: 'Alice', age: 25 }]);
82
+ const rows = table.find({ where: {}, orderBy: { name: 'asc' } });
83
+ expect(rows).toHaveLength(2);
84
+ expect(rows[0].name).toBe('Alice');
85
+ expect(rows[1].name).toBe('Alice');
86
+ });
87
+ });
88
+ describe('update', () => {
89
+ it('updates matching rows and returns count', () => {
90
+ const table = new InMemoryDatabaseTable();
91
+ table.insert([{ name: 'Alice', age: 30 }, { name: 'Bob', age: 25 }]);
92
+ const count = table.update({ name: 'Alice' }, { age: 31 });
93
+ expect(count).toBe(1);
94
+ const rows = table.find({ where: { name: 'Alice' } });
95
+ expect(rows[0].age).toBe(31);
96
+ });
97
+ it('preserves other fields during update', () => {
98
+ const table = new InMemoryDatabaseTable();
99
+ table.insert([{ name: 'Alice', age: 30, email: 'alice@test.com' }]);
100
+ table.update({ name: 'Alice' }, { age: 31 });
101
+ const rows = table.find({ where: { name: 'Alice' } });
102
+ expect(rows[0].email).toBe('alice@test.com');
103
+ expect(rows[0].age).toBe(31);
104
+ });
105
+ it('emits change event', () => {
106
+ const table = new InMemoryDatabaseTable();
107
+ table.insert([{ name: 'Alice' }]);
108
+ const listener = vi.fn();
109
+ table.on('change', listener);
110
+ table.update({ name: 'Alice' }, { name: 'Updated' });
111
+ expect(listener).toHaveBeenCalledOnce();
112
+ });
113
+ });
114
+ describe('delete', () => {
115
+ it('removes matching rows', () => {
116
+ const table = new InMemoryDatabaseTable();
117
+ table.insert([{ name: 'Alice' }, { name: 'Bob' }]);
118
+ table.delete({ name: 'Alice' });
119
+ const rows = table.find({ where: {} });
120
+ expect(rows).toHaveLength(1);
121
+ expect(rows[0].name).toBe('Bob');
122
+ });
123
+ it('emits change event', () => {
124
+ const table = new InMemoryDatabaseTable();
125
+ table.insert([{ name: 'Alice' }]);
126
+ const listener = vi.fn();
127
+ table.on('change', listener);
128
+ table.delete({ name: 'Alice' });
129
+ expect(listener).toHaveBeenCalledOnce();
130
+ });
131
+ });
132
+ describe('toJSON', () => {
133
+ it('returns all rows as an array', () => {
134
+ const table = new InMemoryDatabaseTable();
135
+ const ids = table.insert([{ name: 'Alice' }, { name: 'Bob' }]);
136
+ const json = table.toJSON();
137
+ expect(json).toHaveLength(2);
138
+ expect(json[0]).toEqual({ id: ids[0], name: 'Alice' });
139
+ expect(json[1]).toEqual({ id: ids[1], name: 'Bob' });
140
+ });
141
+ });
142
+ });
143
+ describe('InMemoryDatabase', () => {
144
+ describe('constructor', () => {
145
+ it('creates empty database by default', () => {
146
+ const db = new InMemoryDatabase();
147
+ expect(db.toJSON()).toEqual({});
148
+ });
149
+ it('populates tables from initial data', () => {
150
+ const db = new InMemoryDatabase({
151
+ users: [{ id: '1', name: 'Alice' }],
152
+ });
153
+ const rows = db.table('users').find({ where: {} });
154
+ expect(rows).toHaveLength(1);
155
+ });
156
+ });
157
+ describe('table', () => {
158
+ it('creates a new table on first access', () => {
159
+ const db = new InMemoryDatabase();
160
+ const table = db.table('users');
161
+ expect(table).toBeInstanceOf(InMemoryDatabaseTable);
162
+ });
163
+ it('returns the same table on subsequent access', () => {
164
+ const db = new InMemoryDatabase();
165
+ const table1 = db.table('users');
166
+ const table2 = db.table('users');
167
+ expect(table1).toBe(table2);
168
+ });
169
+ it('propagates change events from table to database', () => {
170
+ const db = new InMemoryDatabase();
171
+ const listener = vi.fn();
172
+ db.on('change', listener);
173
+ db.table('users').insert([{ name: 'Alice' }]);
174
+ expect(listener).toHaveBeenCalledOnce();
175
+ });
176
+ });
177
+ describe('toJSON', () => {
178
+ it('serializes all tables', () => {
179
+ const db = new InMemoryDatabase();
180
+ db.table('users').insert([{ name: 'Alice' }]);
181
+ db.table('posts').insert([{ title: 'Hello' }]);
182
+ const json = db.toJSON();
183
+ expect(Object.keys(json)).toEqual(['users', 'posts']);
184
+ expect(json.users).toHaveLength(1);
185
+ expect(json.posts).toHaveLength(1);
186
+ });
187
+ });
188
+ });
189
+ //# sourceMappingURL=InMemoryDatabase.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"InMemoryDatabase.spec.js","sourceRoot":"","sources":["../../../src/models/__tests__/InMemoryDatabase.spec.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,135 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { JSONCodec, JSONCodecKind } from '../JSONCodec.js';
3
+ const dateKind = new JSONCodecKind('date', (value) => value instanceof Date, (date) => date.toISOString(), (value) => new Date(value));
4
+ const urlKind = new JSONCodecKind('url', (value) => value instanceof URL, (url) => url.toString(), (value) => new URL(value));
5
+ describe('JSONCodecKind', () => {
6
+ it('stores kind name', () => {
7
+ expect(dateKind.kind).toBe('date');
8
+ });
9
+ it('test returns true for matching values', () => {
10
+ expect(dateKind.test(new Date())).toBe(true);
11
+ });
12
+ it('test returns false for non-matching values', () => {
13
+ expect(dateKind.test({ not: 'a date' })).toBe(false);
14
+ });
15
+ it('serialize transforms value', async () => {
16
+ const date = new Date('2025-01-01T00:00:00.000Z');
17
+ const result = await dateKind.serialize(date, {}, v => v);
18
+ expect(result).toBe('2025-01-01T00:00:00.000Z');
19
+ });
20
+ it('parse restores value', async () => {
21
+ const result = await dateKind.parse('2025-01-01T00:00:00.000Z', {}, v => v);
22
+ expect(result).toBeInstanceOf(Date);
23
+ expect(result.toISOString()).toBe('2025-01-01T00:00:00.000Z');
24
+ });
25
+ });
26
+ describe('JSONCodec', () => {
27
+ describe('constructor', () => {
28
+ it('registers kinds', () => {
29
+ const codec = new JSONCodec(dateKind);
30
+ expect(codec).toBeDefined();
31
+ });
32
+ it('throws on duplicate kind registration', () => {
33
+ expect(() => new JSONCodec(dateKind, dateKind)).toThrow('Kind date already registered');
34
+ });
35
+ });
36
+ describe('stringify and parse', () => {
37
+ it('round-trips a Date through serialize/parse', async () => {
38
+ const codec = new JSONCodec(dateKind);
39
+ const original = { createdAt: new Date('2025-06-15T12:00:00.000Z') };
40
+ const json = await codec.stringify(original, {});
41
+ const restored = await codec.parse(json, {});
42
+ expect(restored.createdAt).toBeInstanceOf(Date);
43
+ expect(restored.createdAt.toISOString()).toBe('2025-06-15T12:00:00.000Z');
44
+ });
45
+ it('round-trips multiple kinds', async () => {
46
+ const codec = new JSONCodec(dateKind, urlKind);
47
+ const original = {
48
+ date: new Date('2025-01-01T00:00:00.000Z'),
49
+ url: new URL('https://example.com'),
50
+ };
51
+ const json = await codec.stringify(original, {});
52
+ const restored = await codec.parse(json, {});
53
+ expect(restored.date).toBeInstanceOf(Date);
54
+ expect(restored.url).toBeInstanceOf(URL);
55
+ expect(restored.url.href).toBe('https://example.com/');
56
+ });
57
+ it('preserves plain values', async () => {
58
+ const codec = new JSONCodec(dateKind);
59
+ const original = { name: 'test', count: 42, active: true };
60
+ const json = await codec.stringify(original, {});
61
+ const restored = await codec.parse(json, {});
62
+ expect(restored).toEqual(original);
63
+ });
64
+ it('handles null values', async () => {
65
+ const codec = new JSONCodec(dateKind);
66
+ const original = { value: null };
67
+ const json = await codec.stringify(original, {});
68
+ const restored = await codec.parse(json, {});
69
+ expect(restored.value).toBeNull();
70
+ });
71
+ it('handles arrays', async () => {
72
+ const codec = new JSONCodec(dateKind);
73
+ const original = {
74
+ dates: [
75
+ new Date('2025-01-01T00:00:00.000Z'),
76
+ new Date('2025-06-01T00:00:00.000Z'),
77
+ ],
78
+ };
79
+ const json = await codec.stringify(original, {});
80
+ const restored = await codec.parse(json, {});
81
+ expect(restored.dates).toHaveLength(2);
82
+ expect(restored.dates[0]).toBeInstanceOf(Date);
83
+ expect(restored.dates[1]).toBeInstanceOf(Date);
84
+ });
85
+ it('handles arrays with undefined values by converting to null', async () => {
86
+ const codec = new JSONCodec(dateKind);
87
+ const json = await codec.stringify([undefined, 'a'], {});
88
+ const restored = await codec.parse(json, {});
89
+ expect(restored[0]).toBeNull();
90
+ expect(restored[1]).toBe('a');
91
+ });
92
+ it('handles nested objects', async () => {
93
+ const codec = new JSONCodec(dateKind);
94
+ const original = {
95
+ user: {
96
+ name: 'Alice',
97
+ profile: {
98
+ joinedAt: new Date('2025-03-01T00:00:00.000Z'),
99
+ },
100
+ },
101
+ };
102
+ const json = await codec.stringify(original, {});
103
+ const restored = await codec.parse(json, {});
104
+ expect(restored.user.profile.joinedAt).toBeInstanceOf(Date);
105
+ });
106
+ it('skips undefined object values during stringify', async () => {
107
+ const codec = new JSONCodec(dateKind);
108
+ const original = { a: 'hello', b: undefined };
109
+ const json = await codec.stringify(original, {});
110
+ const parsed = JSON.parse(json);
111
+ expect('b' in parsed).toBe(false);
112
+ });
113
+ });
114
+ describe('stringify output format', () => {
115
+ it('wraps string serialized values with ~kind and ~value', async () => {
116
+ const codec = new JSONCodec(dateKind);
117
+ const original = { d: new Date('2025-01-01T00:00:00.000Z') };
118
+ const json = await codec.stringify(original, {});
119
+ const raw = JSON.parse(json);
120
+ expect(raw.d['~kind']).toBe('date');
121
+ expect(raw.d['~value']).toBe('2025-01-01T00:00:00.000Z');
122
+ });
123
+ it('spreads object serialized values with ~kind', async () => {
124
+ const objKind = new JSONCodecKind('point', (value) => 'x' in value && 'y' in value, (value) => ({ x: value.x, y: value.y }), (value) => ({ x: value.x, y: value.y }));
125
+ const codec = new JSONCodec(objKind);
126
+ const original = { p: { x: 1, y: 2 } };
127
+ const json = await codec.stringify(original, {});
128
+ const raw = JSON.parse(json);
129
+ expect(raw.p['~kind']).toBe('point');
130
+ expect(raw.p.x).toBe(1);
131
+ expect(raw.p.y).toBe(2);
132
+ });
133
+ });
134
+ });
135
+ //# sourceMappingURL=JSONCodec.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"JSONCodec.spec.js","sourceRoot":"","sources":["../../../src/models/__tests__/JSONCodec.spec.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,51 @@
1
+ import { SerializableClass, } from '@t4h.framework/core';
2
+ import { describe, expect, it } from 'vitest';
3
+ import { JSONCodecKindFrameworkSerializableClass } from '../JSONCodecKindFrameworkSerializableClass.js';
4
+ class TestModel extends SerializableClass {
5
+ name;
6
+ value;
7
+ constructor(name, value) {
8
+ super();
9
+ this.name = name;
10
+ this.value = value;
11
+ }
12
+ toSerializable() {
13
+ return { name: this.name, value: this.value };
14
+ }
15
+ fromSerializable(serializable) {
16
+ Object.defineProperty(this, 'name', { value: serializable.name });
17
+ Object.defineProperty(this, 'value', { value: serializable.value });
18
+ }
19
+ }
20
+ const testKind = new JSONCodecKindFrameworkSerializableClass('test-model', TestModel);
21
+ describe('JSONCodecKindFrameworkSerializableClass', () => {
22
+ it('has the correct kind name', () => {
23
+ expect(testKind.kind).toBe('test-model');
24
+ });
25
+ describe('test', () => {
26
+ it('returns true for instances of the class', () => {
27
+ const instance = new TestModel('hello', 42);
28
+ expect(testKind.test(instance)).toBe(true);
29
+ });
30
+ it('returns false for non-instances', () => {
31
+ expect(testKind.test({ name: 'hello', value: 42 })).toBe(false);
32
+ });
33
+ });
34
+ describe('serialize', () => {
35
+ it('calls toSerializable on the instance', async () => {
36
+ const instance = new TestModel('test', 99);
37
+ const serialized = await testKind.serialize(instance, {}, v => v);
38
+ expect(serialized).toEqual({ name: 'test', value: 99 });
39
+ });
40
+ });
41
+ describe('parse', () => {
42
+ it('restores an instance from serialized data', async () => {
43
+ const serialized = { '~kind': 'test-model', name: 'restored', value: 7 };
44
+ const restored = await testKind.parse(serialized, {}, v => v);
45
+ expect(restored).toBeInstanceOf(TestModel);
46
+ expect(restored.name).toBe('restored');
47
+ expect(restored.value).toBe(7);
48
+ });
49
+ });
50
+ });
51
+ //# sourceMappingURL=JSONCodecKindFrameworkSerializableClass.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"JSONCodecKindFrameworkSerializableClass.spec.js","sourceRoot":"","sources":["../../../src/models/__tests__/JSONCodecKindFrameworkSerializableClass.spec.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,GAElB,MAAM,qBAAqB,CAAA;AAC5B,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAA;AAE7C,OAAO,EAAE,uCAAuC,EAAE,MAAM,+CAA+C,CAAA;AAEvG,MAAM,SAAU,SAAQ,iBAAiB;IAErB;IACA;IAFlB,YACkB,IAAY,EACZ,KAAa;QAE7B,KAAK,EAAE,CAAA;QAHS,SAAI,GAAJ,IAAI,CAAQ;QACZ,UAAK,GAAL,KAAK,CAAQ;IAG/B,CAAC;IAEM,cAAc;QACnB,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAA;IAC/C,CAAC;IAES,gBAAgB,CACxB,YAAiE;QAEjE,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,YAAY,CAAC,IAAI,EAAE,CAAC,CAAA;QACjE,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,KAAK,EAAE,YAAY,CAAC,KAAK,EAAE,CAAC,CAAA;IACrE,CAAC;CACF;AAED,MAAM,QAAQ,GAAG,IAAI,uCAAuC,CAAC,YAAY,EAAE,SAAS,CAAC,CAAA;AAErF,QAAQ,CAAC,yCAAyC,EAAE,GAAG,EAAE;IACvD,EAAE,CAAC,2BAA2B,EAAE,GAAG,EAAE;QACnC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAA;IAC1C,CAAC,CAAC,CAAA;IAEF,QAAQ,CAAC,MAAM,EAAE,GAAG,EAAE;QACpB,EAAE,CAAC,yCAAyC,EAAE,GAAG,EAAE;YACjD,MAAM,QAAQ,GAAG,IAAI,SAAS,CAAC,OAAO,EAAE,EAAE,CAAC,CAAA;YAE3C,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAC5C,CAAC,CAAC,CAAA;QAEF,EAAE,CAAC,iCAAiC,EAAE,GAAG,EAAE;YACzC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QACjE,CAAC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,QAAQ,CAAC,WAAW,EAAE,GAAG,EAAE;QACzB,EAAE,CAAC,sCAAsC,EAAE,KAAK,IAAI,EAAE;YACpD,MAAM,QAAQ,GAAG,IAAI,SAAS,CAAC,MAAM,EAAE,EAAE,CAAC,CAAA;YAE1C,MAAM,UAAU,GAAG,MAAM,QAAQ,CAAC,SAAS,CAAC,QAAQ,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;YAEjE,MAAM,CAAC,UAAU,CAAC,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAA;QACzD,CAAC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,QAAQ,CAAC,OAAO,EAAE,GAAG,EAAE;QACrB,EAAE,CAAC,2CAA2C,EAAE,KAAK,IAAI,EAAE;YACzD,MAAM,UAAU,GAAG,EAAE,OAAO,EAAE,YAAqB,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC,EAAE,CAAA;YAEjF,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC,KAAK,CAAC,UAAU,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;YAE7D,MAAM,CAAC,QAAQ,CAAC,CAAC,cAAc,CAAC,SAAS,CAAC,CAAA;YAC1C,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;YACtC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QAChC,CAAC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"}
@@ -0,0 +1,133 @@
1
+ import { describe, expect, it, vi } from 'vitest';
2
+ import { JSONRPCClient } from '../JSONRPCClient.js';
3
+ describe('JSONRPCClient', () => {
4
+ describe('notify', () => {
5
+ it('sends a notification without id', async () => {
6
+ const send = vi.fn();
7
+ const client = new JSONRPCClient(send);
8
+ await client.notify('update', 'data');
9
+ expect(send).toHaveBeenCalledOnce();
10
+ const message = JSON.parse(send.mock.calls[0][0]);
11
+ expect(message.jsonrpc).toBe('2.0');
12
+ expect(message.method).toBe('update');
13
+ expect(message.params).toEqual(['data']);
14
+ expect(message.id).toBeUndefined();
15
+ });
16
+ });
17
+ describe('call', () => {
18
+ it('sends a request with id and resolves on fulfilled response', async () => {
19
+ const send = vi.fn();
20
+ const client = new JSONRPCClient(send);
21
+ const promise = client.call('add', 2, 3);
22
+ const message = JSON.parse(send.mock.calls[0][0]);
23
+ expect(message.jsonrpc).toBe('2.0');
24
+ expect(message.method).toBe('add');
25
+ expect(message.params).toEqual([2, 3]);
26
+ expect(typeof message.id).toBe('string');
27
+ await client.handle({
28
+ jsonrpc: '2.0',
29
+ id: message.id,
30
+ result: 5,
31
+ });
32
+ await expect(promise).resolves.toBe(5);
33
+ });
34
+ it('rejects on error response', async () => {
35
+ const send = vi.fn();
36
+ const client = new JSONRPCClient(send);
37
+ const promise = client.call('fail');
38
+ const message = JSON.parse(send.mock.calls[0][0]);
39
+ await client.handle({
40
+ jsonrpc: '2.0',
41
+ id: message.id,
42
+ error: { code: -32600, message: 'Invalid Request' },
43
+ });
44
+ await expect(promise).rejects.toThrow('Invalid Request');
45
+ });
46
+ it('ignores responses with non-matching id', async () => {
47
+ const send = vi.fn();
48
+ const client = new JSONRPCClient(send);
49
+ const promise = client.call('test');
50
+ await client.handle({
51
+ jsonrpc: '2.0',
52
+ id: 'wrong-id',
53
+ result: 'not for me',
54
+ });
55
+ const message = JSON.parse(send.mock.calls[0][0]);
56
+ await client.handle({
57
+ jsonrpc: '2.0',
58
+ id: message.id,
59
+ result: 'correct',
60
+ });
61
+ await expect(promise).resolves.toBe('correct');
62
+ });
63
+ });
64
+ describe('addListener', () => {
65
+ it('adds a listener and returns a removal function', async () => {
66
+ const send = vi.fn();
67
+ const client = new JSONRPCClient(send);
68
+ const listener = vi.fn();
69
+ const off = client.addListener(listener);
70
+ await client.handle({
71
+ jsonrpc: '2.0',
72
+ id: 'test-1',
73
+ result: 'data',
74
+ });
75
+ expect(listener).toHaveBeenCalledOnce();
76
+ off();
77
+ await client.handle({
78
+ jsonrpc: '2.0',
79
+ id: 'test-2',
80
+ result: 'more data',
81
+ });
82
+ expect(listener).toHaveBeenCalledOnce();
83
+ });
84
+ });
85
+ describe('handle', () => {
86
+ it('handles string messages by parsing JSON', async () => {
87
+ const send = vi.fn();
88
+ const client = new JSONRPCClient(send);
89
+ const listener = vi.fn();
90
+ client.addListener(listener);
91
+ await client.handle(JSON.stringify({
92
+ jsonrpc: '2.0',
93
+ id: 'str-1',
94
+ result: 'parsed',
95
+ }));
96
+ expect(listener).toHaveBeenCalledOnce();
97
+ });
98
+ it('handles Buffer messages', async () => {
99
+ const send = vi.fn();
100
+ const client = new JSONRPCClient(send);
101
+ const listener = vi.fn();
102
+ client.addListener(listener);
103
+ await client.handle(Buffer.from(JSON.stringify({
104
+ jsonrpc: '2.0',
105
+ id: 'buf-1',
106
+ result: 'from-buffer',
107
+ })));
108
+ expect(listener).toHaveBeenCalledOnce();
109
+ });
110
+ it('throws for invalid jsonrpc version', async () => {
111
+ const send = vi.fn();
112
+ const client = new JSONRPCClient(send);
113
+ await expect(client.handle({ jsonrpc: '1.0', id: 'bad', result: 'x' })).rejects.toThrow('Invalid JSON-RPC message');
114
+ });
115
+ it('returns early for messages without id', async () => {
116
+ const send = vi.fn();
117
+ const client = new JSONRPCClient(send);
118
+ const listener = vi.fn();
119
+ client.addListener(listener);
120
+ await client.handle({ jsonrpc: '2.0', method: 'notify', params: [] });
121
+ expect(listener).not.toHaveBeenCalled();
122
+ });
123
+ it('returns early for messages with undefined id', async () => {
124
+ const send = vi.fn();
125
+ const client = new JSONRPCClient(send);
126
+ const listener = vi.fn();
127
+ client.addListener(listener);
128
+ await client.handle({ jsonrpc: '2.0', id: undefined, result: 'x' });
129
+ expect(listener).not.toHaveBeenCalled();
130
+ });
131
+ });
132
+ });
133
+ //# sourceMappingURL=JSONRPCClient.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"JSONRPCClient.spec.js","sourceRoot":"","sources":["../../../src/models/__tests__/JSONRPCClient.spec.ts"],"names":[],"mappings":"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"}