yayson 3.0.0 → 4.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/README.md +586 -67
  2. package/build/legacy.cjs +331 -0
  3. package/build/legacy.d.cts +113 -0
  4. package/build/legacy.d.cts.map +1 -0
  5. package/build/legacy.d.mts +113 -0
  6. package/build/legacy.d.mts.map +1 -0
  7. package/build/legacy.mjs +332 -0
  8. package/build/legacy.mjs.map +1 -0
  9. package/build/symbols-DSjKJ8vh.mjs +26 -0
  10. package/build/symbols-DSjKJ8vh.mjs.map +1 -0
  11. package/build/symbols-nFs99aEX.cjs +61 -0
  12. package/build/types-Do2flKZX.d.mts +129 -0
  13. package/build/types-Do2flKZX.d.mts.map +1 -0
  14. package/build/types-NiKV-lj-.d.cts +129 -0
  15. package/build/types-NiKV-lj-.d.cts.map +1 -0
  16. package/build/utils.cjs +31 -0
  17. package/build/utils.d.cts +11 -0
  18. package/build/utils.d.cts.map +1 -0
  19. package/build/utils.d.mts +11 -0
  20. package/build/utils.d.mts.map +1 -0
  21. package/build/utils.mjs +22 -0
  22. package/build/utils.mjs.map +1 -0
  23. package/build/yayson-3UYKq2H5.d.cts +81 -0
  24. package/build/yayson-3UYKq2H5.d.cts.map +1 -0
  25. package/build/yayson-Ce5uGpgU.d.mts +81 -0
  26. package/build/yayson-Ce5uGpgU.d.mts.map +1 -0
  27. package/build/yayson-CwZg5FNt.mjs +452 -0
  28. package/build/yayson-CwZg5FNt.mjs.map +1 -0
  29. package/build/yayson-l2JKseMH.cjs +468 -0
  30. package/build/yayson.cjs +3 -0
  31. package/build/yayson.d.cts +3 -0
  32. package/build/yayson.d.mts +3 -0
  33. package/build/yayson.mjs +3 -0
  34. package/package.json +72 -28
  35. package/skill/yayson/SKILL.md +233 -0
  36. package/skill/yayson/references/api.md +266 -0
  37. package/.eslintrc.json +0 -28
  38. package/.github/workflows/node.js.yml +0 -30
  39. package/.mocharc.js +0 -15
  40. package/.nvmrc +0 -1
  41. package/RELEASE.md +0 -3
  42. package/babel.config.json +0 -4
  43. package/legacy.js +0 -2
  44. package/prettier.config.js +0 -5
  45. package/src/legacy.js +0 -14
  46. package/src/yayson/adapter.js +0 -18
  47. package/src/yayson/adapters/index.js +0 -1
  48. package/src/yayson/adapters/sequelize.js +0 -11
  49. package/src/yayson/legacy-presenter.js +0 -121
  50. package/src/yayson/legacy-store.js +0 -156
  51. package/src/yayson/presenter.js +0 -198
  52. package/src/yayson/store.js +0 -194
  53. package/src/yayson.js +0 -23
  54. package/tags +0 -59
  55. package/webpack.browser.js +0 -27
  56. package/webpack.common.js +0 -39
  57. package/webpack.dist.js +0 -21
@@ -0,0 +1,332 @@
1
+ import { a as TYPE, n as META, t as LINKS } from "./symbols-DSjKJ8vh.mjs";
2
+ import { n as validate, r as filterByFields, t as yayson_default } from "./yayson-CwZg5FNt.mjs";
3
+
4
+ //#region src/yayson/legacy-presenter.ts
5
+ function hasId$1(value) {
6
+ return typeof value === "object" && value !== null && "id" in value;
7
+ }
8
+ function createLegacyPresenter(Presenter) {
9
+ return class LegacyPresenter extends Presenter {
10
+ static type = "object";
11
+ static plural;
12
+ static fields;
13
+ constructor(scope) {
14
+ super(scope || { data: null });
15
+ if (!scope) delete this.scope.data;
16
+ }
17
+ pluralType() {
18
+ return this.constructor.plural || this.constructor.type + "s";
19
+ }
20
+ attributes(instance) {
21
+ if (!instance) return {};
22
+ const attributes = { ...this.constructor.adapter.get(instance) };
23
+ const relationships = this.relationships();
24
+ if (relationships) for (const key in relationships) {
25
+ let id;
26
+ const data = attributes[key];
27
+ if (data == null) {
28
+ id = attributes[key + "Id"];
29
+ if (id != null) attributes[key] = id;
30
+ } else if (Array.isArray(data)) attributes[key] = data.map((obj) => hasId$1(obj) ? obj.id : obj);
31
+ else if (hasId$1(data)) attributes[key] = data.id;
32
+ }
33
+ const relationshipKeys = relationships ? Object.keys(relationships) : [];
34
+ return filterByFields(attributes, this.constructor.fields ? [...this.constructor.fields, ...relationshipKeys] : void 0);
35
+ }
36
+ includeRelationships(scope, instance) {
37
+ if (!scope.links) scope.links = {};
38
+ const relationships = this.relationships();
39
+ const result = [];
40
+ if (!relationships) return result;
41
+ for (const key in relationships) {
42
+ const factory = relationships[key];
43
+ if (!factory) throw new Error(`Presenter for ${key} in ${this.constructor.type} is not defined`);
44
+ const presenter = new factory(scope);
45
+ const data = this.constructor.adapter.get(instance, key);
46
+ if (data != null) presenter.toJSON(data, { defaultPlural: true });
47
+ const type = scope[this.pluralType()] != null ? this.pluralType() : this.constructor.type;
48
+ const presenterType = presenter.constructor.type;
49
+ const link = { type: scope[presenter.pluralType()] != null ? presenter.pluralType() : presenterType };
50
+ if (scope.links) scope.links[`${type}.${key}`] = link;
51
+ result.push(link);
52
+ }
53
+ return result;
54
+ }
55
+ toJSON(instanceOrCollection, options) {
56
+ const opts = options ?? {};
57
+ if (!this.scope.links) this.scope.links = {};
58
+ if (Array.isArray(instanceOrCollection)) {
59
+ const collection = instanceOrCollection;
60
+ const type = this.pluralType();
61
+ if (!this.scope[type]) this.scope[type] = [];
62
+ collection.forEach((instance) => {
63
+ return this.toJSON(instance);
64
+ });
65
+ } else {
66
+ let links;
67
+ const instance = instanceOrCollection;
68
+ let added = true;
69
+ const attrs = instance ? this.attributes(instance) : null;
70
+ if (links = this.links()) {
71
+ if (attrs) attrs.links = links;
72
+ }
73
+ if (this.scope[this.constructor.type] && !this.scope[this.pluralType()]) {
74
+ const existingValue = this.scope[this.constructor.type];
75
+ if (attrs && hasId$1(existingValue) && existingValue.id !== attrs.id) {
76
+ this.scope[this.pluralType()] = [this.scope[this.constructor.type]];
77
+ delete this.scope[this.constructor.type];
78
+ const pluralArray = this.scope[this.pluralType()];
79
+ if (Array.isArray(pluralArray)) pluralArray.push(attrs);
80
+ } else added = false;
81
+ } else if (this.scope[this.pluralType()]) {
82
+ const existing = this.scope[this.pluralType()];
83
+ if (Array.isArray(existing)) if (attrs && !existing.some((i) => hasId$1(i) && i.id === attrs.id)) existing.push(attrs);
84
+ else added = false;
85
+ } else if (opts.defaultPlural) this.scope[this.pluralType()] = attrs ? [attrs] : [];
86
+ else this.scope[this.constructor.type] = attrs;
87
+ if (added && instance) this.includeRelationships(this.scope, instance);
88
+ }
89
+ return this.scope;
90
+ }
91
+ payload(instance) {
92
+ if (Array.isArray(instance)) throw new Error("payload() expects a single resource, not an array");
93
+ if (instance == null) throw new Error("payload() requires a resource, got null");
94
+ return { [this.constructor.type]: this.attributes(instance) };
95
+ }
96
+ render(instanceOrCollection) {
97
+ return this.toJSON(instanceOrCollection);
98
+ }
99
+ static toJSON(instanceOrCollection, options) {
100
+ return new this().toJSON(instanceOrCollection, options);
101
+ }
102
+ static render(instanceOrCollection, _options) {
103
+ return new this().render(instanceOrCollection);
104
+ }
105
+ static payload(instance) {
106
+ return new this().payload(instance);
107
+ }
108
+ };
109
+ }
110
+
111
+ //#endregion
112
+ //#region src/yayson/legacy-store.ts
113
+ function hasId(model) {
114
+ return model.id != null;
115
+ }
116
+ var LegacyStore = class LegacyStore {
117
+ types;
118
+ records;
119
+ relations;
120
+ schemas;
121
+ strict;
122
+ validationErrors;
123
+ models;
124
+ constructor(options) {
125
+ this.types = options?.types || {};
126
+ this.schemas = options?.schemas;
127
+ this.strict = options?.strict ?? false;
128
+ this.records = [];
129
+ this.relations = {};
130
+ this.validationErrors = [];
131
+ this.models = {};
132
+ }
133
+ reset() {
134
+ this.records = [];
135
+ this.relations = {};
136
+ this.validationErrors = [];
137
+ this.models = {};
138
+ }
139
+ #createStub(type, id) {
140
+ const stub = { id };
141
+ stub[TYPE] = type;
142
+ return stub;
143
+ }
144
+ #resolveRelationships(model, type, resolver) {
145
+ const relations = this.relations[type];
146
+ if (!relations) return;
147
+ for (const attribute in relations) {
148
+ const relationType = relations[attribute];
149
+ const value = model[attribute];
150
+ if (Array.isArray(value)) model[attribute] = value.filter((id) => id != null).map((id) => resolver(relationType, String(id)));
151
+ else if (value != null) model[attribute] = resolver(relationType, String(value));
152
+ else model[attribute] = null;
153
+ }
154
+ }
155
+ #createModel(rec, type, options) {
156
+ const models = options?.models;
157
+ const model = { ...rec.data };
158
+ if (rec.data.id != null) model.id = rec.data.id;
159
+ model[TYPE] = type;
160
+ if (rec.data.meta != null) model[META] = rec.data.meta;
161
+ if (rec.data.links != null) model[LINKS] = rec.data.links;
162
+ if (models && hasId(model)) {
163
+ const idStr = String(model.id);
164
+ if (!models[type]) models[type] = {};
165
+ models[type][idStr] = model;
166
+ }
167
+ const resolver = (relationType, id) => {
168
+ return this.#findModel(relationType, id, models ?? {}) ?? this.#createStub(relationType, id);
169
+ };
170
+ this.#resolveRelationships(model, type, resolver);
171
+ return model;
172
+ }
173
+ toModel(rec, type, models) {
174
+ const idStr = String(rec.data.id);
175
+ if (!models[type]) models[type] = {};
176
+ if (models[type][idStr]) return models[type][idStr];
177
+ const result = this.#createModel(rec, type, { models });
178
+ if (!hasId(result)) throw new Error(`Expected model of type ${type} to have an id`);
179
+ const model = result;
180
+ if (this.schemas && this.schemas[type]) {
181
+ const schema = this.schemas[type];
182
+ const result$1 = validate(schema, model, this.strict);
183
+ if (!result$1.valid) this.validationErrors.push({
184
+ type,
185
+ id: idStr,
186
+ error: result$1.error
187
+ });
188
+ const validatedModel = result$1.data;
189
+ validatedModel[TYPE] = model[TYPE];
190
+ validatedModel[LINKS] = model[LINKS];
191
+ validatedModel[META] = model[META];
192
+ models[type][idStr] = validatedModel;
193
+ return validatedModel;
194
+ }
195
+ return model;
196
+ }
197
+ setupRelations(links) {
198
+ for (const key in links) {
199
+ const value = links[key];
200
+ const parts = key.split(".");
201
+ const typeRaw = parts[0];
202
+ const attribute = parts[1];
203
+ const type = this.types[typeRaw] || typeRaw;
204
+ if (!this.relations[type]) this.relations[type] = {};
205
+ this.relations[type][attribute] = this.types[value.type] || value.type;
206
+ }
207
+ }
208
+ findRecord(type, id) {
209
+ return this.records.find((r) => r.type === type && String(r.data.id) === id);
210
+ }
211
+ findRecords(type) {
212
+ return this.records.filter((r) => r.type === type);
213
+ }
214
+ #findModel(type, id, models) {
215
+ const rec = this.findRecord(type, id);
216
+ if (rec == null) return null;
217
+ return models[type]?.[id] ?? this.toModel(rec, type, models);
218
+ }
219
+ static build(data) {
220
+ return new LegacyStore().build(data);
221
+ }
222
+ build(data) {
223
+ if (data.links) this.setupRelations(data.links);
224
+ let name;
225
+ for (const key in data) if (key !== "meta" && key !== "links") {
226
+ name = key;
227
+ break;
228
+ }
229
+ if (name == null) throw new Error("build() expects a single resource, not an array");
230
+ const value = data[name];
231
+ if (value == null || Array.isArray(value)) throw new Error("build() expects a single resource, not an array");
232
+ const type = this.types[name] || name;
233
+ return this.#createModel({
234
+ type,
235
+ data: value
236
+ }, type);
237
+ }
238
+ /** @deprecated Use retrieve() instead. */
239
+ retrive(type, data) {
240
+ return this.retrieve(type, data);
241
+ }
242
+ retrieve(type, data) {
243
+ const synced = this.syncAll(data);
244
+ const normalizedType = this.types[type] || type;
245
+ const model = synced.find((m) => m[TYPE] === normalizedType);
246
+ if (!model) return null;
247
+ if (synced[META]) model[META] = synced[META];
248
+ return model;
249
+ }
250
+ find(type, id, models) {
251
+ return this.#findModel(type, String(id), models ?? this.models);
252
+ }
253
+ findAll(type, models) {
254
+ const modelsObj = models ?? this.models;
255
+ const recs = this.findRecords(type);
256
+ if (recs.length === 0) return [];
257
+ recs.forEach((rec) => {
258
+ if (!modelsObj[type]) modelsObj[type] = {};
259
+ return this.toModel(rec, type, modelsObj);
260
+ });
261
+ return Object.values(modelsObj[type] || {});
262
+ }
263
+ remove(type, id) {
264
+ const normalizedType = this.types[type] || type;
265
+ const removeOne = (record) => {
266
+ const index = this.records.indexOf(record);
267
+ if (!(index < 0)) this.records.splice(index, 1);
268
+ };
269
+ if (id != null) {
270
+ const idStr = String(id);
271
+ const record = this.findRecord(normalizedType, idStr);
272
+ if (record) removeOne(record);
273
+ } else this.findRecords(normalizedType).forEach(removeOne);
274
+ }
275
+ syncAll(data) {
276
+ this.validationErrors = [];
277
+ this.models = {};
278
+ if (data.links) this.setupRelations(data.links);
279
+ const syncedRecords = [];
280
+ for (const name in data) {
281
+ if (name === "meta" || name === "links") continue;
282
+ const value = data[name];
283
+ const type = this.types[name] || name;
284
+ const add = (d) => {
285
+ this.remove(type, String(d.id));
286
+ const rec = {
287
+ type,
288
+ data: d
289
+ };
290
+ this.records.push(rec);
291
+ syncedRecords.push(rec);
292
+ };
293
+ if (Array.isArray(value)) value.forEach(add);
294
+ else if (typeof value === "object" && value !== null) add(value);
295
+ }
296
+ for (const rec of syncedRecords) this.toModel(rec, rec.type, this.models);
297
+ const result = syncedRecords.map((rec) => this.models[rec.type][String(rec.data.id)]);
298
+ if (data.meta != null) result[META] = data.meta;
299
+ return result;
300
+ }
301
+ sync(data) {
302
+ const result = this.syncAll(data);
303
+ if (result.length === 1) {
304
+ const model = result[0];
305
+ if (result[META]) model[META] = result[META];
306
+ return model;
307
+ }
308
+ return result;
309
+ }
310
+ retrieveAll(type, data) {
311
+ const normalizedType = this.types[type] || type;
312
+ const synced = this.syncAll(data);
313
+ const result = synced.filter((model) => model[TYPE] === normalizedType);
314
+ result[META] = synced[META];
315
+ return result;
316
+ }
317
+ };
318
+
319
+ //#endregion
320
+ //#region src/legacy.ts
321
+ function yayson(options) {
322
+ const { Presenter, Adapter } = yayson_default(options);
323
+ return {
324
+ Store: LegacyStore,
325
+ Presenter: createLegacyPresenter(Presenter),
326
+ Adapter
327
+ };
328
+ }
329
+
330
+ //#endregion
331
+ export { yayson as default };
332
+ //# sourceMappingURL=legacy.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"legacy.mjs","names":["hasId","#findModel","#createStub","#resolveRelationships","#createModel","result","yaysonFactory"],"sources":["../src/yayson/legacy-presenter.ts","../src/yayson/legacy-store.ts","../src/legacy.ts"],"sourcesContent":["import type { ModelLike } from './adapter.js'\nimport type { Presenter } from './presenter.js'\nimport type { JsonApiDocument, JsonApiLinks, LegacyPresenterOptions } from './types.js'\nimport { filterByFields } from './utils.js'\n\nfunction hasId(value: unknown): value is { id: unknown } {\n return typeof value === 'object' && value !== null && 'id' in value\n}\n\ninterface LegacyJsonApiDocument extends JsonApiDocument {\n [key: string]: unknown\n}\n\n// eslint-disable-next-line @typescript-eslint/explicit-function-return-type -- Return type is inferred from class\nexport default function createLegacyPresenter(Presenter: Presenter) {\n return class LegacyPresenter extends Presenter {\n declare ['constructor']: typeof LegacyPresenter\n declare scope: LegacyJsonApiDocument\n\n static type = 'object'\n static plural?: string\n static fields?: string[]\n\n constructor(scope?: JsonApiDocument) {\n // LegacyPresenter doesn't use the 'data' property, so pass an empty scope\n const emptyScope: JsonApiDocument = { data: null }\n super(scope || emptyScope)\n // Remove the 'data' property that the parent constructor adds\n if (!scope) {\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- Need Partial to allow delete\n delete (this.scope as Partial<JsonApiDocument>).data\n }\n }\n\n pluralType(): string {\n return this.constructor.plural || this.constructor.type + 's'\n }\n\n attributes(instance: ModelLike | null): Record<string, unknown> {\n if (!instance) {\n return {}\n }\n const attributes = { ...this.constructor.adapter.get(instance) }\n const relationships = this.relationships()\n if (relationships) {\n for (const key in relationships) {\n let id: unknown\n const data = attributes[key]\n if (data == null) {\n id = attributes[key + 'Id']\n if (id != null) {\n attributes[key] = id\n }\n } else if (Array.isArray(data)) {\n attributes[key] = data.map((obj: unknown) => (hasId(obj) ? obj.id : obj))\n } else if (hasId(data)) {\n attributes[key] = data.id\n }\n }\n }\n\n // Include relationship keys in allowed fields (so users don't need to list them twice)\n const relationshipKeys = relationships ? Object.keys(relationships) : []\n const allowedFields = this.constructor.fields ? [...this.constructor.fields, ...relationshipKeys] : undefined\n\n return filterByFields(attributes, allowedFields)\n }\n\n includeRelationships(scope: LegacyJsonApiDocument, instance: ModelLike): unknown[] {\n if (!scope.links) {\n scope.links = {}\n }\n const relationships = this.relationships()\n const result: unknown[] = []\n\n if (!relationships) {\n return result\n }\n\n for (const key in relationships) {\n const factory = relationships[key]\n if (!factory) throw new Error(`Presenter for ${key} in ${this.constructor.type} is not defined`)\n\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- Factory returns PresenterInstance, we know it's LegacyPresenter\n const presenter = new factory(scope) as LegacyPresenter\n\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- unknown from adapter.get\n const data = this.constructor.adapter.get(instance, key) as ModelLike | ModelLike[] | null\n if (data != null) {\n presenter.toJSON(data, { defaultPlural: true })\n }\n\n const type = scope[this.pluralType()] != null ? this.pluralType() : this.constructor.type\n const presenterType = presenter.constructor.type\n const keyName = scope[presenter.pluralType()] != null ? presenter.pluralType() : presenterType\n const link = { type: keyName }\n if (scope.links) {\n scope.links[`${type}.${key}`] = link\n }\n result.push(link)\n }\n return result\n }\n\n toJSON(\n instanceOrCollection: ModelLike | ModelLike[] | null | undefined,\n options?: LegacyPresenterOptions,\n ): LegacyJsonApiDocument {\n const opts = options ?? {}\n if (!this.scope.links) {\n this.scope.links = {}\n }\n if (Array.isArray(instanceOrCollection)) {\n const collection = instanceOrCollection\n const type = this.pluralType()\n if (!this.scope[type]) {\n this.scope[type] = []\n }\n collection.forEach((instance: ModelLike) => {\n return this.toJSON(instance)\n })\n } else {\n let links: JsonApiLinks | undefined\n const instance = instanceOrCollection\n let added = true\n const attrs = instance ? this.attributes(instance) : null\n if ((links = this.links())) {\n if (attrs) {\n attrs.links = links\n }\n }\n // If eg x.image already exists\n if (this.scope[this.constructor.type] && !this.scope[this.pluralType()]) {\n const existingValue = this.scope[this.constructor.type]\n if (attrs && hasId(existingValue) && existingValue.id !== attrs.id) {\n this.scope[this.pluralType()] = [this.scope[this.constructor.type]]\n delete this.scope[this.constructor.type]\n const pluralArray = this.scope[this.pluralType()]\n if (Array.isArray(pluralArray)) {\n pluralArray.push(attrs)\n }\n } else {\n added = false\n }\n\n // If eg x.images already exists\n } else if (this.scope[this.pluralType()]) {\n const existing = this.scope[this.pluralType()]\n if (Array.isArray(existing)) {\n if (attrs && !existing.some((i) => hasId(i) && i.id === attrs.id)) {\n existing.push(attrs)\n } else {\n added = false\n }\n }\n } else if (opts.defaultPlural) {\n this.scope[this.pluralType()] = attrs ? [attrs] : []\n } else {\n this.scope[this.constructor.type] = attrs\n }\n\n if (added && instance) {\n this.includeRelationships(this.scope, instance)\n }\n }\n return this.scope\n }\n\n payload(instance: ModelLike): LegacyJsonApiDocument {\n if (Array.isArray(instance)) {\n throw new Error('payload() expects a single resource, not an array')\n }\n if (instance == null) {\n throw new Error('payload() requires a resource, got null')\n }\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- Legacy payload intentionally omits `data`\n return { [this.constructor.type]: this.attributes(instance) } as LegacyJsonApiDocument\n }\n\n render(instanceOrCollection: ModelLike | ModelLike[] | null): LegacyJsonApiDocument {\n return this.toJSON(instanceOrCollection)\n }\n\n static toJSON(\n instanceOrCollection: ModelLike | ModelLike[] | null,\n options?: LegacyPresenterOptions,\n ): LegacyJsonApiDocument {\n return new this().toJSON(instanceOrCollection, options)\n }\n\n static render(\n instanceOrCollection: ModelLike | ModelLike[] | null,\n _options?: LegacyPresenterOptions,\n ): LegacyJsonApiDocument {\n return new this().render(instanceOrCollection)\n }\n\n static payload(instance: ModelLike): LegacyJsonApiDocument {\n return new this().payload(instance)\n }\n }\n}\n","import type {\n StoreModel,\n StoreModelWithOptionalId,\n StoreModels,\n StoreResult,\n SchemaRegistry,\n ValidationError,\n InferModelType,\n LegacyStoreOptions,\n} from './types.js'\nimport { TYPE, LINKS, META } from './symbols.js'\nimport { validate } from './schema.js'\n\ninterface LegacyStoreRecordType {\n type: string\n data: Record<string, unknown> & {\n id?: string | number\n meta?: Record<string, unknown>\n links?: Record<string, unknown>\n }\n}\n\ninterface LegacyLinks {\n [key: string]: {\n type: string\n }\n}\n\ntype LegacyDataValue = Record<string, unknown> | Array<Record<string, unknown>>\n\nexport interface LegacyData {\n links?: LegacyLinks\n meta?: Record<string, unknown>\n [key: string]: LegacyDataValue | LegacyLinks | Record<string, unknown> | undefined\n}\n\nfunction hasId<T extends StoreModelWithOptionalId>(model: T): model is T & { id: string | number } {\n return model.id != null\n}\n\nexport default class LegacyStore<S extends SchemaRegistry = SchemaRegistry> {\n types: Record<string, string>\n records: LegacyStoreRecordType[]\n relations: Record<string, Record<string, string>>\n schemas?: S\n strict: boolean\n validationErrors: ValidationError[]\n models: StoreModels\n\n constructor(options?: LegacyStoreOptions<S>) {\n this.types = options?.types || {}\n this.schemas = options?.schemas\n this.strict = options?.strict ?? false\n this.records = []\n this.relations = {}\n this.validationErrors = []\n this.models = {}\n }\n\n reset(): void {\n this.records = []\n this.relations = {}\n this.validationErrors = []\n this.models = {}\n }\n\n #createStub(type: string, id: string): StoreModel {\n const stub: StoreModel = { id }\n stub[TYPE] = type\n return stub\n }\n\n #resolveRelationships(\n model: StoreModel | StoreModelWithOptionalId,\n type: string,\n resolver: (relationType: string, id: string) => StoreModel,\n ): void {\n const relations = this.relations[type]\n if (!relations) return\n\n for (const attribute in relations) {\n const relationType = relations[attribute]!\n const value = model[attribute]\n if (Array.isArray(value)) {\n model[attribute] = value\n .filter((id: unknown) => id != null)\n .map((id: unknown) => resolver(relationType, String(id)))\n } else if (value != null) {\n model[attribute] = resolver(relationType, String(value))\n } else {\n model[attribute] = null\n }\n }\n }\n\n #createModel(rec: LegacyStoreRecordType, type: string, options?: { models?: StoreModels }): StoreModelWithOptionalId {\n const models = options?.models\n\n const model: StoreModelWithOptionalId = { ...rec.data }\n if (rec.data.id != null) {\n model.id = rec.data.id\n }\n model[TYPE] = type\n if (rec.data.meta != null) {\n model[META] = rec.data.meta\n }\n if (rec.data.links != null) {\n model[LINKS] = rec.data.links\n }\n\n if (models && hasId(model)) {\n const idStr = String(model.id)\n if (!models[type]) {\n models[type] = {}\n }\n models[type]![idStr] = model\n }\n\n const resolver = (relationType: string, id: string): StoreModel => {\n return this.#findModel(relationType, id, models ?? {}) ?? this.#createStub(relationType, id)\n }\n this.#resolveRelationships(model, type, resolver)\n\n return model\n }\n\n toModel(rec: LegacyStoreRecordType, type: string, models: StoreModels): StoreModel {\n const idStr = String(rec.data.id)\n\n if (!models[type]) {\n models[type] = {}\n }\n\n if (models[type]![idStr]) {\n return models[type]![idStr]!\n }\n\n const result = this.#createModel(rec, type, { models })\n if (!hasId(result)) {\n throw new Error(`Expected model of type ${type} to have an id`)\n }\n const model = result\n\n if (this.schemas && this.schemas[type]) {\n const schema = this.schemas[type]\n const result = validate(schema, model, this.strict)\n\n if (!result.valid) {\n this.validationErrors.push({\n type,\n id: idStr,\n error: result.error,\n })\n }\n\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- Schema validation returns unknown, cast to StoreModel after validation\n const validatedModel = result.data as StoreModel\n\n // Preserve symbol keys from original model (schema validation may not preserve them)\n validatedModel[TYPE] = model[TYPE]\n validatedModel[LINKS] = model[LINKS]\n validatedModel[META] = model[META]\n\n models[type]![idStr] = validatedModel\n return validatedModel\n }\n\n return model\n }\n\n setupRelations(links: LegacyLinks): void {\n for (const key in links) {\n const value = links[key]!\n const parts = key.split('.')\n const typeRaw = parts[0]!\n const attribute = parts[1]!\n const type = this.types[typeRaw] || typeRaw\n if (!this.relations[type]) {\n this.relations[type] = {}\n }\n this.relations[type]![attribute] = this.types[value.type] || value.type\n }\n }\n\n findRecord(type: string, id: string): LegacyStoreRecordType | undefined {\n return this.records.find((r) => r.type === type && String(r.data.id) === id)\n }\n\n findRecords(type: string): LegacyStoreRecordType[] {\n return this.records.filter((r) => r.type === type)\n }\n\n #findModel(type: string, id: string, models: StoreModels): StoreModel | null {\n const rec = this.findRecord(type, id)\n if (rec == null) {\n return null\n }\n return models[type]?.[id] ?? this.toModel(rec, type, models)\n }\n\n static build(data: LegacyData): StoreModelWithOptionalId {\n return new LegacyStore().build(data)\n }\n\n build(data: LegacyData): StoreModelWithOptionalId {\n if (data.links) {\n this.setupRelations(data.links)\n }\n\n let name: string | undefined\n for (const key in data) {\n if (key !== 'meta' && key !== 'links') {\n name = key\n break\n }\n }\n\n if (name == null) {\n throw new Error('build() expects a single resource, not an array')\n }\n\n const value = data[name]\n if (value == null || Array.isArray(value)) {\n throw new Error('build() expects a single resource, not an array')\n }\n\n const type = this.types[name] || name\n return this.#createModel({ type, data: value }, type)\n }\n\n /** @deprecated Use retrieve() instead. */\n retrive<T extends string>(type: T, data: LegacyData): InferModelType<S, T> | null {\n return this.retrieve(type, data)\n }\n\n retrieve<T extends string>(type: T, data: LegacyData): InferModelType<S, T> | null {\n const synced = this.syncAll(data)\n const normalizedType = this.types[type] || type\n const model = synced.find((m) => m[TYPE] === normalizedType)\n if (!model) return null\n if (synced[META]) {\n model[META] = synced[META]\n }\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- Enable type inference from type parameter\n return model as InferModelType<S, T>\n }\n\n find<T extends string>(type: T, id: string | number, models?: StoreModels): InferModelType<S, T> | null {\n const result = this.#findModel(type, String(id), models ?? this.models)\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- Type inference: maps string literal type parameter to schema type\n return result as InferModelType<S, T> | null\n }\n\n findAll<T extends string>(type: T, models?: StoreModels): InferModelType<S, T>[] {\n const modelsObj = models ?? this.models\n const recs = this.findRecords(type)\n if (recs.length === 0) {\n return []\n }\n recs.forEach((rec) => {\n if (!modelsObj[type]) {\n modelsObj[type] = {}\n }\n return this.toModel(rec, type, modelsObj)\n })\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- Type inference: maps string literal type parameter to schema type\n return Object.values(modelsObj[type] || {}) as InferModelType<S, T>[]\n }\n\n remove(type: string, id?: string | number): void {\n const normalizedType = this.types[type] || type\n\n const removeOne = (record: LegacyStoreRecordType): void => {\n const index = this.records.indexOf(record)\n if (!(index < 0)) {\n this.records.splice(index, 1)\n }\n }\n\n if (id != null) {\n const idStr = String(id)\n const record = this.findRecord(normalizedType, idStr)\n if (record) {\n removeOne(record)\n }\n } else {\n const records = this.findRecords(normalizedType)\n records.forEach(removeOne)\n }\n }\n\n syncAll(data: LegacyData): StoreResult {\n // Clear validation errors and models cache from previous sync\n this.validationErrors = []\n this.models = {}\n\n if (data.links) {\n this.setupRelations(data.links)\n }\n\n const syncedRecords: LegacyStoreRecordType[] = []\n\n for (const name in data) {\n if (name === 'meta' || name === 'links') {\n continue\n }\n\n const value = data[name]!\n const type = this.types[name] || name\n\n const add = (d: Record<string, unknown>): void => {\n this.remove(type, String(d.id))\n const rec: LegacyStoreRecordType = { type, data: d }\n this.records.push(rec)\n syncedRecords.push(rec)\n }\n\n if (Array.isArray(value)) {\n value.forEach(add)\n } else if (typeof value === 'object' && value !== null) {\n add(value)\n }\n }\n\n for (const rec of syncedRecords) {\n this.toModel(rec, rec.type, this.models)\n }\n\n const result: StoreResult = syncedRecords.map((rec) => this.models[rec.type]![String(rec.data.id)]!)\n if (data.meta != null) {\n result[META] = data.meta\n }\n return result\n }\n\n sync(data: LegacyData): StoreModel | StoreResult {\n const result = this.syncAll(data)\n if (result.length === 1) {\n const model = result[0]\n if (result[META]) {\n model[META] = result[META]\n }\n return model\n }\n return result\n }\n\n retrieveAll<T extends string>(type: T, data: LegacyData): StoreResult<InferModelType<S, T>> {\n const normalizedType = this.types[type] || type\n const synced = this.syncAll(data)\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- Enable type inference from type parameter\n const result: StoreResult<InferModelType<S, T>> = synced.filter(\n (model) => model[TYPE] === normalizedType,\n ) as StoreResult<InferModelType<S, T>>\n result[META] = synced[META]\n return result\n }\n}\n","import yaysonFactory from './yayson.js'\nimport createLegacyPresenter from './yayson/legacy-presenter.js'\nimport LegacyStore from './yayson/legacy-store.js'\nimport type { LegacyData } from './yayson/legacy-store.js'\nimport Adapter from './yayson/adapter.js'\nimport type {\n JsonApiDocument,\n JsonApiLink,\n JsonApiLinks,\n JsonApiRelationship,\n JsonApiRelationships,\n JsonApiResource,\n} from './yayson/types.js'\nimport type { YaysonOptions } from './yayson.js'\n\nexport type {\n Adapter,\n JsonApiDocument,\n JsonApiLink,\n JsonApiLinks,\n JsonApiRelationship,\n JsonApiRelationships,\n JsonApiResource,\n LegacyData,\n}\n\ninterface LegacyYaysonResult {\n Store: typeof LegacyStore\n Presenter: ReturnType<typeof createLegacyPresenter>\n Adapter: ReturnType<typeof yaysonFactory>['Adapter']\n}\n\nexport default function yayson(options?: YaysonOptions): LegacyYaysonResult {\n const { Presenter, Adapter } = yaysonFactory(options)\n return {\n Store: LegacyStore,\n Presenter: createLegacyPresenter(Presenter),\n Adapter,\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ //#region src/yayson/adapter.ts
2
+ var Adapter = class {
3
+ static get(model, key) {
4
+ const obj = model;
5
+ if (key) return obj[key];
6
+ return obj;
7
+ }
8
+ static id(model) {
9
+ const id = this.get(model, "id");
10
+ if (id == null) return;
11
+ return `${id}`;
12
+ }
13
+ };
14
+ var adapter_default = Adapter;
15
+
16
+ //#endregion
17
+ //#region src/yayson/symbols.ts
18
+ const TYPE = Symbol("yayson.type");
19
+ const LINKS = Symbol("yayson.links");
20
+ const META = Symbol("yayson.meta");
21
+ const REL_LINKS = Symbol("yayson.rel-links");
22
+ const REL_META = Symbol("yayson.rel-meta");
23
+
24
+ //#endregion
25
+ export { TYPE as a, REL_META as i, META as n, adapter_default as o, REL_LINKS as r, LINKS as t };
26
+ //# sourceMappingURL=symbols-DSjKJ8vh.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"symbols-DSjKJ8vh.mjs","names":[],"sources":["../src/yayson/adapter.ts","../src/yayson/symbols.ts"],"sourcesContent":["export type ModelLike = object\n\nclass Adapter {\n static get(model: ModelLike): Record<string, unknown>\n static get(model: ModelLike, key: string): unknown\n static get(model: ModelLike, key?: string): unknown {\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- ModelLike is object for flexibility, cast for dynamic access\n const obj = model as Record<string, unknown>\n if (key) {\n return obj[key]\n }\n return obj\n }\n\n static id(model: ModelLike): string | undefined {\n const id = this.get(model, 'id')\n if (id == null) {\n return undefined\n }\n return `${id}`\n }\n}\n\nexport default Adapter\n","export const TYPE: unique symbol = Symbol('yayson.type')\nexport const LINKS: unique symbol = Symbol('yayson.links')\nexport const META: unique symbol = Symbol('yayson.meta')\nexport const REL_LINKS: unique symbol = Symbol('yayson.rel-links')\nexport const REL_META: unique symbol = Symbol('yayson.rel-meta')\n"],"mappings":";AAEA,IAAM,UAAN,MAAc;CAGZ,OAAO,IAAI,OAAkB,KAAuB;EAElD,MAAM,MAAM;AACZ,MAAI,IACF,QAAO,IAAI;AAEb,SAAO;;CAGT,OAAO,GAAG,OAAsC;EAC9C,MAAM,KAAK,KAAK,IAAI,OAAO,KAAK;AAChC,MAAI,MAAM,KACR;AAEF,SAAO,GAAG;;;AAId,sBAAe;;;;ACvBf,MAAa,OAAsB,OAAO,cAAc;AACxD,MAAa,QAAuB,OAAO,eAAe;AAC1D,MAAa,OAAsB,OAAO,cAAc;AACxD,MAAa,YAA2B,OAAO,mBAAmB;AAClE,MAAa,WAA0B,OAAO,kBAAkB"}
@@ -0,0 +1,61 @@
1
+
2
+ //#region src/yayson/adapter.ts
3
+ var Adapter = class {
4
+ static get(model, key) {
5
+ const obj = model;
6
+ if (key) return obj[key];
7
+ return obj;
8
+ }
9
+ static id(model) {
10
+ const id = this.get(model, "id");
11
+ if (id == null) return;
12
+ return `${id}`;
13
+ }
14
+ };
15
+ var adapter_default = Adapter;
16
+
17
+ //#endregion
18
+ //#region src/yayson/symbols.ts
19
+ const TYPE = Symbol("yayson.type");
20
+ const LINKS = Symbol("yayson.links");
21
+ const META = Symbol("yayson.meta");
22
+ const REL_LINKS = Symbol("yayson.rel-links");
23
+ const REL_META = Symbol("yayson.rel-meta");
24
+
25
+ //#endregion
26
+ Object.defineProperty(exports, 'LINKS', {
27
+ enumerable: true,
28
+ get: function () {
29
+ return LINKS;
30
+ }
31
+ });
32
+ Object.defineProperty(exports, 'META', {
33
+ enumerable: true,
34
+ get: function () {
35
+ return META;
36
+ }
37
+ });
38
+ Object.defineProperty(exports, 'REL_LINKS', {
39
+ enumerable: true,
40
+ get: function () {
41
+ return REL_LINKS;
42
+ }
43
+ });
44
+ Object.defineProperty(exports, 'REL_META', {
45
+ enumerable: true,
46
+ get: function () {
47
+ return REL_META;
48
+ }
49
+ });
50
+ Object.defineProperty(exports, 'TYPE', {
51
+ enumerable: true,
52
+ get: function () {
53
+ return TYPE;
54
+ }
55
+ });
56
+ Object.defineProperty(exports, 'adapter_default', {
57
+ enumerable: true,
58
+ get: function () {
59
+ return adapter_default;
60
+ }
61
+ });
@@ -0,0 +1,129 @@
1
+ //#region src/yayson/adapter.d.ts
2
+ type ModelLike = object;
3
+ declare class Adapter {
4
+ static get(model: ModelLike): Record<string, unknown>;
5
+ static get(model: ModelLike, key: string): unknown;
6
+ static id(model: ModelLike): string | undefined;
7
+ }
8
+ //#endregion
9
+ //#region src/yayson/symbols.d.ts
10
+ declare const TYPE: unique symbol;
11
+ declare const LINKS: unique symbol;
12
+ declare const META: unique symbol;
13
+ declare const REL_LINKS: unique symbol;
14
+ declare const REL_META: unique symbol;
15
+ //#endregion
16
+ //#region src/yayson/schema.d.ts
17
+ /**
18
+ * Interface for Zod-like schema objects.
19
+ * Any schema library that implements `parse` and `safeParse` methods will work.
20
+ */
21
+ interface ZodLikeSchema {
22
+ parse: (data: unknown) => unknown;
23
+ safeParse: (data: unknown) => {
24
+ success: true;
25
+ data: unknown;
26
+ } | {
27
+ success: false;
28
+ error: unknown;
29
+ };
30
+ }
31
+ //#endregion
32
+ //#region src/yayson/types.d.ts
33
+ interface JsonApiLink extends Record<string, unknown> {
34
+ self?: string;
35
+ related?: string;
36
+ }
37
+ interface JsonApiLinks {
38
+ [key: string]: JsonApiLink | string | undefined;
39
+ }
40
+ interface JsonApiResourceIdentifier {
41
+ id: string | number;
42
+ type: string;
43
+ }
44
+ interface JsonApiRelationship {
45
+ data?: JsonApiResourceIdentifier | JsonApiResourceIdentifier[] | null;
46
+ links?: JsonApiLink;
47
+ meta?: Record<string, unknown>;
48
+ }
49
+ interface JsonApiRelationships {
50
+ [key: string]: JsonApiRelationship;
51
+ }
52
+ interface JsonApiResource {
53
+ id?: string | number;
54
+ type: string;
55
+ attributes?: Record<string, unknown> | null;
56
+ relationships?: JsonApiRelationships | null;
57
+ links?: JsonApiLink;
58
+ meta?: Record<string, unknown>;
59
+ }
60
+ interface JsonApiDocument {
61
+ data: JsonApiResource | JsonApiResource[] | null;
62
+ included?: JsonApiResource[];
63
+ links?: JsonApiLinks;
64
+ meta?: Record<string, unknown>;
65
+ }
66
+ interface PresenterOptions {
67
+ meta?: Record<string, unknown>;
68
+ links?: JsonApiLinks;
69
+ include?: boolean;
70
+ }
71
+ interface LegacyPresenterOptions extends PresenterOptions {
72
+ defaultPlural?: boolean;
73
+ }
74
+ interface StoreRecord {
75
+ id: string | number;
76
+ type: string;
77
+ attributes?: Record<string, unknown>;
78
+ relationships?: JsonApiRelationships;
79
+ links?: JsonApiLink;
80
+ meta?: Record<string, unknown>;
81
+ }
82
+ interface StoreModel extends Record<string, unknown> {
83
+ id: string | number;
84
+ [TYPE]?: string;
85
+ [LINKS]?: JsonApiLink;
86
+ [META]?: Record<string, unknown>;
87
+ [REL_LINKS]?: JsonApiLink;
88
+ [REL_META]?: Record<string, unknown>;
89
+ }
90
+ /** Model type for create payloads where id may be absent */
91
+ interface StoreModelWithOptionalId extends Record<string, unknown> {
92
+ id?: string | number;
93
+ [TYPE]?: string;
94
+ [LINKS]?: JsonApiLink;
95
+ [META]?: Record<string, unknown>;
96
+ }
97
+ interface StoreModels {
98
+ [type: string]: {
99
+ [id: string]: StoreModel;
100
+ };
101
+ }
102
+ interface SchemaRegistry {
103
+ [type: string]: ZodLikeSchema;
104
+ }
105
+ type InferSchemaType<Schema> = Schema extends {
106
+ parse: (data: unknown) => infer ParsedType;
107
+ safeParse: (data: unknown) => unknown;
108
+ } ? ParsedType : unknown;
109
+ type InferModelType<Registry, TypeName extends string> = Registry extends SchemaRegistry ? TypeName extends keyof Registry ? InferSchemaType<Registry[TypeName]> : StoreModel : StoreModel;
110
+ interface StoreResult<T = StoreModel> extends Array<T> {
111
+ [META]?: Record<string, unknown>;
112
+ }
113
+ interface StoreOptions<S extends SchemaRegistry = SchemaRegistry> {
114
+ schemas?: S;
115
+ strict?: boolean;
116
+ }
117
+ interface ValidationError {
118
+ type: string;
119
+ id: string | number;
120
+ error: unknown;
121
+ }
122
+ interface LegacyStoreOptions<S extends SchemaRegistry = SchemaRegistry> {
123
+ types?: Record<string, string>;
124
+ schemas?: S;
125
+ strict?: boolean;
126
+ }
127
+ //#endregion
128
+ export { REL_META as C, ModelLike as E, REL_LINKS as S, Adapter as T, StoreResult as _, JsonApiRelationship as a, LINKS as b, LegacyPresenterOptions as c, SchemaRegistry as d, StoreModel as f, StoreRecord as g, StoreOptions as h, JsonApiLinks as i, LegacyStoreOptions as l, StoreModels as m, JsonApiDocument as n, JsonApiRelationships as o, StoreModelWithOptionalId as p, JsonApiLink as r, JsonApiResource as s, InferModelType as t, PresenterOptions as u, ValidationError as v, TYPE as w, META as x, ZodLikeSchema as y };
129
+ //# sourceMappingURL=types-Do2flKZX.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types-Do2flKZX.d.mts","names":[],"sources":["../../../../../../yayson/adapter.ts","../../../../../../yayson/symbols.ts","../../../../../../yayson/schema.ts","../../../../../../yayson/types.ts"],"mappings":";KAAY,SAAA;AAAA,cAEN,OAAA;EAAA,OACG,GAAA,CAAI,KAAA,EAAO,SAAA,GAAY,MAAA;EAAA,OACvB,GAAA,CAAI,KAAA,EAAO,SAAA,EAAW,GAAA;EAAA,OAUtB,EAAA,CAAG,KAAA,EAAO,SAAA;AAAA;;;cCdN,IAAA;AAAA,cACA,KAAA;AAAA,cACA,IAAA;AAAA,cACA,SAAA;AAAA,cACA,QAAA;;;;ADJb;;;UEIiB,aAAA;EACf,KAAA,GAAQ,IAAA;EACR,SAAA,GAAY,IAAA;IAAoB,OAAA;IAAe,IAAA;EAAA;IAAoB,OAAA;IAAgB,KAAA;EAAA;AAAA;;;UCHpE,WAAA,SAAoB,MAAA;EACnC,IAAA;EACA,OAAA;AAAA;AAAA,UAGe,YAAA;EAAA,CACd,GAAA,WAAc,WAAA;AAAA;AAAA,UAGA,yBAAA;EACf,EAAA;EACA,IAAA;AAAA;AAAA,UAGe,mBAAA;EACf,IAAA,GAAO,yBAAA,GAA4B,yBAAA;EACnC,KAAA,GAAQ,WAAA;EACR,IAAA,GAAO,MAAA;AAAA;AAAA,UAGQ,oBAAA;EAAA,CACd,GAAA,WAAc,mBAAA;AAAA;AAAA,UAGA,eAAA;EACf,EAAA;EACA,IAAA;EACA,UAAA,GAAa,MAAA;EACb,aAAA,GAAgB,oBAAA;EAChB,KAAA,GAAQ,WAAA;EACR,IAAA,GAAO,MAAA;AAAA;AAAA,UAGQ,eAAA;EACf,IAAA,EAAM,eAAA,GAAkB,eAAA;EACxB,QAAA,GAAW,eAAA;EACX,KAAA,GAAQ,YAAA;EACR,IAAA,GAAO,MAAA;AAAA;AAAA,UAGQ,gBAAA;EACf,IAAA,GAAO,MAAA;EACP,KAAA,GAAQ,YAAA;EACR,OAAA;AAAA;AAAA,UAGe,sBAAA,SAA+B,gBAAA;EAC9C,aAAA;AAAA;AAAA,UAGe,WAAA;EACf,EAAA;EACA,IAAA;EACA,UAAA,GAAa,MAAA;EACb,aAAA,GAAgB,oBAAA;EAChB,KAAA,GAAQ,WAAA;EACR,IAAA,GAAO,MAAA;AAAA;AAAA,UAGQ,UAAA,SAAmB,MAAA;EAClC,EAAA;EAAA,CACC,IAAA;EAAA,CACA,KAAA,IAAS,WAAA;EAAA,CACT,IAAA,IAAQ,MAAA;EAAA,CACR,SAAA,IAAa,WAAA;EAAA,CACb,QAAA,IAAY,MAAA;AAAA;ADhEf;AAAA,UCoEiB,wBAAA,SAAiC,MAAA;EAChD,EAAA;EAAA,CACC,IAAA;EAAA,CACA,KAAA,IAAS,WAAA;EAAA,CACT,IAAA,IAAQ,MAAA;AAAA;AAAA,UAGM,WAAA;EAAA,CACd,IAAA;IAAA,CACE,EAAA,WAAa,UAAA;EAAA;AAAA;AAAA,UAID,cAAA;EAAA,CACd,IAAA,WAAe,aAAA;AAAA;AAAA,KAIN,eAAA,WAA0B,MAAA;EACpC,KAAA,GAAQ,IAAA;EACR,SAAA,GAAY,IAAA;AAAA,IAEV,UAAA;AAAA,KAGQ,cAAA,sCAAoD,QAAA,SAAiB,cAAA,GAC7E,QAAA,eAAuB,QAAA,GACrB,eAAA,CAAgB,QAAA,CAAS,QAAA,KACzB,UAAA,GACF,UAAA;AAAA,UAEa,WAAA,KAAgB,UAAA,UAAoB,KAAA,CAAM,CAAA;EAAA,CACxD,IAAA,IAAQ,MAAA;AAAA;AAAA,UAGM,YAAA,WAAuB,cAAA,GAAiB,cAAA;EACvD,OAAA,GAAU,CAAA;EACV,MAAA;AAAA;AAAA,UAGe,eAAA;EACf,IAAA;EACA,EAAA;EACA,KAAA;AAAA;AAAA,UAGe,kBAAA,WAA6B,cAAA,GAAiB,cAAA;EAC7D,KAAA,GAAQ,MAAA;EACR,OAAA,GAAU,CAAA;EACV,MAAA;AAAA"}