@acorex-platform/client-connectivity-mock 0.0.46
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/README.md
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# @acorex-platform/client-connectivity-mock
|
|
2
|
+
|
|
3
|
+
IndexedDB (Dexie) CQRS transport for standalone Angular hosts **without** Nest / `demo-api`.
|
|
4
|
+
|
|
5
|
+
XOR with `@acorex-platform/client-connectivity-api`. Do not import both.
|
|
6
|
+
|
|
7
|
+
```typescript
|
|
8
|
+
import {
|
|
9
|
+
AXP_DEXIE_SEED,
|
|
10
|
+
provideDexieRuntimeTransport,
|
|
11
|
+
provideDexieSeeds,
|
|
12
|
+
} from '@acorex-platform/client-connectivity-mock';
|
|
13
|
+
|
|
14
|
+
export const appConfig = {
|
|
15
|
+
providers: [
|
|
16
|
+
...provideDexieRuntimeTransport(),
|
|
17
|
+
...provideDexieSeeds({ entity: 'Demo.Todo', rows: [{ id: '1', title: 'Sample' }] }),
|
|
18
|
+
],
|
|
19
|
+
};
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
- Entity CRUD uses `Entity:Insert|Update|Delete|Query|GetById:Default` → Dexie `ACoreXClientStore`
|
|
23
|
+
- Boot stubs: `Auth:*`, settings scoped fetch/patch, `Domain:GetEntityLayout` (empty — use `provideXxxLocalEntities()`)
|
|
24
|
+
- Custom commands/queries: register in the **host**, not this library
|
|
25
|
+
- Pack row reuse in the browser is a later split (`module-common-server/seed` is not browser-safe today)
|
|
26
|
+
|
|
27
|
+
Design: `docs/feature/medium/client-connectivity-mock.md`
|
|
@@ -0,0 +1,984 @@
|
|
|
1
|
+
import { AXPFileStorageService, AXP_SETTINGS_SYNC_KEYS } from '@acorex-platform/framework-client/common';
|
|
2
|
+
import { createRandomUuid, AXPFileStorageStatus, runtimeCommandSuccessObject, runtimeCommandFailure, runtimeQuerySuccessObject, runtimeQuerySuccessCollection, runtimeQueryFailure } from '@acorex-platform/framework-shared/core';
|
|
3
|
+
import * as i0 from '@angular/core';
|
|
4
|
+
import { Injectable, InjectionToken, inject, NgModule } from '@angular/core';
|
|
5
|
+
import { AXP_HOOK_PROVIDER, provideAppStartUpTask, AXP_APP_STARTUP_PRIORITY } from '@acorex-platform/framework-client/core';
|
|
6
|
+
import { AXPRuntimeRemoteHookKeys } from '@acorex-platform/framework-client/runtime';
|
|
7
|
+
import { runEntityQuery, filterSortEntityRows, computeEntityAggregates } from '@acorex-platform/framework-client/layout/entity';
|
|
8
|
+
import Dexie from 'dexie';
|
|
9
|
+
import { AUTH_SIGN_IN_DEFAULT, AUTH_REGISTER_DEFAULT, AUTH_REFRESH_DEFAULT, AUTH_LOGOUT_DEFAULT, AUTH_UPDATE_SESSION_DEFAULT, AUTH_VERIFY_TWO_FACTOR_DEFAULT, AUTH_TERMINATE_OWN_DEVICE_SESSION_DEFAULT, AUTH_LIST_PROVIDERS_DEFAULT, AUTH_LIST_TENANTS_DEFAULT, AUTH_LIST_APPLICATIONS_DEFAULT, AUTH_LIST_OWN_DEVICE_SESSIONS_DEFAULT, AUTH_GET_ACCESS_POLICY_DEFAULT, parseDefaultEntityRuntimeKey, resolveEntityNameFromRuntimeInput, parseEntityCommandKey, AXP_BULK_COMMAND_DEFAULT_MAX_ITEMS, AXP_BULK_COMMAND_HARD_MAX_ITEMS, DOMAIN_GET_ENTITY_LAYOUT_DEFAULT, DOMAIN_LIST_ENTITY_LAYOUTS_DEFAULT } from '@acorex-platform/framework-shared/runtime';
|
|
10
|
+
|
|
11
|
+
//#region ----- Imports -----
|
|
12
|
+
//#endregion
|
|
13
|
+
//#region ----- Dexie file storage stub -----
|
|
14
|
+
/**
|
|
15
|
+
* In-memory file storage so the shell (logo resolver) can construct without
|
|
16
|
+
* `client-connectivity-host` / HTTP. XOR hosts must not import the API module.
|
|
17
|
+
*/
|
|
18
|
+
class AXCDexieFileStorageService extends AXPFileStorageService {
|
|
19
|
+
constructor() {
|
|
20
|
+
super(...arguments);
|
|
21
|
+
this.files = new Map();
|
|
22
|
+
}
|
|
23
|
+
getDownloadUrl(fileId) {
|
|
24
|
+
const row = this.files.get(fileId);
|
|
25
|
+
return row ? URL.createObjectURL(row.blob) : '';
|
|
26
|
+
}
|
|
27
|
+
async download(fileId) {
|
|
28
|
+
const row = this.files.get(fileId);
|
|
29
|
+
if (!row) {
|
|
30
|
+
throw new Error(`Dexie mock has no file '${fileId}'`);
|
|
31
|
+
}
|
|
32
|
+
return row.blob;
|
|
33
|
+
}
|
|
34
|
+
async save(request) {
|
|
35
|
+
const fileId = createRandomUuid();
|
|
36
|
+
const info = {
|
|
37
|
+
fileId,
|
|
38
|
+
id: fileId,
|
|
39
|
+
refId: request.refId,
|
|
40
|
+
refType: request.refType,
|
|
41
|
+
category: request.category,
|
|
42
|
+
name: request.name ?? request.file.name,
|
|
43
|
+
mimeType: request.file.type || 'application/octet-stream',
|
|
44
|
+
size: request.file.size,
|
|
45
|
+
isPrimary: request.isPrimary,
|
|
46
|
+
isPublic: false,
|
|
47
|
+
status: request.status ?? AXPFileStorageStatus.Temporary,
|
|
48
|
+
uploadedAt: new Date(),
|
|
49
|
+
binary: request.file,
|
|
50
|
+
metadata: request.path ? { path: request.path } : request.metadata,
|
|
51
|
+
};
|
|
52
|
+
this.files.set(fileId, { info, blob: request.file });
|
|
53
|
+
return info;
|
|
54
|
+
}
|
|
55
|
+
async update(request) {
|
|
56
|
+
const row = this.files.get(request.fileId);
|
|
57
|
+
if (!row) {
|
|
58
|
+
throw new Error(`Dexie mock has no file '${request.fileId}'`);
|
|
59
|
+
}
|
|
60
|
+
row.info = {
|
|
61
|
+
...row.info,
|
|
62
|
+
name: request.name ?? row.info.name,
|
|
63
|
+
isPrimary: request.isPrimary ?? row.info.isPrimary,
|
|
64
|
+
metadata: request.path
|
|
65
|
+
? { ...(row.info.metadata ?? {}), path: request.path }
|
|
66
|
+
: request.metadata ?? row.info.metadata,
|
|
67
|
+
};
|
|
68
|
+
return row.info;
|
|
69
|
+
}
|
|
70
|
+
async find(request) {
|
|
71
|
+
return [...this.files.values()]
|
|
72
|
+
.map((row) => row.info)
|
|
73
|
+
.filter((info) => {
|
|
74
|
+
if (request.refId && info.refId !== request.refId) {
|
|
75
|
+
return false;
|
|
76
|
+
}
|
|
77
|
+
if (request.refType && info.refType !== request.refType) {
|
|
78
|
+
return false;
|
|
79
|
+
}
|
|
80
|
+
if (request.category && info.category !== request.category) {
|
|
81
|
+
return false;
|
|
82
|
+
}
|
|
83
|
+
return true;
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
async findMany(ids) {
|
|
87
|
+
return ids
|
|
88
|
+
.map((id) => this.files.get(id)?.info)
|
|
89
|
+
.filter((info) => info != null)
|
|
90
|
+
.map((info) => ({ ...info, fileId: info.fileId }));
|
|
91
|
+
}
|
|
92
|
+
async getInfo(fileId) {
|
|
93
|
+
const row = this.files.get(fileId);
|
|
94
|
+
if (!row) {
|
|
95
|
+
throw new Error(`Dexie mock has no file '${fileId}'`);
|
|
96
|
+
}
|
|
97
|
+
return row.info;
|
|
98
|
+
}
|
|
99
|
+
async remove(fileId) {
|
|
100
|
+
this.files.delete(fileId);
|
|
101
|
+
}
|
|
102
|
+
async commit(fileId) {
|
|
103
|
+
const row = this.files.get(fileId);
|
|
104
|
+
if (row) {
|
|
105
|
+
row.info.status = AXPFileStorageStatus.Committed;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
async markForDeletion(fileId) {
|
|
109
|
+
const row = this.files.get(fileId);
|
|
110
|
+
if (row) {
|
|
111
|
+
row.info.status = AXPFileStorageStatus.PendingDeletion;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXCDexieFileStorageService, deps: null, target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
115
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXCDexieFileStorageService }); }
|
|
116
|
+
}
|
|
117
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXCDexieFileStorageService, decorators: [{
|
|
118
|
+
type: Injectable
|
|
119
|
+
}] });
|
|
120
|
+
|
|
121
|
+
//#region ----- Imports -----
|
|
122
|
+
//#endregion
|
|
123
|
+
//#region ----- Dexie DB -----
|
|
124
|
+
class AXCDexieClientStore extends Dexie {
|
|
125
|
+
constructor() {
|
|
126
|
+
super('ACoreXClientStore');
|
|
127
|
+
this.version(1).stores({
|
|
128
|
+
records: 'storageId, entity, id, [entity+id]',
|
|
129
|
+
meta: 'entity',
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
const axcDexieClientStore = new AXCDexieClientStore();
|
|
134
|
+
function buildDexieStorageId(entity, id) {
|
|
135
|
+
return `${entity}|${id}`;
|
|
136
|
+
}
|
|
137
|
+
//#endregion
|
|
138
|
+
|
|
139
|
+
//#endregion
|
|
140
|
+
//#region ----- Helpers -----
|
|
141
|
+
function asRecord$2(value) {
|
|
142
|
+
if (value != null && typeof value === 'object' && !Array.isArray(value)) {
|
|
143
|
+
return value;
|
|
144
|
+
}
|
|
145
|
+
return null;
|
|
146
|
+
}
|
|
147
|
+
function recordId(value) {
|
|
148
|
+
const obj = asRecord$2(value);
|
|
149
|
+
if (!obj || obj['id'] == null || obj['id'] === '') {
|
|
150
|
+
return null;
|
|
151
|
+
}
|
|
152
|
+
return String(obj['id']);
|
|
153
|
+
}
|
|
154
|
+
function toPayload(value) {
|
|
155
|
+
const obj = asRecord$2(value);
|
|
156
|
+
return obj ? { ...obj } : null;
|
|
157
|
+
}
|
|
158
|
+
//#endregion
|
|
159
|
+
//#region ----- Dexie entity storage -----
|
|
160
|
+
class AXCDexieEntityStorageService {
|
|
161
|
+
constructor() {
|
|
162
|
+
this.dbName = 'ACoreXClientStore';
|
|
163
|
+
}
|
|
164
|
+
async initial(entityName, collection) {
|
|
165
|
+
const rows = collection ?? [];
|
|
166
|
+
for (const item of rows) {
|
|
167
|
+
await this.upsertOne(entityName, item, { merge: true });
|
|
168
|
+
}
|
|
169
|
+
return rows;
|
|
170
|
+
}
|
|
171
|
+
async getSeedVersion(entityName) {
|
|
172
|
+
const row = await axcDexieClientStore.meta.get(entityName);
|
|
173
|
+
return row?.seedVersion ?? null;
|
|
174
|
+
}
|
|
175
|
+
async setSeedVersion(entityName, seedVersion) {
|
|
176
|
+
await axcDexieClientStore.meta.put({ entity: entityName, seedVersion });
|
|
177
|
+
}
|
|
178
|
+
async getOne(entityName, id) {
|
|
179
|
+
const key = id == null || id === '' ? '' : String(id);
|
|
180
|
+
if (!key) {
|
|
181
|
+
throw new Error(`Entity not found: ${entityName}/`);
|
|
182
|
+
}
|
|
183
|
+
const row = await axcDexieClientStore.records.get(buildDexieStorageId(entityName, key));
|
|
184
|
+
if (!row) {
|
|
185
|
+
throw new Error(`Entity not found: ${entityName}/${key}`);
|
|
186
|
+
}
|
|
187
|
+
return { ...row.payload };
|
|
188
|
+
}
|
|
189
|
+
async getAll(entityName) {
|
|
190
|
+
const rows = await axcDexieClientStore.records.where('entity').equals(entityName).toArray();
|
|
191
|
+
return rows.map((row) => ({ ...row.payload }));
|
|
192
|
+
}
|
|
193
|
+
async query(entityName, request) {
|
|
194
|
+
return runEntityQuery(entityName, request, this.queryAdapters());
|
|
195
|
+
}
|
|
196
|
+
async count(entityName, request) {
|
|
197
|
+
const rows = await filterSortEntityRows(entityName, request, this.queryAdapters());
|
|
198
|
+
return rows.length;
|
|
199
|
+
}
|
|
200
|
+
async queryAll(entityName, request, options) {
|
|
201
|
+
const rows = await filterSortEntityRows(entityName, request, this.queryAdapters());
|
|
202
|
+
const maxRows = options?.maxRows ?? 100_000;
|
|
203
|
+
const items = rows.slice(0, maxRows);
|
|
204
|
+
return {
|
|
205
|
+
items,
|
|
206
|
+
total: rows.length,
|
|
207
|
+
truncated: rows.length > items.length,
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
async getMany(entityName, ids) {
|
|
211
|
+
return Promise.all(ids.map(async (id) => {
|
|
212
|
+
try {
|
|
213
|
+
return await this.getOne(entityName, id);
|
|
214
|
+
}
|
|
215
|
+
catch {
|
|
216
|
+
return null;
|
|
217
|
+
}
|
|
218
|
+
}));
|
|
219
|
+
}
|
|
220
|
+
async exists(entityName, id) {
|
|
221
|
+
try {
|
|
222
|
+
await this.getOne(entityName, id);
|
|
223
|
+
return true;
|
|
224
|
+
}
|
|
225
|
+
catch {
|
|
226
|
+
return false;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
async insertOne(entityName, entity) {
|
|
230
|
+
const payload = toPayload(entity) ?? {};
|
|
231
|
+
const id = recordId(payload) ?? createRandomUuid();
|
|
232
|
+
payload['id'] = id;
|
|
233
|
+
const stored = {
|
|
234
|
+
storageId: buildDexieStorageId(entityName, id),
|
|
235
|
+
entity: entityName,
|
|
236
|
+
id,
|
|
237
|
+
payload,
|
|
238
|
+
};
|
|
239
|
+
await axcDexieClientStore.records.put(stored);
|
|
240
|
+
return id;
|
|
241
|
+
}
|
|
242
|
+
async updateOne(entityName, id, patch) {
|
|
243
|
+
const current = await this.getOne(entityName, id);
|
|
244
|
+
const next = { ...current, ...patch, id: current['id'] };
|
|
245
|
+
const key = String(current['id']);
|
|
246
|
+
await axcDexieClientStore.records.put({
|
|
247
|
+
storageId: buildDexieStorageId(entityName, key),
|
|
248
|
+
entity: entityName,
|
|
249
|
+
id: key,
|
|
250
|
+
payload: next,
|
|
251
|
+
});
|
|
252
|
+
return next;
|
|
253
|
+
}
|
|
254
|
+
async deleteOne(entityName, id) {
|
|
255
|
+
const key = id == null || id === '' ? '' : String(id);
|
|
256
|
+
if (!key) {
|
|
257
|
+
return;
|
|
258
|
+
}
|
|
259
|
+
await axcDexieClientStore.records.delete(buildDexieStorageId(entityName, key));
|
|
260
|
+
}
|
|
261
|
+
async upsertOne(entityName, entity, options) {
|
|
262
|
+
const id = recordId(entity);
|
|
263
|
+
if (id != null && (await this.exists(entityName, id))) {
|
|
264
|
+
const merge = options?.merge !== false;
|
|
265
|
+
const existing = await this.getOne(entityName, id);
|
|
266
|
+
const next = merge ? { ...existing, ...entity, id } : { ...entity, id };
|
|
267
|
+
const { id: _omit, ...patch } = next;
|
|
268
|
+
await this.updateOne(entityName, id, patch);
|
|
269
|
+
return id;
|
|
270
|
+
}
|
|
271
|
+
return this.insertOne(entityName, entity);
|
|
272
|
+
}
|
|
273
|
+
async aggregate(entityName, request, queryRequest) {
|
|
274
|
+
const rows = await filterSortEntityRows(entityName, queryRequest ?? {}, this.queryAdapters());
|
|
275
|
+
return { rows: computeEntityAggregates(rows, request) };
|
|
276
|
+
}
|
|
277
|
+
queryAdapters() {
|
|
278
|
+
return {
|
|
279
|
+
getRawAll: (name) => this.getAll(name),
|
|
280
|
+
getDirectChildCount: async (categoryId, name) => {
|
|
281
|
+
const rows = await this.getAll(name);
|
|
282
|
+
return rows.filter((row) => String(row['parentId'] ?? '') === String(categoryId)).length;
|
|
283
|
+
},
|
|
284
|
+
getAllChildCategoryIds: async (categoryId, name) => {
|
|
285
|
+
const all = await this.getAll(name);
|
|
286
|
+
const children = new Set([String(categoryId)]);
|
|
287
|
+
let added = true;
|
|
288
|
+
while (added) {
|
|
289
|
+
added = false;
|
|
290
|
+
for (const row of all) {
|
|
291
|
+
const id = recordId(row);
|
|
292
|
+
const parent = row['parentId'] == null ? '' : String(row['parentId']);
|
|
293
|
+
if (id && parent && children.has(parent) && !children.has(id)) {
|
|
294
|
+
children.add(id);
|
|
295
|
+
added = true;
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
return [...children];
|
|
300
|
+
},
|
|
301
|
+
};
|
|
302
|
+
}
|
|
303
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXCDexieEntityStorageService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
304
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXCDexieEntityStorageService }); }
|
|
305
|
+
}
|
|
306
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXCDexieEntityStorageService, decorators: [{
|
|
307
|
+
type: Injectable
|
|
308
|
+
}] });
|
|
309
|
+
|
|
310
|
+
//#region ----- Auth catalog entity names -----
|
|
311
|
+
/** Local-owned rows the Dexie auth dispatcher reads. Hosts seed these via `provideDexieSeeds`. */
|
|
312
|
+
const AXC_DEXIE_AUTH_USER_ENTITY = 'Auth.User';
|
|
313
|
+
const AXC_DEXIE_AUTH_TENANT_ENTITY = 'Auth.Tenant';
|
|
314
|
+
const AXC_DEXIE_AUTH_APPLICATION_ENTITY = 'Auth.Application';
|
|
315
|
+
//#endregion
|
|
316
|
+
|
|
317
|
+
//#region ----- Imports -----
|
|
318
|
+
//#endregion
|
|
319
|
+
//#region ----- Defaults -----
|
|
320
|
+
const AXC_DEXIE_DEFAULT_IDENTITY = {
|
|
321
|
+
user: {
|
|
322
|
+
id: 'local-user',
|
|
323
|
+
name: 'local',
|
|
324
|
+
title: 'Local User',
|
|
325
|
+
avatar: null,
|
|
326
|
+
},
|
|
327
|
+
tenant: {
|
|
328
|
+
id: 'local-tenant',
|
|
329
|
+
name: 'local',
|
|
330
|
+
title: 'Local Tenant',
|
|
331
|
+
},
|
|
332
|
+
application: {
|
|
333
|
+
id: 'local-app',
|
|
334
|
+
name: 'local',
|
|
335
|
+
title: 'Local App',
|
|
336
|
+
},
|
|
337
|
+
};
|
|
338
|
+
//#endregion
|
|
339
|
+
//#region ----- Tokens -----
|
|
340
|
+
const AXP_DEXIE_MOCK_IDENTITY = new InjectionToken('AXP_DEXIE_MOCK_IDENTITY', {
|
|
341
|
+
providedIn: 'root',
|
|
342
|
+
factory: () => AXC_DEXIE_DEFAULT_IDENTITY,
|
|
343
|
+
});
|
|
344
|
+
//#endregion
|
|
345
|
+
|
|
346
|
+
//#endregion
|
|
347
|
+
//#region ----- Constants -----
|
|
348
|
+
const AUTH_COMMAND_KEYS = new Set([
|
|
349
|
+
AUTH_SIGN_IN_DEFAULT,
|
|
350
|
+
AUTH_REGISTER_DEFAULT,
|
|
351
|
+
AUTH_REFRESH_DEFAULT,
|
|
352
|
+
AUTH_LOGOUT_DEFAULT,
|
|
353
|
+
AUTH_UPDATE_SESSION_DEFAULT,
|
|
354
|
+
AUTH_VERIFY_TWO_FACTOR_DEFAULT,
|
|
355
|
+
AUTH_TERMINATE_OWN_DEVICE_SESSION_DEFAULT,
|
|
356
|
+
]);
|
|
357
|
+
const AUTH_QUERY_KEYS = new Set([
|
|
358
|
+
AUTH_LIST_PROVIDERS_DEFAULT,
|
|
359
|
+
AUTH_LIST_TENANTS_DEFAULT,
|
|
360
|
+
AUTH_LIST_APPLICATIONS_DEFAULT,
|
|
361
|
+
AUTH_LIST_OWN_DEVICE_SESSIONS_DEFAULT,
|
|
362
|
+
AUTH_GET_ACCESS_POLICY_DEFAULT,
|
|
363
|
+
]);
|
|
364
|
+
//#endregion
|
|
365
|
+
//#region ----- Helpers -----
|
|
366
|
+
function asRecord$1(value) {
|
|
367
|
+
if (value != null && typeof value === 'object' && !Array.isArray(value)) {
|
|
368
|
+
return value;
|
|
369
|
+
}
|
|
370
|
+
return null;
|
|
371
|
+
}
|
|
372
|
+
function asString(value) {
|
|
373
|
+
return value == null ? '' : String(value).trim();
|
|
374
|
+
}
|
|
375
|
+
//#endregion
|
|
376
|
+
//#region ----- Auth dispatcher -----
|
|
377
|
+
class AXCDexieAuthRuntimeDispatcher {
|
|
378
|
+
constructor() {
|
|
379
|
+
this.storage = inject(AXCDexieEntityStorageService);
|
|
380
|
+
this.fallbackIdentity = inject(AXP_DEXIE_MOCK_IDENTITY);
|
|
381
|
+
this.current = null;
|
|
382
|
+
}
|
|
383
|
+
canHandleCommand(name) {
|
|
384
|
+
return AUTH_COMMAND_KEYS.has(name);
|
|
385
|
+
}
|
|
386
|
+
canHandleQuery(name) {
|
|
387
|
+
return AUTH_QUERY_KEYS.has(name);
|
|
388
|
+
}
|
|
389
|
+
async executeCommand(name, input) {
|
|
390
|
+
if (name === AUTH_LOGOUT_DEFAULT || name === AUTH_TERMINATE_OWN_DEVICE_SESSION_DEFAULT) {
|
|
391
|
+
this.current = null;
|
|
392
|
+
return runtimeCommandSuccessObject({});
|
|
393
|
+
}
|
|
394
|
+
if (name === AUTH_SIGN_IN_DEFAULT) {
|
|
395
|
+
return this.signIn(input);
|
|
396
|
+
}
|
|
397
|
+
if (name === AUTH_REGISTER_DEFAULT) {
|
|
398
|
+
return runtimeCommandFailure('Registration is not enabled in the Dexie mock.', {
|
|
399
|
+
code: 'DEXIE_AUTH_REGISTER_DISABLED',
|
|
400
|
+
});
|
|
401
|
+
}
|
|
402
|
+
return runtimeCommandSuccessObject(this.tokenResponse());
|
|
403
|
+
}
|
|
404
|
+
async executeQuery(name) {
|
|
405
|
+
if (name === AUTH_LIST_PROVIDERS_DEFAULT) {
|
|
406
|
+
return runtimeQuerySuccessObject({
|
|
407
|
+
localMethods: [{ id: 'user-pass', title: 'Password', protocol: 'password', enabled: true }],
|
|
408
|
+
identityProviders: [],
|
|
409
|
+
});
|
|
410
|
+
}
|
|
411
|
+
if (name === AUTH_LIST_TENANTS_DEFAULT) {
|
|
412
|
+
const tenants = await this.storage.getAll(AXC_DEXIE_AUTH_TENANT_ENTITY);
|
|
413
|
+
return runtimeQuerySuccessCollection(tenants.length > 0 ? tenants : [this.tenantRow()]);
|
|
414
|
+
}
|
|
415
|
+
if (name === AUTH_LIST_APPLICATIONS_DEFAULT) {
|
|
416
|
+
const applications = await this.storage.getAll(AXC_DEXIE_AUTH_APPLICATION_ENTITY);
|
|
417
|
+
return runtimeQuerySuccessCollection(applications.length > 0 ? applications : [this.applicationRow()]);
|
|
418
|
+
}
|
|
419
|
+
if (name === AUTH_LIST_OWN_DEVICE_SESSIONS_DEFAULT) {
|
|
420
|
+
return runtimeQuerySuccessCollection([]);
|
|
421
|
+
}
|
|
422
|
+
if (name === AUTH_GET_ACCESS_POLICY_DEFAULT) {
|
|
423
|
+
return runtimeQuerySuccessObject({
|
|
424
|
+
permissions: ['*'],
|
|
425
|
+
modulesAndFeatures: { modules: ['*'], features: {} },
|
|
426
|
+
});
|
|
427
|
+
}
|
|
428
|
+
return runtimeQuerySuccessObject({});
|
|
429
|
+
}
|
|
430
|
+
async signIn(input) {
|
|
431
|
+
const body = asRecord$1(input) ?? {};
|
|
432
|
+
const username = asString(body['username']).toLowerCase();
|
|
433
|
+
const password = asString(body['password']);
|
|
434
|
+
if (!username || !password) {
|
|
435
|
+
return runtimeCommandFailure('Invalid username or password', { code: 'DEXIE_AUTH_INVALID_CREDENTIALS' });
|
|
436
|
+
}
|
|
437
|
+
const users = await this.storage.getAll(AXC_DEXIE_AUTH_USER_ENTITY);
|
|
438
|
+
const user = users.find((row) => asString(row['username']).toLowerCase() === username);
|
|
439
|
+
if (!user || asString(user['password']) !== password) {
|
|
440
|
+
return runtimeCommandFailure('Invalid username or password', { code: 'DEXIE_AUTH_INVALID_CREDENTIALS' });
|
|
441
|
+
}
|
|
442
|
+
const tenantId = asString(user['tenantId']);
|
|
443
|
+
const applicationId = asString(user['applicationId']);
|
|
444
|
+
const tenant = (tenantId ? await this.tryGet(AXC_DEXIE_AUTH_TENANT_ENTITY, tenantId) : null) ?? this.tenantRow();
|
|
445
|
+
const application = (applicationId ? await this.tryGet(AXC_DEXIE_AUTH_APPLICATION_ENTITY, applicationId) : null) ??
|
|
446
|
+
this.applicationRow();
|
|
447
|
+
this.current = {
|
|
448
|
+
user: {
|
|
449
|
+
id: asString(user['id']),
|
|
450
|
+
name: asString(user['name'] || user['username']),
|
|
451
|
+
title: asString(user['title'] || user['username']),
|
|
452
|
+
avatar: null,
|
|
453
|
+
},
|
|
454
|
+
tenant: {
|
|
455
|
+
id: asString(tenant['id']),
|
|
456
|
+
name: asString(tenant['name']),
|
|
457
|
+
title: asString(tenant['title'] || tenant['name']),
|
|
458
|
+
},
|
|
459
|
+
application: {
|
|
460
|
+
id: asString(application['id']),
|
|
461
|
+
name: asString(application['name']),
|
|
462
|
+
title: asString(application['title'] || application['name']),
|
|
463
|
+
},
|
|
464
|
+
};
|
|
465
|
+
return runtimeCommandSuccessObject(this.tokenResponse());
|
|
466
|
+
}
|
|
467
|
+
async tryGet(entity, id) {
|
|
468
|
+
try {
|
|
469
|
+
return await this.storage.getOne(entity, id);
|
|
470
|
+
}
|
|
471
|
+
catch {
|
|
472
|
+
return null;
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
tokenResponse() {
|
|
476
|
+
const identity = this.current ?? this.fallbackIdentity;
|
|
477
|
+
return {
|
|
478
|
+
accessToken: 'mock-access',
|
|
479
|
+
refreshToken: 'mock-refresh',
|
|
480
|
+
expiresIn: '24h',
|
|
481
|
+
user: identity.user,
|
|
482
|
+
tenant: {
|
|
483
|
+
id: identity.tenant.id,
|
|
484
|
+
name: identity.tenant.name,
|
|
485
|
+
title: identity.tenant.title,
|
|
486
|
+
},
|
|
487
|
+
application: {
|
|
488
|
+
id: identity.application.id,
|
|
489
|
+
name: identity.application.name,
|
|
490
|
+
title: identity.application.title,
|
|
491
|
+
},
|
|
492
|
+
};
|
|
493
|
+
}
|
|
494
|
+
tenantRow() {
|
|
495
|
+
const tenant = (this.current ?? this.fallbackIdentity).tenant;
|
|
496
|
+
return {
|
|
497
|
+
id: tenant.id,
|
|
498
|
+
name: tenant.name,
|
|
499
|
+
title: tenant.title,
|
|
500
|
+
};
|
|
501
|
+
}
|
|
502
|
+
applicationRow() {
|
|
503
|
+
const application = (this.current ?? this.fallbackIdentity).application;
|
|
504
|
+
return {
|
|
505
|
+
id: application.id,
|
|
506
|
+
name: application.name,
|
|
507
|
+
title: application.title,
|
|
508
|
+
};
|
|
509
|
+
}
|
|
510
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXCDexieAuthRuntimeDispatcher, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
511
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXCDexieAuthRuntimeDispatcher }); }
|
|
512
|
+
}
|
|
513
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXCDexieAuthRuntimeDispatcher, decorators: [{
|
|
514
|
+
type: Injectable
|
|
515
|
+
}] });
|
|
516
|
+
|
|
517
|
+
//#endregion
|
|
518
|
+
//#region ----- Input helpers -----
|
|
519
|
+
function asRecord(value) {
|
|
520
|
+
if (value != null && typeof value === 'object' && !Array.isArray(value)) {
|
|
521
|
+
return value;
|
|
522
|
+
}
|
|
523
|
+
return null;
|
|
524
|
+
}
|
|
525
|
+
function resolveEntityName(name, input) {
|
|
526
|
+
const fromDefault = parseDefaultEntityRuntimeKey(name);
|
|
527
|
+
if (fromDefault) {
|
|
528
|
+
return resolveEntityNameFromRuntimeInput(input);
|
|
529
|
+
}
|
|
530
|
+
return parseEntityCommandKey(name)?.entity ?? null;
|
|
531
|
+
}
|
|
532
|
+
function resolveOperation(name) {
|
|
533
|
+
return parseDefaultEntityRuntimeKey(name) ?? parseEntityCommandKey(name)?.operation ?? null;
|
|
534
|
+
}
|
|
535
|
+
function extractId(input) {
|
|
536
|
+
const obj = asRecord(input);
|
|
537
|
+
if (!obj || obj['id'] == null || obj['id'] === '') {
|
|
538
|
+
return null;
|
|
539
|
+
}
|
|
540
|
+
return String(obj['id']);
|
|
541
|
+
}
|
|
542
|
+
function extractRecordBody(input) {
|
|
543
|
+
const obj = asRecord(input) ?? {};
|
|
544
|
+
const nested = asRecord(obj['data']);
|
|
545
|
+
const source = nested ?? obj;
|
|
546
|
+
const { entity: _entity, data: _data, ...rest } = source;
|
|
547
|
+
return rest;
|
|
548
|
+
}
|
|
549
|
+
function extractQueryRequest(input) {
|
|
550
|
+
const obj = asRecord(input) ?? {};
|
|
551
|
+
const nested = asRecord(obj['queryRequest']);
|
|
552
|
+
const source = nested ?? obj;
|
|
553
|
+
return {
|
|
554
|
+
skip: typeof source['skip'] === 'number' ? source['skip'] : 0,
|
|
555
|
+
take: typeof source['take'] === 'number' ? source['take'] : 10,
|
|
556
|
+
filter: source['filter'],
|
|
557
|
+
sort: source['sort'],
|
|
558
|
+
params: source['params'],
|
|
559
|
+
};
|
|
560
|
+
}
|
|
561
|
+
function extractAggregate(input) {
|
|
562
|
+
const obj = asRecord(input);
|
|
563
|
+
const agg = obj?.['aggregate'];
|
|
564
|
+
if (agg != null && typeof agg === 'object' && !Array.isArray(agg)) {
|
|
565
|
+
return agg;
|
|
566
|
+
}
|
|
567
|
+
return null;
|
|
568
|
+
}
|
|
569
|
+
//#endregion
|
|
570
|
+
//#region ----- Entity dispatcher -----
|
|
571
|
+
class AXCDexieEntityRuntimeDispatcher {
|
|
572
|
+
constructor() {
|
|
573
|
+
this.storage = inject(AXCDexieEntityStorageService);
|
|
574
|
+
}
|
|
575
|
+
canHandleCommand(name) {
|
|
576
|
+
const operation = resolveOperation(name);
|
|
577
|
+
return operation === 'Insert' || operation === 'Update' || operation === 'Delete';
|
|
578
|
+
}
|
|
579
|
+
canHandleQuery(name) {
|
|
580
|
+
const operation = resolveOperation(name);
|
|
581
|
+
return operation === 'Query' || operation === 'GetById';
|
|
582
|
+
}
|
|
583
|
+
async executeCommand(name, input) {
|
|
584
|
+
const entity = resolveEntityName(name, input);
|
|
585
|
+
const operation = resolveOperation(name);
|
|
586
|
+
if (!entity || !operation) {
|
|
587
|
+
return runtimeCommandFailure(`Dexie mock cannot resolve entity for '${name}'`, {
|
|
588
|
+
code: 'DEXIE_ENTITY_UNRESOLVED',
|
|
589
|
+
});
|
|
590
|
+
}
|
|
591
|
+
try {
|
|
592
|
+
if (operation === 'Insert') {
|
|
593
|
+
const body = extractRecordBody(input);
|
|
594
|
+
const id = await this.storage.insertOne(entity, body);
|
|
595
|
+
const record = await this.storage.getOne(entity, id);
|
|
596
|
+
return runtimeCommandSuccessObject({ id, record });
|
|
597
|
+
}
|
|
598
|
+
if (operation === 'Update') {
|
|
599
|
+
const id = extractId(input);
|
|
600
|
+
if (!id) {
|
|
601
|
+
return runtimeCommandFailure('Update requires id', { code: 'DEXIE_ENTITY_ID_REQUIRED' });
|
|
602
|
+
}
|
|
603
|
+
const record = await this.storage.updateOne(entity, id, extractRecordBody(input));
|
|
604
|
+
return runtimeCommandSuccessObject({ id, record });
|
|
605
|
+
}
|
|
606
|
+
if (operation === 'Delete') {
|
|
607
|
+
const id = extractId(input);
|
|
608
|
+
if (!id) {
|
|
609
|
+
return runtimeCommandFailure('Delete requires id', { code: 'DEXIE_ENTITY_ID_REQUIRED' });
|
|
610
|
+
}
|
|
611
|
+
await this.storage.deleteOne(entity, id);
|
|
612
|
+
return runtimeCommandSuccessObject({ id });
|
|
613
|
+
}
|
|
614
|
+
return runtimeCommandFailure(`'${name}' is a query, not a command`, { code: 'DEXIE_ENTITY_WRONG_KIND' });
|
|
615
|
+
}
|
|
616
|
+
catch (error) {
|
|
617
|
+
return runtimeCommandFailure(error instanceof Error ? error.message : String(error), {
|
|
618
|
+
code: 'DEXIE_ENTITY_COMMAND_FAILED',
|
|
619
|
+
});
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
async executeQuery(name, input) {
|
|
623
|
+
const entity = resolveEntityName(name, input);
|
|
624
|
+
const operation = resolveOperation(name);
|
|
625
|
+
if (!entity || !operation) {
|
|
626
|
+
return runtimeQueryFailure(`Dexie mock cannot resolve entity for '${name}'`, {
|
|
627
|
+
code: 'DEXIE_ENTITY_UNRESOLVED',
|
|
628
|
+
});
|
|
629
|
+
}
|
|
630
|
+
try {
|
|
631
|
+
if (operation === 'GetById') {
|
|
632
|
+
const id = extractId(input);
|
|
633
|
+
if (!id) {
|
|
634
|
+
return runtimeQueryFailure('GetById requires id', { code: 'DEXIE_ENTITY_ID_REQUIRED' });
|
|
635
|
+
}
|
|
636
|
+
const record = await this.storage.getOne(entity, id);
|
|
637
|
+
return runtimeQuerySuccessObject(record);
|
|
638
|
+
}
|
|
639
|
+
if (operation !== 'Query') {
|
|
640
|
+
return runtimeQueryFailure(`'${name}' is not a query`, { code: 'DEXIE_ENTITY_WRONG_KIND' });
|
|
641
|
+
}
|
|
642
|
+
const obj = asRecord(input) ?? {};
|
|
643
|
+
const byId = extractId(input);
|
|
644
|
+
if (byId && obj['queryRequest'] == null && obj['skip'] == null && obj['filter'] == null) {
|
|
645
|
+
const record = await this.storage.getOne(entity, byId);
|
|
646
|
+
return runtimeQuerySuccessObject(record);
|
|
647
|
+
}
|
|
648
|
+
const aggregate = extractAggregate(input);
|
|
649
|
+
if (aggregate) {
|
|
650
|
+
const request = extractQueryRequest(input);
|
|
651
|
+
const result = await this.storage.aggregate(entity, aggregate, request);
|
|
652
|
+
const total = await this.storage.count(entity, request);
|
|
653
|
+
return runtimeQuerySuccessCollection({
|
|
654
|
+
items: [],
|
|
655
|
+
total,
|
|
656
|
+
aggregateRows: result.rows,
|
|
657
|
+
});
|
|
658
|
+
}
|
|
659
|
+
const resultMode = typeof obj['resultMode'] === 'string' ? obj['resultMode'] : null;
|
|
660
|
+
const request = extractQueryRequest(input);
|
|
661
|
+
if (resultMode === 'count') {
|
|
662
|
+
const total = await this.storage.count(entity, request);
|
|
663
|
+
return runtimeQuerySuccessCollection({ items: [], total });
|
|
664
|
+
}
|
|
665
|
+
if (resultMode === 'all') {
|
|
666
|
+
const page = await this.storage.queryAll(entity, request);
|
|
667
|
+
return runtimeQuerySuccessCollection(page);
|
|
668
|
+
}
|
|
669
|
+
const page = await this.storage.query(entity, request);
|
|
670
|
+
return runtimeQuerySuccessCollection(page);
|
|
671
|
+
}
|
|
672
|
+
catch (error) {
|
|
673
|
+
return runtimeQueryFailure(error instanceof Error ? error.message : String(error), {
|
|
674
|
+
code: 'DEXIE_ENTITY_QUERY_FAILED',
|
|
675
|
+
});
|
|
676
|
+
}
|
|
677
|
+
}
|
|
678
|
+
async executeBulk(request) {
|
|
679
|
+
const maxItems = Math.min(request.maxItems ?? AXP_BULK_COMMAND_DEFAULT_MAX_ITEMS, AXP_BULK_COMMAND_HARD_MAX_ITEMS);
|
|
680
|
+
const idField = request.idField?.trim() || 'id';
|
|
681
|
+
const page = await this.storage.query(request.entity, {
|
|
682
|
+
filter: request.filter,
|
|
683
|
+
skip: 0,
|
|
684
|
+
take: maxItems + 1,
|
|
685
|
+
});
|
|
686
|
+
const truncated = page.total > maxItems || page.items.length > maxItems;
|
|
687
|
+
const targets = page.items.slice(0, maxItems);
|
|
688
|
+
const results = [];
|
|
689
|
+
for (const row of targets) {
|
|
690
|
+
const id = row[idField] == null ? createRandomUuid() : String(row[idField]);
|
|
691
|
+
const perItem = {
|
|
692
|
+
entity: request.entity,
|
|
693
|
+
[idField]: id,
|
|
694
|
+
...(request.input ?? {}),
|
|
695
|
+
};
|
|
696
|
+
const result = await this.executeCommand(request.name, perItem);
|
|
697
|
+
results.push({
|
|
698
|
+
id,
|
|
699
|
+
success: result.success === true,
|
|
700
|
+
data: result.success ? result.data : undefined,
|
|
701
|
+
message: result.message,
|
|
702
|
+
});
|
|
703
|
+
}
|
|
704
|
+
const succeeded = results.filter((item) => item.success).length;
|
|
705
|
+
return runtimeCommandSuccessObject({
|
|
706
|
+
total: results.length,
|
|
707
|
+
succeeded,
|
|
708
|
+
failed: results.length - succeeded,
|
|
709
|
+
truncated: truncated || undefined,
|
|
710
|
+
results,
|
|
711
|
+
});
|
|
712
|
+
}
|
|
713
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXCDexieEntityRuntimeDispatcher, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
714
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXCDexieEntityRuntimeDispatcher }); }
|
|
715
|
+
}
|
|
716
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXCDexieEntityRuntimeDispatcher, decorators: [{
|
|
717
|
+
type: Injectable
|
|
718
|
+
}] });
|
|
719
|
+
|
|
720
|
+
//#region ----- Settings CQRS keys -----
|
|
721
|
+
/**
|
|
722
|
+
* Same keys as settings-management contracts. Duplicated so this lib does not
|
|
723
|
+
* import that module (XOR hosts must not pull `client-connectivity-api`).
|
|
724
|
+
*/
|
|
725
|
+
const AXC_DEXIE_SETTINGS_SCOPED_FETCH = 'SettingsManagement:ScopedSettings:Fetch';
|
|
726
|
+
const AXC_DEXIE_SETTINGS_SCOPED_PATCH = 'SettingsManagement:ScopedSettings:Patch';
|
|
727
|
+
const AXC_DEXIE_SETTINGS_SYNC_KEYS = {
|
|
728
|
+
scopedFetchQueryKey: AXC_DEXIE_SETTINGS_SCOPED_FETCH,
|
|
729
|
+
scopedPatchCommandKey: AXC_DEXIE_SETTINGS_SCOPED_PATCH,
|
|
730
|
+
};
|
|
731
|
+
//#endregion
|
|
732
|
+
|
|
733
|
+
//#endregion
|
|
734
|
+
//#region ----- Constants -----
|
|
735
|
+
const SYSTEM_COMMAND_KEYS = new Set([AXC_DEXIE_SETTINGS_SCOPED_PATCH]);
|
|
736
|
+
const SYSTEM_QUERY_KEYS = new Set([
|
|
737
|
+
AXC_DEXIE_SETTINGS_SCOPED_FETCH,
|
|
738
|
+
DOMAIN_GET_ENTITY_LAYOUT_DEFAULT,
|
|
739
|
+
DOMAIN_LIST_ENTITY_LAYOUTS_DEFAULT,
|
|
740
|
+
]);
|
|
741
|
+
//#endregion
|
|
742
|
+
//#region ----- System dispatcher -----
|
|
743
|
+
/**
|
|
744
|
+
* Boot queries/commands the shell hits before any host handler exists.
|
|
745
|
+
* Domain layouts stay empty so hosts use {@code provideXxxLocalEntities()}.
|
|
746
|
+
*/
|
|
747
|
+
class AXCDexieSystemRuntimeDispatcher {
|
|
748
|
+
canHandleCommand(name) {
|
|
749
|
+
return SYSTEM_COMMAND_KEYS.has(name);
|
|
750
|
+
}
|
|
751
|
+
canHandleQuery(name) {
|
|
752
|
+
return SYSTEM_QUERY_KEYS.has(name);
|
|
753
|
+
}
|
|
754
|
+
executeCommand(name) {
|
|
755
|
+
if (name === AXC_DEXIE_SETTINGS_SCOPED_PATCH) {
|
|
756
|
+
return runtimeCommandSuccessObject({ updatedAt: new Date().toISOString() });
|
|
757
|
+
}
|
|
758
|
+
return runtimeCommandSuccessObject({});
|
|
759
|
+
}
|
|
760
|
+
executeQuery(name) {
|
|
761
|
+
if (name === AXC_DEXIE_SETTINGS_SCOPED_FETCH) {
|
|
762
|
+
return runtimeQuerySuccessObject({
|
|
763
|
+
changed: false,
|
|
764
|
+
updatedAt: null,
|
|
765
|
+
values: {},
|
|
766
|
+
});
|
|
767
|
+
}
|
|
768
|
+
if (name === DOMAIN_GET_ENTITY_LAYOUT_DEFAULT) {
|
|
769
|
+
return runtimeQuerySuccessObject(null);
|
|
770
|
+
}
|
|
771
|
+
if (name === DOMAIN_LIST_ENTITY_LAYOUTS_DEFAULT) {
|
|
772
|
+
return runtimeQuerySuccessCollection([]);
|
|
773
|
+
}
|
|
774
|
+
return runtimeQuerySuccessObject({});
|
|
775
|
+
}
|
|
776
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXCDexieSystemRuntimeDispatcher, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
777
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXCDexieSystemRuntimeDispatcher }); }
|
|
778
|
+
}
|
|
779
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXCDexieSystemRuntimeDispatcher, decorators: [{
|
|
780
|
+
type: Injectable
|
|
781
|
+
}] });
|
|
782
|
+
|
|
783
|
+
//#region ----- Imports -----
|
|
784
|
+
//#endregion
|
|
785
|
+
//#region ----- Helpers -----
|
|
786
|
+
function unhandledCommand(name) {
|
|
787
|
+
return runtimeCommandFailure(`Dexie mock has no handler for command '${name}'. Register a local command in the host, or seed/use Entity:*:Default.`, { code: 'DEXIE_COMMAND_UNHANDLED' });
|
|
788
|
+
}
|
|
789
|
+
function unhandledQuery(name) {
|
|
790
|
+
return runtimeQueryFailure(`Dexie mock has no handler for query '${name}'. Register a local query in the host, or use Entity:Query:Default / Entity:GetById:Default.`, { code: 'DEXIE_QUERY_UNHANDLED' });
|
|
791
|
+
}
|
|
792
|
+
//#endregion
|
|
793
|
+
//#region ----- Hook providers -----
|
|
794
|
+
const AXCDexieCommandExecuteHookProvider = {
|
|
795
|
+
key: AXPRuntimeRemoteHookKeys.CommandExecute,
|
|
796
|
+
async execute(payload) {
|
|
797
|
+
if (payload.handled) {
|
|
798
|
+
return payload;
|
|
799
|
+
}
|
|
800
|
+
const entities = inject(AXCDexieEntityRuntimeDispatcher);
|
|
801
|
+
const auth = inject(AXCDexieAuthRuntimeDispatcher);
|
|
802
|
+
const system = inject(AXCDexieSystemRuntimeDispatcher);
|
|
803
|
+
if (entities.canHandleCommand(payload.name)) {
|
|
804
|
+
return { ...payload, handled: true, result: await entities.executeCommand(payload.name, payload.input) };
|
|
805
|
+
}
|
|
806
|
+
if (auth.canHandleCommand(payload.name)) {
|
|
807
|
+
return { ...payload, handled: true, result: await auth.executeCommand(payload.name, payload.input) };
|
|
808
|
+
}
|
|
809
|
+
if (system.canHandleCommand(payload.name)) {
|
|
810
|
+
return { ...payload, handled: true, result: system.executeCommand(payload.name) };
|
|
811
|
+
}
|
|
812
|
+
return { ...payload, handled: true, result: unhandledCommand(payload.name) };
|
|
813
|
+
},
|
|
814
|
+
};
|
|
815
|
+
const AXCDexieCommandExecuteBulkHookProvider = {
|
|
816
|
+
key: AXPRuntimeRemoteHookKeys.CommandExecuteBulk,
|
|
817
|
+
async execute(payload) {
|
|
818
|
+
if (payload.handled) {
|
|
819
|
+
return payload;
|
|
820
|
+
}
|
|
821
|
+
const entities = inject(AXCDexieEntityRuntimeDispatcher);
|
|
822
|
+
const result = await entities.executeBulk(payload.request);
|
|
823
|
+
return { ...payload, handled: true, result };
|
|
824
|
+
},
|
|
825
|
+
};
|
|
826
|
+
const AXCDexieCommandBulkProgressHookProvider = {
|
|
827
|
+
key: AXPRuntimeRemoteHookKeys.CommandBulkProgress,
|
|
828
|
+
async execute(payload) {
|
|
829
|
+
if (payload.handled) {
|
|
830
|
+
return payload;
|
|
831
|
+
}
|
|
832
|
+
return {
|
|
833
|
+
...payload,
|
|
834
|
+
handled: true,
|
|
835
|
+
progress: {
|
|
836
|
+
executionId: payload.executionId,
|
|
837
|
+
entity: '',
|
|
838
|
+
name: '',
|
|
839
|
+
current: 0,
|
|
840
|
+
total: 0,
|
|
841
|
+
succeeded: 0,
|
|
842
|
+
failed: 0,
|
|
843
|
+
status: 'completed',
|
|
844
|
+
},
|
|
845
|
+
};
|
|
846
|
+
},
|
|
847
|
+
};
|
|
848
|
+
const AXCDexieQueryExecuteHookProvider = {
|
|
849
|
+
key: AXPRuntimeRemoteHookKeys.QueryExecute,
|
|
850
|
+
async execute(payload) {
|
|
851
|
+
if (payload.handled) {
|
|
852
|
+
return payload;
|
|
853
|
+
}
|
|
854
|
+
const entities = inject(AXCDexieEntityRuntimeDispatcher);
|
|
855
|
+
const auth = inject(AXCDexieAuthRuntimeDispatcher);
|
|
856
|
+
const system = inject(AXCDexieSystemRuntimeDispatcher);
|
|
857
|
+
if (entities.canHandleQuery(payload.name)) {
|
|
858
|
+
return { ...payload, handled: true, result: await entities.executeQuery(payload.name, payload.input) };
|
|
859
|
+
}
|
|
860
|
+
if (auth.canHandleQuery(payload.name)) {
|
|
861
|
+
return { ...payload, handled: true, result: await auth.executeQuery(payload.name) };
|
|
862
|
+
}
|
|
863
|
+
if (system.canHandleQuery(payload.name)) {
|
|
864
|
+
return { ...payload, handled: true, result: system.executeQuery(payload.name) };
|
|
865
|
+
}
|
|
866
|
+
return { ...payload, handled: true, result: unhandledQuery(payload.name) };
|
|
867
|
+
},
|
|
868
|
+
};
|
|
869
|
+
const AXC_DEXIE_RUNTIME_HOOK_PROVIDERS = [
|
|
870
|
+
AXCDexieEntityStorageService,
|
|
871
|
+
AXCDexieEntityRuntimeDispatcher,
|
|
872
|
+
AXCDexieAuthRuntimeDispatcher,
|
|
873
|
+
AXCDexieSystemRuntimeDispatcher,
|
|
874
|
+
{
|
|
875
|
+
provide: AXP_HOOK_PROVIDER,
|
|
876
|
+
useValue: AXCDexieCommandExecuteHookProvider,
|
|
877
|
+
multi: true,
|
|
878
|
+
},
|
|
879
|
+
{
|
|
880
|
+
provide: AXP_HOOK_PROVIDER,
|
|
881
|
+
useValue: AXCDexieCommandExecuteBulkHookProvider,
|
|
882
|
+
multi: true,
|
|
883
|
+
},
|
|
884
|
+
{
|
|
885
|
+
provide: AXP_HOOK_PROVIDER,
|
|
886
|
+
useValue: AXCDexieCommandBulkProgressHookProvider,
|
|
887
|
+
multi: true,
|
|
888
|
+
},
|
|
889
|
+
{
|
|
890
|
+
provide: AXP_HOOK_PROVIDER,
|
|
891
|
+
useValue: AXCDexieQueryExecuteHookProvider,
|
|
892
|
+
multi: true,
|
|
893
|
+
},
|
|
894
|
+
];
|
|
895
|
+
//#endregion
|
|
896
|
+
|
|
897
|
+
//#region ----- Imports -----
|
|
898
|
+
//#endregion
|
|
899
|
+
//#region ----- Tokens -----
|
|
900
|
+
/** Multi token — each host contribution is one `{ entity, rows }` bag. */
|
|
901
|
+
const AXP_DEXIE_SEED = new InjectionToken('AXP_DEXIE_SEED');
|
|
902
|
+
//#endregion
|
|
903
|
+
|
|
904
|
+
//#region ----- Imports -----
|
|
905
|
+
//#endregion
|
|
906
|
+
//#region ----- Seed startup -----
|
|
907
|
+
function provideDexieSeedStartup() {
|
|
908
|
+
return provideAppStartUpTask(() => {
|
|
909
|
+
const storage = inject(AXCDexieEntityStorageService);
|
|
910
|
+
const bags = inject(AXP_DEXIE_SEED, { optional: true }) ?? [];
|
|
911
|
+
return {
|
|
912
|
+
name: 'dexie-entity-seed',
|
|
913
|
+
priority: AXP_APP_STARTUP_PRIORITY.moduleManifests,
|
|
914
|
+
run: async () => {
|
|
915
|
+
for (const bag of bags) {
|
|
916
|
+
const entity = bag.entity?.trim();
|
|
917
|
+
if (!entity) {
|
|
918
|
+
continue;
|
|
919
|
+
}
|
|
920
|
+
await storage.initial(entity, bag.rows ?? []);
|
|
921
|
+
const version = bag.version?.trim() || '1';
|
|
922
|
+
await storage.setSeedVersion(entity, version);
|
|
923
|
+
}
|
|
924
|
+
},
|
|
925
|
+
};
|
|
926
|
+
});
|
|
927
|
+
}
|
|
928
|
+
//#endregion
|
|
929
|
+
|
|
930
|
+
//#region ----- Imports -----
|
|
931
|
+
//#endregion
|
|
932
|
+
//#region ----- Provider factory -----
|
|
933
|
+
/**
|
|
934
|
+
* IndexedDB CQRS transport: `runtime.command.execute` / `runtime.query.execute`
|
|
935
|
+
* against Dexie {@code ACoreXClientStore}.
|
|
936
|
+
*
|
|
937
|
+
* XOR with {@code provideRuntimeRemoteTransport()} from
|
|
938
|
+
* `@acorex-platform/client-connectivity-api`. Do not register both.
|
|
939
|
+
*/
|
|
940
|
+
function provideDexieRuntimeTransport() {
|
|
941
|
+
return [
|
|
942
|
+
...AXC_DEXIE_RUNTIME_HOOK_PROVIDERS,
|
|
943
|
+
provideDexieSeedStartup(),
|
|
944
|
+
{ provide: AXP_SETTINGS_SYNC_KEYS, useValue: AXC_DEXIE_SETTINGS_SYNC_KEYS },
|
|
945
|
+
{ provide: AXPFileStorageService, useClass: AXCDexieFileStorageService },
|
|
946
|
+
];
|
|
947
|
+
}
|
|
948
|
+
/** Registers one or more entity row bags on {@link AXP_DEXIE_SEED}. */
|
|
949
|
+
function provideDexieSeeds(...bags) {
|
|
950
|
+
return bags.map((bag) => ({
|
|
951
|
+
provide: AXP_DEXIE_SEED,
|
|
952
|
+
multi: true,
|
|
953
|
+
useValue: bag,
|
|
954
|
+
}));
|
|
955
|
+
}
|
|
956
|
+
//#endregion
|
|
957
|
+
|
|
958
|
+
//#region ----- Imports -----
|
|
959
|
+
//#endregion
|
|
960
|
+
//#region ----- Module -----
|
|
961
|
+
/**
|
|
962
|
+
* Registers Dexie runtime CQRS hooks used when a query/command is not in
|
|
963
|
+
* {@code provideQuerySetups} / {@code provideCommandSetups}.
|
|
964
|
+
*
|
|
965
|
+
* Do not import together with {@code AXCRuntimeRemoteApiModule}.
|
|
966
|
+
*/
|
|
967
|
+
class AXCRuntimeDexieMockModule {
|
|
968
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXCRuntimeDexieMockModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
969
|
+
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "22.0.8", ngImport: i0, type: AXCRuntimeDexieMockModule }); }
|
|
970
|
+
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXCRuntimeDexieMockModule, providers: provideDexieRuntimeTransport() }); }
|
|
971
|
+
}
|
|
972
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXCRuntimeDexieMockModule, decorators: [{
|
|
973
|
+
type: NgModule,
|
|
974
|
+
args: [{
|
|
975
|
+
providers: provideDexieRuntimeTransport(),
|
|
976
|
+
}]
|
|
977
|
+
}] });
|
|
978
|
+
|
|
979
|
+
/**
|
|
980
|
+
* Generated bundle index. Do not edit.
|
|
981
|
+
*/
|
|
982
|
+
|
|
983
|
+
export { AXCDexieCommandExecuteHookProvider, AXCDexieEntityStorageService, AXCDexieQueryExecuteHookProvider, AXCRuntimeDexieMockModule, AXC_DEXIE_AUTH_APPLICATION_ENTITY, AXC_DEXIE_AUTH_TENANT_ENTITY, AXC_DEXIE_AUTH_USER_ENTITY, AXC_DEXIE_DEFAULT_IDENTITY, AXC_DEXIE_RUNTIME_HOOK_PROVIDERS, AXC_DEXIE_SETTINGS_SCOPED_FETCH, AXC_DEXIE_SETTINGS_SCOPED_PATCH, AXC_DEXIE_SETTINGS_SYNC_KEYS, AXP_DEXIE_MOCK_IDENTITY, AXP_DEXIE_SEED, axcDexieClientStore, buildDexieStorageId, provideDexieRuntimeTransport, provideDexieSeeds };
|
|
984
|
+
//# sourceMappingURL=acorex-platform-client-connectivity-mock.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"acorex-platform-client-connectivity-mock.mjs","sources":["../../../../libs/connectivity/mock/src/lib/file-storage/dexie-file-storage.service.ts","../../../../libs/connectivity/mock/src/lib/dexie/client-store.indexed-db.ts","../../../../libs/connectivity/mock/src/lib/dexie/dexie-entity-storage.service.ts","../../../../libs/connectivity/mock/src/lib/seed/dexie-auth-catalog.constants.ts","../../../../libs/connectivity/mock/src/lib/session/dexie-session.token.ts","../../../../libs/connectivity/mock/src/lib/runtime/auth-runtime.dispatcher.ts","../../../../libs/connectivity/mock/src/lib/runtime/entity-runtime.dispatcher.ts","../../../../libs/connectivity/mock/src/lib/settings/dexie-settings-sync.constants.ts","../../../../libs/connectivity/mock/src/lib/runtime/system-runtime.dispatcher.ts","../../../../libs/connectivity/mock/src/lib/runtime/runtime-mock.hooks.ts","../../../../libs/connectivity/mock/src/lib/seed/dexie-seed.token.ts","../../../../libs/connectivity/mock/src/lib/seed/dexie-seed.startup.ts","../../../../libs/connectivity/mock/src/lib/provide-dexie-runtime-transport.ts","../../../../libs/connectivity/mock/src/lib/runtime-dexie-mock.module.ts","../../../../libs/connectivity/mock/src/acorex-platform-client-connectivity-mock.ts"],"sourcesContent":["//#region ----- Imports -----\n\nimport { AXPFileStorageService } from '@acorex-platform/framework-client/common';\nimport {\n AXPFileManyStorageInfo,\n AXPFileStorageCreateRequest,\n AXPFileStorageFindRequest,\n AXPFileStorageInfo,\n AXPFileStorageStatus,\n AXPFileStorageUpdateRequest,\n createRandomUuid,\n} from '@acorex-platform/framework-shared/core';\nimport { Injectable } from '@angular/core';\n\n//#endregion\n\n//#region ----- Dexie file storage stub -----\n\n/**\n * In-memory file storage so the shell (logo resolver) can construct without\n * `client-connectivity-host` / HTTP. XOR hosts must not import the API module.\n */\n@Injectable()\nexport class AXCDexieFileStorageService extends AXPFileStorageService {\n private readonly files = new Map<string, { info: AXPFileStorageInfo; blob: Blob }>();\n\n getDownloadUrl(fileId: string): string {\n const row = this.files.get(fileId);\n return row ? URL.createObjectURL(row.blob) : '';\n }\n\n async download(fileId: string): Promise<Blob> {\n const row = this.files.get(fileId);\n if (!row) {\n throw new Error(`Dexie mock has no file '${fileId}'`);\n }\n return row.blob;\n }\n\n async save(request: AXPFileStorageCreateRequest): Promise<AXPFileStorageInfo> {\n const fileId = createRandomUuid();\n const info: AXPFileStorageInfo = {\n fileId,\n id: fileId,\n refId: request.refId,\n refType: request.refType,\n category: request.category,\n name: request.name ?? request.file.name,\n mimeType: request.file.type || 'application/octet-stream',\n size: request.file.size,\n isPrimary: request.isPrimary,\n isPublic: false,\n status: request.status ?? AXPFileStorageStatus.Temporary,\n uploadedAt: new Date(),\n binary: request.file,\n metadata: request.path ? { path: request.path } : request.metadata,\n };\n this.files.set(fileId, { info, blob: request.file });\n return info;\n }\n\n async update(request: AXPFileStorageUpdateRequest): Promise<AXPFileStorageInfo> {\n const row = this.files.get(request.fileId);\n if (!row) {\n throw new Error(`Dexie mock has no file '${request.fileId}'`);\n }\n row.info = {\n ...row.info,\n name: request.name ?? row.info.name,\n isPrimary: request.isPrimary ?? row.info.isPrimary,\n metadata: request.path\n ? { ...(row.info.metadata ?? {}), path: request.path }\n : request.metadata ?? row.info.metadata,\n };\n return row.info;\n }\n\n async find(request: AXPFileStorageFindRequest): Promise<AXPFileStorageInfo[]> {\n return [...this.files.values()]\n .map((row) => row.info)\n .filter((info) => {\n if (request.refId && info.refId !== request.refId) {\n return false;\n }\n if (request.refType && info.refType !== request.refType) {\n return false;\n }\n if (request.category && info.category !== request.category) {\n return false;\n }\n return true;\n });\n }\n\n async findMany(ids: string[]): Promise<AXPFileManyStorageInfo[]> {\n return ids\n .map((id) => this.files.get(id)?.info)\n .filter((info): info is AXPFileStorageInfo => info != null)\n .map((info) => ({ ...info, fileId: info.fileId }));\n }\n\n async getInfo(fileId: string): Promise<AXPFileStorageInfo> {\n const row = this.files.get(fileId);\n if (!row) {\n throw new Error(`Dexie mock has no file '${fileId}'`);\n }\n return row.info;\n }\n\n async remove(fileId: string): Promise<void> {\n this.files.delete(fileId);\n }\n\n async commit(fileId: string): Promise<void> {\n const row = this.files.get(fileId);\n if (row) {\n row.info.status = AXPFileStorageStatus.Committed;\n }\n }\n\n async markForDeletion(fileId: string): Promise<void> {\n const row = this.files.get(fileId);\n if (row) {\n row.info.status = AXPFileStorageStatus.PendingDeletion;\n }\n }\n}\n\n//#endregion\n","//#region ----- Imports -----\n\nimport Dexie, { type Table } from 'dexie';\n\n//#endregion\n\n//#region ----- Types -----\n\nexport interface AXCDexieStoredRecord {\n /** `${entity}|${id}` */\n storageId: string;\n entity: string;\n id: string;\n payload: Record<string, unknown>;\n}\n\nexport interface AXCDexieStoreMeta {\n entity: string;\n seedVersion: string;\n}\n\n//#endregion\n\n//#region ----- Dexie DB -----\n\nexport class AXCDexieClientStore extends Dexie {\n records!: Table<AXCDexieStoredRecord, string>;\n meta!: Table<AXCDexieStoreMeta, string>;\n\n constructor() {\n super('ACoreXClientStore');\n this.version(1).stores({\n records: 'storageId, entity, id, [entity+id]',\n meta: 'entity',\n });\n }\n}\n\nexport const axcDexieClientStore = new AXCDexieClientStore();\n\nexport function buildDexieStorageId(entity: string, id: string): string {\n return `${entity}|${id}`;\n}\n\n//#endregion\n","//#region ----- Imports -----\n\nimport type { AXPQueryRequest } from '@acorex-platform/framework-shared/core';\nimport { createRandomUuid } from '@acorex-platform/framework-shared/core';\nimport type {\n AXPEntityAggregateRequest,\n AXPEntityAggregateResult,\n AXPEntityQueryAllOptions,\n AXPEntityQueryAllResult,\n} from '@acorex-platform/framework-shared/entity';\nimport { computeEntityAggregates, filterSortEntityRows, runEntityQuery } from '@acorex-platform/framework-client/layout/entity';\nimport { Injectable } from '@angular/core';\n\nimport {\n axcDexieClientStore,\n buildDexieStorageId,\n type AXCDexieStoredRecord,\n} from './client-store.indexed-db';\n\n//#endregion\n\n//#region ----- Helpers -----\n\nfunction asRecord(value: unknown): Record<string, unknown> | null {\n if (value != null && typeof value === 'object' && !Array.isArray(value)) {\n return value as Record<string, unknown>;\n }\n return null;\n}\n\nfunction recordId(value: unknown): string | null {\n const obj = asRecord(value);\n if (!obj || obj['id'] == null || obj['id'] === '') {\n return null;\n }\n return String(obj['id']);\n}\n\nfunction toPayload(value: unknown): Record<string, unknown> | null {\n const obj = asRecord(value);\n return obj ? { ...obj } : null;\n}\n\n//#endregion\n\n//#region ----- Dexie entity storage -----\n\n@Injectable()\nexport class AXCDexieEntityStorageService {\n readonly dbName = 'ACoreXClientStore';\n\n async initial(entityName: string, collection: unknown[]): Promise<unknown[]> {\n const rows = collection ?? [];\n for (const item of rows) {\n await this.upsertOne(entityName, item as Record<string, unknown>, { merge: true });\n }\n return rows;\n }\n\n async getSeedVersion(entityName: string): Promise<string | null> {\n const row = await axcDexieClientStore.meta.get(entityName);\n return row?.seedVersion ?? null;\n }\n\n async setSeedVersion(entityName: string, seedVersion: string): Promise<void> {\n await axcDexieClientStore.meta.put({ entity: entityName, seedVersion });\n }\n\n async getOne(entityName: string, id: unknown): Promise<Record<string, unknown>> {\n const key = id == null || id === '' ? '' : String(id);\n if (!key) {\n throw new Error(`Entity not found: ${entityName}/`);\n }\n const row = await axcDexieClientStore.records.get(buildDexieStorageId(entityName, key));\n if (!row) {\n throw new Error(`Entity not found: ${entityName}/${key}`);\n }\n return { ...row.payload };\n }\n\n async getAll(entityName: string): Promise<Record<string, unknown>[]> {\n const rows = await axcDexieClientStore.records.where('entity').equals(entityName).toArray();\n return rows.map((row) => ({ ...row.payload }));\n }\n\n async query(\n entityName: string,\n request: AXPQueryRequest,\n ): Promise<{ items: Record<string, unknown>[]; total: number }> {\n return runEntityQuery(entityName, request, this.queryAdapters());\n }\n\n async count(entityName: string, request: Pick<AXPQueryRequest, 'filter' | 'sort'>): Promise<number> {\n const rows = await filterSortEntityRows(entityName, request, this.queryAdapters());\n return rows.length;\n }\n\n async queryAll(\n entityName: string,\n request: Pick<AXPQueryRequest, 'filter' | 'sort'>,\n options?: AXPEntityQueryAllOptions,\n ): Promise<AXPEntityQueryAllResult<Record<string, unknown>>> {\n const rows = await filterSortEntityRows(entityName, request, this.queryAdapters());\n const maxRows = options?.maxRows ?? 100_000;\n const items = rows.slice(0, maxRows);\n return {\n items,\n total: rows.length,\n truncated: rows.length > items.length,\n };\n }\n\n async getMany(entityName: string, ids: unknown[]): Promise<(Record<string, unknown> | null)[]> {\n return Promise.all(\n ids.map(async (id) => {\n try {\n return await this.getOne(entityName, id);\n } catch {\n return null;\n }\n }),\n );\n }\n\n async exists(entityName: string, id: unknown): Promise<boolean> {\n try {\n await this.getOne(entityName, id);\n return true;\n } catch {\n return false;\n }\n }\n\n async insertOne(entityName: string, entity: unknown): Promise<string> {\n const payload = toPayload(entity) ?? {};\n const id = recordId(payload) ?? createRandomUuid();\n payload['id'] = id;\n const stored: AXCDexieStoredRecord = {\n storageId: buildDexieStorageId(entityName, id),\n entity: entityName,\n id,\n payload,\n };\n await axcDexieClientStore.records.put(stored);\n return id;\n }\n\n async updateOne(\n entityName: string,\n id: unknown,\n patch: Record<string, unknown>,\n ): Promise<Record<string, unknown>> {\n const current = await this.getOne(entityName, id);\n const next = { ...current, ...patch, id: current['id'] };\n const key = String(current['id']);\n await axcDexieClientStore.records.put({\n storageId: buildDexieStorageId(entityName, key),\n entity: entityName,\n id: key,\n payload: next,\n });\n return next;\n }\n\n async deleteOne(entityName: string, id: unknown): Promise<void> {\n const key = id == null || id === '' ? '' : String(id);\n if (!key) {\n return;\n }\n await axcDexieClientStore.records.delete(buildDexieStorageId(entityName, key));\n }\n\n async upsertOne(\n entityName: string,\n entity: Record<string, unknown>,\n options?: { merge?: boolean },\n ): Promise<string> {\n const id = recordId(entity);\n if (id != null && (await this.exists(entityName, id))) {\n const merge = options?.merge !== false;\n const existing = await this.getOne(entityName, id);\n const next = merge ? { ...existing, ...entity, id } : { ...entity, id };\n const { id: _omit, ...patch } = next;\n await this.updateOne(entityName, id, patch);\n return id;\n }\n return this.insertOne(entityName, entity);\n }\n\n async aggregate(\n entityName: string,\n request: AXPEntityAggregateRequest,\n queryRequest?: Pick<AXPQueryRequest, 'filter' | 'sort'>,\n ): Promise<AXPEntityAggregateResult> {\n const rows = await filterSortEntityRows(entityName, queryRequest ?? {}, this.queryAdapters());\n return { rows: computeEntityAggregates(rows, request) };\n }\n\n private queryAdapters() {\n return {\n getRawAll: (name: string) => this.getAll(name),\n getDirectChildCount: async (categoryId: string, name: string) => {\n const rows = await this.getAll(name);\n return rows.filter((row) => String(row['parentId'] ?? '') === String(categoryId)).length;\n },\n getAllChildCategoryIds: async (categoryId: string, name: string) => {\n const all = await this.getAll(name);\n const children = new Set<string>([String(categoryId)]);\n let added = true;\n while (added) {\n added = false;\n for (const row of all) {\n const id = recordId(row);\n const parent = row['parentId'] == null ? '' : String(row['parentId']);\n if (id && parent && children.has(parent) && !children.has(id)) {\n children.add(id);\n added = true;\n }\n }\n }\n return [...children];\n },\n };\n }\n}\n\n//#endregion\n","//#region ----- Auth catalog entity names -----\n\n/** Local-owned rows the Dexie auth dispatcher reads. Hosts seed these via `provideDexieSeeds`. */\nexport const AXC_DEXIE_AUTH_USER_ENTITY = 'Auth.User';\nexport const AXC_DEXIE_AUTH_TENANT_ENTITY = 'Auth.Tenant';\nexport const AXC_DEXIE_AUTH_APPLICATION_ENTITY = 'Auth.Application';\n\n//#endregion\n","//#region ----- Imports -----\n\nimport type { AXPApplication, AXPTenant, AXPUser } from '@acorex-platform/framework-client/auth';\nimport { InjectionToken } from '@angular/core';\n\n//#endregion\n\n//#region ----- Types -----\n\n/** Identity returned by Dexie `Auth:SignIn` / refresh / update-session stubs. */\nexport interface AXCDexieMockIdentity {\n user: AXPUser;\n tenant: AXPTenant;\n application: AXPApplication;\n}\n\n//#endregion\n\n//#region ----- Defaults -----\n\nexport const AXC_DEXIE_DEFAULT_IDENTITY: AXCDexieMockIdentity = {\n user: {\n id: 'local-user',\n name: 'local',\n title: 'Local User',\n avatar: null,\n },\n tenant: {\n id: 'local-tenant',\n name: 'local',\n title: 'Local Tenant',\n },\n application: {\n id: 'local-app',\n name: 'local',\n title: 'Local App',\n },\n};\n\n//#endregion\n\n//#region ----- Tokens -----\n\nexport const AXP_DEXIE_MOCK_IDENTITY = new InjectionToken<AXCDexieMockIdentity>('AXP_DEXIE_MOCK_IDENTITY', {\n providedIn: 'root',\n factory: () => AXC_DEXIE_DEFAULT_IDENTITY,\n});\n\n//#endregion\n","//#region ----- Imports -----\n\nimport type { AXPRuntimeCommandResult, AXPRuntimeQueryResult } from '@acorex-platform/framework-shared/core';\nimport {\n runtimeCommandFailure,\n runtimeCommandSuccessObject,\n runtimeQuerySuccessCollection,\n runtimeQuerySuccessObject,\n} from '@acorex-platform/framework-shared/core';\nimport {\n AUTH_GET_ACCESS_POLICY_DEFAULT,\n AUTH_LIST_APPLICATIONS_DEFAULT,\n AUTH_LIST_OWN_DEVICE_SESSIONS_DEFAULT,\n AUTH_LIST_PROVIDERS_DEFAULT,\n AUTH_LIST_TENANTS_DEFAULT,\n AUTH_LOGOUT_DEFAULT,\n AUTH_REFRESH_DEFAULT,\n AUTH_REGISTER_DEFAULT,\n AUTH_SIGN_IN_DEFAULT,\n AUTH_TERMINATE_OWN_DEVICE_SESSION_DEFAULT,\n AUTH_UPDATE_SESSION_DEFAULT,\n AUTH_VERIFY_TWO_FACTOR_DEFAULT,\n} from '@acorex-platform/framework-shared/runtime';\nimport { inject, Injectable } from '@angular/core';\n\nimport { AXCDexieEntityStorageService } from '../dexie/dexie-entity-storage.service';\nimport {\n AXC_DEXIE_AUTH_APPLICATION_ENTITY,\n AXC_DEXIE_AUTH_TENANT_ENTITY,\n AXC_DEXIE_AUTH_USER_ENTITY,\n} from '../seed/dexie-auth-catalog.constants';\nimport type { AXCDexieMockIdentity } from '../session/dexie-session.token';\nimport { AXP_DEXIE_MOCK_IDENTITY } from '../session/dexie-session.token';\n\n//#endregion\n\n//#region ----- Constants -----\n\nconst AUTH_COMMAND_KEYS = new Set<string>([\n AUTH_SIGN_IN_DEFAULT,\n AUTH_REGISTER_DEFAULT,\n AUTH_REFRESH_DEFAULT,\n AUTH_LOGOUT_DEFAULT,\n AUTH_UPDATE_SESSION_DEFAULT,\n AUTH_VERIFY_TWO_FACTOR_DEFAULT,\n AUTH_TERMINATE_OWN_DEVICE_SESSION_DEFAULT,\n]);\n\nconst AUTH_QUERY_KEYS = new Set<string>([\n AUTH_LIST_PROVIDERS_DEFAULT,\n AUTH_LIST_TENANTS_DEFAULT,\n AUTH_LIST_APPLICATIONS_DEFAULT,\n AUTH_LIST_OWN_DEVICE_SESSIONS_DEFAULT,\n AUTH_GET_ACCESS_POLICY_DEFAULT,\n]);\n\n//#endregion\n\n//#region ----- Helpers -----\n\nfunction asRecord(value: unknown): Record<string, unknown> | null {\n if (value != null && typeof value === 'object' && !Array.isArray(value)) {\n return value as Record<string, unknown>;\n }\n return null;\n}\n\nfunction asString(value: unknown): string {\n return value == null ? '' : String(value).trim();\n}\n\n//#endregion\n\n//#region ----- Auth dispatcher -----\n\n@Injectable()\nexport class AXCDexieAuthRuntimeDispatcher {\n private readonly storage = inject(AXCDexieEntityStorageService);\n private readonly fallbackIdentity = inject(AXP_DEXIE_MOCK_IDENTITY);\n private current: AXCDexieMockIdentity | null = null;\n\n canHandleCommand(name: string): boolean {\n return AUTH_COMMAND_KEYS.has(name);\n }\n\n canHandleQuery(name: string): boolean {\n return AUTH_QUERY_KEYS.has(name);\n }\n\n async executeCommand(name: string, input?: unknown): Promise<AXPRuntimeCommandResult> {\n if (name === AUTH_LOGOUT_DEFAULT || name === AUTH_TERMINATE_OWN_DEVICE_SESSION_DEFAULT) {\n this.current = null;\n return runtimeCommandSuccessObject({});\n }\n if (name === AUTH_SIGN_IN_DEFAULT) {\n return this.signIn(input);\n }\n if (name === AUTH_REGISTER_DEFAULT) {\n return runtimeCommandFailure('Registration is not enabled in the Dexie mock.', {\n code: 'DEXIE_AUTH_REGISTER_DISABLED',\n });\n }\n return runtimeCommandSuccessObject(this.tokenResponse());\n }\n\n async executeQuery(name: string): Promise<AXPRuntimeQueryResult> {\n if (name === AUTH_LIST_PROVIDERS_DEFAULT) {\n return runtimeQuerySuccessObject({\n localMethods: [{ id: 'user-pass', title: 'Password', protocol: 'password', enabled: true }],\n identityProviders: [],\n });\n }\n if (name === AUTH_LIST_TENANTS_DEFAULT) {\n const tenants = await this.storage.getAll(AXC_DEXIE_AUTH_TENANT_ENTITY);\n return runtimeQuerySuccessCollection(tenants.length > 0 ? tenants : [this.tenantRow()]);\n }\n if (name === AUTH_LIST_APPLICATIONS_DEFAULT) {\n const applications = await this.storage.getAll(AXC_DEXIE_AUTH_APPLICATION_ENTITY);\n return runtimeQuerySuccessCollection(applications.length > 0 ? applications : [this.applicationRow()]);\n }\n if (name === AUTH_LIST_OWN_DEVICE_SESSIONS_DEFAULT) {\n return runtimeQuerySuccessCollection([]);\n }\n if (name === AUTH_GET_ACCESS_POLICY_DEFAULT) {\n return runtimeQuerySuccessObject({\n permissions: ['*'],\n modulesAndFeatures: { modules: ['*'], features: {} },\n });\n }\n return runtimeQuerySuccessObject({});\n }\n\n private async signIn(input: unknown): Promise<AXPRuntimeCommandResult> {\n const body = asRecord(input) ?? {};\n const username = asString(body['username']).toLowerCase();\n const password = asString(body['password']);\n if (!username || !password) {\n return runtimeCommandFailure('Invalid username or password', { code: 'DEXIE_AUTH_INVALID_CREDENTIALS' });\n }\n\n const users = await this.storage.getAll(AXC_DEXIE_AUTH_USER_ENTITY);\n const user = users.find((row) => asString(row['username']).toLowerCase() === username);\n if (!user || asString(user['password']) !== password) {\n return runtimeCommandFailure('Invalid username or password', { code: 'DEXIE_AUTH_INVALID_CREDENTIALS' });\n }\n\n const tenantId = asString(user['tenantId']);\n const applicationId = asString(user['applicationId']);\n const tenant =\n (tenantId ? await this.tryGet(AXC_DEXIE_AUTH_TENANT_ENTITY, tenantId) : null) ?? this.tenantRow();\n const application =\n (applicationId ? await this.tryGet(AXC_DEXIE_AUTH_APPLICATION_ENTITY, applicationId) : null) ??\n this.applicationRow();\n\n this.current = {\n user: {\n id: asString(user['id']),\n name: asString(user['name'] || user['username']),\n title: asString(user['title'] || user['username']),\n avatar: null,\n },\n tenant: {\n id: asString(tenant['id']),\n name: asString(tenant['name']),\n title: asString(tenant['title'] || tenant['name']),\n },\n application: {\n id: asString(application['id']),\n name: asString(application['name']),\n title: asString(application['title'] || application['name']),\n },\n };\n return runtimeCommandSuccessObject(this.tokenResponse());\n }\n\n private async tryGet(entity: string, id: string): Promise<Record<string, unknown> | null> {\n try {\n return await this.storage.getOne(entity, id);\n } catch {\n return null;\n }\n }\n\n private tokenResponse() {\n const identity = this.current ?? this.fallbackIdentity;\n return {\n accessToken: 'mock-access',\n refreshToken: 'mock-refresh',\n expiresIn: '24h',\n user: identity.user,\n tenant: {\n id: identity.tenant.id,\n name: identity.tenant.name,\n title: identity.tenant.title,\n },\n application: {\n id: identity.application.id,\n name: identity.application.name,\n title: identity.application.title,\n },\n };\n }\n\n private tenantRow() {\n const tenant = (this.current ?? this.fallbackIdentity).tenant;\n return {\n id: tenant.id,\n name: tenant.name,\n title: tenant.title,\n };\n }\n\n private applicationRow() {\n const application = (this.current ?? this.fallbackIdentity).application;\n return {\n id: application.id,\n name: application.name,\n title: application.title,\n };\n }\n}\n\n//#endregion\n","//#region ----- Imports -----\n\nimport type { AXPQueryRequest, AXPRuntimeCommandResult, AXPRuntimeQueryResult } from '@acorex-platform/framework-shared/core';\nimport {\n createRandomUuid,\n runtimeCommandFailure,\n runtimeCommandSuccessObject,\n runtimeQueryFailure,\n runtimeQuerySuccessCollection,\n runtimeQuerySuccessObject,\n} from '@acorex-platform/framework-shared/core';\nimport type { AXPEntityAggregateRequest } from '@acorex-platform/framework-shared/entity';\nimport {\n AXP_BULK_COMMAND_DEFAULT_MAX_ITEMS,\n AXP_BULK_COMMAND_HARD_MAX_ITEMS,\n parseDefaultEntityRuntimeKey,\n parseEntityCommandKey,\n resolveEntityNameFromRuntimeInput,\n type AXPBulkCommandRequest,\n type AXPBulkCommandResultData,\n type EntityCommandOperation,\n} from '@acorex-platform/framework-shared/runtime';\nimport { inject, Injectable } from '@angular/core';\n\nimport { AXCDexieEntityStorageService } from '../dexie/dexie-entity-storage.service';\n\n//#endregion\n\n//#region ----- Input helpers -----\n\nfunction asRecord(value: unknown): Record<string, unknown> | null {\n if (value != null && typeof value === 'object' && !Array.isArray(value)) {\n return value as Record<string, unknown>;\n }\n return null;\n}\n\nfunction resolveEntityName(name: string, input: unknown): string | null {\n const fromDefault = parseDefaultEntityRuntimeKey(name);\n if (fromDefault) {\n return resolveEntityNameFromRuntimeInput(input);\n }\n return parseEntityCommandKey(name)?.entity ?? null;\n}\n\nfunction resolveOperation(name: string): EntityCommandOperation | null {\n return parseDefaultEntityRuntimeKey(name) ?? parseEntityCommandKey(name)?.operation ?? null;\n}\n\nfunction extractId(input: unknown): string | null {\n const obj = asRecord(input);\n if (!obj || obj['id'] == null || obj['id'] === '') {\n return null;\n }\n return String(obj['id']);\n}\n\nfunction extractRecordBody(input: unknown): Record<string, unknown> {\n const obj = asRecord(input) ?? {};\n const nested = asRecord(obj['data']);\n const source = nested ?? obj;\n const { entity: _entity, data: _data, ...rest } = source;\n return rest;\n}\n\nfunction extractQueryRequest(input: unknown): AXPQueryRequest {\n const obj = asRecord(input) ?? {};\n const nested = asRecord(obj['queryRequest']);\n const source = nested ?? obj;\n return {\n skip: typeof source['skip'] === 'number' ? source['skip'] : 0,\n take: typeof source['take'] === 'number' ? source['take'] : 10,\n filter: source['filter'] as AXPQueryRequest['filter'],\n sort: source['sort'] as AXPQueryRequest['sort'],\n params: source['params'] as AXPQueryRequest['params'],\n };\n}\n\nfunction extractAggregate(input: unknown): AXPEntityAggregateRequest | null {\n const obj = asRecord(input);\n const agg = obj?.['aggregate'];\n if (agg != null && typeof agg === 'object' && !Array.isArray(agg)) {\n return agg as AXPEntityAggregateRequest;\n }\n return null;\n}\n\n//#endregion\n\n//#region ----- Entity dispatcher -----\n\n@Injectable()\nexport class AXCDexieEntityRuntimeDispatcher {\n private readonly storage = inject(AXCDexieEntityStorageService);\n\n canHandleCommand(name: string): boolean {\n const operation = resolveOperation(name);\n return operation === 'Insert' || operation === 'Update' || operation === 'Delete';\n }\n\n canHandleQuery(name: string): boolean {\n const operation = resolveOperation(name);\n return operation === 'Query' || operation === 'GetById';\n }\n\n async executeCommand(name: string, input: unknown): Promise<AXPRuntimeCommandResult> {\n const entity = resolveEntityName(name, input);\n const operation = resolveOperation(name);\n if (!entity || !operation) {\n return runtimeCommandFailure(`Dexie mock cannot resolve entity for '${name}'`, {\n code: 'DEXIE_ENTITY_UNRESOLVED',\n });\n }\n\n try {\n if (operation === 'Insert') {\n const body = extractRecordBody(input);\n const id = await this.storage.insertOne(entity, body);\n const record = await this.storage.getOne(entity, id);\n return runtimeCommandSuccessObject({ id, record });\n }\n if (operation === 'Update') {\n const id = extractId(input);\n if (!id) {\n return runtimeCommandFailure('Update requires id', { code: 'DEXIE_ENTITY_ID_REQUIRED' });\n }\n const record = await this.storage.updateOne(entity, id, extractRecordBody(input));\n return runtimeCommandSuccessObject({ id, record });\n }\n if (operation === 'Delete') {\n const id = extractId(input);\n if (!id) {\n return runtimeCommandFailure('Delete requires id', { code: 'DEXIE_ENTITY_ID_REQUIRED' });\n }\n await this.storage.deleteOne(entity, id);\n return runtimeCommandSuccessObject({ id });\n }\n return runtimeCommandFailure(`'${name}' is a query, not a command`, { code: 'DEXIE_ENTITY_WRONG_KIND' });\n } catch (error) {\n return runtimeCommandFailure(error instanceof Error ? error.message : String(error), {\n code: 'DEXIE_ENTITY_COMMAND_FAILED',\n });\n }\n }\n\n async executeQuery(name: string, input: unknown): Promise<AXPRuntimeQueryResult> {\n const entity = resolveEntityName(name, input);\n const operation = resolveOperation(name);\n if (!entity || !operation) {\n return runtimeQueryFailure(`Dexie mock cannot resolve entity for '${name}'`, {\n code: 'DEXIE_ENTITY_UNRESOLVED',\n });\n }\n\n try {\n if (operation === 'GetById') {\n const id = extractId(input);\n if (!id) {\n return runtimeQueryFailure('GetById requires id', { code: 'DEXIE_ENTITY_ID_REQUIRED' });\n }\n const record = await this.storage.getOne(entity, id);\n return runtimeQuerySuccessObject(record);\n }\n\n if (operation !== 'Query') {\n return runtimeQueryFailure(`'${name}' is not a query`, { code: 'DEXIE_ENTITY_WRONG_KIND' });\n }\n\n const obj = asRecord(input) ?? {};\n const byId = extractId(input);\n if (byId && obj['queryRequest'] == null && obj['skip'] == null && obj['filter'] == null) {\n const record = await this.storage.getOne(entity, byId);\n return runtimeQuerySuccessObject(record);\n }\n\n const aggregate = extractAggregate(input);\n if (aggregate) {\n const request = extractQueryRequest(input);\n const result = await this.storage.aggregate(entity, aggregate, request);\n const total = await this.storage.count(entity, request);\n return runtimeQuerySuccessCollection({\n items: [],\n total,\n aggregateRows: result.rows,\n });\n }\n\n const resultMode = typeof obj['resultMode'] === 'string' ? obj['resultMode'] : null;\n const request = extractQueryRequest(input);\n if (resultMode === 'count') {\n const total = await this.storage.count(entity, request);\n return runtimeQuerySuccessCollection({ items: [], total });\n }\n if (resultMode === 'all') {\n const page = await this.storage.queryAll(entity, request);\n return runtimeQuerySuccessCollection(page);\n }\n\n const page = await this.storage.query(entity, request);\n return runtimeQuerySuccessCollection(page);\n } catch (error) {\n return runtimeQueryFailure(error instanceof Error ? error.message : String(error), {\n code: 'DEXIE_ENTITY_QUERY_FAILED',\n });\n }\n }\n\n async executeBulk(request: AXPBulkCommandRequest): Promise<AXPRuntimeCommandResult<AXPBulkCommandResultData>> {\n const maxItems = Math.min(\n request.maxItems ?? AXP_BULK_COMMAND_DEFAULT_MAX_ITEMS,\n AXP_BULK_COMMAND_HARD_MAX_ITEMS,\n );\n const idField = request.idField?.trim() || 'id';\n const page = await this.storage.query(request.entity, {\n filter: request.filter,\n skip: 0,\n take: maxItems + 1,\n });\n const truncated = page.total > maxItems || page.items.length > maxItems;\n const targets = page.items.slice(0, maxItems);\n const results: AXPBulkCommandResultData['results'] = [];\n\n for (const row of targets) {\n const id = row[idField] == null ? createRandomUuid() : String(row[idField]);\n const perItem = {\n entity: request.entity,\n [idField]: id,\n ...(request.input ?? {}),\n };\n const result = await this.executeCommand(request.name, perItem);\n results.push({\n id,\n success: result.success === true,\n data: result.success ? result.data : undefined,\n message: result.message,\n });\n }\n\n const succeeded = results.filter((item) => item.success).length;\n return runtimeCommandSuccessObject({\n total: results.length,\n succeeded,\n failed: results.length - succeeded,\n truncated: truncated || undefined,\n results,\n });\n }\n}\n\n//#endregion\n","import type { AXPSettingsSyncKeys } from '@acorex-platform/framework-shared/core';\n\n//#region ----- Settings CQRS keys -----\n\n/**\n * Same keys as settings-management contracts. Duplicated so this lib does not\n * import that module (XOR hosts must not pull `client-connectivity-api`).\n */\nexport const AXC_DEXIE_SETTINGS_SCOPED_FETCH = 'SettingsManagement:ScopedSettings:Fetch';\nexport const AXC_DEXIE_SETTINGS_SCOPED_PATCH = 'SettingsManagement:ScopedSettings:Patch';\n\nexport const AXC_DEXIE_SETTINGS_SYNC_KEYS: AXPSettingsSyncKeys = {\n scopedFetchQueryKey: AXC_DEXIE_SETTINGS_SCOPED_FETCH,\n scopedPatchCommandKey: AXC_DEXIE_SETTINGS_SCOPED_PATCH,\n};\n\n//#endregion\n","//#region ----- Imports -----\n\nimport type { AXPRuntimeCommandResult, AXPRuntimeQueryResult } from '@acorex-platform/framework-shared/core';\nimport {\n runtimeCommandSuccessObject,\n runtimeQuerySuccessCollection,\n runtimeQuerySuccessObject,\n} from '@acorex-platform/framework-shared/core';\nimport {\n DOMAIN_GET_ENTITY_LAYOUT_DEFAULT,\n DOMAIN_LIST_ENTITY_LAYOUTS_DEFAULT,\n} from '@acorex-platform/framework-shared/runtime';\nimport { Injectable } from '@angular/core';\n\nimport {\n AXC_DEXIE_SETTINGS_SCOPED_FETCH,\n AXC_DEXIE_SETTINGS_SCOPED_PATCH,\n} from '../settings/dexie-settings-sync.constants';\n\n//#endregion\n\n//#region ----- Constants -----\n\nconst SYSTEM_COMMAND_KEYS = new Set<string>([AXC_DEXIE_SETTINGS_SCOPED_PATCH]);\nconst SYSTEM_QUERY_KEYS = new Set<string>([\n AXC_DEXIE_SETTINGS_SCOPED_FETCH,\n DOMAIN_GET_ENTITY_LAYOUT_DEFAULT,\n DOMAIN_LIST_ENTITY_LAYOUTS_DEFAULT,\n]);\n\n//#endregion\n\n//#region ----- System dispatcher -----\n\n/**\n * Boot queries/commands the shell hits before any host handler exists.\n * Domain layouts stay empty so hosts use {@code provideXxxLocalEntities()}.\n */\n@Injectable()\nexport class AXCDexieSystemRuntimeDispatcher {\n canHandleCommand(name: string): boolean {\n return SYSTEM_COMMAND_KEYS.has(name);\n }\n\n canHandleQuery(name: string): boolean {\n return SYSTEM_QUERY_KEYS.has(name);\n }\n\n executeCommand(name: string): AXPRuntimeCommandResult {\n if (name === AXC_DEXIE_SETTINGS_SCOPED_PATCH) {\n return runtimeCommandSuccessObject({ updatedAt: new Date().toISOString() });\n }\n return runtimeCommandSuccessObject({});\n }\n\n executeQuery(name: string): AXPRuntimeQueryResult {\n if (name === AXC_DEXIE_SETTINGS_SCOPED_FETCH) {\n return runtimeQuerySuccessObject({\n changed: false,\n updatedAt: null,\n values: {},\n });\n }\n if (name === DOMAIN_GET_ENTITY_LAYOUT_DEFAULT) {\n return runtimeQuerySuccessObject(null);\n }\n if (name === DOMAIN_LIST_ENTITY_LAYOUTS_DEFAULT) {\n return runtimeQuerySuccessCollection([]);\n }\n return runtimeQuerySuccessObject({});\n }\n}\n\n//#endregion\n","//#region ----- Imports -----\n\nimport {\n AXP_HOOK_PROVIDER,\n type AXPHookProvider,\n} from '@acorex-platform/framework-client/core';\nimport {\n AXPRuntimeRemoteHookKeys,\n type AXPRuntimeCommandBulkProgressHookPayload,\n type AXPRuntimeCommandExecuteBulkHookPayload,\n type AXPRuntimeCommandExecuteHookPayload,\n type AXPRuntimeQueryExecuteHookPayload,\n} from '@acorex-platform/framework-client/runtime';\nimport {\n runtimeCommandFailure,\n runtimeQueryFailure,\n} from '@acorex-platform/framework-shared/core';\nimport { inject, type Provider } from '@angular/core';\n\nimport { AXCDexieEntityStorageService } from '../dexie/dexie-entity-storage.service';\nimport { AXCDexieAuthRuntimeDispatcher } from './auth-runtime.dispatcher';\nimport { AXCDexieEntityRuntimeDispatcher } from './entity-runtime.dispatcher';\nimport { AXCDexieSystemRuntimeDispatcher } from './system-runtime.dispatcher';\n\n//#endregion\n\n//#region ----- Helpers -----\n\nfunction unhandledCommand(name: string) {\n return runtimeCommandFailure(\n `Dexie mock has no handler for command '${name}'. Register a local command in the host, or seed/use Entity:*:Default.`,\n { code: 'DEXIE_COMMAND_UNHANDLED' },\n );\n}\n\nfunction unhandledQuery(name: string) {\n return runtimeQueryFailure(\n `Dexie mock has no handler for query '${name}'. Register a local query in the host, or use Entity:Query:Default / Entity:GetById:Default.`,\n { code: 'DEXIE_QUERY_UNHANDLED' },\n );\n}\n\n//#endregion\n\n//#region ----- Hook providers -----\n\nexport const AXCDexieCommandExecuteHookProvider: AXPHookProvider<\n AXPRuntimeCommandExecuteHookPayload,\n AXPRuntimeCommandExecuteHookPayload\n> = {\n key: AXPRuntimeRemoteHookKeys.CommandExecute,\n async execute(payload) {\n if (payload.handled) {\n return payload;\n }\n const entities = inject(AXCDexieEntityRuntimeDispatcher);\n const auth = inject(AXCDexieAuthRuntimeDispatcher);\n const system = inject(AXCDexieSystemRuntimeDispatcher);\n\n if (entities.canHandleCommand(payload.name)) {\n return { ...payload, handled: true, result: await entities.executeCommand(payload.name, payload.input) };\n }\n if (auth.canHandleCommand(payload.name)) {\n return { ...payload, handled: true, result: await auth.executeCommand(payload.name, payload.input) };\n }\n if (system.canHandleCommand(payload.name)) {\n return { ...payload, handled: true, result: system.executeCommand(payload.name) };\n }\n return { ...payload, handled: true, result: unhandledCommand(payload.name) };\n },\n};\n\nexport const AXCDexieCommandExecuteBulkHookProvider: AXPHookProvider<\n AXPRuntimeCommandExecuteBulkHookPayload,\n AXPRuntimeCommandExecuteBulkHookPayload\n> = {\n key: AXPRuntimeRemoteHookKeys.CommandExecuteBulk,\n async execute(payload) {\n if (payload.handled) {\n return payload;\n }\n const entities = inject(AXCDexieEntityRuntimeDispatcher);\n const result = await entities.executeBulk(payload.request);\n return { ...payload, handled: true, result };\n },\n};\n\nexport const AXCDexieCommandBulkProgressHookProvider: AXPHookProvider<\n AXPRuntimeCommandBulkProgressHookPayload,\n AXPRuntimeCommandBulkProgressHookPayload\n> = {\n key: AXPRuntimeRemoteHookKeys.CommandBulkProgress,\n async execute(payload) {\n if (payload.handled) {\n return payload;\n }\n return {\n ...payload,\n handled: true,\n progress: {\n executionId: payload.executionId,\n entity: '',\n name: '',\n current: 0,\n total: 0,\n succeeded: 0,\n failed: 0,\n status: 'completed',\n },\n };\n },\n};\n\nexport const AXCDexieQueryExecuteHookProvider: AXPHookProvider<\n AXPRuntimeQueryExecuteHookPayload,\n AXPRuntimeQueryExecuteHookPayload\n> = {\n key: AXPRuntimeRemoteHookKeys.QueryExecute,\n async execute(payload) {\n if (payload.handled) {\n return payload;\n }\n const entities = inject(AXCDexieEntityRuntimeDispatcher);\n const auth = inject(AXCDexieAuthRuntimeDispatcher);\n const system = inject(AXCDexieSystemRuntimeDispatcher);\n\n if (entities.canHandleQuery(payload.name)) {\n return { ...payload, handled: true, result: await entities.executeQuery(payload.name, payload.input) };\n }\n if (auth.canHandleQuery(payload.name)) {\n return { ...payload, handled: true, result: await auth.executeQuery(payload.name) };\n }\n if (system.canHandleQuery(payload.name)) {\n return { ...payload, handled: true, result: system.executeQuery(payload.name) };\n }\n return { ...payload, handled: true, result: unhandledQuery(payload.name) };\n },\n};\n\nexport const AXC_DEXIE_RUNTIME_HOOK_PROVIDERS: Provider[] = [\n AXCDexieEntityStorageService,\n AXCDexieEntityRuntimeDispatcher,\n AXCDexieAuthRuntimeDispatcher,\n AXCDexieSystemRuntimeDispatcher,\n {\n provide: AXP_HOOK_PROVIDER,\n useValue: AXCDexieCommandExecuteHookProvider,\n multi: true,\n },\n {\n provide: AXP_HOOK_PROVIDER,\n useValue: AXCDexieCommandExecuteBulkHookProvider,\n multi: true,\n },\n {\n provide: AXP_HOOK_PROVIDER,\n useValue: AXCDexieCommandBulkProgressHookProvider,\n multi: true,\n },\n {\n provide: AXP_HOOK_PROVIDER,\n useValue: AXCDexieQueryExecuteHookProvider,\n multi: true,\n },\n];\n\n//#endregion\n","//#region ----- Imports -----\n\nimport { InjectionToken } from '@angular/core';\n\nimport type { AXCDexieSeed } from './dexie-seed.types';\n\n//#endregion\n\n//#region ----- Tokens -----\n\n/** Multi token — each host contribution is one `{ entity, rows }` bag. */\nexport const AXP_DEXIE_SEED = new InjectionToken<readonly AXCDexieSeed[]>('AXP_DEXIE_SEED');\n\n//#endregion\n","//#region ----- Imports -----\n\nimport { AXP_APP_STARTUP_PRIORITY, provideAppStartUpTask } from '@acorex-platform/framework-client/core';\nimport { inject, type Provider } from '@angular/core';\n\nimport { AXCDexieEntityStorageService } from '../dexie/dexie-entity-storage.service';\nimport { AXP_DEXIE_SEED } from './dexie-seed.token';\n\n//#endregion\n\n//#region ----- Seed startup -----\n\nexport function provideDexieSeedStartup(): Provider {\n return provideAppStartUpTask(() => {\n const storage = inject(AXCDexieEntityStorageService);\n const bags = inject(AXP_DEXIE_SEED, { optional: true }) ?? [];\n return {\n name: 'dexie-entity-seed',\n priority: AXP_APP_STARTUP_PRIORITY.moduleManifests,\n run: async () => {\n for (const bag of bags) {\n const entity = bag.entity?.trim();\n if (!entity) {\n continue;\n }\n await storage.initial(entity, bag.rows ?? []);\n const version = bag.version?.trim() || '1';\n await storage.setSeedVersion(entity, version);\n }\n },\n };\n });\n}\n\n//#endregion\n","//#region ----- Imports -----\n\nimport { AXP_SETTINGS_SYNC_KEYS, AXPFileStorageService } from '@acorex-platform/framework-client/common';\nimport type { Provider } from '@angular/core';\n\nimport { AXCDexieFileStorageService } from './file-storage/dexie-file-storage.service';\nimport { AXC_DEXIE_RUNTIME_HOOK_PROVIDERS } from './runtime/runtime-mock.hooks';\nimport { AXP_DEXIE_SEED } from './seed/dexie-seed.token';\nimport type { AXCDexieSeed } from './seed/dexie-seed.types';\nimport { provideDexieSeedStartup } from './seed/dexie-seed.startup';\nimport { AXC_DEXIE_SETTINGS_SYNC_KEYS } from './settings/dexie-settings-sync.constants';\n\n//#endregion\n\n//#region ----- Provider factory -----\n\n/**\n * IndexedDB CQRS transport: `runtime.command.execute` / `runtime.query.execute`\n * against Dexie {@code ACoreXClientStore}.\n *\n * XOR with {@code provideRuntimeRemoteTransport()} from\n * `@acorex-platform/client-connectivity-api`. Do not register both.\n */\nexport function provideDexieRuntimeTransport(): Provider[] {\n return [\n ...AXC_DEXIE_RUNTIME_HOOK_PROVIDERS,\n provideDexieSeedStartup(),\n { provide: AXP_SETTINGS_SYNC_KEYS, useValue: AXC_DEXIE_SETTINGS_SYNC_KEYS },\n { provide: AXPFileStorageService, useClass: AXCDexieFileStorageService },\n ];\n}\n\n/** Registers one or more entity row bags on {@link AXP_DEXIE_SEED}. */\nexport function provideDexieSeeds(...bags: AXCDexieSeed[]): Provider[] {\n return bags.map((bag) => ({\n provide: AXP_DEXIE_SEED,\n multi: true,\n useValue: bag,\n }));\n}\n\n//#endregion\n","//#region ----- Imports -----\n\nimport { NgModule } from '@angular/core';\n\nimport { provideDexieRuntimeTransport } from './provide-dexie-runtime-transport';\n\n//#endregion\n\n//#region ----- Module -----\n\n/**\n * Registers Dexie runtime CQRS hooks used when a query/command is not in\n * {@code provideQuerySetups} / {@code provideCommandSetups}.\n *\n * Do not import together with {@code AXCRuntimeRemoteApiModule}.\n */\n@NgModule({\n providers: provideDexieRuntimeTransport(),\n})\nexport class AXCRuntimeDexieMockModule {}\n\n//#endregion\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["asRecord"],"mappings":";;;;;;;;;;AAAA;AAcA;AAEA;AAEA;;;AAGG;AAEG,MAAO,0BAA2B,SAAQ,qBAAqB,CAAA;AADrE,IAAA,WAAA,GAAA;;AAEmB,QAAA,IAAA,CAAA,KAAK,GAAG,IAAI,GAAG,EAAoD;AAsGrF,IAAA;AApGC,IAAA,cAAc,CAAC,MAAc,EAAA;QAC3B,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC;AAClC,QAAA,OAAO,GAAG,GAAG,GAAG,CAAC,eAAe,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE;IACjD;IAEA,MAAM,QAAQ,CAAC,MAAc,EAAA;QAC3B,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC;QAClC,IAAI,CAAC,GAAG,EAAE;AACR,YAAA,MAAM,IAAI,KAAK,CAAC,2BAA2B,MAAM,CAAA,CAAA,CAAG,CAAC;QACvD;QACA,OAAO,GAAG,CAAC,IAAI;IACjB;IAEA,MAAM,IAAI,CAAC,OAAoC,EAAA;AAC7C,QAAA,MAAM,MAAM,GAAG,gBAAgB,EAAE;AACjC,QAAA,MAAM,IAAI,GAAuB;YAC/B,MAAM;AACN,YAAA,EAAE,EAAE,MAAM;YACV,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,OAAO,EAAE,OAAO,CAAC,OAAO;YACxB,QAAQ,EAAE,OAAO,CAAC,QAAQ;YAC1B,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,IAAI;AACvC,YAAA,QAAQ,EAAE,OAAO,CAAC,IAAI,CAAC,IAAI,IAAI,0BAA0B;AACzD,YAAA,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,IAAI;YACvB,SAAS,EAAE,OAAO,CAAC,SAAS;AAC5B,YAAA,QAAQ,EAAE,KAAK;AACf,YAAA,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,oBAAoB,CAAC,SAAS;YACxD,UAAU,EAAE,IAAI,IAAI,EAAE;YACtB,MAAM,EAAE,OAAO,CAAC,IAAI;AACpB,YAAA,QAAQ,EAAE,OAAO,CAAC,IAAI,GAAG,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,GAAG,OAAO,CAAC,QAAQ;SACnE;AACD,QAAA,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC;AACpD,QAAA,OAAO,IAAI;IACb;IAEA,MAAM,MAAM,CAAC,OAAoC,EAAA;AAC/C,QAAA,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC;QAC1C,IAAI,CAAC,GAAG,EAAE;YACR,MAAM,IAAI,KAAK,CAAC,CAAA,wBAAA,EAA2B,OAAO,CAAC,MAAM,CAAA,CAAA,CAAG,CAAC;QAC/D;QACA,GAAG,CAAC,IAAI,GAAG;YACT,GAAG,GAAG,CAAC,IAAI;YACX,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI,GAAG,CAAC,IAAI,CAAC,IAAI;YACnC,SAAS,EAAE,OAAO,CAAC,SAAS,IAAI,GAAG,CAAC,IAAI,CAAC,SAAS;YAClD,QAAQ,EAAE,OAAO,CAAC;AAChB,kBAAE,EAAE,IAAI,GAAG,CAAC,IAAI,CAAC,QAAQ,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI;kBAClD,OAAO,CAAC,QAAQ,IAAI,GAAG,CAAC,IAAI,CAAC,QAAQ;SAC1C;QACD,OAAO,GAAG,CAAC,IAAI;IACjB;IAEA,MAAM,IAAI,CAAC,OAAkC,EAAA;QAC3C,OAAO,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE;aAC3B,GAAG,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC,IAAI;AACrB,aAAA,MAAM,CAAC,CAAC,IAAI,KAAI;AACf,YAAA,IAAI,OAAO,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,KAAK,OAAO,CAAC,KAAK,EAAE;AACjD,gBAAA,OAAO,KAAK;YACd;AACA,YAAA,IAAI,OAAO,CAAC,OAAO,IAAI,IAAI,CAAC,OAAO,KAAK,OAAO,CAAC,OAAO,EAAE;AACvD,gBAAA,OAAO,KAAK;YACd;AACA,YAAA,IAAI,OAAO,CAAC,QAAQ,IAAI,IAAI,CAAC,QAAQ,KAAK,OAAO,CAAC,QAAQ,EAAE;AAC1D,gBAAA,OAAO,KAAK;YACd;AACA,YAAA,OAAO,IAAI;AACb,QAAA,CAAC,CAAC;IACN;IAEA,MAAM,QAAQ,CAAC,GAAa,EAAA;AAC1B,QAAA,OAAO;AACJ,aAAA,GAAG,CAAC,CAAC,EAAE,KAAK,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,IAAI;aACpC,MAAM,CAAC,CAAC,IAAI,KAAiC,IAAI,IAAI,IAAI;AACzD,aAAA,GAAG,CAAC,CAAC,IAAI,MAAM,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;IACtD;IAEA,MAAM,OAAO,CAAC,MAAc,EAAA;QAC1B,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC;QAClC,IAAI,CAAC,GAAG,EAAE;AACR,YAAA,MAAM,IAAI,KAAK,CAAC,2BAA2B,MAAM,CAAA,CAAA,CAAG,CAAC;QACvD;QACA,OAAO,GAAG,CAAC,IAAI;IACjB;IAEA,MAAM,MAAM,CAAC,MAAc,EAAA;AACzB,QAAA,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC;IAC3B;IAEA,MAAM,MAAM,CAAC,MAAc,EAAA;QACzB,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC;QAClC,IAAI,GAAG,EAAE;YACP,GAAG,CAAC,IAAI,CAAC,MAAM,GAAG,oBAAoB,CAAC,SAAS;QAClD;IACF;IAEA,MAAM,eAAe,CAAC,MAAc,EAAA;QAClC,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC;QAClC,IAAI,GAAG,EAAE;YACP,GAAG,CAAC,IAAI,CAAC,MAAM,GAAG,oBAAoB,CAAC,eAAe;QACxD;IACF;8GAtGW,0BAA0B,EAAA,IAAA,EAAA,IAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA,CAAA;kHAA1B,0BAA0B,EAAA,CAAA,CAAA;;2FAA1B,0BAA0B,EAAA,UAAA,EAAA,CAAA;kBADtC;;;ACtBD;AAqBA;AAEA;AAEM,MAAO,mBAAoB,SAAQ,KAAK,CAAA;AAI5C,IAAA,WAAA,GAAA;QACE,KAAK,CAAC,mBAAmB,CAAC;AAC1B,QAAA,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;AACrB,YAAA,OAAO,EAAE,oCAAoC;AAC7C,YAAA,IAAI,EAAE,QAAQ;AACf,SAAA,CAAC;IACJ;AACD;AAEM,MAAM,mBAAmB,GAAG,IAAI,mBAAmB;AAEpD,SAAU,mBAAmB,CAAC,MAAc,EAAE,EAAU,EAAA;AAC5D,IAAA,OAAO,CAAA,EAAG,MAAM,CAAA,CAAA,EAAI,EAAE,EAAE;AAC1B;AAEA;;ACzBA;AAEA;AAEA,SAASA,UAAQ,CAAC,KAAc,EAAA;AAC9B,IAAA,IAAI,KAAK,IAAI,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;AACvE,QAAA,OAAO,KAAgC;IACzC;AACA,IAAA,OAAO,IAAI;AACb;AAEA,SAAS,QAAQ,CAAC,KAAc,EAAA;AAC9B,IAAA,MAAM,GAAG,GAAGA,UAAQ,CAAC,KAAK,CAAC;AAC3B,IAAA,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI,IAAI,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,EAAE;AACjD,QAAA,OAAO,IAAI;IACb;AACA,IAAA,OAAO,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AAC1B;AAEA,SAAS,SAAS,CAAC,KAAc,EAAA;AAC/B,IAAA,MAAM,GAAG,GAAGA,UAAQ,CAAC,KAAK,CAAC;AAC3B,IAAA,OAAO,GAAG,GAAG,EAAE,GAAG,GAAG,EAAE,GAAG,IAAI;AAChC;AAEA;AAEA;MAGa,4BAA4B,CAAA;AADzC,IAAA,WAAA,GAAA;QAEW,IAAA,CAAA,MAAM,GAAG,mBAAmB;AA+KtC,IAAA;AA7KC,IAAA,MAAM,OAAO,CAAC,UAAkB,EAAE,UAAqB,EAAA;AACrD,QAAA,MAAM,IAAI,GAAG,UAAU,IAAI,EAAE;AAC7B,QAAA,KAAK,MAAM,IAAI,IAAI,IAAI,EAAE;AACvB,YAAA,MAAM,IAAI,CAAC,SAAS,CAAC,UAAU,EAAE,IAA+B,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;QACpF;AACA,QAAA,OAAO,IAAI;IACb;IAEA,MAAM,cAAc,CAAC,UAAkB,EAAA;QACrC,MAAM,GAAG,GAAG,MAAM,mBAAmB,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC;AAC1D,QAAA,OAAO,GAAG,EAAE,WAAW,IAAI,IAAI;IACjC;AAEA,IAAA,MAAM,cAAc,CAAC,UAAkB,EAAE,WAAmB,EAAA;AAC1D,QAAA,MAAM,mBAAmB,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,WAAW,EAAE,CAAC;IACzE;AAEA,IAAA,MAAM,MAAM,CAAC,UAAkB,EAAE,EAAW,EAAA;QAC1C,MAAM,GAAG,GAAG,EAAE,IAAI,IAAI,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,MAAM,CAAC,EAAE,CAAC;QACrD,IAAI,CAAC,GAAG,EAAE;AACR,YAAA,MAAM,IAAI,KAAK,CAAC,qBAAqB,UAAU,CAAA,CAAA,CAAG,CAAC;QACrD;AACA,QAAA,MAAM,GAAG,GAAG,MAAM,mBAAmB,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC;QACvF,IAAI,CAAC,GAAG,EAAE;YACR,MAAM,IAAI,KAAK,CAAC,CAAA,kBAAA,EAAqB,UAAU,CAAA,CAAA,EAAI,GAAG,CAAA,CAAE,CAAC;QAC3D;AACA,QAAA,OAAO,EAAE,GAAG,GAAG,CAAC,OAAO,EAAE;IAC3B;IAEA,MAAM,MAAM,CAAC,UAAkB,EAAA;AAC7B,QAAA,MAAM,IAAI,GAAG,MAAM,mBAAmB,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,OAAO,EAAE;AAC3F,QAAA,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,MAAM,EAAE,GAAG,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;IAChD;AAEA,IAAA,MAAM,KAAK,CACT,UAAkB,EAClB,OAAwB,EAAA;QAExB,OAAO,cAAc,CAAC,UAAU,EAAE,OAAO,EAAE,IAAI,CAAC,aAAa,EAAE,CAAC;IAClE;AAEA,IAAA,MAAM,KAAK,CAAC,UAAkB,EAAE,OAAiD,EAAA;AAC/E,QAAA,MAAM,IAAI,GAAG,MAAM,oBAAoB,CAAC,UAAU,EAAE,OAAO,EAAE,IAAI,CAAC,aAAa,EAAE,CAAC;QAClF,OAAO,IAAI,CAAC,MAAM;IACpB;AAEA,IAAA,MAAM,QAAQ,CACZ,UAAkB,EAClB,OAAiD,EACjD,OAAkC,EAAA;AAElC,QAAA,MAAM,IAAI,GAAG,MAAM,oBAAoB,CAAC,UAAU,EAAE,OAAO,EAAE,IAAI,CAAC,aAAa,EAAE,CAAC;AAClF,QAAA,MAAM,OAAO,GAAG,OAAO,EAAE,OAAO,IAAI,OAAO;QAC3C,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC;QACpC,OAAO;YACL,KAAK;YACL,KAAK,EAAE,IAAI,CAAC,MAAM;AAClB,YAAA,SAAS,EAAE,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM;SACtC;IACH;AAEA,IAAA,MAAM,OAAO,CAAC,UAAkB,EAAE,GAAc,EAAA;AAC9C,QAAA,OAAO,OAAO,CAAC,GAAG,CAChB,GAAG,CAAC,GAAG,CAAC,OAAO,EAAE,KAAI;AACnB,YAAA,IAAI;gBACF,OAAO,MAAM,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,EAAE,CAAC;YAC1C;AAAE,YAAA,MAAM;AACN,gBAAA,OAAO,IAAI;YACb;QACF,CAAC,CAAC,CACH;IACH;AAEA,IAAA,MAAM,MAAM,CAAC,UAAkB,EAAE,EAAW,EAAA;AAC1C,QAAA,IAAI;YACF,MAAM,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,EAAE,CAAC;AACjC,YAAA,OAAO,IAAI;QACb;AAAE,QAAA,MAAM;AACN,YAAA,OAAO,KAAK;QACd;IACF;AAEA,IAAA,MAAM,SAAS,CAAC,UAAkB,EAAE,MAAe,EAAA;QACjD,MAAM,OAAO,GAAG,SAAS,CAAC,MAAM,CAAC,IAAI,EAAE;QACvC,MAAM,EAAE,GAAG,QAAQ,CAAC,OAAO,CAAC,IAAI,gBAAgB,EAAE;AAClD,QAAA,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE;AAClB,QAAA,MAAM,MAAM,GAAyB;AACnC,YAAA,SAAS,EAAE,mBAAmB,CAAC,UAAU,EAAE,EAAE,CAAC;AAC9C,YAAA,MAAM,EAAE,UAAU;YAClB,EAAE;YACF,OAAO;SACR;QACD,MAAM,mBAAmB,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC;AAC7C,QAAA,OAAO,EAAE;IACX;AAEA,IAAA,MAAM,SAAS,CACb,UAAkB,EAClB,EAAW,EACX,KAA8B,EAAA;QAE9B,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,EAAE,CAAC;AACjD,QAAA,MAAM,IAAI,GAAG,EAAE,GAAG,OAAO,EAAE,GAAG,KAAK,EAAE,EAAE,EAAE,OAAO,CAAC,IAAI,CAAC,EAAE;QACxD,MAAM,GAAG,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;AACjC,QAAA,MAAM,mBAAmB,CAAC,OAAO,CAAC,GAAG,CAAC;AACpC,YAAA,SAAS,EAAE,mBAAmB,CAAC,UAAU,EAAE,GAAG,CAAC;AAC/C,YAAA,MAAM,EAAE,UAAU;AAClB,YAAA,EAAE,EAAE,GAAG;AACP,YAAA,OAAO,EAAE,IAAI;AACd,SAAA,CAAC;AACF,QAAA,OAAO,IAAI;IACb;AAEA,IAAA,MAAM,SAAS,CAAC,UAAkB,EAAE,EAAW,EAAA;QAC7C,MAAM,GAAG,GAAG,EAAE,IAAI,IAAI,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,MAAM,CAAC,EAAE,CAAC;QACrD,IAAI,CAAC,GAAG,EAAE;YACR;QACF;AACA,QAAA,MAAM,mBAAmB,CAAC,OAAO,CAAC,MAAM,CAAC,mBAAmB,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC;IAChF;AAEA,IAAA,MAAM,SAAS,CACb,UAAkB,EAClB,MAA+B,EAC/B,OAA6B,EAAA;AAE7B,QAAA,MAAM,EAAE,GAAG,QAAQ,CAAC,MAAM,CAAC;AAC3B,QAAA,IAAI,EAAE,IAAI,IAAI,KAAK,MAAM,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,EAAE;AACrD,YAAA,MAAM,KAAK,GAAG,OAAO,EAAE,KAAK,KAAK,KAAK;YACtC,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,EAAE,CAAC;YAClD,MAAM,IAAI,GAAG,KAAK,GAAG,EAAE,GAAG,QAAQ,EAAE,GAAG,MAAM,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,MAAM,EAAE,EAAE,EAAE;YACvE,MAAM,EAAE,EAAE,EAAE,KAAK,EAAE,GAAG,KAAK,EAAE,GAAG,IAAI;YACpC,MAAM,IAAI,CAAC,SAAS,CAAC,UAAU,EAAE,EAAE,EAAE,KAAK,CAAC;AAC3C,YAAA,OAAO,EAAE;QACX;QACA,OAAO,IAAI,CAAC,SAAS,CAAC,UAAU,EAAE,MAAM,CAAC;IAC3C;AAEA,IAAA,MAAM,SAAS,CACb,UAAkB,EAClB,OAAkC,EAClC,YAAuD,EAAA;AAEvD,QAAA,MAAM,IAAI,GAAG,MAAM,oBAAoB,CAAC,UAAU,EAAE,YAAY,IAAI,EAAE,EAAE,IAAI,CAAC,aAAa,EAAE,CAAC;QAC7F,OAAO,EAAE,IAAI,EAAE,uBAAuB,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE;IACzD;IAEQ,aAAa,GAAA;QACnB,OAAO;YACL,SAAS,EAAE,CAAC,IAAY,KAAK,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;AAC9C,YAAA,mBAAmB,EAAE,OAAO,UAAkB,EAAE,IAAY,KAAI;gBAC9D,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;gBACpC,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,KAAK,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC,KAAK,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,MAAM;YAC1F,CAAC;AACD,YAAA,sBAAsB,EAAE,OAAO,UAAkB,EAAE,IAAY,KAAI;gBACjE,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;AACnC,gBAAA,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAS,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC;gBACtD,IAAI,KAAK,GAAG,IAAI;gBAChB,OAAO,KAAK,EAAE;oBACZ,KAAK,GAAG,KAAK;AACb,oBAAA,KAAK,MAAM,GAAG,IAAI,GAAG,EAAE;AACrB,wBAAA,MAAM,EAAE,GAAG,QAAQ,CAAC,GAAG,CAAC;wBACxB,MAAM,MAAM,GAAG,GAAG,CAAC,UAAU,CAAC,IAAI,IAAI,GAAG,EAAE,GAAG,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;AACrE,wBAAA,IAAI,EAAE,IAAI,MAAM,IAAI,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE;AAC7D,4BAAA,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;4BAChB,KAAK,GAAG,IAAI;wBACd;oBACF;gBACF;AACA,gBAAA,OAAO,CAAC,GAAG,QAAQ,CAAC;YACtB,CAAC;SACF;IACH;8GA/KW,4BAA4B,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA,CAAA;kHAA5B,4BAA4B,EAAA,CAAA,CAAA;;2FAA5B,4BAA4B,EAAA,UAAA,EAAA,CAAA;kBADxC;;;AC/CD;AAEA;AACO,MAAM,0BAA0B,GAAG;AACnC,MAAM,4BAA4B,GAAG;AACrC,MAAM,iCAAiC,GAAG;AAEjD;;ACPA;AAgBA;AAEA;AAEO,MAAM,0BAA0B,GAAyB;AAC9D,IAAA,IAAI,EAAE;AACJ,QAAA,EAAE,EAAE,YAAY;AAChB,QAAA,IAAI,EAAE,OAAO;AACb,QAAA,KAAK,EAAE,YAAY;AACnB,QAAA,MAAM,EAAE,IAAI;AACb,KAAA;AACD,IAAA,MAAM,EAAE;AACN,QAAA,EAAE,EAAE,cAAc;AAClB,QAAA,IAAI,EAAE,OAAO;AACb,QAAA,KAAK,EAAE,cAAc;AACtB,KAAA;AACD,IAAA,WAAW,EAAE;AACX,QAAA,EAAE,EAAE,WAAW;AACf,QAAA,IAAI,EAAE,OAAO;AACb,QAAA,KAAK,EAAE,WAAW;AACnB,KAAA;;AAGH;AAEA;MAEa,uBAAuB,GAAG,IAAI,cAAc,CAAuB,yBAAyB,EAAE;AACzG,IAAA,UAAU,EAAE,MAAM;AAClB,IAAA,OAAO,EAAE,MAAM,0BAA0B;AAC1C,CAAA;AAED;;ACdA;AAEA;AAEA,MAAM,iBAAiB,GAAG,IAAI,GAAG,CAAS;IACxC,oBAAoB;IACpB,qBAAqB;IACrB,oBAAoB;IACpB,mBAAmB;IACnB,2BAA2B;IAC3B,8BAA8B;IAC9B,yCAAyC;AAC1C,CAAA,CAAC;AAEF,MAAM,eAAe,GAAG,IAAI,GAAG,CAAS;IACtC,2BAA2B;IAC3B,yBAAyB;IACzB,8BAA8B;IAC9B,qCAAqC;IACrC,8BAA8B;AAC/B,CAAA,CAAC;AAEF;AAEA;AAEA,SAASA,UAAQ,CAAC,KAAc,EAAA;AAC9B,IAAA,IAAI,KAAK,IAAI,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;AACvE,QAAA,OAAO,KAAgC;IACzC;AACA,IAAA,OAAO,IAAI;AACb;AAEA,SAAS,QAAQ,CAAC,KAAc,EAAA;AAC9B,IAAA,OAAO,KAAK,IAAI,IAAI,GAAG,EAAE,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE;AAClD;AAEA;AAEA;MAGa,6BAA6B,CAAA;AAD1C,IAAA,WAAA,GAAA;AAEmB,QAAA,IAAA,CAAA,OAAO,GAAG,MAAM,CAAC,4BAA4B,CAAC;AAC9C,QAAA,IAAA,CAAA,gBAAgB,GAAG,MAAM,CAAC,uBAAuB,CAAC;QAC3D,IAAA,CAAA,OAAO,GAAgC,IAAI;AA6IpD,IAAA;AA3IC,IAAA,gBAAgB,CAAC,IAAY,EAAA;AAC3B,QAAA,OAAO,iBAAiB,CAAC,GAAG,CAAC,IAAI,CAAC;IACpC;AAEA,IAAA,cAAc,CAAC,IAAY,EAAA;AACzB,QAAA,OAAO,eAAe,CAAC,GAAG,CAAC,IAAI,CAAC;IAClC;AAEA,IAAA,MAAM,cAAc,CAAC,IAAY,EAAE,KAAe,EAAA;QAChD,IAAI,IAAI,KAAK,mBAAmB,IAAI,IAAI,KAAK,yCAAyC,EAAE;AACtF,YAAA,IAAI,CAAC,OAAO,GAAG,IAAI;AACnB,YAAA,OAAO,2BAA2B,CAAC,EAAE,CAAC;QACxC;AACA,QAAA,IAAI,IAAI,KAAK,oBAAoB,EAAE;AACjC,YAAA,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC;QAC3B;AACA,QAAA,IAAI,IAAI,KAAK,qBAAqB,EAAE;YAClC,OAAO,qBAAqB,CAAC,gDAAgD,EAAE;AAC7E,gBAAA,IAAI,EAAE,8BAA8B;AACrC,aAAA,CAAC;QACJ;AACA,QAAA,OAAO,2BAA2B,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC;IAC1D;IAEA,MAAM,YAAY,CAAC,IAAY,EAAA;AAC7B,QAAA,IAAI,IAAI,KAAK,2BAA2B,EAAE;AACxC,YAAA,OAAO,yBAAyB,CAAC;AAC/B,gBAAA,YAAY,EAAE,CAAC,EAAE,EAAE,EAAE,WAAW,EAAE,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,UAAU,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;AAC3F,gBAAA,iBAAiB,EAAE,EAAE;AACtB,aAAA,CAAC;QACJ;AACA,QAAA,IAAI,IAAI,KAAK,yBAAyB,EAAE;YACtC,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,4BAA4B,CAAC;YACvE,OAAO,6BAA6B,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,GAAG,OAAO,GAAG,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC;QACzF;AACA,QAAA,IAAI,IAAI,KAAK,8BAA8B,EAAE;YAC3C,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,iCAAiC,CAAC;YACjF,OAAO,6BAA6B,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,GAAG,YAAY,GAAG,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC,CAAC;QACxG;AACA,QAAA,IAAI,IAAI,KAAK,qCAAqC,EAAE;AAClD,YAAA,OAAO,6BAA6B,CAAC,EAAE,CAAC;QAC1C;AACA,QAAA,IAAI,IAAI,KAAK,8BAA8B,EAAE;AAC3C,YAAA,OAAO,yBAAyB,CAAC;gBAC/B,WAAW,EAAE,CAAC,GAAG,CAAC;gBAClB,kBAAkB,EAAE,EAAE,OAAO,EAAE,CAAC,GAAG,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE;AACrD,aAAA,CAAC;QACJ;AACA,QAAA,OAAO,yBAAyB,CAAC,EAAE,CAAC;IACtC;IAEQ,MAAM,MAAM,CAAC,KAAc,EAAA;QACjC,MAAM,IAAI,GAAGA,UAAQ,CAAC,KAAK,CAAC,IAAI,EAAE;AAClC,QAAA,MAAM,QAAQ,GAAG,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,WAAW,EAAE;QACzD,MAAM,QAAQ,GAAG,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;AAC3C,QAAA,IAAI,CAAC,QAAQ,IAAI,CAAC,QAAQ,EAAE;YAC1B,OAAO,qBAAqB,CAAC,8BAA8B,EAAE,EAAE,IAAI,EAAE,gCAAgC,EAAE,CAAC;QAC1G;QAEA,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,0BAA0B,CAAC;QACnE,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,KAAK,QAAQ,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,WAAW,EAAE,KAAK,QAAQ,CAAC;AACtF,QAAA,IAAI,CAAC,IAAI,IAAI,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,KAAK,QAAQ,EAAE;YACpD,OAAO,qBAAqB,CAAC,8BAA8B,EAAE,EAAE,IAAI,EAAE,gCAAgC,EAAE,CAAC;QAC1G;QAEA,MAAM,QAAQ,GAAG,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAC3C,MAAM,aAAa,GAAG,QAAQ,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;QACrD,MAAM,MAAM,GACV,CAAC,QAAQ,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,4BAA4B,EAAE,QAAQ,CAAC,GAAG,IAAI,KAAK,IAAI,CAAC,SAAS,EAAE;QACnG,MAAM,WAAW,GACf,CAAC,aAAa,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,iCAAiC,EAAE,aAAa,CAAC,GAAG,IAAI;YAC3F,IAAI,CAAC,cAAc,EAAE;QAEvB,IAAI,CAAC,OAAO,GAAG;AACb,YAAA,IAAI,EAAE;AACJ,gBAAA,EAAE,EAAE,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACxB,gBAAA,IAAI,EAAE,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,CAAC;AAChD,gBAAA,KAAK,EAAE,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,CAAC;AAClD,gBAAA,MAAM,EAAE,IAAI;AACb,aAAA;AACD,YAAA,MAAM,EAAE;AACN,gBAAA,EAAE,EAAE,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;AAC1B,gBAAA,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;AAC9B,gBAAA,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,MAAM,CAAC,MAAM,CAAC,CAAC;AACnD,aAAA;AACD,YAAA,WAAW,EAAE;AACX,gBAAA,EAAE,EAAE,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;AAC/B,gBAAA,IAAI,EAAE,QAAQ,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;AACnC,gBAAA,KAAK,EAAE,QAAQ,CAAC,WAAW,CAAC,OAAO,CAAC,IAAI,WAAW,CAAC,MAAM,CAAC,CAAC;AAC7D,aAAA;SACF;AACD,QAAA,OAAO,2BAA2B,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC;IAC1D;AAEQ,IAAA,MAAM,MAAM,CAAC,MAAc,EAAE,EAAU,EAAA;AAC7C,QAAA,IAAI;YACF,OAAO,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC;QAC9C;AAAE,QAAA,MAAM;AACN,YAAA,OAAO,IAAI;QACb;IACF;IAEQ,aAAa,GAAA;QACnB,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,gBAAgB;QACtD,OAAO;AACL,YAAA,WAAW,EAAE,aAAa;AAC1B,YAAA,YAAY,EAAE,cAAc;AAC5B,YAAA,SAAS,EAAE,KAAK;YAChB,IAAI,EAAE,QAAQ,CAAC,IAAI;AACnB,YAAA,MAAM,EAAE;AACN,gBAAA,EAAE,EAAE,QAAQ,CAAC,MAAM,CAAC,EAAE;AACtB,gBAAA,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,IAAI;AAC1B,gBAAA,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,KAAK;AAC7B,aAAA;AACD,YAAA,WAAW,EAAE;AACX,gBAAA,EAAE,EAAE,QAAQ,CAAC,WAAW,CAAC,EAAE;AAC3B,gBAAA,IAAI,EAAE,QAAQ,CAAC,WAAW,CAAC,IAAI;AAC/B,gBAAA,KAAK,EAAE,QAAQ,CAAC,WAAW,CAAC,KAAK;AAClC,aAAA;SACF;IACH;IAEQ,SAAS,GAAA;AACf,QAAA,MAAM,MAAM,GAAG,CAAC,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,gBAAgB,EAAE,MAAM;QAC7D,OAAO;YACL,EAAE,EAAE,MAAM,CAAC,EAAE;YACb,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,KAAK,EAAE,MAAM,CAAC,KAAK;SACpB;IACH;IAEQ,cAAc,GAAA;AACpB,QAAA,MAAM,WAAW,GAAG,CAAC,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,gBAAgB,EAAE,WAAW;QACvE,OAAO;YACL,EAAE,EAAE,WAAW,CAAC,EAAE;YAClB,IAAI,EAAE,WAAW,CAAC,IAAI;YACtB,KAAK,EAAE,WAAW,CAAC,KAAK;SACzB;IACH;8GA/IW,6BAA6B,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA,CAAA;kHAA7B,6BAA6B,EAAA,CAAA,CAAA;;2FAA7B,6BAA6B,EAAA,UAAA,EAAA,CAAA;kBADzC;;;ACjDD;AAEA;AAEA,SAAS,QAAQ,CAAC,KAAc,EAAA;AAC9B,IAAA,IAAI,KAAK,IAAI,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;AACvE,QAAA,OAAO,KAAgC;IACzC;AACA,IAAA,OAAO,IAAI;AACb;AAEA,SAAS,iBAAiB,CAAC,IAAY,EAAE,KAAc,EAAA;AACrD,IAAA,MAAM,WAAW,GAAG,4BAA4B,CAAC,IAAI,CAAC;IACtD,IAAI,WAAW,EAAE;AACf,QAAA,OAAO,iCAAiC,CAAC,KAAK,CAAC;IACjD;IACA,OAAO,qBAAqB,CAAC,IAAI,CAAC,EAAE,MAAM,IAAI,IAAI;AACpD;AAEA,SAAS,gBAAgB,CAAC,IAAY,EAAA;AACpC,IAAA,OAAO,4BAA4B,CAAC,IAAI,CAAC,IAAI,qBAAqB,CAAC,IAAI,CAAC,EAAE,SAAS,IAAI,IAAI;AAC7F;AAEA,SAAS,SAAS,CAAC,KAAc,EAAA;AAC/B,IAAA,MAAM,GAAG,GAAG,QAAQ,CAAC,KAAK,CAAC;AAC3B,IAAA,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI,IAAI,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,EAAE;AACjD,QAAA,OAAO,IAAI;IACb;AACA,IAAA,OAAO,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AAC1B;AAEA,SAAS,iBAAiB,CAAC,KAAc,EAAA;IACvC,MAAM,GAAG,GAAG,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE;IACjC,MAAM,MAAM,GAAG,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;AACpC,IAAA,MAAM,MAAM,GAAG,MAAM,IAAI,GAAG;AAC5B,IAAA,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,IAAI,EAAE,GAAG,MAAM;AACxD,IAAA,OAAO,IAAI;AACb;AAEA,SAAS,mBAAmB,CAAC,KAAc,EAAA;IACzC,MAAM,GAAG,GAAG,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE;IACjC,MAAM,MAAM,GAAG,QAAQ,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;AAC5C,IAAA,MAAM,MAAM,GAAG,MAAM,IAAI,GAAG;IAC5B,OAAO;AACL,QAAA,IAAI,EAAE,OAAO,MAAM,CAAC,MAAM,CAAC,KAAK,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC;AAC7D,QAAA,IAAI,EAAE,OAAO,MAAM,CAAC,MAAM,CAAC,KAAK,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE;AAC9D,QAAA,MAAM,EAAE,MAAM,CAAC,QAAQ,CAA8B;AACrD,QAAA,IAAI,EAAE,MAAM,CAAC,MAAM,CAA4B;AAC/C,QAAA,MAAM,EAAE,MAAM,CAAC,QAAQ,CAA8B;KACtD;AACH;AAEA,SAAS,gBAAgB,CAAC,KAAc,EAAA;AACtC,IAAA,MAAM,GAAG,GAAG,QAAQ,CAAC,KAAK,CAAC;AAC3B,IAAA,MAAM,GAAG,GAAG,GAAG,GAAG,WAAW,CAAC;AAC9B,IAAA,IAAI,GAAG,IAAI,IAAI,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE;AACjE,QAAA,OAAO,GAAgC;IACzC;AACA,IAAA,OAAO,IAAI;AACb;AAEA;AAEA;MAGa,+BAA+B,CAAA;AAD5C,IAAA,WAAA,GAAA;AAEmB,QAAA,IAAA,CAAA,OAAO,GAAG,MAAM,CAAC,4BAA4B,CAAC;AA0JhE,IAAA;AAxJC,IAAA,gBAAgB,CAAC,IAAY,EAAA;AAC3B,QAAA,MAAM,SAAS,GAAG,gBAAgB,CAAC,IAAI,CAAC;QACxC,OAAO,SAAS,KAAK,QAAQ,IAAI,SAAS,KAAK,QAAQ,IAAI,SAAS,KAAK,QAAQ;IACnF;AAEA,IAAA,cAAc,CAAC,IAAY,EAAA;AACzB,QAAA,MAAM,SAAS,GAAG,gBAAgB,CAAC,IAAI,CAAC;AACxC,QAAA,OAAO,SAAS,KAAK,OAAO,IAAI,SAAS,KAAK,SAAS;IACzD;AAEA,IAAA,MAAM,cAAc,CAAC,IAAY,EAAE,KAAc,EAAA;QAC/C,MAAM,MAAM,GAAG,iBAAiB,CAAC,IAAI,EAAE,KAAK,CAAC;AAC7C,QAAA,MAAM,SAAS,GAAG,gBAAgB,CAAC,IAAI,CAAC;AACxC,QAAA,IAAI,CAAC,MAAM,IAAI,CAAC,SAAS,EAAE;AACzB,YAAA,OAAO,qBAAqB,CAAC,CAAA,sCAAA,EAAyC,IAAI,GAAG,EAAE;AAC7E,gBAAA,IAAI,EAAE,yBAAyB;AAChC,aAAA,CAAC;QACJ;AAEA,QAAA,IAAI;AACF,YAAA,IAAI,SAAS,KAAK,QAAQ,EAAE;AAC1B,gBAAA,MAAM,IAAI,GAAG,iBAAiB,CAAC,KAAK,CAAC;AACrC,gBAAA,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,CAAC;AACrD,gBAAA,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC;gBACpD,OAAO,2BAA2B,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC;YACpD;AACA,YAAA,IAAI,SAAS,KAAK,QAAQ,EAAE;AAC1B,gBAAA,MAAM,EAAE,GAAG,SAAS,CAAC,KAAK,CAAC;gBAC3B,IAAI,CAAC,EAAE,EAAE;oBACP,OAAO,qBAAqB,CAAC,oBAAoB,EAAE,EAAE,IAAI,EAAE,0BAA0B,EAAE,CAAC;gBAC1F;AACA,gBAAA,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,MAAM,EAAE,EAAE,EAAE,iBAAiB,CAAC,KAAK,CAAC,CAAC;gBACjF,OAAO,2BAA2B,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC;YACpD;AACA,YAAA,IAAI,SAAS,KAAK,QAAQ,EAAE;AAC1B,gBAAA,MAAM,EAAE,GAAG,SAAS,CAAC,KAAK,CAAC;gBAC3B,IAAI,CAAC,EAAE,EAAE;oBACP,OAAO,qBAAqB,CAAC,oBAAoB,EAAE,EAAE,IAAI,EAAE,0BAA0B,EAAE,CAAC;gBAC1F;gBACA,MAAM,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,MAAM,EAAE,EAAE,CAAC;AACxC,gBAAA,OAAO,2BAA2B,CAAC,EAAE,EAAE,EAAE,CAAC;YAC5C;AACA,YAAA,OAAO,qBAAqB,CAAC,CAAA,CAAA,EAAI,IAAI,CAAA,2BAAA,CAA6B,EAAE,EAAE,IAAI,EAAE,yBAAyB,EAAE,CAAC;QAC1G;QAAE,OAAO,KAAK,EAAE;AACd,YAAA,OAAO,qBAAqB,CAAC,KAAK,YAAY,KAAK,GAAG,KAAK,CAAC,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,EAAE;AACnF,gBAAA,IAAI,EAAE,6BAA6B;AACpC,aAAA,CAAC;QACJ;IACF;AAEA,IAAA,MAAM,YAAY,CAAC,IAAY,EAAE,KAAc,EAAA;QAC7C,MAAM,MAAM,GAAG,iBAAiB,CAAC,IAAI,EAAE,KAAK,CAAC;AAC7C,QAAA,MAAM,SAAS,GAAG,gBAAgB,CAAC,IAAI,CAAC;AACxC,QAAA,IAAI,CAAC,MAAM,IAAI,CAAC,SAAS,EAAE;AACzB,YAAA,OAAO,mBAAmB,CAAC,CAAA,sCAAA,EAAyC,IAAI,GAAG,EAAE;AAC3E,gBAAA,IAAI,EAAE,yBAAyB;AAChC,aAAA,CAAC;QACJ;AAEA,QAAA,IAAI;AACF,YAAA,IAAI,SAAS,KAAK,SAAS,EAAE;AAC3B,gBAAA,MAAM,EAAE,GAAG,SAAS,CAAC,KAAK,CAAC;gBAC3B,IAAI,CAAC,EAAE,EAAE;oBACP,OAAO,mBAAmB,CAAC,qBAAqB,EAAE,EAAE,IAAI,EAAE,0BAA0B,EAAE,CAAC;gBACzF;AACA,gBAAA,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC;AACpD,gBAAA,OAAO,yBAAyB,CAAC,MAAM,CAAC;YAC1C;AAEA,YAAA,IAAI,SAAS,KAAK,OAAO,EAAE;AACzB,gBAAA,OAAO,mBAAmB,CAAC,CAAA,CAAA,EAAI,IAAI,CAAA,gBAAA,CAAkB,EAAE,EAAE,IAAI,EAAE,yBAAyB,EAAE,CAAC;YAC7F;YAEA,MAAM,GAAG,GAAG,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE;AACjC,YAAA,MAAM,IAAI,GAAG,SAAS,CAAC,KAAK,CAAC;YAC7B,IAAI,IAAI,IAAI,GAAG,CAAC,cAAc,CAAC,IAAI,IAAI,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,IAAI,IAAI,GAAG,CAAC,QAAQ,CAAC,IAAI,IAAI,EAAE;AACvF,gBAAA,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC;AACtD,gBAAA,OAAO,yBAAyB,CAAC,MAAM,CAAC;YAC1C;AAEA,YAAA,MAAM,SAAS,GAAG,gBAAgB,CAAC,KAAK,CAAC;YACzC,IAAI,SAAS,EAAE;AACb,gBAAA,MAAM,OAAO,GAAG,mBAAmB,CAAC,KAAK,CAAC;AAC1C,gBAAA,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,MAAM,EAAE,SAAS,EAAE,OAAO,CAAC;AACvE,gBAAA,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,OAAO,CAAC;AACvD,gBAAA,OAAO,6BAA6B,CAAC;AACnC,oBAAA,KAAK,EAAE,EAAE;oBACT,KAAK;oBACL,aAAa,EAAE,MAAM,CAAC,IAAI;AAC3B,iBAAA,CAAC;YACJ;YAEA,MAAM,UAAU,GAAG,OAAO,GAAG,CAAC,YAAY,CAAC,KAAK,QAAQ,GAAG,GAAG,CAAC,YAAY,CAAC,GAAG,IAAI;AACnF,YAAA,MAAM,OAAO,GAAG,mBAAmB,CAAC,KAAK,CAAC;AAC1C,YAAA,IAAI,UAAU,KAAK,OAAO,EAAE;AAC1B,gBAAA,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,OAAO,CAAC;gBACvD,OAAO,6BAA6B,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC;YAC5D;AACA,YAAA,IAAI,UAAU,KAAK,KAAK,EAAE;AACxB,gBAAA,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;AACzD,gBAAA,OAAO,6BAA6B,CAAC,IAAI,CAAC;YAC5C;AAEA,YAAA,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,OAAO,CAAC;AACtD,YAAA,OAAO,6BAA6B,CAAC,IAAI,CAAC;QAC5C;QAAE,OAAO,KAAK,EAAE;AACd,YAAA,OAAO,mBAAmB,CAAC,KAAK,YAAY,KAAK,GAAG,KAAK,CAAC,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,EAAE;AACjF,gBAAA,IAAI,EAAE,2BAA2B;AAClC,aAAA,CAAC;QACJ;IACF;IAEA,MAAM,WAAW,CAAC,OAA8B,EAAA;AAC9C,QAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CACvB,OAAO,CAAC,QAAQ,IAAI,kCAAkC,EACtD,+BAA+B,CAChC;QACD,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,IAAI;AAC/C,QAAA,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE;YACpD,MAAM,EAAE,OAAO,CAAC,MAAM;AACtB,YAAA,IAAI,EAAE,CAAC;YACP,IAAI,EAAE,QAAQ,GAAG,CAAC;AACnB,SAAA,CAAC;AACF,QAAA,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,GAAG,QAAQ,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,QAAQ;AACvE,QAAA,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC;QAC7C,MAAM,OAAO,GAAwC,EAAE;AAEvD,QAAA,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE;YACzB,MAAM,EAAE,GAAG,GAAG,CAAC,OAAO,CAAC,IAAI,IAAI,GAAG,gBAAgB,EAAE,GAAG,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;AAC3E,YAAA,MAAM,OAAO,GAAG;gBACd,MAAM,EAAE,OAAO,CAAC,MAAM;gBACtB,CAAC,OAAO,GAAG,EAAE;AACb,gBAAA,IAAI,OAAO,CAAC,KAAK,IAAI,EAAE,CAAC;aACzB;AACD,YAAA,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC;YAC/D,OAAO,CAAC,IAAI,CAAC;gBACX,EAAE;AACF,gBAAA,OAAO,EAAE,MAAM,CAAC,OAAO,KAAK,IAAI;AAChC,gBAAA,IAAI,EAAE,MAAM,CAAC,OAAO,GAAG,MAAM,CAAC,IAAI,GAAG,SAAS;gBAC9C,OAAO,EAAE,MAAM,CAAC,OAAO;AACxB,aAAA,CAAC;QACJ;AAEA,QAAA,MAAM,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM;AAC/D,QAAA,OAAO,2BAA2B,CAAC;YACjC,KAAK,EAAE,OAAO,CAAC,MAAM;YACrB,SAAS;AACT,YAAA,MAAM,EAAE,OAAO,CAAC,MAAM,GAAG,SAAS;YAClC,SAAS,EAAE,SAAS,IAAI,SAAS;YACjC,OAAO;AACR,SAAA,CAAC;IACJ;8GA1JW,+BAA+B,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA,CAAA;kHAA/B,+BAA+B,EAAA,CAAA,CAAA;;2FAA/B,+BAA+B,EAAA,UAAA,EAAA,CAAA;kBAD3C;;;ACzFD;AAEA;;;AAGG;AACI,MAAM,+BAA+B,GAAG;AACxC,MAAM,+BAA+B,GAAG;AAExC,MAAM,4BAA4B,GAAwB;AAC/D,IAAA,mBAAmB,EAAE,+BAA+B;AACpD,IAAA,qBAAqB,EAAE,+BAA+B;;AAGxD;;ACGA;AAEA;AAEA,MAAM,mBAAmB,GAAG,IAAI,GAAG,CAAS,CAAC,+BAA+B,CAAC,CAAC;AAC9E,MAAM,iBAAiB,GAAG,IAAI,GAAG,CAAS;IACxC,+BAA+B;IAC/B,gCAAgC;IAChC,kCAAkC;AACnC,CAAA,CAAC;AAEF;AAEA;AAEA;;;AAGG;MAEU,+BAA+B,CAAA;AAC1C,IAAA,gBAAgB,CAAC,IAAY,EAAA;AAC3B,QAAA,OAAO,mBAAmB,CAAC,GAAG,CAAC,IAAI,CAAC;IACtC;AAEA,IAAA,cAAc,CAAC,IAAY,EAAA;AACzB,QAAA,OAAO,iBAAiB,CAAC,GAAG,CAAC,IAAI,CAAC;IACpC;AAEA,IAAA,cAAc,CAAC,IAAY,EAAA;AACzB,QAAA,IAAI,IAAI,KAAK,+BAA+B,EAAE;AAC5C,YAAA,OAAO,2BAA2B,CAAC,EAAE,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC;QAC7E;AACA,QAAA,OAAO,2BAA2B,CAAC,EAAE,CAAC;IACxC;AAEA,IAAA,YAAY,CAAC,IAAY,EAAA;AACvB,QAAA,IAAI,IAAI,KAAK,+BAA+B,EAAE;AAC5C,YAAA,OAAO,yBAAyB,CAAC;AAC/B,gBAAA,OAAO,EAAE,KAAK;AACd,gBAAA,SAAS,EAAE,IAAI;AACf,gBAAA,MAAM,EAAE,EAAE;AACX,aAAA,CAAC;QACJ;AACA,QAAA,IAAI,IAAI,KAAK,gCAAgC,EAAE;AAC7C,YAAA,OAAO,yBAAyB,CAAC,IAAI,CAAC;QACxC;AACA,QAAA,IAAI,IAAI,KAAK,kCAAkC,EAAE;AAC/C,YAAA,OAAO,6BAA6B,CAAC,EAAE,CAAC;QAC1C;AACA,QAAA,OAAO,yBAAyB,CAAC,EAAE,CAAC;IACtC;8GA/BW,+BAA+B,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA,CAAA;kHAA/B,+BAA+B,EAAA,CAAA,CAAA;;2FAA/B,+BAA+B,EAAA,UAAA,EAAA,CAAA;kBAD3C;;;ACtCD;AAwBA;AAEA;AAEA,SAAS,gBAAgB,CAAC,IAAY,EAAA;AACpC,IAAA,OAAO,qBAAqB,CAC1B,CAAA,uCAAA,EAA0C,IAAI,CAAA,sEAAA,CAAwE,EACtH,EAAE,IAAI,EAAE,yBAAyB,EAAE,CACpC;AACH;AAEA,SAAS,cAAc,CAAC,IAAY,EAAA;AAClC,IAAA,OAAO,mBAAmB,CACxB,CAAA,qCAAA,EAAwC,IAAI,CAAA,4FAAA,CAA8F,EAC1I,EAAE,IAAI,EAAE,uBAAuB,EAAE,CAClC;AACH;AAEA;AAEA;AAEO,MAAM,kCAAkC,GAG3C;IACF,GAAG,EAAE,wBAAwB,CAAC,cAAc;IAC5C,MAAM,OAAO,CAAC,OAAO,EAAA;AACnB,QAAA,IAAI,OAAO,CAAC,OAAO,EAAE;AACnB,YAAA,OAAO,OAAO;QAChB;AACA,QAAA,MAAM,QAAQ,GAAG,MAAM,CAAC,+BAA+B,CAAC;AACxD,QAAA,MAAM,IAAI,GAAG,MAAM,CAAC,6BAA6B,CAAC;AAClD,QAAA,MAAM,MAAM,GAAG,MAAM,CAAC,+BAA+B,CAAC;QAEtD,IAAI,QAAQ,CAAC,gBAAgB,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;YAC3C,OAAO,EAAE,GAAG,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC,cAAc,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,KAAK,CAAC,EAAE;QAC1G;QACA,IAAI,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;YACvC,OAAO,EAAE,GAAG,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,KAAK,CAAC,EAAE;QACtG;QACA,IAAI,MAAM,CAAC,gBAAgB,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;AACzC,YAAA,OAAO,EAAE,GAAG,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,cAAc,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;QACnF;AACA,QAAA,OAAO,EAAE,GAAG,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,gBAAgB,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;IAC9E,CAAC;;AAGI,MAAM,sCAAsC,GAG/C;IACF,GAAG,EAAE,wBAAwB,CAAC,kBAAkB;IAChD,MAAM,OAAO,CAAC,OAAO,EAAA;AACnB,QAAA,IAAI,OAAO,CAAC,OAAO,EAAE;AACnB,YAAA,OAAO,OAAO;QAChB;AACA,QAAA,MAAM,QAAQ,GAAG,MAAM,CAAC,+BAA+B,CAAC;QACxD,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,WAAW,CAAC,OAAO,CAAC,OAAO,CAAC;QAC1D,OAAO,EAAE,GAAG,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE;IAC9C,CAAC;CACF;AAEM,MAAM,uCAAuC,GAGhD;IACF,GAAG,EAAE,wBAAwB,CAAC,mBAAmB;IACjD,MAAM,OAAO,CAAC,OAAO,EAAA;AACnB,QAAA,IAAI,OAAO,CAAC,OAAO,EAAE;AACnB,YAAA,OAAO,OAAO;QAChB;QACA,OAAO;AACL,YAAA,GAAG,OAAO;AACV,YAAA,OAAO,EAAE,IAAI;AACb,YAAA,QAAQ,EAAE;gBACR,WAAW,EAAE,OAAO,CAAC,WAAW;AAChC,gBAAA,MAAM,EAAE,EAAE;AACV,gBAAA,IAAI,EAAE,EAAE;AACR,gBAAA,OAAO,EAAE,CAAC;AACV,gBAAA,KAAK,EAAE,CAAC;AACR,gBAAA,SAAS,EAAE,CAAC;AACZ,gBAAA,MAAM,EAAE,CAAC;AACT,gBAAA,MAAM,EAAE,WAAW;AACpB,aAAA;SACF;IACH,CAAC;CACF;AAEM,MAAM,gCAAgC,GAGzC;IACF,GAAG,EAAE,wBAAwB,CAAC,YAAY;IAC1C,MAAM,OAAO,CAAC,OAAO,EAAA;AACnB,QAAA,IAAI,OAAO,CAAC,OAAO,EAAE;AACnB,YAAA,OAAO,OAAO;QAChB;AACA,QAAA,MAAM,QAAQ,GAAG,MAAM,CAAC,+BAA+B,CAAC;AACxD,QAAA,MAAM,IAAI,GAAG,MAAM,CAAC,6BAA6B,CAAC;AAClD,QAAA,MAAM,MAAM,GAAG,MAAM,CAAC,+BAA+B,CAAC;QAEtD,IAAI,QAAQ,CAAC,cAAc,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;YACzC,OAAO,EAAE,GAAG,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC,YAAY,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,KAAK,CAAC,EAAE;QACxG;QACA,IAAI,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;YACrC,OAAO,EAAE,GAAG,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;QACrF;QACA,IAAI,MAAM,CAAC,cAAc,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;AACvC,YAAA,OAAO,EAAE,GAAG,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;QACjF;AACA,QAAA,OAAO,EAAE,GAAG,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,cAAc,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;IAC5E,CAAC;;AAGI,MAAM,gCAAgC,GAAe;IAC1D,4BAA4B;IAC5B,+BAA+B;IAC/B,6BAA6B;IAC7B,+BAA+B;AAC/B,IAAA;AACE,QAAA,OAAO,EAAE,iBAAiB;AAC1B,QAAA,QAAQ,EAAE,kCAAkC;AAC5C,QAAA,KAAK,EAAE,IAAI;AACZ,KAAA;AACD,IAAA;AACE,QAAA,OAAO,EAAE,iBAAiB;AAC1B,QAAA,QAAQ,EAAE,sCAAsC;AAChD,QAAA,KAAK,EAAE,IAAI;AACZ,KAAA;AACD,IAAA;AACE,QAAA,OAAO,EAAE,iBAAiB;AAC1B,QAAA,QAAQ,EAAE,uCAAuC;AACjD,QAAA,KAAK,EAAE,IAAI;AACZ,KAAA;AACD,IAAA;AACE,QAAA,OAAO,EAAE,iBAAiB;AAC1B,QAAA,QAAQ,EAAE,gCAAgC;AAC1C,QAAA,KAAK,EAAE,IAAI;AACZ,KAAA;;AAGH;;ACtKA;AAMA;AAEA;AAEA;MACa,cAAc,GAAG,IAAI,cAAc,CAA0B,gBAAgB;AAE1F;;ACbA;AAQA;AAEA;SAEgB,uBAAuB,GAAA;IACrC,OAAO,qBAAqB,CAAC,MAAK;AAChC,QAAA,MAAM,OAAO,GAAG,MAAM,CAAC,4BAA4B,CAAC;AACpD,QAAA,MAAM,IAAI,GAAG,MAAM,CAAC,cAAc,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,IAAI,EAAE;QAC7D,OAAO;AACL,YAAA,IAAI,EAAE,mBAAmB;YACzB,QAAQ,EAAE,wBAAwB,CAAC,eAAe;YAClD,GAAG,EAAE,YAAW;AACd,gBAAA,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE;oBACtB,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE;oBACjC,IAAI,CAAC,MAAM,EAAE;wBACX;oBACF;AACA,oBAAA,MAAM,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC;oBAC7C,MAAM,OAAO,GAAG,GAAG,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,GAAG;oBAC1C,MAAM,OAAO,CAAC,cAAc,CAAC,MAAM,EAAE,OAAO,CAAC;gBAC/C;YACF,CAAC;SACF;AACH,IAAA,CAAC,CAAC;AACJ;AAEA;;AClCA;AAYA;AAEA;AAEA;;;;;;AAMG;SACa,4BAA4B,GAAA;IAC1C,OAAO;AACL,QAAA,GAAG,gCAAgC;AACnC,QAAA,uBAAuB,EAAE;AACzB,QAAA,EAAE,OAAO,EAAE,sBAAsB,EAAE,QAAQ,EAAE,4BAA4B,EAAE;AAC3E,QAAA,EAAE,OAAO,EAAE,qBAAqB,EAAE,QAAQ,EAAE,0BAA0B,EAAE;KACzE;AACH;AAEA;AACM,SAAU,iBAAiB,CAAC,GAAG,IAAoB,EAAA;IACvD,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,MAAM;AACxB,QAAA,OAAO,EAAE,cAAc;AACvB,QAAA,KAAK,EAAE,IAAI;AACX,QAAA,QAAQ,EAAE,GAAG;AACd,KAAA,CAAC,CAAC;AACL;AAEA;;ACzCA;AAMA;AAEA;AAEA;;;;;AAKG;MAIU,yBAAyB,CAAA;8GAAzB,yBAAyB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,QAAA,EAAA,CAAA,CAAA;+GAAzB,yBAAyB,EAAA,CAAA,CAAA;+GAAzB,yBAAyB,EAAA,SAAA,EAFzB,4BAA4B,EAAE,EAAA,CAAA,CAAA;;2FAE9B,yBAAyB,EAAA,UAAA,EAAA,CAAA;kBAHrC,QAAQ;AAAC,YAAA,IAAA,EAAA,CAAA;oBACR,SAAS,EAAE,4BAA4B,EAAE;AAC1C,iBAAA;;;AClBD;;AAEG;;"}
|
package/package.json
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@acorex-platform/client-connectivity-mock",
|
|
3
|
+
"version": "0.0.46",
|
|
4
|
+
"sideEffects": false,
|
|
5
|
+
"peerDependencies": {
|
|
6
|
+
"@acorex-platform/framework-client": "0.0.46",
|
|
7
|
+
"@acorex-platform/framework-shared": "0.0.46",
|
|
8
|
+
"@angular/core": "^21.0.0 || ^22.0.0",
|
|
9
|
+
"dexie": "^3.2.7"
|
|
10
|
+
},
|
|
11
|
+
"dependencies": {
|
|
12
|
+
"tslib": "^2.3.0"
|
|
13
|
+
},
|
|
14
|
+
"module": "fesm2022/acorex-platform-client-connectivity-mock.mjs",
|
|
15
|
+
"typings": "types/acorex-platform-client-connectivity-mock.d.ts",
|
|
16
|
+
"exports": {
|
|
17
|
+
"./package.json": {
|
|
18
|
+
"default": "./package.json"
|
|
19
|
+
},
|
|
20
|
+
".": {
|
|
21
|
+
"types": "./types/acorex-platform-client-connectivity-mock.d.ts",
|
|
22
|
+
"default": "./fesm2022/acorex-platform-client-connectivity-mock.mjs"
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
"type": "module"
|
|
26
|
+
}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { Provider, InjectionToken } from '@angular/core';
|
|
3
|
+
import { AXPQueryRequest, AXPSettingsSyncKeys } from '@acorex-platform/framework-shared/core';
|
|
4
|
+
import { AXPEntityQueryAllOptions, AXPEntityQueryAllResult, AXPEntityAggregateRequest, AXPEntityAggregateResult } from '@acorex-platform/framework-shared/entity';
|
|
5
|
+
import Dexie, { Table } from 'dexie';
|
|
6
|
+
import { AXPUser, AXPTenant, AXPApplication } from '@acorex-platform/framework-client/auth';
|
|
7
|
+
import { AXPHookProvider } from '@acorex-platform/framework-client/core';
|
|
8
|
+
import { AXPRuntimeCommandExecuteHookPayload, AXPRuntimeQueryExecuteHookPayload } from '@acorex-platform/framework-client/runtime';
|
|
9
|
+
|
|
10
|
+
/** Host-provided entity rows for IndexedDB `initial` / upsert. */
|
|
11
|
+
interface AXCDexieSeed {
|
|
12
|
+
entity: string;
|
|
13
|
+
rows: Record<string, unknown>[];
|
|
14
|
+
/**
|
|
15
|
+
* When this value changes, seed rows are upserted again.
|
|
16
|
+
* Existing extra rows (user-created) are kept.
|
|
17
|
+
*/
|
|
18
|
+
version?: string;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* IndexedDB CQRS transport: `runtime.command.execute` / `runtime.query.execute`
|
|
23
|
+
* against Dexie {@code ACoreXClientStore}.
|
|
24
|
+
*
|
|
25
|
+
* XOR with {@code provideRuntimeRemoteTransport()} from
|
|
26
|
+
* `@acorex-platform/client-connectivity-api`. Do not register both.
|
|
27
|
+
*/
|
|
28
|
+
declare function provideDexieRuntimeTransport(): Provider[];
|
|
29
|
+
/** Registers one or more entity row bags on {@link AXP_DEXIE_SEED}. */
|
|
30
|
+
declare function provideDexieSeeds(...bags: AXCDexieSeed[]): Provider[];
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Registers Dexie runtime CQRS hooks used when a query/command is not in
|
|
34
|
+
* {@code provideQuerySetups} / {@code provideCommandSetups}.
|
|
35
|
+
*
|
|
36
|
+
* Do not import together with {@code AXCRuntimeRemoteApiModule}.
|
|
37
|
+
*/
|
|
38
|
+
declare class AXCRuntimeDexieMockModule {
|
|
39
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<AXCRuntimeDexieMockModule, never>;
|
|
40
|
+
static ɵmod: i0.ɵɵNgModuleDeclaration<AXCRuntimeDexieMockModule, never, never, never>;
|
|
41
|
+
static ɵinj: i0.ɵɵInjectorDeclaration<AXCRuntimeDexieMockModule>;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
declare class AXCDexieEntityStorageService {
|
|
45
|
+
readonly dbName = "ACoreXClientStore";
|
|
46
|
+
initial(entityName: string, collection: unknown[]): Promise<unknown[]>;
|
|
47
|
+
getSeedVersion(entityName: string): Promise<string | null>;
|
|
48
|
+
setSeedVersion(entityName: string, seedVersion: string): Promise<void>;
|
|
49
|
+
getOne(entityName: string, id: unknown): Promise<Record<string, unknown>>;
|
|
50
|
+
getAll(entityName: string): Promise<Record<string, unknown>[]>;
|
|
51
|
+
query(entityName: string, request: AXPQueryRequest): Promise<{
|
|
52
|
+
items: Record<string, unknown>[];
|
|
53
|
+
total: number;
|
|
54
|
+
}>;
|
|
55
|
+
count(entityName: string, request: Pick<AXPQueryRequest, 'filter' | 'sort'>): Promise<number>;
|
|
56
|
+
queryAll(entityName: string, request: Pick<AXPQueryRequest, 'filter' | 'sort'>, options?: AXPEntityQueryAllOptions): Promise<AXPEntityQueryAllResult<Record<string, unknown>>>;
|
|
57
|
+
getMany(entityName: string, ids: unknown[]): Promise<(Record<string, unknown> | null)[]>;
|
|
58
|
+
exists(entityName: string, id: unknown): Promise<boolean>;
|
|
59
|
+
insertOne(entityName: string, entity: unknown): Promise<string>;
|
|
60
|
+
updateOne(entityName: string, id: unknown, patch: Record<string, unknown>): Promise<Record<string, unknown>>;
|
|
61
|
+
deleteOne(entityName: string, id: unknown): Promise<void>;
|
|
62
|
+
upsertOne(entityName: string, entity: Record<string, unknown>, options?: {
|
|
63
|
+
merge?: boolean;
|
|
64
|
+
}): Promise<string>;
|
|
65
|
+
aggregate(entityName: string, request: AXPEntityAggregateRequest, queryRequest?: Pick<AXPQueryRequest, 'filter' | 'sort'>): Promise<AXPEntityAggregateResult>;
|
|
66
|
+
private queryAdapters;
|
|
67
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<AXCDexieEntityStorageService, never>;
|
|
68
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<AXCDexieEntityStorageService>;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
interface AXCDexieStoredRecord {
|
|
72
|
+
/** `${entity}|${id}` */
|
|
73
|
+
storageId: string;
|
|
74
|
+
entity: string;
|
|
75
|
+
id: string;
|
|
76
|
+
payload: Record<string, unknown>;
|
|
77
|
+
}
|
|
78
|
+
interface AXCDexieStoreMeta {
|
|
79
|
+
entity: string;
|
|
80
|
+
seedVersion: string;
|
|
81
|
+
}
|
|
82
|
+
declare class AXCDexieClientStore extends Dexie {
|
|
83
|
+
records: Table<AXCDexieStoredRecord, string>;
|
|
84
|
+
meta: Table<AXCDexieStoreMeta, string>;
|
|
85
|
+
constructor();
|
|
86
|
+
}
|
|
87
|
+
declare const axcDexieClientStore: AXCDexieClientStore;
|
|
88
|
+
declare function buildDexieStorageId(entity: string, id: string): string;
|
|
89
|
+
|
|
90
|
+
/** Multi token — each host contribution is one `{ entity, rows }` bag. */
|
|
91
|
+
declare const AXP_DEXIE_SEED: InjectionToken<readonly AXCDexieSeed[]>;
|
|
92
|
+
|
|
93
|
+
/** Local-owned rows the Dexie auth dispatcher reads. Hosts seed these via `provideDexieSeeds`. */
|
|
94
|
+
declare const AXC_DEXIE_AUTH_USER_ENTITY = "Auth.User";
|
|
95
|
+
declare const AXC_DEXIE_AUTH_TENANT_ENTITY = "Auth.Tenant";
|
|
96
|
+
declare const AXC_DEXIE_AUTH_APPLICATION_ENTITY = "Auth.Application";
|
|
97
|
+
|
|
98
|
+
/** Identity returned by Dexie `Auth:SignIn` / refresh / update-session stubs. */
|
|
99
|
+
interface AXCDexieMockIdentity {
|
|
100
|
+
user: AXPUser;
|
|
101
|
+
tenant: AXPTenant;
|
|
102
|
+
application: AXPApplication;
|
|
103
|
+
}
|
|
104
|
+
declare const AXC_DEXIE_DEFAULT_IDENTITY: AXCDexieMockIdentity;
|
|
105
|
+
declare const AXP_DEXIE_MOCK_IDENTITY: InjectionToken<AXCDexieMockIdentity>;
|
|
106
|
+
|
|
107
|
+
declare const AXCDexieCommandExecuteHookProvider: AXPHookProvider<AXPRuntimeCommandExecuteHookPayload, AXPRuntimeCommandExecuteHookPayload>;
|
|
108
|
+
declare const AXCDexieQueryExecuteHookProvider: AXPHookProvider<AXPRuntimeQueryExecuteHookPayload, AXPRuntimeQueryExecuteHookPayload>;
|
|
109
|
+
declare const AXC_DEXIE_RUNTIME_HOOK_PROVIDERS: Provider[];
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Same keys as settings-management contracts. Duplicated so this lib does not
|
|
113
|
+
* import that module (XOR hosts must not pull `client-connectivity-api`).
|
|
114
|
+
*/
|
|
115
|
+
declare const AXC_DEXIE_SETTINGS_SCOPED_FETCH = "SettingsManagement:ScopedSettings:Fetch";
|
|
116
|
+
declare const AXC_DEXIE_SETTINGS_SCOPED_PATCH = "SettingsManagement:ScopedSettings:Patch";
|
|
117
|
+
declare const AXC_DEXIE_SETTINGS_SYNC_KEYS: AXPSettingsSyncKeys;
|
|
118
|
+
|
|
119
|
+
export { AXCDexieCommandExecuteHookProvider, AXCDexieEntityStorageService, AXCDexieQueryExecuteHookProvider, AXCRuntimeDexieMockModule, AXC_DEXIE_AUTH_APPLICATION_ENTITY, AXC_DEXIE_AUTH_TENANT_ENTITY, AXC_DEXIE_AUTH_USER_ENTITY, AXC_DEXIE_DEFAULT_IDENTITY, AXC_DEXIE_RUNTIME_HOOK_PROVIDERS, AXC_DEXIE_SETTINGS_SCOPED_FETCH, AXC_DEXIE_SETTINGS_SCOPED_PATCH, AXC_DEXIE_SETTINGS_SYNC_KEYS, AXP_DEXIE_MOCK_IDENTITY, AXP_DEXIE_SEED, axcDexieClientStore, buildDexieStorageId, provideDexieRuntimeTransport, provideDexieSeeds };
|
|
120
|
+
export type { AXCDexieMockIdentity, AXCDexieSeed, AXCDexieStoreMeta, AXCDexieStoredRecord };
|