libmodulor 0.18.1 → 0.20.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 (92) hide show
  1. package/CHANGELOG.md +41 -0
  2. package/README.md +1 -1
  3. package/dist/esm/apps/Helper/src/lib/project.js +8 -8
  4. package/dist/esm/convention.d.ts +2 -0
  5. package/dist/esm/convention.js +2 -0
  6. package/dist/esm/error/index.d.ts +3 -0
  7. package/dist/esm/error/index.js +3 -0
  8. package/dist/esm/error/internal/NotAvailableError.d.ts +3 -0
  9. package/dist/esm/error/internal/NotAvailableError.js +7 -0
  10. package/dist/esm/error/internal/NotCallableError.d.ts +4 -0
  11. package/dist/esm/error/internal/NotCallableError.js +7 -0
  12. package/dist/esm/error/internal/NotImplementedError.d.ts +3 -0
  13. package/dist/esm/error/internal/NotImplementedError.js +7 -0
  14. package/dist/esm/index.cloudflare-worker-hono.d.ts +5 -0
  15. package/dist/esm/index.cloudflare-worker-hono.js +5 -0
  16. package/dist/esm/index.d.ts +1 -0
  17. package/dist/esm/index.js +1 -0
  18. package/dist/esm/index.node-express.d.ts +2 -0
  19. package/dist/esm/index.node-express.js +2 -0
  20. package/dist/esm/index.node-hono.d.ts +1 -0
  21. package/dist/esm/index.node-hono.js +1 -0
  22. package/dist/esm/product/index.d.ts +1 -0
  23. package/dist/esm/product/index.js +1 -0
  24. package/dist/esm/product/workers/SyncProductUCsLoader.d.ts +15 -0
  25. package/dist/esm/product/workers/SyncProductUCsLoader.js +52 -0
  26. package/dist/esm/std/ShellCommandExecutor.d.ts +1 -0
  27. package/dist/esm/std/impl/FakeFSManager.js +2 -1
  28. package/dist/esm/std/impl/FakeJobManager.d.ts +1 -0
  29. package/dist/esm/std/impl/FakeJobManager.js +3 -0
  30. package/dist/esm/std/impl/NodeSpawnShellCommandExecutor.js +6 -0
  31. package/dist/esm/std/impl/SimpleMapI18nManager.d.ts +2 -0
  32. package/dist/esm/std/impl/SimpleMapI18nManager.js +14 -8
  33. package/dist/esm/std/impl/UCDataStoreExternalResourceManager.js +1 -1
  34. package/dist/esm/std/impl/WebCryptoManager.js +5 -4
  35. package/dist/esm/std/impl/WebFSManager.js +15 -14
  36. package/dist/esm/target/edge-worker-hono-server/SyncEdgeWorkerHonoServerManager.d.ts +32 -0
  37. package/dist/esm/target/edge-worker-hono-server/SyncEdgeWorkerHonoServerManager.js +87 -0
  38. package/dist/esm/target/lib/mcp-server/MCPServerBooter.d.ts +3 -2
  39. package/dist/esm/target/lib/mcp-server/MCPServerBooter.js +10 -6
  40. package/dist/esm/target/lib/react/UCContainer.js +1 -1
  41. package/dist/esm/target/lib/server/ServerBooter.d.ts +1 -0
  42. package/dist/esm/target/lib/server/ServerBooter.js +41 -44
  43. package/dist/esm/target/lib/server/ServerManager.d.ts +7 -0
  44. package/dist/esm/target/lib/server/SyncEdgeWorkerInitializer.d.ts +17 -0
  45. package/dist/esm/target/lib/server/SyncEdgeWorkerInitializer.js +76 -0
  46. package/dist/esm/target/lib/server/funcs.d.ts +3 -0
  47. package/dist/esm/target/lib/server/funcs.js +11 -0
  48. package/dist/esm/target/lib/server-express/HelmetMiddlewareBuilder.d.ts +12 -0
  49. package/dist/esm/target/lib/server-express/HelmetMiddlewareBuilder.js +39 -0
  50. package/dist/esm/target/lib/server-express/funcs.d.ts +15 -0
  51. package/dist/esm/target/lib/server-express/funcs.js +103 -0
  52. package/dist/esm/target/lib/server-hono/funcs.d.ts +10 -0
  53. package/dist/esm/target/lib/server-hono/funcs.js +72 -0
  54. package/dist/esm/target/lib/server-node/funcs.d.ts +5 -0
  55. package/dist/esm/target/lib/server-node/funcs.js +25 -0
  56. package/dist/esm/target/lib/server-node/types.d.ts +2 -0
  57. package/dist/esm/target/nextjs-server/NextJSServerManager.d.ts +2 -0
  58. package/dist/esm/target/nextjs-server/NextJSServerManager.js +6 -0
  59. package/dist/esm/target/node-core-cli/NodeCoreCLIManager.d.ts +3 -1
  60. package/dist/esm/target/node-core-cli/NodeCoreCLIManager.js +8 -5
  61. package/dist/esm/target/node-express-server/NodeExpressServerManager.d.ts +6 -5
  62. package/dist/esm/target/node-express-server/NodeExpressServerManager.js +16 -103
  63. package/dist/esm/target/node-hono-server/NodeHonoServerManager.d.ts +7 -5
  64. package/dist/esm/target/node-hono-server/NodeHonoServerManager.js +16 -67
  65. package/dist/esm/target/node-mcp-server/NodeLocalStdioMCPServerManager.d.ts +5 -1
  66. package/dist/esm/target/node-mcp-server/NodeLocalStdioMCPServerManager.js +42 -29
  67. package/dist/esm/testing/AppTester.d.ts +5 -2
  68. package/dist/esm/testing/AppTester.js +17 -4
  69. package/dist/esm/testing/UCDataStoreTester.js +3 -3
  70. package/dist/esm/testing/impl/VitestAppTestSuiteEmitter.js +132 -115
  71. package/dist/esm/testing/impl/VitestAppTestSuiteRunner.d.ts +2 -3
  72. package/dist/esm/testing/impl/VitestAppTestSuiteRunner.js +6 -8
  73. package/dist/esm/testing/workers/checkers/UCDefChecker.d.ts +2 -0
  74. package/dist/esm/testing/workers/checkers/UCDefChecker.js +4 -1
  75. package/dist/esm/uc/data-store.d.ts +3 -4
  76. package/dist/esm/uc/helpers/UCOutputBuilder.js +1 -0
  77. package/dist/esm/uc/impl/CloudflareD1UCDataStore.d.ts +34 -0
  78. package/dist/esm/uc/impl/CloudflareD1UCDataStore.js +201 -0
  79. package/dist/esm/uc/impl/InMemoryUCDataStore.d.ts +3 -2
  80. package/dist/esm/uc/impl/InMemoryUCDataStore.js +17 -14
  81. package/dist/esm/uc/impl/KnexUCDataStore.d.ts +3 -2
  82. package/dist/esm/uc/impl/KnexUCDataStore.js +9 -5
  83. package/dist/esm/uc/impl/SimpleUCManager.d.ts +1 -1
  84. package/dist/esm/uc/impl/SimpleUCManager.js +2 -2
  85. package/dist/esm/uc/manager.d.ts +1 -1
  86. package/dist/esm/uc/settings/consts.js +1 -1
  87. package/dist/esm/utils/concerns/Initializable.d.ts +1 -0
  88. package/dist/esm/utils/ioc/bindCloudflareWorker.d.ts +2 -0
  89. package/dist/esm/utils/ioc/bindCloudflareWorker.js +15 -0
  90. package/package.json +17 -14
  91. package/pnpm-workspace.yaml +1 -1
  92. package/tsconfig.json +0 -1
@@ -29,6 +29,7 @@ import { AppManifestChecker } from './workers/checkers/AppManifestChecker.js';
29
29
  import { UCDefChecker } from './workers/checkers/UCDefChecker.js';
30
30
  import { UCDefSourcesChecker, } from './workers/checkers/UCDefSourcesChecker.js';
31
31
  import { UCExecutor, } from './workers/UCExecutor.js';
32
+ const ERR_UCD_NOT_FOUND = (ucName) => `Could not find a ucd for ${ucName}`;
32
33
  let AppTester = class AppTester {
33
34
  appDocsEmitter;
34
35
  appFolderChecker;
@@ -50,6 +51,8 @@ let AppTester = class AppTester {
50
51
  */
51
52
  safeSrcImporter;
52
53
  // biome-ignore lint/suspicious/noExplicitAny: can be anything
54
+ ucds;
55
+ // biome-ignore lint/suspicious/noExplicitAny: can be anything
53
56
  testResults;
54
57
  testSummary;
55
58
  ucDefSourcesCheckerOutput;
@@ -66,6 +69,7 @@ let AppTester = class AppTester {
66
69
  this.ucDefChecker = ucDefChecker;
67
70
  this.ucDefSourcesChecker = ucDefSourcesChecker;
68
71
  this.ucExecutor = ucExecutor;
72
+ this.ucds = new Map();
69
73
  this.testResults = [];
70
74
  this.testSummary = {
71
75
  counts: {
@@ -115,13 +119,13 @@ let AppTester = class AppTester {
115
119
  });
116
120
  }
117
121
  async checkUC(ucdRef) {
118
- const { errors } = await this.ucDefChecker.exec({ ucdRef });
122
+ const { errors, ucd } = await this.ucDefChecker.exec({ ucdRef });
119
123
  if (errors.length > 0) {
120
124
  throw new Error(errors[0]);
121
125
  }
122
- const { source } = ucdRef;
123
- const ucd = source[`${Object.keys(source)[0]}`];
124
- return ucd;
126
+ if (ucd) {
127
+ this.ucds.set(ucdRef.name, ucd);
128
+ }
125
129
  }
126
130
  async execFlow(flow) {
127
131
  const output = [];
@@ -226,6 +230,13 @@ let AppTester = class AppTester {
226
230
  getCtx() {
227
231
  return this.ctx;
228
232
  }
233
+ getUCD(ucName) {
234
+ const ucd = this.ucds.get(ucName);
235
+ if (!ucd) {
236
+ throw new Error(ERR_UCD_NOT_FOUND(ucName));
237
+ }
238
+ return ucd;
239
+ }
229
240
  async init({ appPath, configurator, serverClientSettings, srcImporter, }) {
230
241
  this.configurator = configurator;
231
242
  this.safeSrcImporter = (path) => Promise.race([
@@ -243,6 +254,8 @@ let AppTester = class AppTester {
243
254
  await this.configurator.seed(this.ctx);
244
255
  await this.bindI18n();
245
256
  await this.bindServerClientSettings(serverClientSettings);
257
+ }
258
+ async initForUCExec() {
246
259
  await this.initI18n();
247
260
  await this.initServer();
248
261
  }
@@ -16,7 +16,7 @@ import { APP_NAME_PLACEHOLDER } from '../convention.js';
16
16
  import { TAmount, TCompanyName, } from '../dt/index.js';
17
17
  import { UCExecMode, } from '../uc/index.js';
18
18
  const ERR_SHOULD_NOT_EXIST_AFTER_DESTROY = 'It should not exist after destroy';
19
- const ERR_SHOULD_EXIST_AFTER_INSTALL = 'It should exist after install';
19
+ const ERR_SHOULD_EXIST_AFTER_INIT = 'It should exist after init';
20
20
  const ERR_SHOULD_RETURN_X_RECORDS = (n) => `It should return ${n} record(s)`;
21
21
  /**
22
22
  * Test that a {@link UCDataStore} conforms to the spec
@@ -52,10 +52,10 @@ let UCDataStoreTester = class UCDataStoreTester {
52
52
  if (this.exists) {
53
53
  throw new Error(ERR_SHOULD_NOT_EXIST_AFTER_DESTROY);
54
54
  }
55
- await ucDataStore.install();
55
+ await ucDataStore.init();
56
56
  this.exists = await ucDataStore.exists();
57
57
  if (!this.exists) {
58
- throw new Error(ERR_SHOULD_EXIST_AFTER_INSTALL);
58
+ throw new Error(ERR_SHOULD_EXIST_AFTER_INIT);
59
59
  }
60
60
  this.readRes = await ucDataStore.read();
61
61
  this.expectXRecords(0);
@@ -52,14 +52,14 @@ const template = (serverPortRangeStart, idx, monkeyTestingTimeoutInMs) => `/*
52
52
  import { join } from 'node:path';
53
53
 
54
54
  import {
55
- assert,
56
55
  type Arbitrary,
57
56
  type AsyncCommand,
58
- type ModelRunSetup,
59
57
  anything,
58
+ assert,
60
59
  asyncModelRun,
61
60
  asyncProperty,
62
61
  commands,
62
+ type ModelRunSetup,
63
63
  record,
64
64
  } from 'fast-check';
65
65
  import {
@@ -70,7 +70,7 @@ import {
70
70
  type UCInput,
71
71
  } from 'libmodulor';
72
72
  import { newNodeAppTester } from 'libmodulor/node-test';
73
- import { afterAll, afterEach, describe, expect, test } from 'vitest';
73
+ import { afterAll, afterEach, beforeAll, describe, expect, test } from 'vitest';
74
74
 
75
75
  import { Configurator } from './Configurator.js';
76
76
 
@@ -84,116 +84,92 @@ const runner = await newNodeAppTester(${serverPortRangeStart}, ${idx}, {
84
84
  const ctx = runner.getCtx();
85
85
  const logger = ctx.container.get<Logger>('Logger');
86
86
 
87
+ const flows = await configurator.flows();
88
+
87
89
  afterAll(async () => {
88
90
  await runner.finalize();
89
91
  });
90
92
 
91
- test('Sources should be valid', async () => {
92
- await runner.checkUCDSources();
93
- });
94
-
95
- test('Folder should be valid', async () => {
96
- await runner.checkAppFolder();
97
- });
98
-
99
- test('${APP_MANIFEST_NAME} should be valid', async () => {
100
- await runner.checkAppManifest();
101
- });
93
+ describe('Check', () => {
94
+ test('Sources should be valid', async () => {
95
+ await runner.checkUCDSources();
96
+ });
102
97
 
103
- test('${APP_I18N_NAME} should be valid', async () => {
104
- await runner.checkAppI18n();
105
- });
98
+ test('Folder should be valid', async () => {
99
+ await runner.checkAppFolder();
100
+ });
106
101
 
107
- test('${APP_INDEX_NAME} should be valid', async () => {
108
- await runner.checkAppIndex();
109
- });
102
+ test('${APP_MANIFEST_NAME} should be valid', async () => {
103
+ await runner.checkAppManifest();
104
+ });
110
105
 
111
- const flows = await configurator.flows();
112
- describe.runIf(flows.length > 0)('Flows', async () => {
113
- afterEach(async () => {
114
- await configurator.clearExecution(ctx);
106
+ test('${APP_I18N_NAME} should be valid', async () => {
107
+ await runner.checkAppI18n();
115
108
  });
116
109
 
117
- test.each(flows)('should execute flow $name', async (flow) => {
118
- const output = await runner.execFlow(flow);
110
+ test('${APP_INDEX_NAME} should be valid', async () => {
111
+ await runner.checkAppIndex();
112
+ });
119
113
 
120
- for (const out of output) {
121
- if (out.err !== null) {
122
- if (!(out.err instanceof CustomError)) {
123
- logger.error(out.err);
124
- }
125
- expect(out.err).toBeInstanceOf(CustomError);
126
- }
127
- }
114
+ describe.runIf(ctx.ucdRefs.length > 0)('Use Cases', () => {
115
+ describe.each(ctx.ucdRefs)('$name', async (ucdRef) => {
116
+ test('should be valid', async () => {
117
+ await runner.checkUC(ucdRef);
118
+ });
119
+ });
128
120
  });
129
121
  });
130
122
 
131
- const { ucdRefs } = ctx;
132
- describe.runIf(ucdRefs.length > 0)('Use Cases', () => {
133
- describe.each(ucdRefs)('$name', async (ucdRef) => {
123
+ describe('Run', async () => {
124
+ beforeAll(async () => {
125
+ await runner.initForUCExec();
126
+ });
127
+
128
+ describe.runIf(flows.length > 0)('Flows', async () => {
134
129
  afterEach(async () => {
135
130
  await configurator.clearExecution(ctx);
136
131
  });
137
132
 
138
- // biome-ignore lint/suspicious/noExplicitAny: can be anything
139
- let ucd: UCDef<any, any, any>;
140
-
141
- test('should be valid', async () => {
142
- ucd = await runner.checkUC(ucdRef);
143
- });
144
-
145
- const data = await runner.ucTestData(ucdRef);
146
-
147
- test.each(data)(
148
- 'should execute with auth $authName and input $inputFillerName',
149
- async ({ auth, authName, inputFiller, inputFillerName }) => {
150
- const { out, sideEffects } = await runner.execUC({
151
- auth,
152
- authName: authName as UCAuthSetterName,
153
- inputFiller,
154
- inputFillerName,
155
- ucd,
156
- });
133
+ test.each(flows)('should execute flow $name', async (flow) => {
134
+ const output = await runner.execFlow(flow);
157
135
 
136
+ for (const out of output) {
158
137
  if (out.err !== null) {
159
138
  if (!(out.err instanceof CustomError)) {
160
139
  logger.error(out.err);
161
140
  }
162
141
  expect(out.err).toBeInstanceOf(CustomError);
163
142
  }
143
+ }
144
+ });
145
+ });
164
146
 
165
- const { hash } = out;
166
- const assertion = hash
167
- ? (await configurator.specificAssertions())?.get(hash)
168
- : undefined;
169
- if (assertion) {
170
- expect(out).toSatisfy(assertion);
171
- } else {
172
- expect({ out, sideEffects }).toMatchSnapshot(
173
- \`hash = \${hash\}\`,
174
- );
175
- }
176
- },
177
- );
178
-
179
- test('should execute with monkey testing', async () => {
180
- // Given
181
- // biome-ignore lint/complexity/noBannedTypes: nothing for now
182
- type Model = {};
183
- // biome-ignore lint/complexity/noBannedTypes: nothing for now
184
- type RealSystem = {};
185
-
186
- class MyCommand<I extends UCInput | undefined = undefined>
187
- implements AsyncCommand<Model, RealSystem>
188
- {
189
- constructor(private input: I) {}
190
-
191
- public check(_m: Readonly<Model>): boolean {
192
- return true;
193
- }
147
+ describe.runIf(ctx.ucdRefs.length > 0)('Use Cases', () => {
148
+ describe.each(ctx.ucdRefs)('$name', async (ucdRef) => {
149
+ afterEach(async () => {
150
+ await configurator.clearExecution(ctx);
151
+ });
152
+
153
+ // biome-ignore lint/suspicious/noExplicitAny: can be anything
154
+ let ucd: UCDef<any, any, any>;
194
155
 
195
- public async run(_m: Model, _r: RealSystem): Promise<void> {
196
- const out = await runner.execMonkeyTest(ucd, this.input);
156
+ beforeAll(() => {
157
+ // biome-ignore lint/suspicious/noExplicitAny: can be anything
158
+ ucd = runner.getUCD<any, any, any>(ucdRef.name);
159
+ });
160
+
161
+ const data = await runner.ucTestData(ucdRef);
162
+
163
+ test.each(data)(
164
+ 'should execute with auth $authName and input $inputFillerName',
165
+ async ({ auth, authName, inputFiller, inputFillerName }) => {
166
+ const { out, sideEffects } = await runner.execUC({
167
+ auth,
168
+ authName: authName as UCAuthSetterName,
169
+ inputFiller,
170
+ inputFillerName,
171
+ ucd,
172
+ });
197
173
 
198
174
  if (out.err !== null) {
199
175
  if (!(out.err instanceof CustomError)) {
@@ -201,41 +177,82 @@ describe.runIf(ucdRefs.length > 0)('Use Cases', () => {
201
177
  }
202
178
  expect(out.err).toBeInstanceOf(CustomError);
203
179
  }
204
- }
205
180
 
206
- public toString(): string {
207
- return \`\${ucd.metadata.name\}(\${JSON.stringify(this.input)\})\`;
181
+ const { hash } = out;
182
+ const assertion = hash
183
+ ? (await configurator.specificAssertions())?.get(hash)
184
+ : undefined;
185
+ if (assertion) {
186
+ expect(out).toSatisfy(assertion);
187
+ } else {
188
+ expect({ out, sideEffects }).toMatchSnapshot(
189
+ \`hash = \${hash\}\`,
190
+ );
191
+ }
192
+ },
193
+ );
194
+
195
+ test('should execute with monkey testing', async () => {
196
+ // Given
197
+ // biome-ignore lint/complexity/noBannedTypes: nothing for now
198
+ type Model = {};
199
+ // biome-ignore lint/complexity/noBannedTypes: nothing for now
200
+ type RealSystem = {};
201
+
202
+ class MyCommand<I extends UCInput | undefined = undefined>
203
+ implements AsyncCommand<Model, RealSystem>
204
+ {
205
+ constructor(private input: I) {}
206
+
207
+ public check(_m: Readonly<Model>): boolean {
208
+ return true;
209
+ }
210
+
211
+ public async run(_m: Model, _r: RealSystem): Promise<void> {
212
+ const out = await runner.execMonkeyTest(ucd, this.input);
213
+
214
+ if (out.err !== null) {
215
+ if (!(out.err instanceof CustomError)) {
216
+ logger.error(out.err);
217
+ }
218
+ expect(out.err).toBeInstanceOf(CustomError);
219
+ }
220
+ }
221
+
222
+ public toString(): string {
223
+ return \`\${ucd.metadata.name\}(\${JSON.stringify(this.input)\})\`;
224
+ }
208
225
  }
209
- }
210
226
 
211
- const inputFields = ucd.io.i?.fields;
212
- if (!inputFields || Object.keys(inputFields).length > 0) {
213
- // Mainly to prevent monkey testing from running indefinitely
214
- return;
215
- }
227
+ const inputFields = ucd.io.i?.fields;
228
+ if (!inputFields || Object.keys(inputFields).length > 0) {
229
+ // Mainly to prevent monkey testing from running indefinitely
230
+ return;
231
+ }
216
232
 
217
- // biome-ignore lint/suspicious/noExplicitAny: can be anything
218
- const inputLike: Record<string, Arbitrary<any>> = {};
219
- for (const k of Object.keys(inputFields)) {
220
- inputLike[k] = anything();
221
- }
222
- const cmdArbs = record(inputLike, { requiredKeys: [] }).map(
223
- (r) => new MyCommand(r),
224
- );
233
+ // biome-ignore lint/suspicious/noExplicitAny: can be anything
234
+ const inputLike: Record<string, Arbitrary<any>> = {};
235
+ for (const k of Object.keys(inputFields)) {
236
+ inputLike[k] = anything();
237
+ }
238
+ const cmdArbs = record(inputLike, { requiredKeys: [] }).map(
239
+ (r) => new MyCommand(r),
240
+ );
225
241
 
226
- const modelRunSetup: ModelRunSetup<Model, RealSystem> = () => ({
227
- model: {},
228
- real: {},
229
- });
242
+ const modelRunSetup: ModelRunSetup<Model, RealSystem> = () => ({
243
+ model: {},
244
+ real: {},
245
+ });
230
246
 
231
- // When
232
- const property = asyncProperty(commands([cmdArbs]), (cmds) =>
233
- asyncModelRun(modelRunSetup, cmds),
234
- );
247
+ // When
248
+ const property = asyncProperty(commands([cmdArbs]), (cmds) =>
249
+ asyncModelRun(modelRunSetup, cmds),
250
+ );
235
251
 
236
- // Then
237
- await assert(property);
238
- }, ${monkeyTestingTimeoutInMs});
252
+ // Then
253
+ await assert(property);
254
+ }, ${monkeyTestingTimeoutInMs});
255
+ });
239
256
  });
240
257
  });
241
258
  `;
@@ -1,11 +1,10 @@
1
1
  import type { FilePath } from '../../dt/index.js';
2
- import type { FSManager, Logger, ShellCommandExecutor } from '../../std/index.js';
2
+ import type { FSManager, ShellCommandExecutor } from '../../std/index.js';
3
3
  import type { AppTestSuiteRunner, Input } from '../workers/AppTestSuiteRunner.js';
4
4
  export declare class VitestAppTestSuiteRunner implements AppTestSuiteRunner {
5
5
  private fsManager;
6
- private logger;
7
6
  private shellCommandExecutor;
8
- constructor(fsManager: FSManager, logger: Logger, shellCommandExecutor: ShellCommandExecutor);
7
+ constructor(fsManager: FSManager, shellCommandExecutor: ShellCommandExecutor);
9
8
  exec({ appPath, skipCoverage, updateSnapshots, }: Input): Promise<void>;
10
9
  coverageReportEntrypointPath(appPath: FilePath): Promise<FilePath>;
11
10
  private coverageReportPath;
@@ -14,17 +14,16 @@ import { inject, injectable } from 'inversify';
14
14
  import { APP_TEST_DIR_NAME, APP_TEST_REPORTS_DIR_NAME, } from '../../convention.js';
15
15
  let VitestAppTestSuiteRunner = class VitestAppTestSuiteRunner {
16
16
  fsManager;
17
- logger;
18
17
  shellCommandExecutor;
19
- constructor(fsManager, logger, shellCommandExecutor) {
18
+ constructor(fsManager, shellCommandExecutor) {
20
19
  this.fsManager = fsManager;
21
- this.logger = logger;
22
20
  this.shellCommandExecutor = shellCommandExecutor;
23
21
  }
24
22
  async exec({ appPath, skipCoverage, updateSnapshots, }) {
25
23
  const testPath = this.fsManager.path(appPath, APP_TEST_DIR_NAME);
26
24
  const args = [
27
25
  'run',
26
+ '--color',
28
27
  '--dir',
29
28
  appPath,
30
29
  ];
@@ -34,13 +33,13 @@ let VitestAppTestSuiteRunner = class VitestAppTestSuiteRunner {
34
33
  if (updateSnapshots) {
35
34
  args.push('--update');
36
35
  }
37
- const output = await this.shellCommandExecutor.exec({
36
+ await this.shellCommandExecutor.exec({
38
37
  bin: './node_modules/.bin/vitest',
39
38
  opts: {
40
39
  args,
40
+ streamData: true,
41
41
  },
42
42
  });
43
- this.logger.info(output);
44
43
  }
45
44
  async coverageReportEntrypointPath(appPath) {
46
45
  return this.fsManager.path(this.coverageReportPath(appPath), 'index.html');
@@ -53,8 +52,7 @@ let VitestAppTestSuiteRunner = class VitestAppTestSuiteRunner {
53
52
  VitestAppTestSuiteRunner = __decorate([
54
53
  injectable(),
55
54
  __param(0, inject('FSManager')),
56
- __param(1, inject('Logger')),
57
- __param(2, inject('ShellCommandExecutor')),
58
- __metadata("design:paramtypes", [Object, Object, Object])
55
+ __param(1, inject('ShellCommandExecutor')),
56
+ __metadata("design:paramtypes", [Object, Object])
59
57
  ], VitestAppTestSuiteRunner);
60
58
  export { VitestAppTestSuiteRunner };
@@ -1,11 +1,13 @@
1
1
  import type { ErrorMessage } from '../../../dt/index.js';
2
2
  import type { Worker } from '../../../std/index.js';
3
+ import type { UCDef } from '../../../uc/index.js';
3
4
  import type { AppTesterUCDRef } from '../../ctx.js';
4
5
  export interface Input {
5
6
  ucdRef: AppTesterUCDRef;
6
7
  }
7
8
  export interface Output {
8
9
  errors: ErrorMessage[];
10
+ ucd: UCDef | null;
9
11
  }
10
12
  export declare class UCDefChecker implements Worker<Input, Promise<Output>> {
11
13
  private output;
@@ -15,7 +15,7 @@ const ERR_UCD_NAMES = (fileName, name, ucdKey) => `The file name and the const n
15
15
  let UCDefChecker = class UCDefChecker {
16
16
  output;
17
17
  constructor() {
18
- this.output = { errors: [] };
18
+ this.output = { errors: [], ucd: null };
19
19
  }
20
20
  async exec({ ucdRef }) {
21
21
  const { fileName, source } = ucdRef;
@@ -35,6 +35,9 @@ let UCDefChecker = class UCDefChecker {
35
35
  name !== ucdKey.replaceAll(UC_DEF_SUFFIX, '')) {
36
36
  this.output.errors.push(ERR_UCD_NAMES(fileName, name, ucdKey));
37
37
  }
38
+ if (this.output.errors.length === 0) {
39
+ this.output.ucd = ucd;
40
+ }
38
41
  return this.output;
39
42
  }
40
43
  };
@@ -1,6 +1,6 @@
1
1
  import type { AppName } from '../app/index.js';
2
2
  import type { UIntQuantity, UUID } from '../dt/index.js';
3
- import type { Clearable, StringKeys } from '../utils/index.js';
3
+ import type { Clearable, Initializable, StringKeys } from '../utils/index.js';
4
4
  import type { UCData } from './data.js';
5
5
  import type { UCExecMode } from './exec.js';
6
6
  import type { UCInput } from './input.js';
@@ -55,13 +55,12 @@ export interface UCDataStoreRecord<I extends UCInput | undefined = undefined, D
55
55
  organizationId: UUID | null;
56
56
  userId: UUID | null;
57
57
  }
58
- export interface UCDataStore extends Clearable {
58
+ export interface UCDataStore extends Clearable, Initializable {
59
59
  destroy(): Promise<void>;
60
60
  exists(): Promise<boolean>;
61
- initTx(): Promise<UCDataStoreTx['ref']>;
62
- install(): Promise<void>;
63
61
  read<I extends UCInput | undefined = undefined, D extends UCData | null = null>(opts?: UCDataStoreReadOpts<I, D>): Promise<UCDataStoreReadResponse<I, D>>;
64
62
  readProjection<T extends object>(name: string, opts?: UCDataStoreReadProjectionOpts<T>): Promise<T[]>;
63
+ startTx(): Promise<UCDataStoreTx['ref']>;
65
64
  supportedSpecificBindings(): UCDataStoreWriteProjectionSpecificBinding[];
66
65
  testKey(encryptionKey: Uint8Array): Promise<void>;
67
66
  write<I extends UCInput | undefined = undefined, D extends UCData | null = null>(record: UCDataStoreRecord<I, D>, opts?: UCDataStoreWriteOpts): Promise<void>;
@@ -51,6 +51,7 @@ export class UCOutputBuilder {
51
51
  const idx = this.output.parts._0.items.findIndex(predicate);
52
52
  if (idx > -1) {
53
53
  this.output.parts._0.items.splice(idx, 1);
54
+ this.output.parts._0.total -= 1;
54
55
  }
55
56
  return this;
56
57
  }
@@ -0,0 +1,34 @@
1
+ import type { D1Database } from '@cloudflare/workers-types';
2
+ import type { Configurable, SettingsManager } from '../../std/index.js';
3
+ import type { UCData } from '../data.js';
4
+ import type { UCDataStore, UCDataStoreReadOpts, UCDataStoreReadProjectionOpts, UCDataStoreReadResponse, UCDataStoreRecord, UCDataStoreTx, UCDataStoreWriteOpts, UCDataStoreWriteProjectionOpts, UCDataStoreWriteProjectionSpecificBinding } from '../data-store.js';
5
+ import type { UCInput } from '../input.js';
6
+ import type { UCSettings } from '../settings.js';
7
+ type S = Pick<UCSettings, 'uc_data_store_ucs_dataset_name'>;
8
+ export declare const ROW_COLS: (keyof UCDataStoreRecord)[];
9
+ /**
10
+ * @alpha This implementation is still a WIP and needs improvement
11
+ */
12
+ export declare class CloudflareD1UCDataStore implements Configurable<S>, UCDataStore {
13
+ protected settingsManager: SettingsManager<S>;
14
+ protected client?: D1Database | undefined;
15
+ constructor(settingsManager: SettingsManager<S>);
16
+ s(): S;
17
+ clear(): Promise<void>;
18
+ destroy(): Promise<void>;
19
+ exists(): Promise<boolean>;
20
+ init(): Promise<void>;
21
+ initSync(): void;
22
+ read<I extends UCInput | undefined = undefined, D extends UCData | null = null>(opts?: UCDataStoreReadOpts<I, D>): Promise<UCDataStoreReadResponse<I, D>>;
23
+ readProjection<T extends object>(_name: string, _opts?: UCDataStoreReadProjectionOpts<T>): Promise<T[]>;
24
+ startTx(): Promise<UCDataStoreTx['ref']>;
25
+ supportedSpecificBindings(): UCDataStoreWriteProjectionSpecificBinding[];
26
+ testKey(_encryptionKey: Uint8Array): Promise<void>;
27
+ write<I extends UCInput | undefined = undefined, D extends UCData | null = null>(record: UCDataStoreRecord<I, D>, _opts?: UCDataStoreWriteOpts): Promise<void>;
28
+ writeBulk<I extends UCInput | undefined = undefined, D extends UCData | null = null>(_records: UCDataStoreRecord<I, D>[], _opts?: UCDataStoreWriteOpts): Promise<void>;
29
+ writeProjection<T extends object>(_name: string, _data: T, _opts?: UCDataStoreWriteProjectionOpts): Promise<void>;
30
+ setClient(client: D1Database): void;
31
+ private assertClient;
32
+ private filter;
33
+ }
34
+ export {};