@objectstack/core 1.0.2 → 1.0.5

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 (125) hide show
  1. package/.turbo/turbo-build.log +58 -0
  2. package/CHANGELOG.md +25 -0
  3. package/dist/index.cjs +4294 -0
  4. package/dist/index.cjs.map +1 -0
  5. package/dist/index.d.cts +1777 -0
  6. package/dist/index.d.ts +1776 -21
  7. package/dist/index.js +4246 -23
  8. package/dist/index.js.map +1 -0
  9. package/package.json +4 -4
  10. package/tsconfig.json +1 -3
  11. package/dist/api-registry-plugin.d.ts +0 -54
  12. package/dist/api-registry-plugin.d.ts.map +0 -1
  13. package/dist/api-registry-plugin.js +0 -53
  14. package/dist/api-registry-plugin.test.d.ts +0 -2
  15. package/dist/api-registry-plugin.test.d.ts.map +0 -1
  16. package/dist/api-registry-plugin.test.js +0 -334
  17. package/dist/api-registry.d.ts +0 -259
  18. package/dist/api-registry.d.ts.map +0 -1
  19. package/dist/api-registry.js +0 -600
  20. package/dist/api-registry.test.d.ts +0 -2
  21. package/dist/api-registry.test.d.ts.map +0 -1
  22. package/dist/api-registry.test.js +0 -957
  23. package/dist/contracts/data-engine.d.ts +0 -62
  24. package/dist/contracts/data-engine.d.ts.map +0 -1
  25. package/dist/contracts/data-engine.js +0 -1
  26. package/dist/contracts/http-server.d.ts +0 -119
  27. package/dist/contracts/http-server.d.ts.map +0 -1
  28. package/dist/contracts/http-server.js +0 -11
  29. package/dist/contracts/logger.d.ts +0 -63
  30. package/dist/contracts/logger.d.ts.map +0 -1
  31. package/dist/contracts/logger.js +0 -1
  32. package/dist/dependency-resolver.d.ts +0 -62
  33. package/dist/dependency-resolver.d.ts.map +0 -1
  34. package/dist/dependency-resolver.js +0 -317
  35. package/dist/dependency-resolver.test.d.ts +0 -2
  36. package/dist/dependency-resolver.test.d.ts.map +0 -1
  37. package/dist/dependency-resolver.test.js +0 -241
  38. package/dist/health-monitor.d.ts +0 -65
  39. package/dist/health-monitor.d.ts.map +0 -1
  40. package/dist/health-monitor.js +0 -269
  41. package/dist/health-monitor.test.d.ts +0 -2
  42. package/dist/health-monitor.test.d.ts.map +0 -1
  43. package/dist/health-monitor.test.js +0 -68
  44. package/dist/hot-reload.d.ts +0 -79
  45. package/dist/hot-reload.d.ts.map +0 -1
  46. package/dist/hot-reload.js +0 -313
  47. package/dist/index.d.ts.map +0 -1
  48. package/dist/kernel-base.d.ts +0 -84
  49. package/dist/kernel-base.d.ts.map +0 -1
  50. package/dist/kernel-base.js +0 -219
  51. package/dist/kernel.d.ts +0 -113
  52. package/dist/kernel.d.ts.map +0 -1
  53. package/dist/kernel.js +0 -472
  54. package/dist/kernel.test.d.ts +0 -2
  55. package/dist/kernel.test.d.ts.map +0 -1
  56. package/dist/kernel.test.js +0 -414
  57. package/dist/lite-kernel.d.ts +0 -55
  58. package/dist/lite-kernel.d.ts.map +0 -1
  59. package/dist/lite-kernel.js +0 -112
  60. package/dist/lite-kernel.test.d.ts +0 -2
  61. package/dist/lite-kernel.test.d.ts.map +0 -1
  62. package/dist/lite-kernel.test.js +0 -161
  63. package/dist/logger.d.ts +0 -71
  64. package/dist/logger.d.ts.map +0 -1
  65. package/dist/logger.js +0 -312
  66. package/dist/logger.test.d.ts +0 -2
  67. package/dist/logger.test.d.ts.map +0 -1
  68. package/dist/logger.test.js +0 -92
  69. package/dist/plugin-loader.d.ts +0 -164
  70. package/dist/plugin-loader.d.ts.map +0 -1
  71. package/dist/plugin-loader.js +0 -319
  72. package/dist/plugin-loader.test.d.ts +0 -2
  73. package/dist/plugin-loader.test.d.ts.map +0 -1
  74. package/dist/plugin-loader.test.js +0 -348
  75. package/dist/qa/adapter.d.ts +0 -14
  76. package/dist/qa/adapter.d.ts.map +0 -1
  77. package/dist/qa/adapter.js +0 -1
  78. package/dist/qa/http-adapter.d.ts +0 -16
  79. package/dist/qa/http-adapter.d.ts.map +0 -1
  80. package/dist/qa/http-adapter.js +0 -107
  81. package/dist/qa/index.d.ts +0 -4
  82. package/dist/qa/index.d.ts.map +0 -1
  83. package/dist/qa/index.js +0 -3
  84. package/dist/qa/runner.d.ts +0 -27
  85. package/dist/qa/runner.d.ts.map +0 -1
  86. package/dist/qa/runner.js +0 -157
  87. package/dist/security/index.d.ts +0 -17
  88. package/dist/security/index.d.ts.map +0 -1
  89. package/dist/security/index.js +0 -17
  90. package/dist/security/permission-manager.d.ts +0 -96
  91. package/dist/security/permission-manager.d.ts.map +0 -1
  92. package/dist/security/permission-manager.js +0 -235
  93. package/dist/security/permission-manager.test.d.ts +0 -2
  94. package/dist/security/permission-manager.test.d.ts.map +0 -1
  95. package/dist/security/permission-manager.test.js +0 -220
  96. package/dist/security/plugin-config-validator.d.ts +0 -79
  97. package/dist/security/plugin-config-validator.d.ts.map +0 -1
  98. package/dist/security/plugin-config-validator.js +0 -166
  99. package/dist/security/plugin-config-validator.test.d.ts +0 -2
  100. package/dist/security/plugin-config-validator.test.d.ts.map +0 -1
  101. package/dist/security/plugin-config-validator.test.js +0 -223
  102. package/dist/security/plugin-permission-enforcer.d.ts +0 -154
  103. package/dist/security/plugin-permission-enforcer.d.ts.map +0 -1
  104. package/dist/security/plugin-permission-enforcer.js +0 -323
  105. package/dist/security/plugin-permission-enforcer.test.d.ts +0 -2
  106. package/dist/security/plugin-permission-enforcer.test.d.ts.map +0 -1
  107. package/dist/security/plugin-permission-enforcer.test.js +0 -205
  108. package/dist/security/plugin-signature-verifier.d.ts +0 -96
  109. package/dist/security/plugin-signature-verifier.d.ts.map +0 -1
  110. package/dist/security/plugin-signature-verifier.js +0 -250
  111. package/dist/security/sandbox-runtime.d.ts +0 -115
  112. package/dist/security/sandbox-runtime.d.ts.map +0 -1
  113. package/dist/security/sandbox-runtime.js +0 -311
  114. package/dist/security/security-scanner.d.ts +0 -92
  115. package/dist/security/security-scanner.d.ts.map +0 -1
  116. package/dist/security/security-scanner.js +0 -273
  117. package/dist/types.d.ts +0 -89
  118. package/dist/types.d.ts.map +0 -1
  119. package/dist/types.js +0 -1
  120. package/dist/utils/env.d.ts +0 -20
  121. package/dist/utils/env.d.ts.map +0 -1
  122. package/dist/utils/env.js +0 -46
  123. package/dist/utils/env.test.d.ts +0 -2
  124. package/dist/utils/env.test.d.ts.map +0 -1
  125. package/dist/utils/env.test.js +0 -52
@@ -1,348 +0,0 @@
1
- import { describe, it, expect, beforeEach } from 'vitest';
2
- import { PluginLoader, ServiceLifecycle } from './plugin-loader';
3
- import { createLogger } from './logger';
4
- describe('PluginLoader', () => {
5
- let loader;
6
- beforeEach(() => {
7
- const logger = createLogger({ level: 'error' }); // Suppress logs in tests
8
- loader = new PluginLoader(logger);
9
- loader.setContext({
10
- registerService: () => { },
11
- getService: () => { throw new Error('Mock service not found'); },
12
- hook: () => { },
13
- trigger: async () => { },
14
- getServices: () => new Map(),
15
- logger: logger,
16
- getKernel: () => ({})
17
- });
18
- });
19
- describe('Plugin Loading', () => {
20
- it('should load a valid plugin', async () => {
21
- const plugin = {
22
- name: 'test-plugin',
23
- version: '1.0.0',
24
- init: async () => { },
25
- };
26
- const result = await loader.loadPlugin(plugin);
27
- expect(result.success).toBe(true);
28
- expect(result.plugin?.name).toBe('test-plugin');
29
- expect(result.plugin?.version).toBe('1.0.0');
30
- expect(result.loadTime).toBeGreaterThanOrEqual(0);
31
- });
32
- it('should reject plugin with invalid name', async () => {
33
- const plugin = {
34
- name: '',
35
- init: async () => { },
36
- };
37
- const result = await loader.loadPlugin(plugin);
38
- expect(result.success).toBe(false);
39
- expect(result.error?.message).toContain('name is required');
40
- });
41
- it('should reject plugin without init function', async () => {
42
- const plugin = {
43
- name: 'invalid-plugin',
44
- };
45
- const result = await loader.loadPlugin(plugin);
46
- expect(result.success).toBe(false);
47
- expect(result.error?.message).toContain('init function is required');
48
- });
49
- it('should use default version 0.0.0 if not provided', async () => {
50
- const plugin = {
51
- name: 'no-version',
52
- init: async () => { },
53
- };
54
- const result = await loader.loadPlugin(plugin);
55
- expect(result.success).toBe(true);
56
- expect(result.plugin?.version).toBe('0.0.0');
57
- });
58
- });
59
- describe('Version Compatibility', () => {
60
- it('should accept valid semantic versions', async () => {
61
- const validVersions = ['1.0.0', '2.3.4', '0.0.1', '10.20.30'];
62
- for (const version of validVersions) {
63
- const plugin = {
64
- name: `plugin-${version}`,
65
- version,
66
- init: async () => { },
67
- };
68
- const result = await loader.loadPlugin(plugin);
69
- expect(result.success).toBe(true);
70
- }
71
- });
72
- it('should accept versions with pre-release tags', async () => {
73
- const plugin = {
74
- name: 'prerelease',
75
- version: '1.0.0-alpha.1',
76
- init: async () => { },
77
- };
78
- const result = await loader.loadPlugin(plugin);
79
- expect(result.success).toBe(true);
80
- });
81
- it('should accept versions with build metadata', async () => {
82
- const plugin = {
83
- name: 'build-meta',
84
- version: '1.0.0+20230101',
85
- init: async () => { },
86
- };
87
- const result = await loader.loadPlugin(plugin);
88
- expect(result.success).toBe(true);
89
- });
90
- it('should reject invalid semantic versions', async () => {
91
- const invalidVersions = ['1.0', 'v1.0.0', '1', 'invalid'];
92
- for (const version of invalidVersions) {
93
- const plugin = {
94
- name: `invalid-${version}`,
95
- version,
96
- init: async () => { },
97
- };
98
- const result = await loader.loadPlugin(plugin);
99
- expect(result.success).toBe(false);
100
- }
101
- });
102
- });
103
- describe('Service Factory Registration', () => {
104
- it('should register a singleton service factory', () => {
105
- let callCount = 0;
106
- const factory = () => {
107
- callCount++;
108
- return { value: callCount };
109
- };
110
- loader.registerServiceFactory({
111
- name: 'singleton-service',
112
- factory,
113
- lifecycle: ServiceLifecycle.SINGLETON,
114
- });
115
- expect(() => {
116
- loader.registerServiceFactory({
117
- name: 'singleton-service',
118
- factory,
119
- lifecycle: ServiceLifecycle.SINGLETON,
120
- });
121
- }).toThrow('already registered');
122
- });
123
- it('should register multiple service factories with different names', () => {
124
- loader.registerServiceFactory({
125
- name: 'service-1',
126
- factory: () => ({ id: 1 }),
127
- lifecycle: ServiceLifecycle.SINGLETON,
128
- });
129
- loader.registerServiceFactory({
130
- name: 'service-2',
131
- factory: () => ({ id: 2 }),
132
- lifecycle: ServiceLifecycle.TRANSIENT,
133
- });
134
- // Should not throw
135
- expect(true).toBe(true);
136
- });
137
- });
138
- describe('Service Retrieval with Lifecycle', () => {
139
- it('should create singleton service only once', async () => {
140
- let callCount = 0;
141
- loader.registerServiceFactory({
142
- name: 'counter',
143
- factory: () => {
144
- callCount++;
145
- return { count: callCount };
146
- },
147
- lifecycle: ServiceLifecycle.SINGLETON,
148
- });
149
- const service1 = await loader.getService('counter');
150
- const service2 = await loader.getService('counter');
151
- expect(callCount).toBe(1);
152
- expect(service1).toBe(service2);
153
- });
154
- it('should create new transient service on each request', async () => {
155
- let callCount = 0;
156
- loader.registerServiceFactory({
157
- name: 'transient',
158
- factory: () => {
159
- callCount++;
160
- return { count: callCount };
161
- },
162
- lifecycle: ServiceLifecycle.TRANSIENT,
163
- });
164
- const service1 = await loader.getService('transient');
165
- const service2 = await loader.getService('transient');
166
- expect(callCount).toBe(2);
167
- expect(service1).not.toBe(service2);
168
- expect(service1.count).toBe(1);
169
- expect(service2.count).toBe(2);
170
- });
171
- it('should create scoped service once per scope', async () => {
172
- let callCount = 0;
173
- loader.registerServiceFactory({
174
- name: 'scoped',
175
- factory: () => {
176
- callCount++;
177
- return { count: callCount };
178
- },
179
- lifecycle: ServiceLifecycle.SCOPED,
180
- });
181
- const scope1Service1 = await loader.getService('scoped', 'scope-1');
182
- const scope1Service2 = await loader.getService('scoped', 'scope-1');
183
- const scope2Service1 = await loader.getService('scoped', 'scope-2');
184
- expect(callCount).toBe(2); // Once per scope
185
- expect(scope1Service1).toBe(scope1Service2); // Same within scope
186
- expect(scope1Service1).not.toBe(scope2Service1); // Different across scopes
187
- });
188
- it('should throw error for scoped service without scope ID', async () => {
189
- loader.registerServiceFactory({
190
- name: 'scoped-no-id',
191
- factory: () => ({ value: 'test' }),
192
- lifecycle: ServiceLifecycle.SCOPED,
193
- });
194
- await expect(async () => {
195
- await loader.getService('scoped-no-id');
196
- }).rejects.toThrow('Scope ID required');
197
- });
198
- it('should throw error for non-existent service', async () => {
199
- await expect(async () => {
200
- await loader.getService('non-existent');
201
- }).rejects.toThrow('not found');
202
- });
203
- });
204
- describe('Circular Dependency Detection', () => {
205
- it('should detect simple circular dependency', () => {
206
- loader.registerServiceFactory({
207
- name: 'service-a',
208
- factory: () => ({}),
209
- lifecycle: ServiceLifecycle.SINGLETON,
210
- dependencies: ['service-b'],
211
- });
212
- loader.registerServiceFactory({
213
- name: 'service-b',
214
- factory: () => ({}),
215
- lifecycle: ServiceLifecycle.SINGLETON,
216
- dependencies: ['service-a'],
217
- });
218
- const cycles = loader.detectCircularDependencies();
219
- expect(cycles.length).toBeGreaterThan(0);
220
- expect(cycles[0]).toContain('service-a');
221
- expect(cycles[0]).toContain('service-b');
222
- });
223
- it('should detect complex circular dependency', () => {
224
- loader.registerServiceFactory({
225
- name: 'service-a',
226
- factory: () => ({}),
227
- lifecycle: ServiceLifecycle.SINGLETON,
228
- dependencies: ['service-b'],
229
- });
230
- loader.registerServiceFactory({
231
- name: 'service-b',
232
- factory: () => ({}),
233
- lifecycle: ServiceLifecycle.SINGLETON,
234
- dependencies: ['service-c'],
235
- });
236
- loader.registerServiceFactory({
237
- name: 'service-c',
238
- factory: () => ({}),
239
- lifecycle: ServiceLifecycle.SINGLETON,
240
- dependencies: ['service-a'],
241
- });
242
- const cycles = loader.detectCircularDependencies();
243
- expect(cycles.length).toBeGreaterThan(0);
244
- });
245
- it('should not report false positives for valid dependency chains', () => {
246
- loader.registerServiceFactory({
247
- name: 'service-a',
248
- factory: () => ({}),
249
- lifecycle: ServiceLifecycle.SINGLETON,
250
- dependencies: ['service-b'],
251
- });
252
- loader.registerServiceFactory({
253
- name: 'service-b',
254
- factory: () => ({}),
255
- lifecycle: ServiceLifecycle.SINGLETON,
256
- dependencies: ['service-c'],
257
- });
258
- loader.registerServiceFactory({
259
- name: 'service-c',
260
- factory: () => ({}),
261
- lifecycle: ServiceLifecycle.SINGLETON,
262
- });
263
- const cycles = loader.detectCircularDependencies();
264
- expect(cycles.length).toBe(0);
265
- });
266
- });
267
- describe('Plugin Health Checks', () => {
268
- it('should return healthy for plugin without health check', async () => {
269
- const plugin = {
270
- name: 'no-health-check',
271
- version: '1.0.0',
272
- init: async () => { },
273
- };
274
- await loader.loadPlugin(plugin);
275
- const health = await loader.checkPluginHealth('no-health-check');
276
- expect(health.healthy).toBe(true);
277
- expect(health.message).toContain('No health check');
278
- });
279
- it('should execute plugin health check', async () => {
280
- const plugin = {
281
- name: 'with-health-check',
282
- version: '1.0.0',
283
- init: async () => { },
284
- healthCheck: async () => ({
285
- healthy: true,
286
- message: 'All systems operational',
287
- }),
288
- };
289
- await loader.loadPlugin(plugin);
290
- const health = await loader.checkPluginHealth('with-health-check');
291
- expect(health.healthy).toBe(true);
292
- expect(health.message).toBe('All systems operational');
293
- expect(health.lastCheck).toBeInstanceOf(Date);
294
- });
295
- it('should handle failing health check', async () => {
296
- const plugin = {
297
- name: 'failing-health',
298
- version: '1.0.0',
299
- init: async () => { },
300
- healthCheck: async () => {
301
- throw new Error('Service unavailable');
302
- },
303
- };
304
- await loader.loadPlugin(plugin);
305
- const health = await loader.checkPluginHealth('failing-health');
306
- expect(health.healthy).toBe(false);
307
- expect(health.message).toContain('Health check failed');
308
- });
309
- it('should return not found for unknown plugin', async () => {
310
- const health = await loader.checkPluginHealth('unknown-plugin');
311
- expect(health.healthy).toBe(false);
312
- expect(health.message).toContain('not found');
313
- });
314
- });
315
- describe('Scope Management', () => {
316
- it('should clear scoped services', async () => {
317
- let callCount = 0;
318
- loader.registerServiceFactory({
319
- name: 'scoped-clear',
320
- factory: () => {
321
- callCount++;
322
- return { count: callCount };
323
- },
324
- lifecycle: ServiceLifecycle.SCOPED,
325
- });
326
- const service1 = await loader.getService('scoped-clear', 'scope-1');
327
- expect(service1.count).toBe(1);
328
- loader.clearScope('scope-1');
329
- const service2 = await loader.getService('scoped-clear', 'scope-1');
330
- expect(service2.count).toBe(2); // New instance created
331
- });
332
- });
333
- describe('Static Service Registration', () => {
334
- it('should register static service instance', () => {
335
- const service = { value: 'test' };
336
- loader.registerService('static-service', service);
337
- expect(() => {
338
- loader.registerService('static-service', service);
339
- }).toThrow('already registered');
340
- });
341
- it('should retrieve static service', async () => {
342
- const service = { value: 'static' };
343
- loader.registerService('static', service);
344
- const retrieved = await loader.getService('static');
345
- expect(retrieved).toBe(service);
346
- });
347
- });
348
- });
@@ -1,14 +0,0 @@
1
- import { QA } from '@objectstack/spec';
2
- /**
3
- * Interface for executing test actions against a target system.
4
- * The target could be a local Kernel instance or a remote API.
5
- */
6
- export interface TestExecutionAdapter {
7
- /**
8
- * Execute a single test action.
9
- * @param action The action to perform (create_record, api_call, etc.)
10
- * @returns The result of the action (e.g. created record, API response)
11
- */
12
- execute(action: QA.TestAction, context: Record<string, unknown>): Promise<unknown>;
13
- }
14
- //# sourceMappingURL=adapter.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../src/qa/adapter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,mBAAmB,CAAC;AAEvC;;;GAGG;AACH,MAAM,WAAW,oBAAoB;IACnC;;;;OAIG;IACH,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,UAAU,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACpF"}
@@ -1 +0,0 @@
1
- export {};
@@ -1,16 +0,0 @@
1
- import { QA } from '@objectstack/spec';
2
- import { TestExecutionAdapter } from './adapter.js';
3
- export declare class HttpTestAdapter implements TestExecutionAdapter {
4
- private baseUrl;
5
- private authToken?;
6
- constructor(baseUrl: string, authToken?: string | undefined);
7
- execute(action: QA.TestAction, _context: Record<string, unknown>): Promise<unknown>;
8
- private createRecord;
9
- private updateRecord;
10
- private deleteRecord;
11
- private readRecord;
12
- private queryRecords;
13
- private rawApiCall;
14
- private handleResponse;
15
- }
16
- //# sourceMappingURL=http-adapter.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"http-adapter.d.ts","sourceRoot":"","sources":["../../src/qa/http-adapter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,mBAAmB,CAAC;AACvC,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAEpD,qBAAa,eAAgB,YAAW,oBAAoB;IAC9C,OAAO,CAAC,OAAO;IAAU,OAAO,CAAC,SAAS,CAAC;gBAAnC,OAAO,EAAE,MAAM,EAAU,SAAS,CAAC,EAAE,MAAM,YAAA;IAEzD,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,UAAU,EAAE,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC;YAiC3E,YAAY;YASZ,YAAY;YAWZ,YAAY;YAUZ,UAAU;YAUV,YAAY;YAUZ,UAAU;YAaV,cAAc;CAW7B"}
@@ -1,107 +0,0 @@
1
- export class HttpTestAdapter {
2
- constructor(baseUrl, authToken) {
3
- this.baseUrl = baseUrl;
4
- this.authToken = authToken;
5
- }
6
- async execute(action, _context) {
7
- const headers = {
8
- 'Content-Type': 'application/json',
9
- };
10
- if (this.authToken) {
11
- headers['Authorization'] = `Bearer ${this.authToken}`;
12
- }
13
- // If action.user is specified, maybe add a specific header for impersonation if supported?
14
- if (action.user) {
15
- headers['X-Run-As'] = action.user;
16
- }
17
- switch (action.type) {
18
- case 'create_record':
19
- return this.createRecord(action.target, action.payload || {}, headers);
20
- case 'update_record':
21
- return this.updateRecord(action.target, action.payload || {}, headers);
22
- case 'delete_record':
23
- return this.deleteRecord(action.target, action.payload || {}, headers);
24
- case 'read_record':
25
- return this.readRecord(action.target, action.payload || {}, headers);
26
- case 'query_records':
27
- return this.queryRecords(action.target, action.payload || {}, headers);
28
- case 'api_call':
29
- return this.rawApiCall(action.target, action.payload || {}, headers);
30
- case 'wait':
31
- const ms = Number(action.payload?.duration || 1000);
32
- return new Promise(resolve => setTimeout(() => resolve({ waited: ms }), ms));
33
- default:
34
- throw new Error(`Unsupported action type in HttpAdapter: ${action.type}`);
35
- }
36
- }
37
- async createRecord(objectName, data, headers) {
38
- const response = await fetch(`${this.baseUrl}/api/data/${objectName}`, {
39
- method: 'POST',
40
- headers,
41
- body: JSON.stringify(data)
42
- });
43
- return this.handleResponse(response);
44
- }
45
- async updateRecord(objectName, data, headers) {
46
- const id = data._id || data.id;
47
- if (!id)
48
- throw new Error('Update record requires _id or id in payload');
49
- const response = await fetch(`${this.baseUrl}/api/data/${objectName}/${id}`, {
50
- method: 'PUT',
51
- headers,
52
- body: JSON.stringify(data)
53
- });
54
- return this.handleResponse(response);
55
- }
56
- async deleteRecord(objectName, data, headers) {
57
- const id = data._id || data.id;
58
- if (!id)
59
- throw new Error('Delete record requires _id or id in payload');
60
- const response = await fetch(`${this.baseUrl}/api/data/${objectName}/${id}`, {
61
- method: 'DELETE',
62
- headers
63
- });
64
- return this.handleResponse(response);
65
- }
66
- async readRecord(objectName, data, headers) {
67
- const id = data._id || data.id;
68
- if (!id)
69
- throw new Error('Read record requires _id or id in payload');
70
- const response = await fetch(`${this.baseUrl}/api/data/${objectName}/${id}`, {
71
- method: 'GET',
72
- headers
73
- });
74
- return this.handleResponse(response);
75
- }
76
- async queryRecords(objectName, data, headers) {
77
- // Assuming query via POST or GraphQL-like endpoint
78
- const response = await fetch(`${this.baseUrl}/api/data/${objectName}/query`, {
79
- method: 'POST',
80
- headers,
81
- body: JSON.stringify(data)
82
- });
83
- return this.handleResponse(response);
84
- }
85
- async rawApiCall(endpoint, data, headers) {
86
- const method = data.method || 'GET';
87
- const body = data.body ? JSON.stringify(data.body) : undefined;
88
- const url = endpoint.startsWith('http') ? endpoint : `${this.baseUrl}${endpoint}`;
89
- const response = await fetch(url, {
90
- method,
91
- headers,
92
- body
93
- });
94
- return this.handleResponse(response);
95
- }
96
- async handleResponse(response) {
97
- if (!response.ok) {
98
- const text = await response.text();
99
- throw new Error(`HTTP Error ${response.status}: ${text}`);
100
- }
101
- const contentType = response.headers.get('content-type');
102
- if (contentType && contentType.includes('application/json')) {
103
- return response.json();
104
- }
105
- return response.text();
106
- }
107
- }
@@ -1,4 +0,0 @@
1
- export * from './adapter.js';
2
- export * from './runner.js';
3
- export * from './http-adapter.js';
4
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/qa/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,mBAAmB,CAAC"}
package/dist/qa/index.js DELETED
@@ -1,3 +0,0 @@
1
- export * from './adapter.js';
2
- export * from './runner.js';
3
- export * from './http-adapter.js';
@@ -1,27 +0,0 @@
1
- import { QA } from '@objectstack/spec';
2
- import { TestExecutionAdapter } from './adapter.js';
3
- export interface TestResult {
4
- scenarioId: string;
5
- passed: boolean;
6
- steps: StepResult[];
7
- error?: unknown;
8
- duration: number;
9
- }
10
- export interface StepResult {
11
- stepName: string;
12
- passed: boolean;
13
- error?: unknown;
14
- output?: unknown;
15
- duration: number;
16
- }
17
- export declare class TestRunner {
18
- private adapter;
19
- constructor(adapter: TestExecutionAdapter);
20
- runSuite(suite: QA.TestSuite): Promise<TestResult[]>;
21
- runScenario(scenario: QA.TestScenario): Promise<TestResult>;
22
- private runStep;
23
- private resolveVariables;
24
- private getValueByPath;
25
- private assert;
26
- }
27
- //# sourceMappingURL=runner.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../src/qa/runner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,mBAAmB,CAAC;AACvC,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAEpD,MAAM,WAAW,UAAU;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,OAAO,CAAC;IAChB,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC;IAChB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,qBAAa,UAAU;IACT,OAAO,CAAC,OAAO;gBAAP,OAAO,EAAE,oBAAoB;IAE3C,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAC,SAAS,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;IAQpD,WAAW,CAAC,QAAQ,EAAE,EAAE,CAAC,YAAY,GAAG,OAAO,CAAC,UAAU,CAAC;YA4EnD,OAAO;IAyBrB,OAAO,CAAC,gBAAgB;IAMxB,OAAO,CAAC,cAAc;IAWtB,OAAO,CAAC,MAAM;CA8Bf"}