@constantant/openapi-resource-mocks 0.1.1
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.
- package/CHANGELOG.md +12 -0
- package/README.md +293 -0
- package/package.json +29 -0
- package/src/index.d.ts +7 -0
- package/src/index.js +13 -0
- package/src/index.js.map +1 -0
- package/src/lib/inject-mock-resource.d.ts +2 -0
- package/src/lib/inject-mock-resource.js +16 -0
- package/src/lib/inject-mock-resource.js.map +1 -0
- package/src/lib/mock-events.d.ts +30 -0
- package/src/lib/mock-events.js +3 -0
- package/src/lib/mock-events.js.map +1 -0
- package/src/lib/mock-resource-bus.d.ts +34 -0
- package/src/lib/mock-resource-bus.js +94 -0
- package/src/lib/mock-resource-bus.js.map +1 -0
- package/src/lib/mock-resource-ref.d.ts +35 -0
- package/src/lib/mock-resource-ref.js +91 -0
- package/src/lib/mock-resource-ref.js.map +1 -0
- package/src/lib/provide-mock-resource.d.ts +4 -0
- package/src/lib/provide-mock-resource.js +21 -0
- package/src/lib/provide-mock-resource.js.map +1 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
## 0.1.1 (2026-06-08)
|
|
2
|
+
|
|
3
|
+
### 🩹 Fixes
|
|
4
|
+
|
|
5
|
+
- **openapi-resource-mocks:** add comment to empty destroy() to satisfy no-empty-function lint rule ([868fb39](https://github.com/constantant/angular-openapi-gen/commit/868fb39))
|
|
6
|
+
|
|
7
|
+
### ❤️ Thank You
|
|
8
|
+
|
|
9
|
+
- Claude Sonnet 4.6
|
|
10
|
+
- kk
|
|
11
|
+
|
|
12
|
+
# Changelog
|
package/README.md
ADDED
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
# @constantant/openapi-resource-mocks
|
|
2
|
+
|
|
3
|
+
Mock bus for [`@constantant/openapi-resource-gen`](https://www.npmjs.com/package/@constantant/openapi-resource-gen) tokens.
|
|
4
|
+
|
|
5
|
+
Provides zero-HTTP, pure-DI mocks for Angular `InjectionToken`-based data-access libs — with a cross-boundary API so **Playwright E2E tests** and a future **Chrome Extension devtools panel** can observe and control every token's state from outside the Angular context.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Install
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm install -D @constantant/openapi-resource-mocks
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Peer dependencies: `@angular/core >=22`, `@angular/common >=22`.
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Core concept
|
|
20
|
+
|
|
21
|
+
Each mock token is registered in a `MockResourceBus`. The bus:
|
|
22
|
+
|
|
23
|
+
- Exposes `window.__openApiMocks__` — a plain object keyed by token name, accessible from Playwright's `page.evaluate()` or a Chrome Extension content script.
|
|
24
|
+
- Emits DOM events (`openapi-mock-event`) on every state change so the extension can observe in real time.
|
|
25
|
+
- Listens for DOM events (`openapi-mock-control`) so the extension can push data into the app.
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## Setup
|
|
30
|
+
|
|
31
|
+
Add `provideMockResourceBus()` once, then one `provideMockResource()` per token:
|
|
32
|
+
|
|
33
|
+
```typescript
|
|
34
|
+
// app.config.mock.ts (used in tests / E2E variant)
|
|
35
|
+
import { provideMockResourceBus, provideMockResource } from '@constantant/openapi-resource-mocks';
|
|
36
|
+
import { FIND_PETS_BY_STATUS, UPLOAD_FILE } from '@myapp/petstore-data-access';
|
|
37
|
+
|
|
38
|
+
export const mockProviders = [
|
|
39
|
+
provideMockResourceBus(),
|
|
40
|
+
provideMockResource(FIND_PETS_BY_STATUS, 'FIND_PETS_BY_STATUS'),
|
|
41
|
+
provideMockResource(UPLOAD_FILE, 'UPLOAD_FILE'),
|
|
42
|
+
];
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## Unit tests / Storybook (in-process control)
|
|
48
|
+
|
|
49
|
+
```typescript
|
|
50
|
+
import { TestBed } from '@angular/core/testing';
|
|
51
|
+
import { injectMockResource, provideMockResourceBus, provideMockResource } from '@constantant/openapi-resource-mocks';
|
|
52
|
+
import type { FindPetsByStatusResponse } from '@myapp/petstore-data-access';
|
|
53
|
+
|
|
54
|
+
TestBed.configureTestingModule({
|
|
55
|
+
providers: [
|
|
56
|
+
provideMockResourceBus(),
|
|
57
|
+
provideMockResource(FIND_PETS_BY_STATUS, 'FIND_PETS_BY_STATUS'),
|
|
58
|
+
],
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
const mock = TestBed.runInInjectionContext(() =>
|
|
62
|
+
injectMockResource<FindPetsByStatusResponse>('FIND_PETS_BY_STATUS'),
|
|
63
|
+
);
|
|
64
|
+
|
|
65
|
+
// Preset states
|
|
66
|
+
mock.resolve([{ id: 1, name: 'Rex', status: 'available' }]);
|
|
67
|
+
mock.setLoading();
|
|
68
|
+
mock.fail(new Error('network'));
|
|
69
|
+
mock.reset();
|
|
70
|
+
|
|
71
|
+
// Delayed response (loading → data after 500 ms)
|
|
72
|
+
mock.resolveAfter(500, []);
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Types come from the generated lib — no hand-written interfaces needed.
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
## File upload / download progress
|
|
80
|
+
|
|
81
|
+
### In-process (unit tests / Storybook)
|
|
82
|
+
|
|
83
|
+
```typescript
|
|
84
|
+
const mock = TestBed.runInInjectionContext(() =>
|
|
85
|
+
injectMockResource<UploadResponse>('UPLOAD_FILE'),
|
|
86
|
+
);
|
|
87
|
+
|
|
88
|
+
// Animate through 10 steps over 2 s, then resolve
|
|
89
|
+
mock.simulateProgress('upload', 4_000_000, 2000, { id: 'abc123' });
|
|
90
|
+
|
|
91
|
+
// Or drive progress manually for precise test control
|
|
92
|
+
mock.setProgress('upload', 1_000_000, 4_000_000); // 25 %
|
|
93
|
+
mock.setProgress('upload', 4_000_000, 4_000_000); // 100 %
|
|
94
|
+
mock.resolve({ id: 'abc123' });
|
|
95
|
+
|
|
96
|
+
// Download progress (total unknown — streaming)
|
|
97
|
+
mock.setProgress('download', 16_384);
|
|
98
|
+
|
|
99
|
+
// Simulate failure mid-upload — progress is preserved so the UI can show "failed at 25%"
|
|
100
|
+
mock.setProgress('upload', 1_000_000, 4_000_000);
|
|
101
|
+
mock.fail(new Error('connection reset'));
|
|
102
|
+
console.log(mock.progress()); // { type: 'upload', loaded: 1_000_000, total: 4_000_000 }
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### E2E (Playwright)
|
|
106
|
+
|
|
107
|
+
```typescript
|
|
108
|
+
// Animate upload progress then resolve
|
|
109
|
+
await page.evaluate(() =>
|
|
110
|
+
window.__openApiMocks__['UPLOAD_FILE'].simulateProgress('upload', 4_000_000, 2000, { id: 'abc123' }),
|
|
111
|
+
);
|
|
112
|
+
await expect(page.locator('[data-testid="progress-bar"]')).toBeVisible();
|
|
113
|
+
|
|
114
|
+
// Manual steps
|
|
115
|
+
await page.evaluate(() =>
|
|
116
|
+
window.__openApiMocks__['UPLOAD_FILE'].setProgress('upload', 1_000_000, 4_000_000),
|
|
117
|
+
);
|
|
118
|
+
await expect(page.locator('[data-testid="progress-bar"]')).toHaveAttribute('aria-valuenow', '25');
|
|
119
|
+
|
|
120
|
+
// Fail mid-upload
|
|
121
|
+
await page.evaluate(() => window.__openApiMocks__['UPLOAD_FILE'].fail(new Error('timeout')));
|
|
122
|
+
const state = await page.evaluate(() => window.__openApiMocks__['UPLOAD_FILE'].getState());
|
|
123
|
+
console.log(state.progress); // { type: 'upload', loaded: 1_000_000, total: 4_000_000 }
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### Chrome Extension → app
|
|
127
|
+
|
|
128
|
+
```javascript
|
|
129
|
+
// Animate upload
|
|
130
|
+
document.dispatchEvent(new CustomEvent('openapi-mock-control', {
|
|
131
|
+
detail: {
|
|
132
|
+
key: 'UPLOAD_FILE',
|
|
133
|
+
action: 'simulateProgress',
|
|
134
|
+
progressType: 'upload',
|
|
135
|
+
total: 4_000_000,
|
|
136
|
+
delayMs: 2000,
|
|
137
|
+
value: { id: 'abc123' },
|
|
138
|
+
steps: 20, // optional, default 10
|
|
139
|
+
},
|
|
140
|
+
}));
|
|
141
|
+
|
|
142
|
+
// Single progress step
|
|
143
|
+
document.dispatchEvent(new CustomEvent('openapi-mock-control', {
|
|
144
|
+
detail: { key: 'UPLOAD_FILE', action: 'setProgress', progressType: 'download', loaded: 512, total: 1024 },
|
|
145
|
+
}));
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
---
|
|
149
|
+
|
|
150
|
+
## E2E tests (Playwright)
|
|
151
|
+
|
|
152
|
+
```typescript
|
|
153
|
+
// Resolve with data
|
|
154
|
+
await page.evaluate(() =>
|
|
155
|
+
window.__openApiMocks__['FIND_PETS_BY_STATUS'].resolve([
|
|
156
|
+
{ id: 1, name: 'Rex', status: 'available' },
|
|
157
|
+
]),
|
|
158
|
+
);
|
|
159
|
+
await expect(page.locator('mat-row')).toHaveCount(1);
|
|
160
|
+
|
|
161
|
+
// Test loading skeleton
|
|
162
|
+
await page.evaluate(() => window.__openApiMocks__['FIND_PETS_BY_STATUS'].setLoading());
|
|
163
|
+
await expect(page.locator('mat-progress-bar')).toBeVisible();
|
|
164
|
+
|
|
165
|
+
// Simulate slow network
|
|
166
|
+
await page.evaluate(() =>
|
|
167
|
+
window.__openApiMocks__['FIND_PETS_BY_STATUS'].resolveAfter(1000, []),
|
|
168
|
+
);
|
|
169
|
+
|
|
170
|
+
// Inspect current state (includes progress if active)
|
|
171
|
+
const state = await page.evaluate(() =>
|
|
172
|
+
window.__openApiMocks__['FIND_PETS_BY_STATUS'].getState(),
|
|
173
|
+
);
|
|
174
|
+
|
|
175
|
+
// Full event history (requests + responses + progress ticks)
|
|
176
|
+
const history = await page.evaluate(() =>
|
|
177
|
+
window.__openApiMocks__['FIND_PETS_BY_STATUS'].getHistory(),
|
|
178
|
+
);
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
---
|
|
182
|
+
|
|
183
|
+
## Chrome Extension integration
|
|
184
|
+
|
|
185
|
+
**Extension content script → app (control):**
|
|
186
|
+
|
|
187
|
+
```javascript
|
|
188
|
+
document.dispatchEvent(new CustomEvent('openapi-mock-control', {
|
|
189
|
+
detail: { key: 'FIND_PETS_BY_STATUS', action: 'resolve', value: [...] },
|
|
190
|
+
}));
|
|
191
|
+
// actions: resolve | resolveAfter | setLoading | fail | reset
|
|
192
|
+
// setProgress | simulateProgress
|
|
193
|
+
// resolveAfter: delayMs: number
|
|
194
|
+
// setProgress: progressType: 'upload'|'download', loaded: number, total?: number
|
|
195
|
+
// simulateProgress: progressType, total: number, delayMs: number, value, steps?: number
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
**App → extension (observe):**
|
|
199
|
+
|
|
200
|
+
```javascript
|
|
201
|
+
document.addEventListener('openapi-mock-event', (e) => {
|
|
202
|
+
const { key, event } = e.detail;
|
|
203
|
+
// event.type: 'request' | 'resolve' | 'loading' | 'error' | 'reset' | 'progress'
|
|
204
|
+
devtoolsPanel.update(key, event);
|
|
205
|
+
});
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
---
|
|
209
|
+
|
|
210
|
+
## API reference
|
|
211
|
+
|
|
212
|
+
### `provideMockResourceBus()`
|
|
213
|
+
|
|
214
|
+
Returns `EnvironmentProviders`. Call once in your root providers or TestBed setup.
|
|
215
|
+
|
|
216
|
+
### `provideMockResource(token, key, initialState?)`
|
|
217
|
+
|
|
218
|
+
Returns `FactoryProvider`. Registers `token` in the bus under `key`.
|
|
219
|
+
|
|
220
|
+
`initialState` can be `{ value: T }`, `{ loading: true }`, or `{ error: unknown }`.
|
|
221
|
+
|
|
222
|
+
### `injectMockResource<T>(key)`
|
|
223
|
+
|
|
224
|
+
Must be called inside an injection context (e.g. `TestBed.runInInjectionContext`). Returns `MockResourceRef<T>`.
|
|
225
|
+
|
|
226
|
+
### `createMockResourceRef<T>(initialState?)`
|
|
227
|
+
|
|
228
|
+
Creates a standalone ref without the bus — useful when passing the ref to `provideMockResource` yourself for fine-grained test setup.
|
|
229
|
+
|
|
230
|
+
### `MockResourceRef<T>`
|
|
231
|
+
|
|
232
|
+
| Member | Description |
|
|
233
|
+
|--------|-------------|
|
|
234
|
+
| `value: Signal<T \| undefined>` | Current response data |
|
|
235
|
+
| `status: Signal<ResourceStatus>` | `'idle' \| 'loading' \| 'reloading' \| 'resolved' \| 'error' \| 'local'` |
|
|
236
|
+
| `error: Signal<unknown>` | Current error, if any |
|
|
237
|
+
| `isLoading: Signal<boolean>` | `true` while status is `'loading'` or `'reloading'` |
|
|
238
|
+
| `progress: Signal<MockProgress \| undefined>` | Current transfer progress, if active |
|
|
239
|
+
| `hasValue(): boolean` | `true` when value is set |
|
|
240
|
+
| `resolve(value: T)` | Set value, clear error and progress → `'resolved'` |
|
|
241
|
+
| `resolveAfter(ms, value)` | Set loading immediately, resolve after delay |
|
|
242
|
+
| `setLoading()` | Clear error → `'loading'` |
|
|
243
|
+
| `fail(error)` | Set error → `'error'` (progress preserved) |
|
|
244
|
+
| `reset()` | Clear all including progress → `'idle'` |
|
|
245
|
+
| `setProgress(type, loaded, total?)` | Set progress and status → `'loading'` |
|
|
246
|
+
| `simulateProgress(type, totalBytes, durationMs, finalValue, steps?)` | Animate incremental progress over `durationMs` ms then resolve |
|
|
247
|
+
| `set(value)` | Local mutation → `'local'` (ResourceRef interface) |
|
|
248
|
+
| `update(fn)` | Local update → `'local'` (ResourceRef interface) |
|
|
249
|
+
| `onRequest(cb)` | Subscribe to factory invocations; returns unsubscribe fn |
|
|
250
|
+
| `reload()` | No-op, returns `false` |
|
|
251
|
+
|
|
252
|
+
### `MockProgress`
|
|
253
|
+
|
|
254
|
+
```typescript
|
|
255
|
+
interface MockProgress {
|
|
256
|
+
type: 'upload' | 'download';
|
|
257
|
+
loaded: number; // bytes transferred
|
|
258
|
+
total?: number; // total bytes (undefined for streaming / unknown-length responses)
|
|
259
|
+
}
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
### `window.__openApiMocks__[key]`
|
|
263
|
+
|
|
264
|
+
| Member | Description |
|
|
265
|
+
|--------|-------------|
|
|
266
|
+
| `resolve(value)` | Set value (JSON-serializable) |
|
|
267
|
+
| `resolveAfter(ms, value)` | Delayed resolve |
|
|
268
|
+
| `setLoading()` | Start loading state |
|
|
269
|
+
| `fail(error)` | Set error state |
|
|
270
|
+
| `reset()` | Return to idle |
|
|
271
|
+
| `setProgress(type, loaded, total?)` | Set transfer progress |
|
|
272
|
+
| `simulateProgress(type, totalBytes, durationMs, finalValue, steps?)` | Animate progress then resolve |
|
|
273
|
+
| `getState()` | `{ status, value, error, progress }` snapshot |
|
|
274
|
+
| `getHistory()` | Array of all `MockEvent` entries (requests, responses, progress ticks) |
|
|
275
|
+
| `onEvent(cb)` | Subscribe to all events; returns unsubscribe fn |
|
|
276
|
+
|
|
277
|
+
### `MockEvent` types
|
|
278
|
+
|
|
279
|
+
```typescript
|
|
280
|
+
type MockEvent =
|
|
281
|
+
| { type: 'request'; args: unknown[]; ts: number } // factory called by component
|
|
282
|
+
| { type: 'resolve'; value: unknown; ts: number }
|
|
283
|
+
| { type: 'loading'; ts: number }
|
|
284
|
+
| { type: 'error'; error: unknown; ts: number }
|
|
285
|
+
| { type: 'reset'; ts: number }
|
|
286
|
+
| { type: 'progress'; progressType: 'upload' | 'download'; loaded: number; total?: number; ts: number };
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
---
|
|
290
|
+
|
|
291
|
+
## License
|
|
292
|
+
|
|
293
|
+
MIT
|
package/package.json
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@constantant/openapi-resource-mocks",
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"description": "Mock bus for @constantant/openapi-resource-gen tokens — unit tests, E2E, and Chrome Extension devtools",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"main": "src/index.js",
|
|
7
|
+
"types": "src/index.d.ts",
|
|
8
|
+
"publishConfig": {
|
|
9
|
+
"access": "public"
|
|
10
|
+
},
|
|
11
|
+
"peerDependencies": {
|
|
12
|
+
"@angular/common": ">=22.0.0",
|
|
13
|
+
"@angular/core": ">=22.0.0"
|
|
14
|
+
},
|
|
15
|
+
"dependencies": {
|
|
16
|
+
"tslib": "^2.3.0"
|
|
17
|
+
},
|
|
18
|
+
"keywords": [
|
|
19
|
+
"angular",
|
|
20
|
+
"testing",
|
|
21
|
+
"mock",
|
|
22
|
+
"httpResource",
|
|
23
|
+
"InjectionToken",
|
|
24
|
+
"openapi",
|
|
25
|
+
"e2e",
|
|
26
|
+
"devtools"
|
|
27
|
+
],
|
|
28
|
+
"type": "commonjs"
|
|
29
|
+
}
|
package/src/index.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { createMockResourceRef } from './lib/mock-resource-ref';
|
|
2
|
+
export type { MockResourceRef, MockResourceRefInternal, MockResourceState } from './lib/mock-resource-ref';
|
|
3
|
+
export { MockResourceBus, provideMockResourceBus } from './lib/mock-resource-bus';
|
|
4
|
+
export type { WindowMockEntry } from './lib/mock-resource-bus';
|
|
5
|
+
export { provideMockResource } from './lib/provide-mock-resource';
|
|
6
|
+
export { injectMockResource } from './lib/inject-mock-resource';
|
|
7
|
+
export type { MockEvent, MockProgress } from './lib/mock-events';
|
package/src/index.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.injectMockResource = exports.provideMockResource = exports.provideMockResourceBus = exports.MockResourceBus = exports.createMockResourceRef = void 0;
|
|
4
|
+
var mock_resource_ref_1 = require("./lib/mock-resource-ref");
|
|
5
|
+
Object.defineProperty(exports, "createMockResourceRef", { enumerable: true, get: function () { return mock_resource_ref_1.createMockResourceRef; } });
|
|
6
|
+
var mock_resource_bus_1 = require("./lib/mock-resource-bus");
|
|
7
|
+
Object.defineProperty(exports, "MockResourceBus", { enumerable: true, get: function () { return mock_resource_bus_1.MockResourceBus; } });
|
|
8
|
+
Object.defineProperty(exports, "provideMockResourceBus", { enumerable: true, get: function () { return mock_resource_bus_1.provideMockResourceBus; } });
|
|
9
|
+
var provide_mock_resource_1 = require("./lib/provide-mock-resource");
|
|
10
|
+
Object.defineProperty(exports, "provideMockResource", { enumerable: true, get: function () { return provide_mock_resource_1.provideMockResource; } });
|
|
11
|
+
var inject_mock_resource_1 = require("./lib/inject-mock-resource");
|
|
12
|
+
Object.defineProperty(exports, "injectMockResource", { enumerable: true, get: function () { return inject_mock_resource_1.injectMockResource; } });
|
|
13
|
+
//# sourceMappingURL=index.js.map
|
package/src/index.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../tools/openapi-resource-mocks/src/index.ts"],"names":[],"mappings":";;;AAAA,6DAAgE;AAAvD,0HAAA,qBAAqB,OAAA;AAE9B,6DAAkF;AAAzE,oHAAA,eAAe,OAAA;AAAE,2HAAA,sBAAsB,OAAA;AAEhD,qEAAkE;AAAzD,4HAAA,mBAAmB,OAAA;AAC5B,mEAAgE;AAAvD,0HAAA,kBAAkB,OAAA"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.injectMockResource = injectMockResource;
|
|
4
|
+
const core_1 = require("@angular/core");
|
|
5
|
+
const mock_resource_bus_1 = require("./mock-resource-bus");
|
|
6
|
+
function injectMockResource(key) {
|
|
7
|
+
const bus = (0, core_1.inject)(mock_resource_bus_1.MockResourceBus);
|
|
8
|
+
const ref = bus.get(key);
|
|
9
|
+
if (!ref) {
|
|
10
|
+
throw new Error(`[openapi-resource-mocks] No mock registered for key "${key}". ` +
|
|
11
|
+
`Ensure provideMockResource(token, "${key}") is in the providers array ` +
|
|
12
|
+
`before calling injectMockResource("${key}").`);
|
|
13
|
+
}
|
|
14
|
+
return ref;
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=inject-mock-resource.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inject-mock-resource.js","sourceRoot":"","sources":["../../../../../tools/openapi-resource-mocks/src/lib/inject-mock-resource.ts"],"names":[],"mappings":";;AAIA,gDAWC;AAfD,wCAAuC;AACvC,2DAAsD;AAGtD,SAAgB,kBAAkB,CAAI,GAAW;IAC/C,MAAM,GAAG,GAAG,IAAA,aAAM,EAAC,mCAAe,CAAC,CAAC;IACpC,MAAM,GAAG,GAAG,GAAG,CAAC,GAAG,CAAI,GAAG,CAAC,CAAC;IAC5B,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,MAAM,IAAI,KAAK,CACb,wDAAwD,GAAG,KAAK;YAC9D,sCAAsC,GAAG,+BAA+B;YACxE,sCAAsC,GAAG,KAAK,CACjD,CAAC;IACJ,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export type MockEvent = {
|
|
2
|
+
type: 'request';
|
|
3
|
+
args: unknown[];
|
|
4
|
+
ts: number;
|
|
5
|
+
} | {
|
|
6
|
+
type: 'resolve';
|
|
7
|
+
value: unknown;
|
|
8
|
+
ts: number;
|
|
9
|
+
} | {
|
|
10
|
+
type: 'loading';
|
|
11
|
+
ts: number;
|
|
12
|
+
} | {
|
|
13
|
+
type: 'error';
|
|
14
|
+
error: unknown;
|
|
15
|
+
ts: number;
|
|
16
|
+
} | {
|
|
17
|
+
type: 'reset';
|
|
18
|
+
ts: number;
|
|
19
|
+
} | {
|
|
20
|
+
type: 'progress';
|
|
21
|
+
progressType: 'upload' | 'download';
|
|
22
|
+
loaded: number;
|
|
23
|
+
total?: number;
|
|
24
|
+
ts: number;
|
|
25
|
+
};
|
|
26
|
+
export interface MockProgress {
|
|
27
|
+
type: 'upload' | 'download';
|
|
28
|
+
loaded: number;
|
|
29
|
+
total?: number;
|
|
30
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mock-events.js","sourceRoot":"","sources":["../../../../../tools/openapi-resource-mocks/src/lib/mock-events.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { EnvironmentProviders } from '@angular/core';
|
|
2
|
+
import type { MockResourceRef } from './mock-resource-ref';
|
|
3
|
+
import type { MockEvent } from './mock-events';
|
|
4
|
+
export interface WindowMockEntry {
|
|
5
|
+
resolve(value: unknown): void;
|
|
6
|
+
resolveAfter(delayMs: number, value: unknown): void;
|
|
7
|
+
setLoading(): void;
|
|
8
|
+
fail(error: unknown): void;
|
|
9
|
+
reset(): void;
|
|
10
|
+
setProgress(type: 'upload' | 'download', loaded: number, total?: number): void;
|
|
11
|
+
simulateProgress(type: 'upload' | 'download', totalBytes: number, durationMs: number, finalValue: unknown, steps?: number): void;
|
|
12
|
+
getState(): {
|
|
13
|
+
status: string;
|
|
14
|
+
value: unknown;
|
|
15
|
+
error: unknown;
|
|
16
|
+
progress: unknown;
|
|
17
|
+
};
|
|
18
|
+
getHistory(): MockEvent[];
|
|
19
|
+
onEvent(cb: (event: MockEvent) => void): () => void;
|
|
20
|
+
}
|
|
21
|
+
declare global {
|
|
22
|
+
interface Window {
|
|
23
|
+
__openApiMocks__?: Record<string, WindowMockEntry>;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
export declare class MockResourceBus {
|
|
27
|
+
private readonly refs;
|
|
28
|
+
register<T>(key: string, ref: MockResourceRef<T>): void;
|
|
29
|
+
get<T>(key: string): MockResourceRef<T> | undefined;
|
|
30
|
+
private exposeToWindow;
|
|
31
|
+
private dispatchDomEvent;
|
|
32
|
+
constructor();
|
|
33
|
+
}
|
|
34
|
+
export declare function provideMockResourceBus(): EnvironmentProviders;
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MockResourceBus = void 0;
|
|
4
|
+
exports.provideMockResourceBus = provideMockResourceBus;
|
|
5
|
+
const core_1 = require("@angular/core");
|
|
6
|
+
class MockResourceBus {
|
|
7
|
+
refs = new Map();
|
|
8
|
+
register(key, ref) {
|
|
9
|
+
const internal = ref;
|
|
10
|
+
this.refs.set(key, internal);
|
|
11
|
+
this.exposeToWindow(key, internal);
|
|
12
|
+
}
|
|
13
|
+
get(key) {
|
|
14
|
+
return this.refs.get(key);
|
|
15
|
+
}
|
|
16
|
+
exposeToWindow(key, ref) {
|
|
17
|
+
window.__openApiMocks__ ??= {};
|
|
18
|
+
const history = [];
|
|
19
|
+
const listeners = new Set();
|
|
20
|
+
const emit = (e) => {
|
|
21
|
+
history.push(e);
|
|
22
|
+
listeners.forEach((cb) => cb(e));
|
|
23
|
+
this.dispatchDomEvent(key, e);
|
|
24
|
+
};
|
|
25
|
+
ref.onRequest((args) => emit({ type: 'request', args, ts: Date.now() }));
|
|
26
|
+
window.__openApiMocks__[key] = {
|
|
27
|
+
resolve: (v) => { ref.resolve(v); emit({ type: 'resolve', value: v, ts: Date.now() }); },
|
|
28
|
+
resolveAfter: (ms, v) => { ref.resolveAfter(ms, v); },
|
|
29
|
+
setLoading: () => { ref.setLoading(); emit({ type: 'loading', ts: Date.now() }); },
|
|
30
|
+
fail: (e) => { ref.fail(e); emit({ type: 'error', error: e, ts: Date.now() }); },
|
|
31
|
+
reset: () => { ref.reset(); emit({ type: 'reset', ts: Date.now() }); },
|
|
32
|
+
setProgress: (pt, l, t) => {
|
|
33
|
+
ref.setProgress(pt, l, t);
|
|
34
|
+
emit({ type: 'progress', progressType: pt, loaded: l, total: t, ts: Date.now() });
|
|
35
|
+
},
|
|
36
|
+
simulateProgress: (pt, total, dur, v, steps) => {
|
|
37
|
+
ref.simulateProgress(pt, total, dur, v, steps);
|
|
38
|
+
},
|
|
39
|
+
getState: () => ({
|
|
40
|
+
status: String(ref.status()),
|
|
41
|
+
value: ref.value(),
|
|
42
|
+
error: ref.error(),
|
|
43
|
+
progress: ref.progress(),
|
|
44
|
+
}),
|
|
45
|
+
getHistory: () => [...history],
|
|
46
|
+
onEvent: (cb) => { listeners.add(cb); return () => listeners.delete(cb); },
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
dispatchDomEvent(key, event) {
|
|
50
|
+
if (typeof document === 'undefined')
|
|
51
|
+
return;
|
|
52
|
+
document.dispatchEvent(new CustomEvent('openapi-mock-event', { detail: { key, event } }));
|
|
53
|
+
}
|
|
54
|
+
constructor() {
|
|
55
|
+
if (typeof document === 'undefined')
|
|
56
|
+
return;
|
|
57
|
+
document.addEventListener('openapi-mock-control', (e) => {
|
|
58
|
+
const detail = e.detail;
|
|
59
|
+
const ref = this.refs.get(detail.key);
|
|
60
|
+
if (!ref)
|
|
61
|
+
return;
|
|
62
|
+
switch (detail.action) {
|
|
63
|
+
case 'resolve':
|
|
64
|
+
ref.resolve(detail.value);
|
|
65
|
+
break;
|
|
66
|
+
case 'resolveAfter':
|
|
67
|
+
ref.resolveAfter(detail.delayMs ?? 0, detail.value);
|
|
68
|
+
break;
|
|
69
|
+
case 'setLoading':
|
|
70
|
+
ref.setLoading();
|
|
71
|
+
break;
|
|
72
|
+
case 'fail':
|
|
73
|
+
ref.fail(detail.value);
|
|
74
|
+
break;
|
|
75
|
+
case 'reset':
|
|
76
|
+
ref.reset();
|
|
77
|
+
break;
|
|
78
|
+
case 'setProgress':
|
|
79
|
+
ref.setProgress(detail.progressType, detail.loaded, detail.total);
|
|
80
|
+
break;
|
|
81
|
+
case 'simulateProgress':
|
|
82
|
+
ref.simulateProgress(detail.progressType, detail.total, detail.delayMs ?? 1000, detail.value, detail.steps);
|
|
83
|
+
break;
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
exports.MockResourceBus = MockResourceBus;
|
|
89
|
+
function provideMockResourceBus() {
|
|
90
|
+
return (0, core_1.makeEnvironmentProviders)([
|
|
91
|
+
{ provide: MockResourceBus, useFactory: () => new MockResourceBus() },
|
|
92
|
+
]);
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=mock-resource-bus.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mock-resource-bus.js","sourceRoot":"","sources":["../../../../../tools/openapi-resource-mocks/src/lib/mock-resource-bus.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { Signal } from '@angular/core';
|
|
2
|
+
import type { ResourceStatus } from '@angular/core';
|
|
3
|
+
import type { MockProgress } from './mock-events';
|
|
4
|
+
export type MockResourceState<T> = {
|
|
5
|
+
value: T;
|
|
6
|
+
} | {
|
|
7
|
+
loading: true;
|
|
8
|
+
} | {
|
|
9
|
+
error: unknown;
|
|
10
|
+
};
|
|
11
|
+
export interface MockResourceRef<T> {
|
|
12
|
+
readonly value: Signal<T | undefined>;
|
|
13
|
+
readonly status: Signal<ResourceStatus>;
|
|
14
|
+
readonly error: Signal<unknown>;
|
|
15
|
+
readonly isLoading: Signal<boolean>;
|
|
16
|
+
readonly progress: Signal<MockProgress | undefined>;
|
|
17
|
+
hasValue(): boolean;
|
|
18
|
+
reload(): boolean;
|
|
19
|
+
destroy(): void;
|
|
20
|
+
set(value: T): void;
|
|
21
|
+
update(updater: (value: T | undefined) => T): void;
|
|
22
|
+
asReadonly(): MockResourceRef<T>;
|
|
23
|
+
resolve(value: T): void;
|
|
24
|
+
resolveAfter(delayMs: number, value: T): void;
|
|
25
|
+
setLoading(): void;
|
|
26
|
+
fail(error: unknown): void;
|
|
27
|
+
reset(): void;
|
|
28
|
+
setProgress(type: 'upload' | 'download', loaded: number, total?: number): void;
|
|
29
|
+
simulateProgress(type: 'upload' | 'download', totalBytes: number, durationMs: number, finalValue: T, steps?: number): void;
|
|
30
|
+
onRequest(cb: (args: unknown[]) => void): () => void;
|
|
31
|
+
}
|
|
32
|
+
export interface MockResourceRefInternal<T> extends MockResourceRef<T> {
|
|
33
|
+
_notifyRequest(args: unknown[]): void;
|
|
34
|
+
}
|
|
35
|
+
export declare function createMockResourceRef<T>(initialState?: MockResourceState<T>): MockResourceRef<T>;
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createMockResourceRef = createMockResourceRef;
|
|
4
|
+
const core_1 = require("@angular/core");
|
|
5
|
+
function createMockResourceRef(initialState) {
|
|
6
|
+
const _status = (0, core_1.signal)('idle');
|
|
7
|
+
const _value = (0, core_1.signal)(undefined);
|
|
8
|
+
const _error = (0, core_1.signal)(undefined);
|
|
9
|
+
const _progress = (0, core_1.signal)(undefined);
|
|
10
|
+
const requestListeners = new Set();
|
|
11
|
+
if (initialState) {
|
|
12
|
+
if ('value' in initialState) {
|
|
13
|
+
_value.set(initialState.value);
|
|
14
|
+
_status.set('resolved');
|
|
15
|
+
}
|
|
16
|
+
else if ('loading' in initialState) {
|
|
17
|
+
_status.set('loading');
|
|
18
|
+
}
|
|
19
|
+
else if ('error' in initialState) {
|
|
20
|
+
_error.set(initialState.error);
|
|
21
|
+
_status.set('error');
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
const ref = {
|
|
25
|
+
value: _value.asReadonly(),
|
|
26
|
+
status: _status.asReadonly(),
|
|
27
|
+
error: _error.asReadonly(),
|
|
28
|
+
progress: _progress.asReadonly(),
|
|
29
|
+
isLoading: (0, core_1.computed)(() => _status() === 'loading' || _status() === 'reloading'),
|
|
30
|
+
hasValue: () => _value() !== undefined,
|
|
31
|
+
resolve(v) {
|
|
32
|
+
_value.set(v);
|
|
33
|
+
_error.set(undefined);
|
|
34
|
+
_progress.set(undefined);
|
|
35
|
+
_status.set('resolved');
|
|
36
|
+
},
|
|
37
|
+
resolveAfter(ms, v) {
|
|
38
|
+
ref.setLoading();
|
|
39
|
+
setTimeout(() => ref.resolve(v), ms);
|
|
40
|
+
},
|
|
41
|
+
setLoading() {
|
|
42
|
+
_error.set(undefined);
|
|
43
|
+
_status.set('loading');
|
|
44
|
+
},
|
|
45
|
+
fail(e) {
|
|
46
|
+
_error.set(e);
|
|
47
|
+
// progress intentionally kept — shows where transfer was when it failed
|
|
48
|
+
_status.set('error');
|
|
49
|
+
},
|
|
50
|
+
reset() {
|
|
51
|
+
_value.set(undefined);
|
|
52
|
+
_error.set(undefined);
|
|
53
|
+
_progress.set(undefined);
|
|
54
|
+
_status.set('idle');
|
|
55
|
+
},
|
|
56
|
+
set(v) {
|
|
57
|
+
_value.set(v);
|
|
58
|
+
_status.set('local');
|
|
59
|
+
},
|
|
60
|
+
update(fn) {
|
|
61
|
+
_value.update(fn);
|
|
62
|
+
_status.set('local');
|
|
63
|
+
},
|
|
64
|
+
setProgress(type, loaded, total) {
|
|
65
|
+
_progress.set({ type, loaded, total });
|
|
66
|
+
_status.set('loading');
|
|
67
|
+
},
|
|
68
|
+
simulateProgress(type, totalBytes, durationMs, finalValue, steps = 10) {
|
|
69
|
+
ref.setLoading();
|
|
70
|
+
const stepDelay = durationMs / steps;
|
|
71
|
+
for (let i = 1; i <= steps; i++) {
|
|
72
|
+
setTimeout(() => {
|
|
73
|
+
ref.setProgress(type, Math.round((totalBytes / steps) * i), totalBytes);
|
|
74
|
+
}, stepDelay * i);
|
|
75
|
+
}
|
|
76
|
+
setTimeout(() => ref.resolve(finalValue), durationMs + stepDelay);
|
|
77
|
+
},
|
|
78
|
+
reload: () => false,
|
|
79
|
+
destroy: () => { },
|
|
80
|
+
asReadonly: () => ref,
|
|
81
|
+
onRequest: (cb) => {
|
|
82
|
+
requestListeners.add(cb);
|
|
83
|
+
return () => requestListeners.delete(cb);
|
|
84
|
+
},
|
|
85
|
+
_notifyRequest: (args) => {
|
|
86
|
+
requestListeners.forEach((cb) => cb(args));
|
|
87
|
+
},
|
|
88
|
+
};
|
|
89
|
+
return ref;
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=mock-resource-ref.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mock-resource-ref.js","sourceRoot":"","sources":["../../../../../tools/openapi-resource-mocks/src/lib/mock-resource-ref.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { InjectionToken, FactoryProvider } from '@angular/core';
|
|
2
|
+
import { httpResource } from '@angular/common/http';
|
|
3
|
+
import { type MockResourceState } from './mock-resource-ref';
|
|
4
|
+
export declare function provideMockResource<T>(token: InjectionToken<(...args: unknown[]) => ReturnType<typeof httpResource<T>>>, key: string, initialState?: MockResourceState<T>): FactoryProvider;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.provideMockResource = provideMockResource;
|
|
4
|
+
const core_1 = require("@angular/core");
|
|
5
|
+
const mock_resource_bus_1 = require("./mock-resource-bus");
|
|
6
|
+
const mock_resource_ref_1 = require("./mock-resource-ref");
|
|
7
|
+
function provideMockResource(token, key, initialState) {
|
|
8
|
+
return {
|
|
9
|
+
provide: token,
|
|
10
|
+
useFactory: () => {
|
|
11
|
+
const bus = (0, core_1.inject)(mock_resource_bus_1.MockResourceBus);
|
|
12
|
+
const ref = (0, mock_resource_ref_1.createMockResourceRef)(initialState);
|
|
13
|
+
bus.register(key, ref);
|
|
14
|
+
return (...args) => {
|
|
15
|
+
ref._notifyRequest(args);
|
|
16
|
+
return ref;
|
|
17
|
+
};
|
|
18
|
+
},
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=provide-mock-resource.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provide-mock-resource.js","sourceRoot":"","sources":["../../../../../tools/openapi-resource-mocks/src/lib/provide-mock-resource.ts"],"names":[],"mappings":";;AASA,kDAiBC;AA1BD,wCAAwE;AAExE,2DAAsD;AACtD,2DAI6B;AAE7B,SAAgB,mBAAmB,CACjC,KAAiF,EACjF,GAAW,EACX,YAAmC;IAEnC,OAAO;QACL,OAAO,EAAE,KAAK;QACd,UAAU,EAAE,GAAG,EAAE;YACf,MAAM,GAAG,GAAG,IAAA,aAAM,EAAC,mCAAe,CAAC,CAAC;YACpC,MAAM,GAAG,GAAG,IAAA,yCAAqB,EAAI,YAAY,CAAC,CAAC;YACnD,GAAG,CAAC,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;YACvB,OAAO,CAAC,GAAG,IAAe,EAAsC,EAAE;gBAC/D,GAAkC,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;gBACzD,OAAO,GAAoD,CAAC;YAC9D,CAAC,CAAC;QACJ,CAAC;KACF,CAAC;AACJ,CAAC"}
|