@iamjulianacosta/mobx-data 1.1.0 → 1.4.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.
- package/README.md +273 -102
- package/dist/{CacheHandler-BTU_rYkv.js → CacheHandler-BhfbVHed.js} +17 -20
- package/dist/CacheHandler-BhfbVHed.js.map +1 -0
- package/dist/{CacheHandler-CXgY9IJo.cjs → CacheHandler-Q5VXOgh9.cjs} +2 -2
- package/dist/CacheHandler-Q5VXOgh9.cjs.map +1 -0
- package/dist/EmbeddedRecordsMixin-6mSCXsJ3.js +173 -0
- package/dist/EmbeddedRecordsMixin-6mSCXsJ3.js.map +1 -0
- package/dist/EmbeddedRecordsMixin-BkF7MdbY.cjs +2 -0
- package/dist/EmbeddedRecordsMixin-BkF7MdbY.cjs.map +1 -0
- package/dist/{JsonApiSerializer-BLoE046A.js → JsonApiSerializer-BV61cFAZ.js} +3 -3
- package/dist/JsonApiSerializer-BV61cFAZ.js.map +1 -0
- package/dist/{JsonApiSerializer-DKemcyw-.cjs → JsonApiSerializer-Dt_Y_FIo.cjs} +2 -2
- package/dist/JsonApiSerializer-Dt_Y_FIo.cjs.map +1 -0
- package/dist/JsonSerializer-BzUCyUSf.cjs +2 -0
- package/dist/JsonSerializer-BzUCyUSf.cjs.map +1 -0
- package/dist/JsonSerializer-CFqo6GjC.js +98 -0
- package/dist/JsonSerializer-CFqo6GjC.js.map +1 -0
- package/dist/MdqlMemoryExecutor-BUlsalKm.cjs +2 -0
- package/dist/MdqlMemoryExecutor-BUlsalKm.cjs.map +1 -0
- package/dist/MdqlMemoryExecutor-BWMP31zG.js +127 -0
- package/dist/MdqlMemoryExecutor-BWMP31zG.js.map +1 -0
- package/dist/{MemoryAdapter-Bp-BGHH3.js → MemoryAdapter-BW1HKixm.js} +2 -2
- package/dist/{MemoryAdapter-Bp-BGHH3.js.map → MemoryAdapter-BW1HKixm.js.map} +1 -1
- package/dist/{MemoryAdapter-DH-gzSSl.cjs → MemoryAdapter-C8iXAa2v.cjs} +2 -2
- package/dist/{MemoryAdapter-DH-gzSSl.cjs.map → MemoryAdapter-C8iXAa2v.cjs.map} +1 -1
- package/dist/{ODataAdapter-RQUjVTcf.js → ODataAdapter-CeBJblLQ.js} +25 -22
- package/dist/ODataAdapter-CeBJblLQ.js.map +1 -0
- package/dist/{ODataAdapter-CrDFvBEZ.cjs → ODataAdapter-DdE6MWkG.cjs} +2 -2
- package/dist/ODataAdapter-DdE6MWkG.cjs.map +1 -0
- package/dist/RestAdapter-D7GSrsJo.cjs +2 -0
- package/dist/RestAdapter-D7GSrsJo.cjs.map +1 -0
- package/dist/{RestAdapter-D6bGIHZT.js → RestAdapter-DYUoyV5h.js} +112 -77
- package/dist/RestAdapter-DYUoyV5h.js.map +1 -0
- package/dist/SchemaService-C_pkh-vI.js +180 -0
- package/dist/SchemaService-C_pkh-vI.js.map +1 -0
- package/dist/SchemaService-DbJLoYb9.cjs +2 -0
- package/dist/SchemaService-DbJLoYb9.cjs.map +1 -0
- package/dist/Serializer-Bap9U-kR.cjs +2 -0
- package/dist/Serializer-Bap9U-kR.cjs.map +1 -0
- package/dist/{Serializer-FxJbsZ50.js → Serializer-Ca6w_QNQ.js} +63 -49
- package/dist/Serializer-Ca6w_QNQ.js.map +1 -0
- package/dist/adapter/index.cjs +1 -1
- package/dist/adapter/index.js +2 -2
- package/dist/createStore-7PecKT54.cjs +2 -0
- package/dist/createStore-7PecKT54.cjs.map +1 -0
- package/dist/createStore-BfmRfZ_2.js +1229 -0
- package/dist/createStore-BfmRfZ_2.js.map +1 -0
- package/dist/date-Bj4O2W1F.js.map +1 -1
- package/dist/date-CRCe-9gf.cjs.map +1 -1
- package/dist/decorators-CKneHgoF.js +56 -0
- package/dist/decorators-CKneHgoF.js.map +1 -0
- package/dist/decorators-DCVYKzrL.cjs +2 -0
- package/dist/decorators-DCVYKzrL.cjs.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +100 -90
- package/dist/index.js.map +1 -1
- package/dist/inspector/ConsoleInspector.d.ts +49 -0
- package/dist/inspector/ConsoleInspector.d.ts.map +1 -0
- package/dist/inspector/DevToolsBridge.d.ts +21 -0
- package/dist/inspector/DevToolsBridge.d.ts.map +1 -0
- package/dist/inspector/QueryParser.d.ts +21 -0
- package/dist/inspector/QueryParser.d.ts.map +1 -0
- package/dist/inspector/StoreInspector.d.ts +31 -0
- package/dist/inspector/StoreInspector.d.ts.map +1 -0
- package/dist/inspector/index.cjs +17 -0
- package/dist/inspector/index.cjs.map +1 -0
- package/dist/inspector/index.d.ts +9 -0
- package/dist/inspector/index.d.ts.map +1 -0
- package/dist/inspector/index.js +896 -0
- package/dist/inspector/index.js.map +1 -0
- package/dist/inspector/integration.d.ts +15 -0
- package/dist/inspector/integration.d.ts.map +1 -0
- package/dist/inspector/serialization.d.ts +7 -0
- package/dist/inspector/serialization.d.ts.map +1 -0
- package/dist/inspector/types.d.ts +139 -0
- package/dist/inspector/types.d.ts.map +1 -0
- package/dist/json-api/index.cjs +1 -1
- package/dist/json-api/index.js +1 -1
- package/dist/mdql/MdqlMemoryExecutor.d.ts +17 -0
- package/dist/mdql/MdqlMemoryExecutor.d.ts.map +1 -0
- package/dist/mdql/MdqlQueryBuilder.d.ts +38 -0
- package/dist/mdql/MdqlQueryBuilder.d.ts.map +1 -0
- package/dist/mdql/MdqlValidator.d.ts +13 -0
- package/dist/mdql/MdqlValidator.d.ts.map +1 -0
- package/dist/mdql/index.d.ts +6 -0
- package/dist/mdql/index.d.ts.map +1 -0
- package/dist/mdql/types.d.ts +48 -0
- package/dist/mdql/types.d.ts.map +1 -0
- package/dist/model/Model.d.ts +4 -0
- package/dist/model/Model.d.ts.map +1 -1
- package/dist/model/Snapshot.d.ts +2 -0
- package/dist/model/Snapshot.d.ts.map +1 -1
- package/dist/model/index.cjs +1 -1
- package/dist/model/index.js +1 -1
- package/dist/odata/ODataAdapter.d.ts.map +1 -1
- package/dist/odata/index.cjs +1 -1
- package/dist/odata/index.js +1 -1
- package/dist/relationships-BgM0NKdb.cjs +2 -0
- package/dist/relationships-BgM0NKdb.cjs.map +1 -0
- package/dist/{relationships-BEXANmWg.js → relationships-DvSi8fVN.js} +37 -28
- package/dist/relationships-DvSi8fVN.js.map +1 -0
- package/dist/request/CacheHandler.d.ts.map +1 -1
- package/dist/request/index.cjs +1 -1
- package/dist/request/index.js +1 -1
- package/dist/schema/SchemaService.d.ts +38 -1
- package/dist/schema/SchemaService.d.ts.map +1 -1
- package/dist/schema/decorators.d.ts +20 -1
- package/dist/schema/decorators.d.ts.map +1 -1
- package/dist/schema/index.cjs +1 -1
- package/dist/schema/index.d.ts +1 -1
- package/dist/schema/index.d.ts.map +1 -1
- package/dist/schema/index.js +10 -8
- package/dist/schema/types.d.ts +31 -0
- package/dist/schema/types.d.ts.map +1 -1
- package/dist/serializer/JsonSerializer.d.ts +2 -0
- package/dist/serializer/JsonSerializer.d.ts.map +1 -1
- package/dist/serializer/Serializer.d.ts +9 -0
- package/dist/serializer/Serializer.d.ts.map +1 -1
- package/dist/serializer/index.cjs +1 -1
- package/dist/serializer/index.js +6 -5
- package/dist/serializer/index.js.map +1 -1
- package/dist/store/Store.d.ts +3 -0
- package/dist/store/Store.d.ts.map +1 -1
- package/dist/store/createStore.d.ts +12 -0
- package/dist/store/createStore.d.ts.map +1 -0
- package/dist/store/index.cjs +1 -1
- package/dist/store/index.d.ts +1 -0
- package/dist/store/index.d.ts.map +1 -1
- package/dist/store/index.js +5 -4
- package/dist/types-CC2fG3FP.js +8 -0
- package/dist/types-CC2fG3FP.js.map +1 -0
- package/dist/types-DCLy5XYj.cjs +2 -0
- package/dist/types-DCLy5XYj.cjs.map +1 -0
- package/package.json +7 -1
- package/src/index.ts +3 -0
- package/src/inspector/ConsoleInspector.ts +470 -0
- package/src/inspector/DevToolsBridge.ts +214 -0
- package/src/inspector/QueryParser.ts +343 -0
- package/src/inspector/StoreInspector.ts +162 -0
- package/src/inspector/index.ts +20 -0
- package/src/inspector/integration.ts +56 -0
- package/src/inspector/serialization.ts +100 -0
- package/src/inspector/types.ts +161 -0
- package/src/mdql/MdqlMemoryExecutor.ts +229 -0
- package/src/mdql/MdqlQueryBuilder.ts +170 -0
- package/src/mdql/MdqlValidator.ts +193 -0
- package/src/mdql/index.ts +21 -0
- package/src/mdql/types.ts +107 -0
- package/src/model/Model.ts +15 -0
- package/src/model/Snapshot.ts +3 -0
- package/src/odata/ODataAdapter.ts +4 -1
- package/src/request/CacheHandler.ts +2 -6
- package/src/schema/SchemaService.ts +123 -1
- package/src/schema/decorators.ts +29 -0
- package/src/schema/index.ts +1 -1
- package/src/schema/types.ts +34 -0
- package/src/serializer/JsonSerializer.ts +14 -2
- package/src/serializer/Serializer.ts +24 -1
- package/src/store/Store.ts +57 -14
- package/src/store/createStore.ts +39 -0
- package/src/store/index.ts +1 -0
- package/dist/CacheHandler-BTU_rYkv.js.map +0 -1
- package/dist/CacheHandler-CXgY9IJo.cjs.map +0 -1
- package/dist/EmbeddedRecordsMixin-CBvqNdgC.cjs +0 -2
- package/dist/EmbeddedRecordsMixin-CBvqNdgC.cjs.map +0 -1
- package/dist/EmbeddedRecordsMixin-VoHluHCT.js +0 -261
- package/dist/EmbeddedRecordsMixin-VoHluHCT.js.map +0 -1
- package/dist/JsonApiSerializer-BLoE046A.js.map +0 -1
- package/dist/JsonApiSerializer-DKemcyw-.cjs.map +0 -1
- package/dist/ODataAdapter-CrDFvBEZ.cjs.map +0 -1
- package/dist/ODataAdapter-RQUjVTcf.js.map +0 -1
- package/dist/RestAdapter-CSoJg7D2.cjs +0 -2
- package/dist/RestAdapter-CSoJg7D2.cjs.map +0 -1
- package/dist/RestAdapter-D6bGIHZT.js.map +0 -1
- package/dist/SchemaService-DZwkFgZu.js +0 -102
- package/dist/SchemaService-DZwkFgZu.js.map +0 -1
- package/dist/SchemaService-Di_yjVzU.cjs +0 -2
- package/dist/SchemaService-Di_yjVzU.cjs.map +0 -1
- package/dist/Serializer-95gi5edy.cjs +0 -2
- package/dist/Serializer-95gi5edy.cjs.map +0 -1
- package/dist/Serializer-FxJbsZ50.js.map +0 -1
- package/dist/Store-Bm5JivTc.js +0 -957
- package/dist/Store-Bm5JivTc.js.map +0 -1
- package/dist/Store-DX9D0Mmy.cjs +0 -2
- package/dist/Store-DX9D0Mmy.cjs.map +0 -1
- package/dist/cache-utils-B2wFhisx.js +0 -39
- package/dist/cache-utils-B2wFhisx.js.map +0 -1
- package/dist/cache-utils-CSwsqOi3.cjs +0 -2
- package/dist/cache-utils-CSwsqOi3.cjs.map +0 -1
- package/dist/decorators-HQ1KnRdh.cjs +0 -2
- package/dist/decorators-HQ1KnRdh.cjs.map +0 -1
- package/dist/decorators-Zr35qr6A.js +0 -50
- package/dist/decorators-Zr35qr6A.js.map +0 -1
- package/dist/relationships-B55LBaCW.cjs +0 -2
- package/dist/relationships-B55LBaCW.cjs.map +0 -1
- package/dist/relationships-BEXANmWg.js.map +0 -1
- package/dist/types-C9NB2gRj.js +0 -7
- package/dist/types-C9NB2gRj.js.map +0 -1
- package/dist/types-uWOXMPWW.cjs +0 -2
- package/dist/types-uWOXMPWW.cjs.map +0 -1
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import "reflect-metadata";
|
|
2
|
+
import { singleton as p } from "tsyringe";
|
|
3
|
+
import { a as u, R as d, A as m } from "./types-CC2fG3FP.js";
|
|
4
|
+
var y = Object.getOwnPropertyDescriptor, g = (e, t, n, i) => {
|
|
5
|
+
for (var o = i > 1 ? void 0 : i ? y(t, n) : t, r = e.length - 1, s; r >= 0; r--)
|
|
6
|
+
(s = e[r]) && (o = s(o) || o);
|
|
7
|
+
return o;
|
|
8
|
+
};
|
|
9
|
+
function l(e, t) {
|
|
10
|
+
const n = [];
|
|
11
|
+
let i = e;
|
|
12
|
+
for (; i && i !== Object.prototype; )
|
|
13
|
+
n.push(i), i = Object.getPrototypeOf(i);
|
|
14
|
+
const o = /* @__PURE__ */ new Map();
|
|
15
|
+
for (const r of n.reverse()) {
|
|
16
|
+
const s = Reflect.getOwnMetadata(t, r);
|
|
17
|
+
if (s)
|
|
18
|
+
for (const [c, a] of s)
|
|
19
|
+
o.set(c, a);
|
|
20
|
+
}
|
|
21
|
+
return o;
|
|
22
|
+
}
|
|
23
|
+
let h = class {
|
|
24
|
+
constructor() {
|
|
25
|
+
this.entries = /* @__PURE__ */ new Map();
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Registers a model class under `modelName`.
|
|
29
|
+
*
|
|
30
|
+
* Walks the prototype chain at registration time so lookups are O(1).
|
|
31
|
+
* Calling this a second time for the same `modelName` replaces the entry.
|
|
32
|
+
*/
|
|
33
|
+
registerModel(e, t) {
|
|
34
|
+
const n = l(
|
|
35
|
+
t.prototype,
|
|
36
|
+
m
|
|
37
|
+
), i = l(
|
|
38
|
+
t.prototype,
|
|
39
|
+
d
|
|
40
|
+
), o = { modelClass: t, attributes: n, relationships: i }, r = Reflect.getOwnMetadata(u, t);
|
|
41
|
+
r != null && r.abstract && (o.abstract = !0), r != null && r.discriminator && (o.discriminator = {
|
|
42
|
+
key: r.discriminator.key ?? "type",
|
|
43
|
+
map: r.discriminator.map
|
|
44
|
+
}), r != null && r.clientGeneratedIds && (o.clientGeneratedIds = !0), this.entries.set(e, o), this.linkPolymorphicChild(e, t);
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* After registering a model, checks whether any already-registered
|
|
48
|
+
* polymorphic parent lists this model in its discriminator map and, if so,
|
|
49
|
+
* stores the `polymorphicRoot` back-link.
|
|
50
|
+
*/
|
|
51
|
+
linkPolymorphicChild(e, t) {
|
|
52
|
+
for (const [n, i] of this.entries)
|
|
53
|
+
if (!(!i.discriminator || n === e)) {
|
|
54
|
+
for (const o of Object.values(i.discriminator.map))
|
|
55
|
+
if (o() === t) {
|
|
56
|
+
const r = this.entries.get(e);
|
|
57
|
+
r && (r.polymorphicRoot = n);
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Returns the constructor for the given `modelName`.
|
|
64
|
+
* @throws if the model has not been registered.
|
|
65
|
+
*/
|
|
66
|
+
modelFor(e) {
|
|
67
|
+
const t = this.entries.get(e);
|
|
68
|
+
if (!t)
|
|
69
|
+
throw new Error(`No model registered for type "${e}"`);
|
|
70
|
+
return t.modelClass;
|
|
71
|
+
}
|
|
72
|
+
/** Returns all registered model names. */
|
|
73
|
+
registeredNames() {
|
|
74
|
+
return Array.from(this.entries.keys());
|
|
75
|
+
}
|
|
76
|
+
/** Returns `true` when a model class has been registered for `modelName`. */
|
|
77
|
+
doesTypeExist(e) {
|
|
78
|
+
return this.entries.has(e);
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Returns the merged attribute definitions for `modelName`.
|
|
82
|
+
* @throws if the model has not been registered.
|
|
83
|
+
*/
|
|
84
|
+
attributesDefinitionFor(e) {
|
|
85
|
+
const t = this.entries.get(e);
|
|
86
|
+
if (!t)
|
|
87
|
+
throw new Error(`No model registered for type "${e}"`);
|
|
88
|
+
return t.attributes;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Returns the merged relationship definitions for `modelName`.
|
|
92
|
+
* @throws if the model has not been registered.
|
|
93
|
+
*/
|
|
94
|
+
relationshipsDefinitionFor(e) {
|
|
95
|
+
const t = this.entries.get(e);
|
|
96
|
+
if (!t)
|
|
97
|
+
throw new Error(`No model registered for type "${e}"`);
|
|
98
|
+
return t.relationships;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Iterates over every attribute definition for `modelName`, invoking
|
|
102
|
+
* `callback` with the attribute name and its `AttributeDef`.
|
|
103
|
+
*/
|
|
104
|
+
eachAttribute(e, t) {
|
|
105
|
+
const n = this.attributesDefinitionFor(e);
|
|
106
|
+
for (const [i, o] of n)
|
|
107
|
+
t(i, o);
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Iterates over every relationship definition for `modelName`, invoking
|
|
111
|
+
* `callback` with the relationship name and its `RelationshipDef`.
|
|
112
|
+
*/
|
|
113
|
+
eachRelationship(e, t) {
|
|
114
|
+
const n = this.relationshipsDefinitionFor(e);
|
|
115
|
+
for (const [i, o] of n)
|
|
116
|
+
t(i, o);
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Returns the discriminator definition for `modelName`, or `undefined`
|
|
120
|
+
* when the model is not polymorphic.
|
|
121
|
+
*/
|
|
122
|
+
discriminatorFor(e) {
|
|
123
|
+
var t;
|
|
124
|
+
return (t = this.entries.get(e)) == null ? void 0 : t.discriminator;
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Returns the polymorphic root model name for a concrete child, or `null`
|
|
128
|
+
* when `modelName` is not part of a polymorphic hierarchy.
|
|
129
|
+
*/
|
|
130
|
+
polymorphicRootFor(e) {
|
|
131
|
+
var t;
|
|
132
|
+
return ((t = this.entries.get(e)) == null ? void 0 : t.polymorphicRoot) ?? null;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Returns `true` when `modelName` is declared abstract.
|
|
136
|
+
*/
|
|
137
|
+
isAbstract(e) {
|
|
138
|
+
var t;
|
|
139
|
+
return ((t = this.entries.get(e)) == null ? void 0 : t.abstract) === !0;
|
|
140
|
+
}
|
|
141
|
+
/** Returns `true` when the model uses client-generated ids. */
|
|
142
|
+
hasClientGeneratedIds(e) {
|
|
143
|
+
var t;
|
|
144
|
+
return ((t = this.entries.get(e)) == null ? void 0 : t.clientGeneratedIds) === !0;
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Resolves the concrete model class for a polymorphic parent given a raw
|
|
148
|
+
* payload. Reads the discriminator key from the payload and returns the
|
|
149
|
+
* resolved model name and class.
|
|
150
|
+
*
|
|
151
|
+
* @throws when the discriminator key is missing from the payload.
|
|
152
|
+
* @throws when the discriminator value is not in the map.
|
|
153
|
+
* @returns `null` when `modelName` has no discriminator (not polymorphic).
|
|
154
|
+
*/
|
|
155
|
+
resolveConcreteModel(e, t) {
|
|
156
|
+
const n = this.entries.get(e);
|
|
157
|
+
if (!(n != null && n.discriminator)) return null;
|
|
158
|
+
const { key: i, map: o } = n.discriminator, r = t[i];
|
|
159
|
+
if (r == null)
|
|
160
|
+
throw new Error(
|
|
161
|
+
`Missing discriminator key "${i}" in payload for polymorphic model "${e}".`
|
|
162
|
+
);
|
|
163
|
+
const s = String(r), c = o[s];
|
|
164
|
+
if (!c) {
|
|
165
|
+
const f = Object.keys(o).join(", ");
|
|
166
|
+
throw new Error(
|
|
167
|
+
`Unknown discriminator value "${s}" for model "${e}" (key: "${i}"). Known values: ${f}.`
|
|
168
|
+
);
|
|
169
|
+
}
|
|
170
|
+
const a = c();
|
|
171
|
+
return { modelName: a.modelName ?? s, modelClass: a };
|
|
172
|
+
}
|
|
173
|
+
};
|
|
174
|
+
h = g([
|
|
175
|
+
p()
|
|
176
|
+
], h);
|
|
177
|
+
export {
|
|
178
|
+
h as S
|
|
179
|
+
};
|
|
180
|
+
//# sourceMappingURL=SchemaService-C_pkh-vI.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SchemaService-C_pkh-vI.js","sources":["../src/schema/SchemaService.ts"],"sourcesContent":["/**\r\n * Central registry for model classes and their schema metadata.\r\n *\r\n * `SchemaService` is a tsyringe singleton that acts as the authoritative\r\n * source of truth for every model registered with the store. At registration\r\n * time it walks the full prototype chain (deepest ancestor first) and merges\r\n * all `@attr` / `@belongsTo` / `@hasMany` definitions so subclasses\r\n * transparently inherit parent schema.\r\n *\r\n * Consumers (Store, serializers, snapshot helpers) call `attributesDefinitionFor`\r\n * and `relationshipsDefinitionFor` rather than reading reflect-metadata directly.\r\n */\r\n\r\nimport 'reflect-metadata';\r\nimport { singleton } from 'tsyringe';\r\nimport {\r\n ATTRIBUTES_META_KEY,\r\n RELATIONSHIPS_META_KEY,\r\n MODEL_OPTIONS_META_KEY,\r\n type AttributeDef,\r\n type AttributeDefinitionsMap,\r\n type DiscriminatorDef,\r\n type ModelOptions,\r\n type RelationshipDef,\r\n type RelationshipDefinitionsMap,\r\n} from './types.js';\r\n\r\n/** Minimal shape of a model constructor that SchemaService can register. */\r\nexport interface ModelClass {\r\n modelName?: string;\r\n prototype: unknown;\r\n new (...args: never[]): unknown;\r\n}\r\n\r\n/** Internal entry stored per registered model name. */\r\ninterface Entry {\r\n modelClass: ModelClass;\r\n /** Merged attribute definitions (ancestors → leaf, leaf wins). */\r\n attributes: AttributeDefinitionsMap;\r\n /** Merged relationship definitions (ancestors → leaf, leaf wins). */\r\n relationships: RelationshipDefinitionsMap;\r\n /** When `true`, the model is abstract and cannot be instantiated directly. */\r\n abstract?: boolean;\r\n /** Discriminator configuration for polymorphic hierarchies. */\r\n discriminator?: DiscriminatorDef;\r\n /** Model name of the polymorphic root when this is a concrete child. */\r\n polymorphicRoot?: string;\r\n /** When `true`, the client-generated id is sent to the server on create. */\r\n clientGeneratedIds?: boolean;\r\n}\r\n\r\n/**\r\n * Walks the prototype chain from the class root down to the leaf, collecting\r\n * own-metadata from each level and merging into a single Map. Later entries\r\n * (i.e. the subclass) override earlier ones so subclass declarations win.\r\n */\r\nfunction walkPrototypeChain<V>(\r\n prototype: object | null,\r\n metadataKey: symbol,\r\n): Map<string, V> {\r\n // Walk from Object root down to the leaf so subclass entries override parents.\r\n const chain: object[] = [];\r\n let current: object | null = prototype;\r\n while (current && current !== Object.prototype) {\r\n chain.push(current);\r\n current = Object.getPrototypeOf(current);\r\n }\r\n const merged = new Map<string, V>();\r\n for (const proto of chain.reverse()) {\r\n const local = Reflect.getOwnMetadata(metadataKey, proto) as\r\n | Map<string, V>\r\n | undefined;\r\n if (local) {\r\n for (const [key, value] of local) {\r\n merged.set(key, value);\r\n }\r\n }\r\n }\r\n return merged;\r\n}\r\n\r\n@singleton()\r\nexport class SchemaService {\r\n private entries = new Map<string, Entry>();\r\n\r\n /**\r\n * Registers a model class under `modelName`.\r\n *\r\n * Walks the prototype chain at registration time so lookups are O(1).\r\n * Calling this a second time for the same `modelName` replaces the entry.\r\n */\r\n registerModel(modelName: string, modelClass: ModelClass): void {\r\n const attributes = walkPrototypeChain<AttributeDef>(\r\n modelClass.prototype as object,\r\n ATTRIBUTES_META_KEY,\r\n );\r\n const relationships = walkPrototypeChain<RelationshipDef>(\r\n modelClass.prototype as object,\r\n RELATIONSHIPS_META_KEY,\r\n );\r\n const entry: Entry = { modelClass, attributes, relationships };\r\n\r\n const options = Reflect.getOwnMetadata(MODEL_OPTIONS_META_KEY, modelClass) as\r\n | ModelOptions\r\n | undefined;\r\n if (options?.abstract) {\r\n entry.abstract = true;\r\n }\r\n if (options?.discriminator) {\r\n entry.discriminator = {\r\n key: options.discriminator.key ?? 'type',\r\n map: options.discriminator.map,\r\n };\r\n }\r\n if (options?.clientGeneratedIds) {\r\n entry.clientGeneratedIds = true;\r\n }\r\n\r\n this.entries.set(modelName, entry);\r\n this.linkPolymorphicChild(modelName, modelClass);\r\n }\r\n\r\n /**\r\n * After registering a model, checks whether any already-registered\r\n * polymorphic parent lists this model in its discriminator map and, if so,\r\n * stores the `polymorphicRoot` back-link.\r\n */\r\n private linkPolymorphicChild(childName: string, childClass: ModelClass): void {\r\n for (const [parentName, parentEntry] of this.entries) {\r\n if (!parentEntry.discriminator || parentName === childName) continue;\r\n for (const factory of Object.values(parentEntry.discriminator.map)) {\r\n if (factory() === childClass) {\r\n const childEntry = this.entries.get(childName);\r\n if (childEntry) {\r\n childEntry.polymorphicRoot = parentName;\r\n }\r\n return;\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Returns the constructor for the given `modelName`.\r\n * @throws if the model has not been registered.\r\n */\r\n modelFor(modelName: string): ModelClass {\r\n const entry = this.entries.get(modelName);\r\n if (!entry) {\r\n throw new Error(`No model registered for type \"${modelName}\"`);\r\n }\r\n return entry.modelClass;\r\n }\r\n\r\n /** Returns all registered model names. */\r\n registeredNames(): string[] {\r\n return Array.from(this.entries.keys());\r\n }\r\n\r\n /** Returns `true` when a model class has been registered for `modelName`. */\r\n doesTypeExist(modelName: string): boolean {\r\n return this.entries.has(modelName);\r\n }\r\n\r\n /**\r\n * Returns the merged attribute definitions for `modelName`.\r\n * @throws if the model has not been registered.\r\n */\r\n attributesDefinitionFor(modelName: string): AttributeDefinitionsMap {\r\n const entry = this.entries.get(modelName);\r\n if (!entry) {\r\n throw new Error(`No model registered for type \"${modelName}\"`);\r\n }\r\n return entry.attributes;\r\n }\r\n\r\n /**\r\n * Returns the merged relationship definitions for `modelName`.\r\n * @throws if the model has not been registered.\r\n */\r\n relationshipsDefinitionFor(modelName: string): RelationshipDefinitionsMap {\r\n const entry = this.entries.get(modelName);\r\n if (!entry) {\r\n throw new Error(`No model registered for type \"${modelName}\"`);\r\n }\r\n return entry.relationships;\r\n }\r\n\r\n /**\r\n * Iterates over every attribute definition for `modelName`, invoking\r\n * `callback` with the attribute name and its `AttributeDef`.\r\n */\r\n eachAttribute(\r\n modelName: string,\r\n callback: (name: string, meta: AttributeDef) => void,\r\n ): void {\r\n const attributes = this.attributesDefinitionFor(modelName);\r\n for (const [name, meta] of attributes) {\r\n callback(name, meta);\r\n }\r\n }\r\n\r\n /**\r\n * Iterates over every relationship definition for `modelName`, invoking\r\n * `callback` with the relationship name and its `RelationshipDef`.\r\n */\r\n eachRelationship(\r\n modelName: string,\r\n callback: (name: string, meta: RelationshipDef) => void,\r\n ): void {\r\n const relationships = this.relationshipsDefinitionFor(modelName);\r\n for (const [name, meta] of relationships) {\r\n callback(name, meta);\r\n }\r\n }\r\n\r\n /**\r\n * Returns the discriminator definition for `modelName`, or `undefined`\r\n * when the model is not polymorphic.\r\n */\r\n discriminatorFor(modelName: string): DiscriminatorDef | undefined {\r\n return this.entries.get(modelName)?.discriminator;\r\n }\r\n\r\n /**\r\n * Returns the polymorphic root model name for a concrete child, or `null`\r\n * when `modelName` is not part of a polymorphic hierarchy.\r\n */\r\n polymorphicRootFor(modelName: string): string | null {\r\n return this.entries.get(modelName)?.polymorphicRoot ?? null;\r\n }\r\n\r\n /**\r\n * Returns `true` when `modelName` is declared abstract.\r\n */\r\n isAbstract(modelName: string): boolean {\r\n return this.entries.get(modelName)?.abstract === true;\r\n }\r\n\r\n /** Returns `true` when the model uses client-generated ids. */\r\n hasClientGeneratedIds(modelName: string): boolean {\r\n return this.entries.get(modelName)?.clientGeneratedIds === true;\r\n }\r\n\r\n /**\r\n * Resolves the concrete model class for a polymorphic parent given a raw\r\n * payload. Reads the discriminator key from the payload and returns the\r\n * resolved model name and class.\r\n *\r\n * @throws when the discriminator key is missing from the payload.\r\n * @throws when the discriminator value is not in the map.\r\n * @returns `null` when `modelName` has no discriminator (not polymorphic).\r\n */\r\n resolveConcreteModel(\r\n modelName: string,\r\n payload: Record<string, unknown>,\r\n ): { modelName: string; modelClass: ModelClass } | null {\r\n const entry = this.entries.get(modelName);\r\n if (!entry?.discriminator) return null;\r\n\r\n const { key, map } = entry.discriminator;\r\n const discriminatorValue = payload[key];\r\n if (discriminatorValue === undefined || discriminatorValue === null) {\r\n throw new Error(\r\n `Missing discriminator key \"${key}\" in payload for polymorphic model \"${modelName}\".`,\r\n );\r\n }\r\n\r\n const valueString = String(discriminatorValue);\r\n const factory = map[valueString];\r\n if (!factory) {\r\n const knownValues = Object.keys(map).join(', ');\r\n throw new Error(\r\n `Unknown discriminator value \"${valueString}\" for model \"${modelName}\" `\r\n + `(key: \"${key}\"). Known values: ${knownValues}.`,\r\n );\r\n }\r\n\r\n const concreteClass = factory() as ModelClass;\r\n const concreteName = concreteClass.modelName ?? valueString;\r\n return { modelName: concreteName, modelClass: concreteClass };\r\n }\r\n}\r\n"],"names":["walkPrototypeChain","prototype","metadataKey","chain","current","merged","proto","local","key","value","SchemaService","modelName","modelClass","attributes","ATTRIBUTES_META_KEY","relationships","RELATIONSHIPS_META_KEY","entry","options","MODEL_OPTIONS_META_KEY","childName","childClass","parentName","parentEntry","factory","childEntry","callback","name","meta","_a","payload","map","discriminatorValue","valueString","knownValues","concreteClass","__decorateClass","singleton"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";require("reflect-metadata");const p=require("tsyringe"),h=require("./types-DCLy5XYj.cjs");var y=Object.getOwnPropertyDescriptor,d=(s,e,t,i)=>{for(var n=i>1?void 0:i?y(e,t):e,o=s.length-1,r;o>=0;o--)(r=s[o])&&(n=r(n)||n);return n};function u(s,e){const t=[];let i=s;for(;i&&i!==Object.prototype;)t.push(i),i=Object.getPrototypeOf(i);const n=new Map;for(const o of t.reverse()){const r=Reflect.getOwnMetadata(e,o);if(r)for(const[c,a]of r)n.set(c,a)}return n}exports.SchemaService=class{constructor(){this.entries=new Map}registerModel(e,t){const i=u(t.prototype,h.ATTRIBUTES_META_KEY),n=u(t.prototype,h.RELATIONSHIPS_META_KEY),o={modelClass:t,attributes:i,relationships:n},r=Reflect.getOwnMetadata(h.MODEL_OPTIONS_META_KEY,t);r!=null&&r.abstract&&(o.abstract=!0),r!=null&&r.discriminator&&(o.discriminator={key:r.discriminator.key??"type",map:r.discriminator.map}),r!=null&&r.clientGeneratedIds&&(o.clientGeneratedIds=!0),this.entries.set(e,o),this.linkPolymorphicChild(e,t)}linkPolymorphicChild(e,t){for(const[i,n]of this.entries)if(!(!n.discriminator||i===e)){for(const o of Object.values(n.discriminator.map))if(o()===t){const r=this.entries.get(e);r&&(r.polymorphicRoot=i);return}}}modelFor(e){const t=this.entries.get(e);if(!t)throw new Error(`No model registered for type "${e}"`);return t.modelClass}registeredNames(){return Array.from(this.entries.keys())}doesTypeExist(e){return this.entries.has(e)}attributesDefinitionFor(e){const t=this.entries.get(e);if(!t)throw new Error(`No model registered for type "${e}"`);return t.attributes}relationshipsDefinitionFor(e){const t=this.entries.get(e);if(!t)throw new Error(`No model registered for type "${e}"`);return t.relationships}eachAttribute(e,t){const i=this.attributesDefinitionFor(e);for(const[n,o]of i)t(n,o)}eachRelationship(e,t){const i=this.relationshipsDefinitionFor(e);for(const[n,o]of i)t(n,o)}discriminatorFor(e){var t;return(t=this.entries.get(e))==null?void 0:t.discriminator}polymorphicRootFor(e){var t;return((t=this.entries.get(e))==null?void 0:t.polymorphicRoot)??null}isAbstract(e){var t;return((t=this.entries.get(e))==null?void 0:t.abstract)===!0}hasClientGeneratedIds(e){var t;return((t=this.entries.get(e))==null?void 0:t.clientGeneratedIds)===!0}resolveConcreteModel(e,t){const i=this.entries.get(e);if(!(i!=null&&i.discriminator))return null;const{key:n,map:o}=i.discriminator,r=t[n];if(r==null)throw new Error(`Missing discriminator key "${n}" in payload for polymorphic model "${e}".`);const c=String(r),a=o[c];if(!a){const f=Object.keys(o).join(", ");throw new Error(`Unknown discriminator value "${c}" for model "${e}" (key: "${n}"). Known values: ${f}.`)}const l=a();return{modelName:l.modelName??c,modelClass:l}}};exports.SchemaService=d([p.singleton()],exports.SchemaService);
|
|
2
|
+
//# sourceMappingURL=SchemaService-DbJLoYb9.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SchemaService-DbJLoYb9.cjs","sources":["../src/schema/SchemaService.ts"],"sourcesContent":["/**\r\n * Central registry for model classes and their schema metadata.\r\n *\r\n * `SchemaService` is a tsyringe singleton that acts as the authoritative\r\n * source of truth for every model registered with the store. At registration\r\n * time it walks the full prototype chain (deepest ancestor first) and merges\r\n * all `@attr` / `@belongsTo` / `@hasMany` definitions so subclasses\r\n * transparently inherit parent schema.\r\n *\r\n * Consumers (Store, serializers, snapshot helpers) call `attributesDefinitionFor`\r\n * and `relationshipsDefinitionFor` rather than reading reflect-metadata directly.\r\n */\r\n\r\nimport 'reflect-metadata';\r\nimport { singleton } from 'tsyringe';\r\nimport {\r\n ATTRIBUTES_META_KEY,\r\n RELATIONSHIPS_META_KEY,\r\n MODEL_OPTIONS_META_KEY,\r\n type AttributeDef,\r\n type AttributeDefinitionsMap,\r\n type DiscriminatorDef,\r\n type ModelOptions,\r\n type RelationshipDef,\r\n type RelationshipDefinitionsMap,\r\n} from './types.js';\r\n\r\n/** Minimal shape of a model constructor that SchemaService can register. */\r\nexport interface ModelClass {\r\n modelName?: string;\r\n prototype: unknown;\r\n new (...args: never[]): unknown;\r\n}\r\n\r\n/** Internal entry stored per registered model name. */\r\ninterface Entry {\r\n modelClass: ModelClass;\r\n /** Merged attribute definitions (ancestors → leaf, leaf wins). */\r\n attributes: AttributeDefinitionsMap;\r\n /** Merged relationship definitions (ancestors → leaf, leaf wins). */\r\n relationships: RelationshipDefinitionsMap;\r\n /** When `true`, the model is abstract and cannot be instantiated directly. */\r\n abstract?: boolean;\r\n /** Discriminator configuration for polymorphic hierarchies. */\r\n discriminator?: DiscriminatorDef;\r\n /** Model name of the polymorphic root when this is a concrete child. */\r\n polymorphicRoot?: string;\r\n /** When `true`, the client-generated id is sent to the server on create. */\r\n clientGeneratedIds?: boolean;\r\n}\r\n\r\n/**\r\n * Walks the prototype chain from the class root down to the leaf, collecting\r\n * own-metadata from each level and merging into a single Map. Later entries\r\n * (i.e. the subclass) override earlier ones so subclass declarations win.\r\n */\r\nfunction walkPrototypeChain<V>(\r\n prototype: object | null,\r\n metadataKey: symbol,\r\n): Map<string, V> {\r\n // Walk from Object root down to the leaf so subclass entries override parents.\r\n const chain: object[] = [];\r\n let current: object | null = prototype;\r\n while (current && current !== Object.prototype) {\r\n chain.push(current);\r\n current = Object.getPrototypeOf(current);\r\n }\r\n const merged = new Map<string, V>();\r\n for (const proto of chain.reverse()) {\r\n const local = Reflect.getOwnMetadata(metadataKey, proto) as\r\n | Map<string, V>\r\n | undefined;\r\n if (local) {\r\n for (const [key, value] of local) {\r\n merged.set(key, value);\r\n }\r\n }\r\n }\r\n return merged;\r\n}\r\n\r\n@singleton()\r\nexport class SchemaService {\r\n private entries = new Map<string, Entry>();\r\n\r\n /**\r\n * Registers a model class under `modelName`.\r\n *\r\n * Walks the prototype chain at registration time so lookups are O(1).\r\n * Calling this a second time for the same `modelName` replaces the entry.\r\n */\r\n registerModel(modelName: string, modelClass: ModelClass): void {\r\n const attributes = walkPrototypeChain<AttributeDef>(\r\n modelClass.prototype as object,\r\n ATTRIBUTES_META_KEY,\r\n );\r\n const relationships = walkPrototypeChain<RelationshipDef>(\r\n modelClass.prototype as object,\r\n RELATIONSHIPS_META_KEY,\r\n );\r\n const entry: Entry = { modelClass, attributes, relationships };\r\n\r\n const options = Reflect.getOwnMetadata(MODEL_OPTIONS_META_KEY, modelClass) as\r\n | ModelOptions\r\n | undefined;\r\n if (options?.abstract) {\r\n entry.abstract = true;\r\n }\r\n if (options?.discriminator) {\r\n entry.discriminator = {\r\n key: options.discriminator.key ?? 'type',\r\n map: options.discriminator.map,\r\n };\r\n }\r\n if (options?.clientGeneratedIds) {\r\n entry.clientGeneratedIds = true;\r\n }\r\n\r\n this.entries.set(modelName, entry);\r\n this.linkPolymorphicChild(modelName, modelClass);\r\n }\r\n\r\n /**\r\n * After registering a model, checks whether any already-registered\r\n * polymorphic parent lists this model in its discriminator map and, if so,\r\n * stores the `polymorphicRoot` back-link.\r\n */\r\n private linkPolymorphicChild(childName: string, childClass: ModelClass): void {\r\n for (const [parentName, parentEntry] of this.entries) {\r\n if (!parentEntry.discriminator || parentName === childName) continue;\r\n for (const factory of Object.values(parentEntry.discriminator.map)) {\r\n if (factory() === childClass) {\r\n const childEntry = this.entries.get(childName);\r\n if (childEntry) {\r\n childEntry.polymorphicRoot = parentName;\r\n }\r\n return;\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Returns the constructor for the given `modelName`.\r\n * @throws if the model has not been registered.\r\n */\r\n modelFor(modelName: string): ModelClass {\r\n const entry = this.entries.get(modelName);\r\n if (!entry) {\r\n throw new Error(`No model registered for type \"${modelName}\"`);\r\n }\r\n return entry.modelClass;\r\n }\r\n\r\n /** Returns all registered model names. */\r\n registeredNames(): string[] {\r\n return Array.from(this.entries.keys());\r\n }\r\n\r\n /** Returns `true` when a model class has been registered for `modelName`. */\r\n doesTypeExist(modelName: string): boolean {\r\n return this.entries.has(modelName);\r\n }\r\n\r\n /**\r\n * Returns the merged attribute definitions for `modelName`.\r\n * @throws if the model has not been registered.\r\n */\r\n attributesDefinitionFor(modelName: string): AttributeDefinitionsMap {\r\n const entry = this.entries.get(modelName);\r\n if (!entry) {\r\n throw new Error(`No model registered for type \"${modelName}\"`);\r\n }\r\n return entry.attributes;\r\n }\r\n\r\n /**\r\n * Returns the merged relationship definitions for `modelName`.\r\n * @throws if the model has not been registered.\r\n */\r\n relationshipsDefinitionFor(modelName: string): RelationshipDefinitionsMap {\r\n const entry = this.entries.get(modelName);\r\n if (!entry) {\r\n throw new Error(`No model registered for type \"${modelName}\"`);\r\n }\r\n return entry.relationships;\r\n }\r\n\r\n /**\r\n * Iterates over every attribute definition for `modelName`, invoking\r\n * `callback` with the attribute name and its `AttributeDef`.\r\n */\r\n eachAttribute(\r\n modelName: string,\r\n callback: (name: string, meta: AttributeDef) => void,\r\n ): void {\r\n const attributes = this.attributesDefinitionFor(modelName);\r\n for (const [name, meta] of attributes) {\r\n callback(name, meta);\r\n }\r\n }\r\n\r\n /**\r\n * Iterates over every relationship definition for `modelName`, invoking\r\n * `callback` with the relationship name and its `RelationshipDef`.\r\n */\r\n eachRelationship(\r\n modelName: string,\r\n callback: (name: string, meta: RelationshipDef) => void,\r\n ): void {\r\n const relationships = this.relationshipsDefinitionFor(modelName);\r\n for (const [name, meta] of relationships) {\r\n callback(name, meta);\r\n }\r\n }\r\n\r\n /**\r\n * Returns the discriminator definition for `modelName`, or `undefined`\r\n * when the model is not polymorphic.\r\n */\r\n discriminatorFor(modelName: string): DiscriminatorDef | undefined {\r\n return this.entries.get(modelName)?.discriminator;\r\n }\r\n\r\n /**\r\n * Returns the polymorphic root model name for a concrete child, or `null`\r\n * when `modelName` is not part of a polymorphic hierarchy.\r\n */\r\n polymorphicRootFor(modelName: string): string | null {\r\n return this.entries.get(modelName)?.polymorphicRoot ?? null;\r\n }\r\n\r\n /**\r\n * Returns `true` when `modelName` is declared abstract.\r\n */\r\n isAbstract(modelName: string): boolean {\r\n return this.entries.get(modelName)?.abstract === true;\r\n }\r\n\r\n /** Returns `true` when the model uses client-generated ids. */\r\n hasClientGeneratedIds(modelName: string): boolean {\r\n return this.entries.get(modelName)?.clientGeneratedIds === true;\r\n }\r\n\r\n /**\r\n * Resolves the concrete model class for a polymorphic parent given a raw\r\n * payload. Reads the discriminator key from the payload and returns the\r\n * resolved model name and class.\r\n *\r\n * @throws when the discriminator key is missing from the payload.\r\n * @throws when the discriminator value is not in the map.\r\n * @returns `null` when `modelName` has no discriminator (not polymorphic).\r\n */\r\n resolveConcreteModel(\r\n modelName: string,\r\n payload: Record<string, unknown>,\r\n ): { modelName: string; modelClass: ModelClass } | null {\r\n const entry = this.entries.get(modelName);\r\n if (!entry?.discriminator) return null;\r\n\r\n const { key, map } = entry.discriminator;\r\n const discriminatorValue = payload[key];\r\n if (discriminatorValue === undefined || discriminatorValue === null) {\r\n throw new Error(\r\n `Missing discriminator key \"${key}\" in payload for polymorphic model \"${modelName}\".`,\r\n );\r\n }\r\n\r\n const valueString = String(discriminatorValue);\r\n const factory = map[valueString];\r\n if (!factory) {\r\n const knownValues = Object.keys(map).join(', ');\r\n throw new Error(\r\n `Unknown discriminator value \"${valueString}\" for model \"${modelName}\" `\r\n + `(key: \"${key}\"). Known values: ${knownValues}.`,\r\n );\r\n }\r\n\r\n const concreteClass = factory() as ModelClass;\r\n const concreteName = concreteClass.modelName ?? valueString;\r\n return { modelName: concreteName, modelClass: concreteClass };\r\n }\r\n}\r\n"],"names":["walkPrototypeChain","prototype","metadataKey","chain","current","merged","proto","local","key","value","SchemaService","modelName","modelClass","attributes","ATTRIBUTES_META_KEY","relationships","RELATIONSHIPS_META_KEY","entry","options","MODEL_OPTIONS_META_KEY","childName","childClass","parentName","parentEntry","factory","childEntry","callback","name","meta","_a","payload","map","discriminatorValue","valueString","knownValues","concreteClass","__decorateClass","singleton"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";class u{constructor(){this.primaryKey="id"}normalizeFindRecordResponse(t,i,e,n,r){return this.normalizeResponse(t,i,e,n,r)}normalizeFindAllResponse(t,i,e,n,r){return this.normalizeResponse(t,i,e,n,r)}normalizeQueryResponse(t,i,e,n,r){return this.normalizeResponse(t,i,e,n,r)}normalizeQueryRecordResponse(t,i,e,n,r){return this.normalizeResponse(t,i,e,n,r)}normalizeCreateRecordResponse(t,i,e,n,r){return this.normalizeResponse(t,i,e,n,r)}normalizeUpdateRecordResponse(t,i,e,n,r){return this.normalizeResponse(t,i,e,n,r)}normalizeDeleteRecordResponse(t,i,e,n,r){return this.normalizeResponse(t,i,e,n,r)}serializeAttribute(t,i,e,n){i[this.keyForAttribute(e)]=t.attr(e)}serializeBelongsTo(t,i,e){const n=t.belongsTo(e.name,{id:!0});i[this.keyForRelationship(e.name)]=n??null}serializeHasMany(t,i,e){const n=t.hasMany(e.name,{ids:!0});i[this.keyForRelationship(e.name)]=n??[]}extractAttributes(t,i){const e={};for(const[n]of t.attributes){const r=this.keyForAttribute(n);r in i&&(e[n]=i[r])}return e}extractAllAttributes(t,i){const e=new Set;for(const[r]of t.relationships)e.add(this.keyForRelationship(r));const n={};for(const[r,o]of Object.entries(i))r===this.primaryKey||e.has(r)||(n[r]=o);return n}extractRelationships(t,i){const e={};for(const[n,r]of t.relationships){const o=this.keyForRelationship(n);if(!(o in i))continue;const s=i[o];if(r.kind==="belongsTo")s==null?e[n]={data:null}:(typeof s=="string"||typeof s=="number")&&(e[n]={data:{type:r.type,id:String(s)}});else if(Array.isArray(s)){const a=s.filter(l=>typeof l=="string"||typeof l=="number").map(l=>({type:r.type,id:String(l)}));a.length===s.length&&(e[n]={data:a})}}return e}extractId(t,i){const e=i[this.primaryKey];return e==null?null:String(e)}extractErrors(t,i,e,n){if(e&&typeof e=="object"&&"errors"in e){const r=e.errors;if(r&&typeof r=="object"&&!Array.isArray(r)){const o={};for(const[s,a]of Object.entries(r))o[s]=Array.isArray(a)?a.map(String):[String(a)];return o}}return{}}keyForAttribute(t){return t}keyForRelationship(t){return t}}exports.Serializer=u;
|
|
2
|
+
//# sourceMappingURL=Serializer-Bap9U-kR.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Serializer-Bap9U-kR.cjs","sources":["../src/serializer/Serializer.ts"],"sourcesContent":["/**\r\n * Abstract base class for all serializers.\r\n *\r\n * A serializer translates between the raw wire format returned by an adapter\r\n * and the normalized document format consumed by the `Store`. It also\r\n * converts a record `Snapshot` back into a wire-format payload for create /\r\n * update requests.\r\n *\r\n * ## Normalization pipeline\r\n *\r\n * ```\r\n * raw payload\r\n * → normalizeResponse() (dispatches to the per-operation override)\r\n * → normalizeFindRecordResponse() / normalizeQueryResponse() / …\r\n * → normalize() (normalizes a single resource hash)\r\n * → extractId()\r\n * → extractAttributes()\r\n * → extractRelationships()\r\n * → NormalizedDocument\r\n * ```\r\n *\r\n * ## Serialization pipeline\r\n *\r\n * ```\r\n * Snapshot\r\n * → serialize()\r\n * → serializeAttribute() (for each @attr)\r\n * → serializeBelongsTo() (for each @belongsTo)\r\n * → serializeHasMany() (for each @hasMany)\r\n * → wire payload object\r\n * ```\r\n *\r\n * Subclasses (`JsonSerializer`, `RestSerializer`, `JsonApiSerializer`) override\r\n * selected methods to handle their specific wire formats.\r\n */\r\n\r\nimport type { AttributeDef, RelationshipDef } from '@mobx-data/schema';\r\n\r\n/** Union of all request types that trigger a normalization call. */\r\nexport type NormalizeRequestType =\r\n | 'findRecord'\r\n | 'findAll'\r\n | 'findBelongsTo'\r\n | 'findHasMany'\r\n | 'findMany'\r\n | 'query'\r\n | 'queryRecord'\r\n | 'createRecord'\r\n | 'updateRecord'\r\n | 'deleteRecord';\r\n\r\n/**\r\n * Normalized representation of a single server resource.\r\n * This is the internal format understood by the `Store`.\r\n */\r\nexport interface NormalizedResource {\r\n /** Model name. */\r\n type: string;\r\n /** Server-assigned id, or `null` for new records. */\r\n id: string | null;\r\n /** Flat attribute map keyed by property name. */\r\n attributes?: Record<string, unknown>;\r\n /**\r\n * Relationship references keyed by property name.\r\n * Each value contains `data` — a single `{ type, id }` or an array of them.\r\n */\r\n relationships?: Record<\r\n string,\r\n {\r\n data:\r\n | { type: string; id: string }\r\n | Array<{ type: string; id: string }>\r\n | null;\r\n }\r\n >;\r\n}\r\n\r\n/**\r\n * Top-level normalized document returned by `normalizeResponse`.\r\n * Mirrors the JSON:API document structure but is also used for REST payloads.\r\n */\r\nexport interface NormalizedDocument {\r\n /** Primary resource(s), or `null` for empty responses. */\r\n data: NormalizedResource | NormalizedResource[] | null;\r\n /** Side-loaded or compound-document secondary resources. */\r\n included?: NormalizedResource[];\r\n /** Server-side metadata (pagination, total counts, etc.). */\r\n meta?: Record<string, unknown>;\r\n /** Pagination or related links. */\r\n links?: Record<string, string>;\r\n}\r\n\r\n/**\r\n * Snapshot-like interface consumed by `serialize` and the `serialize*` helpers.\r\n * Serializers only read from snapshots; they never mutate records.\r\n */\r\nexport interface SerializerSnapshot {\r\n /** Server-assigned id, or `null` for new records. */\r\n id: string | null;\r\n /** Client-generated identifier, always present. */\r\n clientId: string;\r\n /** Model name. */\r\n modelName: string;\r\n /** Returns the snapshot-time value for an attribute key. */\r\n attr(key: string): unknown;\r\n /** Returns the `belongsTo` reference (or just the id when `{ id: true }`). */\r\n belongsTo(key: string, options?: { id: boolean }): unknown;\r\n /** Returns the `hasMany` references (or just ids when `{ ids: true }`). */\r\n hasMany(key: string, options?: { ids: boolean }): unknown;\r\n /** Returns `{ [key]: [original, current] }` pairs for dirty attributes. */\r\n changedAttributes(): Record<string, [unknown, unknown]>;\r\n /** Iterates over all attribute definitions. */\r\n eachAttribute(fn: (key: string, meta: AttributeDef) => void): void;\r\n /** Iterates over all relationship definitions. */\r\n eachRelationship(fn: (key: string, meta: RelationshipDef) => void): void;\r\n /** Live record reference (treated as read-only in serializer context). */\r\n record: unknown;\r\n}\r\n\r\n/** Minimal model class descriptor passed to serializer methods. */\r\nexport interface ModelClassMeta {\r\n /** Registered model name. */\r\n modelName: string;\r\n /** Merged attribute definitions. */\r\n attributes: Map<string, AttributeDef>;\r\n /** Merged relationship definitions. */\r\n relationships: Map<string, RelationshipDef>;\r\n}\r\n\r\nexport abstract class Serializer {\r\n /** Name of the field used as the primary key in raw payloads. Default: `'id'`. */\r\n primaryKey: string = 'id';\r\n\r\n /**\r\n * Normalizes a single raw resource hash into a `NormalizedResource`.\r\n * Returns `null` for absent or non-object payloads.\r\n */\r\n abstract normalize(\r\n store: unknown,\r\n modelClass: ModelClassMeta,\r\n payload: unknown,\r\n prop?: string,\r\n ): NormalizedResource | null;\r\n\r\n /**\r\n * Entry point for normalization. Dispatches to the appropriate\r\n * `normalize*Response` method based on `requestType`, then builds the full\r\n * `NormalizedDocument`.\r\n */\r\n abstract normalizeResponse(\r\n store: unknown,\r\n modelClass: ModelClassMeta,\r\n payload: unknown,\r\n id: string | null,\r\n requestType: NormalizeRequestType,\r\n ): NormalizedDocument;\r\n\r\n /**\r\n * Serializes a record snapshot into a plain object suitable for a create\r\n * or update request body.\r\n */\r\n abstract serialize(\r\n snapshot: SerializerSnapshot,\r\n options?: { includeId?: boolean; clientGeneratedIds?: boolean },\r\n ): Record<string, unknown>;\r\n\r\n // Per-operation normalization hooks — default to calling `normalizeResponse`.\r\n\r\n /** Called when normalizing a `findRecord` response. */\r\n normalizeFindRecordResponse(\r\n store: unknown,\r\n modelClass: ModelClassMeta,\r\n payload: unknown,\r\n id: string | null,\r\n requestType: NormalizeRequestType,\r\n ): NormalizedDocument {\r\n return this.normalizeResponse(store, modelClass, payload, id, requestType);\r\n }\r\n\r\n /** Called when normalizing a `findAll` response. */\r\n normalizeFindAllResponse(\r\n store: unknown,\r\n modelClass: ModelClassMeta,\r\n payload: unknown,\r\n id: string | null,\r\n requestType: NormalizeRequestType,\r\n ): NormalizedDocument {\r\n return this.normalizeResponse(store, modelClass, payload, id, requestType);\r\n }\r\n\r\n /** Called when normalizing a `query` response. */\r\n normalizeQueryResponse(\r\n store: unknown,\r\n modelClass: ModelClassMeta,\r\n payload: unknown,\r\n id: string | null,\r\n requestType: NormalizeRequestType,\r\n ): NormalizedDocument {\r\n return this.normalizeResponse(store, modelClass, payload, id, requestType);\r\n }\r\n\r\n /** Called when normalizing a `queryRecord` response. */\r\n normalizeQueryRecordResponse(\r\n store: unknown,\r\n modelClass: ModelClassMeta,\r\n payload: unknown,\r\n id: string | null,\r\n requestType: NormalizeRequestType,\r\n ): NormalizedDocument {\r\n return this.normalizeResponse(store, modelClass, payload, id, requestType);\r\n }\r\n\r\n /** Called when normalizing a `createRecord` response. */\r\n normalizeCreateRecordResponse(\r\n store: unknown,\r\n modelClass: ModelClassMeta,\r\n payload: unknown,\r\n id: string | null,\r\n requestType: NormalizeRequestType,\r\n ): NormalizedDocument {\r\n return this.normalizeResponse(store, modelClass, payload, id, requestType);\r\n }\r\n\r\n /** Called when normalizing an `updateRecord` response. */\r\n normalizeUpdateRecordResponse(\r\n store: unknown,\r\n modelClass: ModelClassMeta,\r\n payload: unknown,\r\n id: string | null,\r\n requestType: NormalizeRequestType,\r\n ): NormalizedDocument {\r\n return this.normalizeResponse(store, modelClass, payload, id, requestType);\r\n }\r\n\r\n /** Called when normalizing a `deleteRecord` response. */\r\n normalizeDeleteRecordResponse(\r\n store: unknown,\r\n modelClass: ModelClassMeta,\r\n payload: unknown,\r\n id: string | null,\r\n requestType: NormalizeRequestType,\r\n ): NormalizedDocument {\r\n return this.normalizeResponse(store, modelClass, payload, id, requestType);\r\n }\r\n\r\n /**\r\n * Writes a single attribute value into `json`.\r\n * Default: writes `snapshot.attr(key)` under the key returned by `keyForAttribute`.\r\n */\r\n serializeAttribute(\r\n snapshot: SerializerSnapshot,\r\n json: Record<string, unknown>,\r\n key: string,\r\n _attribute: AttributeDef,\r\n ): void {\r\n json[this.keyForAttribute(key)] = snapshot.attr(key);\r\n }\r\n\r\n /**\r\n * Writes a `belongsTo` relationship id into `json`.\r\n * Default: writes the related record's id (or `null`) under `keyForRelationship`.\r\n */\r\n serializeBelongsTo(\r\n snapshot: SerializerSnapshot,\r\n json: Record<string, unknown>,\r\n relationship: RelationshipDef,\r\n ): void {\r\n const id = snapshot.belongsTo(relationship.name, { id: true }) as\r\n | string\r\n | null;\r\n json[this.keyForRelationship(relationship.name)] = id ?? null;\r\n }\r\n\r\n /**\r\n * Writes a `hasMany` relationship id array into `json`.\r\n * Default: writes the array of related ids under `keyForRelationship`.\r\n */\r\n serializeHasMany(\r\n snapshot: SerializerSnapshot,\r\n json: Record<string, unknown>,\r\n relationship: RelationshipDef,\r\n ): void {\r\n const ids = snapshot.hasMany(relationship.name, { ids: true }) as string[];\r\n json[this.keyForRelationship(relationship.name)] = ids ?? [];\r\n }\r\n\r\n /**\r\n * Extracts attribute values from a raw resource hash.\r\n * Returns a map of `{ propertyName: value }` using `keyForAttribute` to\r\n * locate the payload key.\r\n */\r\n extractAttributes(\r\n modelClass: ModelClassMeta,\r\n resourceHash: Record<string, unknown>,\r\n ): Record<string, unknown> {\r\n const attributes: Record<string, unknown> = {};\r\n for (const [name] of modelClass.attributes) {\r\n const payloadKey = this.keyForAttribute(name);\r\n if (payloadKey in resourceHash) {\r\n attributes[name] = resourceHash[payloadKey];\r\n }\r\n }\r\n return attributes;\r\n }\r\n\r\n /**\r\n * Extracts all non-id, non-relationship fields from a raw payload.\r\n * Used for polymorphic models where the concrete child may have attributes\r\n * not declared on the abstract parent.\r\n */\r\n extractAllAttributes(\r\n modelClass: ModelClassMeta,\r\n resourceHash: Record<string, unknown>,\r\n ): Record<string, unknown> {\r\n const relationshipKeys = new Set<string>();\r\n for (const [name] of modelClass.relationships) {\r\n relationshipKeys.add(this.keyForRelationship(name));\r\n }\r\n const attributes: Record<string, unknown> = {};\r\n for (const [key, value] of Object.entries(resourceHash)) {\r\n if (key === this.primaryKey || relationshipKeys.has(key)) continue;\r\n attributes[key] = value;\r\n }\r\n return attributes;\r\n }\r\n\r\n /**\r\n * Extracts relationship references from a raw resource hash.\r\n *\r\n * - `belongsTo`: raw id (string or number) → `{ data: { type, id } }`\r\n * - `hasMany`: array of raw ids → `{ data: [{ type, id }, …] }`\r\n *\r\n * Returns only the relationships whose payload keys are present in `resourceHash`.\r\n */\r\n extractRelationships(\r\n modelClass: ModelClassMeta,\r\n resourceHash: Record<string, unknown>,\r\n ): NormalizedResource['relationships'] {\r\n const relationships: NonNullable<NormalizedResource['relationships']> = {};\r\n for (const [name, rel] of modelClass.relationships) {\r\n const payloadKey = this.keyForRelationship(name);\r\n if (!(payloadKey in resourceHash)) {\r\n continue;\r\n }\r\n const raw = resourceHash[payloadKey];\r\n if (rel.kind === 'belongsTo') {\r\n if (raw === null || raw === undefined) {\r\n relationships[name] = { data: null };\r\n } else if (typeof raw === 'string' || typeof raw === 'number') {\r\n relationships[name] = {\r\n data: { type: rel.type, id: String(raw) },\r\n };\r\n }\r\n } else if (Array.isArray(raw)) {\r\n const ids = raw\r\n .filter((entry) => typeof entry === 'string' || typeof entry === 'number')\r\n .map((entry) => ({ type: rel.type, id: String(entry) }));\r\n if (ids.length === raw.length) {\r\n relationships[name] = { data: ids };\r\n }\r\n }\r\n }\r\n return relationships;\r\n }\r\n\r\n /**\r\n * Extracts the primary key from a raw resource hash.\r\n * Returns `null` when the key is absent.\r\n */\r\n extractId(\r\n _modelClass: ModelClassMeta,\r\n resourceHash: Record<string, unknown>,\r\n ): string | null {\r\n const raw = resourceHash[this.primaryKey];\r\n if (raw === null || raw === undefined) {\r\n return null;\r\n }\r\n return String(raw);\r\n }\r\n\r\n /**\r\n * Extracts field-level validation errors from a server error payload.\r\n * Default: looks for `{ errors: { field: string | string[] } }`.\r\n * Returns an empty object when no recognisable error structure is found.\r\n */\r\n extractErrors(\r\n _store: unknown,\r\n _modelClass: ModelClassMeta,\r\n payload: unknown,\r\n _id: string | null,\r\n ): Record<string, string[]> {\r\n if (payload && typeof payload === 'object' && 'errors' in payload) {\r\n const errs = (payload as { errors: unknown }).errors;\r\n if (errs && typeof errs === 'object' && !Array.isArray(errs)) {\r\n const out: Record<string, string[]> = {};\r\n for (const [attribute, value] of Object.entries(errs as Record<string, unknown>)) {\r\n out[attribute] = Array.isArray(value) ? value.map(String) : [String(value)];\r\n }\r\n return out;\r\n }\r\n }\r\n return {};\r\n }\r\n\r\n /**\r\n * Maps a camelCase property name to the payload key used by this format.\r\n * Default: identity (no transformation).\r\n */\r\n keyForAttribute(key: string): string {\r\n return key;\r\n }\r\n\r\n /**\r\n * Maps a camelCase relationship name to the payload key used by this format.\r\n * Default: identity (no transformation).\r\n */\r\n keyForRelationship(key: string): string {\r\n return key;\r\n }\r\n}\r\n"],"names":["Serializer","store","modelClass","payload","id","requestType","snapshot","json","key","_attribute","relationship","ids","resourceHash","attributes","name","payloadKey","relationshipKeys","value","relationships","rel","raw","entry","_modelClass","_store","_id","errs","out","attribute"],"mappings":"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"}
|
|
@@ -4,69 +4,83 @@ class p {
|
|
|
4
4
|
}
|
|
5
5
|
// Per-operation normalization hooks — default to calling `normalizeResponse`.
|
|
6
6
|
/** Called when normalizing a `findRecord` response. */
|
|
7
|
-
normalizeFindRecordResponse(
|
|
8
|
-
return this.normalizeResponse(
|
|
7
|
+
normalizeFindRecordResponse(t, i, e, n, r) {
|
|
8
|
+
return this.normalizeResponse(t, i, e, n, r);
|
|
9
9
|
}
|
|
10
10
|
/** Called when normalizing a `findAll` response. */
|
|
11
|
-
normalizeFindAllResponse(
|
|
12
|
-
return this.normalizeResponse(
|
|
11
|
+
normalizeFindAllResponse(t, i, e, n, r) {
|
|
12
|
+
return this.normalizeResponse(t, i, e, n, r);
|
|
13
13
|
}
|
|
14
14
|
/** Called when normalizing a `query` response. */
|
|
15
|
-
normalizeQueryResponse(
|
|
16
|
-
return this.normalizeResponse(
|
|
15
|
+
normalizeQueryResponse(t, i, e, n, r) {
|
|
16
|
+
return this.normalizeResponse(t, i, e, n, r);
|
|
17
17
|
}
|
|
18
18
|
/** Called when normalizing a `queryRecord` response. */
|
|
19
|
-
normalizeQueryRecordResponse(
|
|
20
|
-
return this.normalizeResponse(
|
|
19
|
+
normalizeQueryRecordResponse(t, i, e, n, r) {
|
|
20
|
+
return this.normalizeResponse(t, i, e, n, r);
|
|
21
21
|
}
|
|
22
22
|
/** Called when normalizing a `createRecord` response. */
|
|
23
|
-
normalizeCreateRecordResponse(
|
|
24
|
-
return this.normalizeResponse(
|
|
23
|
+
normalizeCreateRecordResponse(t, i, e, n, r) {
|
|
24
|
+
return this.normalizeResponse(t, i, e, n, r);
|
|
25
25
|
}
|
|
26
26
|
/** Called when normalizing an `updateRecord` response. */
|
|
27
|
-
normalizeUpdateRecordResponse(
|
|
28
|
-
return this.normalizeResponse(
|
|
27
|
+
normalizeUpdateRecordResponse(t, i, e, n, r) {
|
|
28
|
+
return this.normalizeResponse(t, i, e, n, r);
|
|
29
29
|
}
|
|
30
30
|
/** Called when normalizing a `deleteRecord` response. */
|
|
31
|
-
normalizeDeleteRecordResponse(
|
|
32
|
-
return this.normalizeResponse(
|
|
31
|
+
normalizeDeleteRecordResponse(t, i, e, n, r) {
|
|
32
|
+
return this.normalizeResponse(t, i, e, n, r);
|
|
33
33
|
}
|
|
34
34
|
/**
|
|
35
35
|
* Writes a single attribute value into `json`.
|
|
36
36
|
* Default: writes `snapshot.attr(key)` under the key returned by `keyForAttribute`.
|
|
37
37
|
*/
|
|
38
|
-
serializeAttribute(
|
|
39
|
-
|
|
38
|
+
serializeAttribute(t, i, e, n) {
|
|
39
|
+
i[this.keyForAttribute(e)] = t.attr(e);
|
|
40
40
|
}
|
|
41
41
|
/**
|
|
42
42
|
* Writes a `belongsTo` relationship id into `json`.
|
|
43
43
|
* Default: writes the related record's id (or `null`) under `keyForRelationship`.
|
|
44
44
|
*/
|
|
45
|
-
serializeBelongsTo(
|
|
46
|
-
const n =
|
|
47
|
-
|
|
45
|
+
serializeBelongsTo(t, i, e) {
|
|
46
|
+
const n = t.belongsTo(e.name, { id: !0 });
|
|
47
|
+
i[this.keyForRelationship(e.name)] = n ?? null;
|
|
48
48
|
}
|
|
49
49
|
/**
|
|
50
50
|
* Writes a `hasMany` relationship id array into `json`.
|
|
51
51
|
* Default: writes the array of related ids under `keyForRelationship`.
|
|
52
52
|
*/
|
|
53
|
-
serializeHasMany(
|
|
54
|
-
const n =
|
|
55
|
-
|
|
53
|
+
serializeHasMany(t, i, e) {
|
|
54
|
+
const n = t.hasMany(e.name, { ids: !0 });
|
|
55
|
+
i[this.keyForRelationship(e.name)] = n ?? [];
|
|
56
56
|
}
|
|
57
57
|
/**
|
|
58
58
|
* Extracts attribute values from a raw resource hash.
|
|
59
59
|
* Returns a map of `{ propertyName: value }` using `keyForAttribute` to
|
|
60
60
|
* locate the payload key.
|
|
61
61
|
*/
|
|
62
|
-
extractAttributes(
|
|
62
|
+
extractAttributes(t, i) {
|
|
63
63
|
const e = {};
|
|
64
|
-
for (const [n] of
|
|
65
|
-
const
|
|
66
|
-
|
|
64
|
+
for (const [n] of t.attributes) {
|
|
65
|
+
const r = this.keyForAttribute(n);
|
|
66
|
+
r in i && (e[n] = i[r]);
|
|
67
67
|
}
|
|
68
68
|
return e;
|
|
69
69
|
}
|
|
70
|
+
/**
|
|
71
|
+
* Extracts all non-id, non-relationship fields from a raw payload.
|
|
72
|
+
* Used for polymorphic models where the concrete child may have attributes
|
|
73
|
+
* not declared on the abstract parent.
|
|
74
|
+
*/
|
|
75
|
+
extractAllAttributes(t, i) {
|
|
76
|
+
const e = /* @__PURE__ */ new Set();
|
|
77
|
+
for (const [r] of t.relationships)
|
|
78
|
+
e.add(this.keyForRelationship(r));
|
|
79
|
+
const n = {};
|
|
80
|
+
for (const [r, o] of Object.entries(i))
|
|
81
|
+
r === this.primaryKey || e.has(r) || (n[r] = o);
|
|
82
|
+
return n;
|
|
83
|
+
}
|
|
70
84
|
/**
|
|
71
85
|
* Extracts relationship references from a raw resource hash.
|
|
72
86
|
*
|
|
@@ -75,20 +89,20 @@ class p {
|
|
|
75
89
|
*
|
|
76
90
|
* Returns only the relationships whose payload keys are present in `resourceHash`.
|
|
77
91
|
*/
|
|
78
|
-
extractRelationships(
|
|
92
|
+
extractRelationships(t, i) {
|
|
79
93
|
const e = {};
|
|
80
|
-
for (const [n,
|
|
81
|
-
const
|
|
82
|
-
if (!(
|
|
94
|
+
for (const [n, r] of t.relationships) {
|
|
95
|
+
const o = this.keyForRelationship(n);
|
|
96
|
+
if (!(o in i))
|
|
83
97
|
continue;
|
|
84
|
-
const s =
|
|
85
|
-
if (
|
|
98
|
+
const s = i[o];
|
|
99
|
+
if (r.kind === "belongsTo")
|
|
86
100
|
s == null ? e[n] = { data: null } : (typeof s == "string" || typeof s == "number") && (e[n] = {
|
|
87
|
-
data: { type:
|
|
101
|
+
data: { type: r.type, id: String(s) }
|
|
88
102
|
});
|
|
89
103
|
else if (Array.isArray(s)) {
|
|
90
|
-
const
|
|
91
|
-
|
|
104
|
+
const a = s.filter((l) => typeof l == "string" || typeof l == "number").map((l) => ({ type: r.type, id: String(l) }));
|
|
105
|
+
a.length === s.length && (e[n] = { data: a });
|
|
92
106
|
}
|
|
93
107
|
}
|
|
94
108
|
return e;
|
|
@@ -97,8 +111,8 @@ class p {
|
|
|
97
111
|
* Extracts the primary key from a raw resource hash.
|
|
98
112
|
* Returns `null` when the key is absent.
|
|
99
113
|
*/
|
|
100
|
-
extractId(
|
|
101
|
-
const e =
|
|
114
|
+
extractId(t, i) {
|
|
115
|
+
const e = i[this.primaryKey];
|
|
102
116
|
return e == null ? null : String(e);
|
|
103
117
|
}
|
|
104
118
|
/**
|
|
@@ -106,14 +120,14 @@ class p {
|
|
|
106
120
|
* Default: looks for `{ errors: { field: string | string[] } }`.
|
|
107
121
|
* Returns an empty object when no recognisable error structure is found.
|
|
108
122
|
*/
|
|
109
|
-
extractErrors(
|
|
123
|
+
extractErrors(t, i, e, n) {
|
|
110
124
|
if (e && typeof e == "object" && "errors" in e) {
|
|
111
|
-
const
|
|
112
|
-
if (
|
|
113
|
-
const
|
|
114
|
-
for (const [s,
|
|
115
|
-
|
|
116
|
-
return
|
|
125
|
+
const r = e.errors;
|
|
126
|
+
if (r && typeof r == "object" && !Array.isArray(r)) {
|
|
127
|
+
const o = {};
|
|
128
|
+
for (const [s, a] of Object.entries(r))
|
|
129
|
+
o[s] = Array.isArray(a) ? a.map(String) : [String(a)];
|
|
130
|
+
return o;
|
|
117
131
|
}
|
|
118
132
|
}
|
|
119
133
|
return {};
|
|
@@ -122,18 +136,18 @@ class p {
|
|
|
122
136
|
* Maps a camelCase property name to the payload key used by this format.
|
|
123
137
|
* Default: identity (no transformation).
|
|
124
138
|
*/
|
|
125
|
-
keyForAttribute(
|
|
126
|
-
return
|
|
139
|
+
keyForAttribute(t) {
|
|
140
|
+
return t;
|
|
127
141
|
}
|
|
128
142
|
/**
|
|
129
143
|
* Maps a camelCase relationship name to the payload key used by this format.
|
|
130
144
|
* Default: identity (no transformation).
|
|
131
145
|
*/
|
|
132
|
-
keyForRelationship(
|
|
133
|
-
return
|
|
146
|
+
keyForRelationship(t) {
|
|
147
|
+
return t;
|
|
134
148
|
}
|
|
135
149
|
}
|
|
136
150
|
export {
|
|
137
151
|
p as S
|
|
138
152
|
};
|
|
139
|
-
//# sourceMappingURL=Serializer-
|
|
153
|
+
//# sourceMappingURL=Serializer-Ca6w_QNQ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Serializer-Ca6w_QNQ.js","sources":["../src/serializer/Serializer.ts"],"sourcesContent":["/**\r\n * Abstract base class for all serializers.\r\n *\r\n * A serializer translates between the raw wire format returned by an adapter\r\n * and the normalized document format consumed by the `Store`. It also\r\n * converts a record `Snapshot` back into a wire-format payload for create /\r\n * update requests.\r\n *\r\n * ## Normalization pipeline\r\n *\r\n * ```\r\n * raw payload\r\n * → normalizeResponse() (dispatches to the per-operation override)\r\n * → normalizeFindRecordResponse() / normalizeQueryResponse() / …\r\n * → normalize() (normalizes a single resource hash)\r\n * → extractId()\r\n * → extractAttributes()\r\n * → extractRelationships()\r\n * → NormalizedDocument\r\n * ```\r\n *\r\n * ## Serialization pipeline\r\n *\r\n * ```\r\n * Snapshot\r\n * → serialize()\r\n * → serializeAttribute() (for each @attr)\r\n * → serializeBelongsTo() (for each @belongsTo)\r\n * → serializeHasMany() (for each @hasMany)\r\n * → wire payload object\r\n * ```\r\n *\r\n * Subclasses (`JsonSerializer`, `RestSerializer`, `JsonApiSerializer`) override\r\n * selected methods to handle their specific wire formats.\r\n */\r\n\r\nimport type { AttributeDef, RelationshipDef } from '@mobx-data/schema';\r\n\r\n/** Union of all request types that trigger a normalization call. */\r\nexport type NormalizeRequestType =\r\n | 'findRecord'\r\n | 'findAll'\r\n | 'findBelongsTo'\r\n | 'findHasMany'\r\n | 'findMany'\r\n | 'query'\r\n | 'queryRecord'\r\n | 'createRecord'\r\n | 'updateRecord'\r\n | 'deleteRecord';\r\n\r\n/**\r\n * Normalized representation of a single server resource.\r\n * This is the internal format understood by the `Store`.\r\n */\r\nexport interface NormalizedResource {\r\n /** Model name. */\r\n type: string;\r\n /** Server-assigned id, or `null` for new records. */\r\n id: string | null;\r\n /** Flat attribute map keyed by property name. */\r\n attributes?: Record<string, unknown>;\r\n /**\r\n * Relationship references keyed by property name.\r\n * Each value contains `data` — a single `{ type, id }` or an array of them.\r\n */\r\n relationships?: Record<\r\n string,\r\n {\r\n data:\r\n | { type: string; id: string }\r\n | Array<{ type: string; id: string }>\r\n | null;\r\n }\r\n >;\r\n}\r\n\r\n/**\r\n * Top-level normalized document returned by `normalizeResponse`.\r\n * Mirrors the JSON:API document structure but is also used for REST payloads.\r\n */\r\nexport interface NormalizedDocument {\r\n /** Primary resource(s), or `null` for empty responses. */\r\n data: NormalizedResource | NormalizedResource[] | null;\r\n /** Side-loaded or compound-document secondary resources. */\r\n included?: NormalizedResource[];\r\n /** Server-side metadata (pagination, total counts, etc.). */\r\n meta?: Record<string, unknown>;\r\n /** Pagination or related links. */\r\n links?: Record<string, string>;\r\n}\r\n\r\n/**\r\n * Snapshot-like interface consumed by `serialize` and the `serialize*` helpers.\r\n * Serializers only read from snapshots; they never mutate records.\r\n */\r\nexport interface SerializerSnapshot {\r\n /** Server-assigned id, or `null` for new records. */\r\n id: string | null;\r\n /** Client-generated identifier, always present. */\r\n clientId: string;\r\n /** Model name. */\r\n modelName: string;\r\n /** Returns the snapshot-time value for an attribute key. */\r\n attr(key: string): unknown;\r\n /** Returns the `belongsTo` reference (or just the id when `{ id: true }`). */\r\n belongsTo(key: string, options?: { id: boolean }): unknown;\r\n /** Returns the `hasMany` references (or just ids when `{ ids: true }`). */\r\n hasMany(key: string, options?: { ids: boolean }): unknown;\r\n /** Returns `{ [key]: [original, current] }` pairs for dirty attributes. */\r\n changedAttributes(): Record<string, [unknown, unknown]>;\r\n /** Iterates over all attribute definitions. */\r\n eachAttribute(fn: (key: string, meta: AttributeDef) => void): void;\r\n /** Iterates over all relationship definitions. */\r\n eachRelationship(fn: (key: string, meta: RelationshipDef) => void): void;\r\n /** Live record reference (treated as read-only in serializer context). */\r\n record: unknown;\r\n}\r\n\r\n/** Minimal model class descriptor passed to serializer methods. */\r\nexport interface ModelClassMeta {\r\n /** Registered model name. */\r\n modelName: string;\r\n /** Merged attribute definitions. */\r\n attributes: Map<string, AttributeDef>;\r\n /** Merged relationship definitions. */\r\n relationships: Map<string, RelationshipDef>;\r\n}\r\n\r\nexport abstract class Serializer {\r\n /** Name of the field used as the primary key in raw payloads. Default: `'id'`. */\r\n primaryKey: string = 'id';\r\n\r\n /**\r\n * Normalizes a single raw resource hash into a `NormalizedResource`.\r\n * Returns `null` for absent or non-object payloads.\r\n */\r\n abstract normalize(\r\n store: unknown,\r\n modelClass: ModelClassMeta,\r\n payload: unknown,\r\n prop?: string,\r\n ): NormalizedResource | null;\r\n\r\n /**\r\n * Entry point for normalization. Dispatches to the appropriate\r\n * `normalize*Response` method based on `requestType`, then builds the full\r\n * `NormalizedDocument`.\r\n */\r\n abstract normalizeResponse(\r\n store: unknown,\r\n modelClass: ModelClassMeta,\r\n payload: unknown,\r\n id: string | null,\r\n requestType: NormalizeRequestType,\r\n ): NormalizedDocument;\r\n\r\n /**\r\n * Serializes a record snapshot into a plain object suitable for a create\r\n * or update request body.\r\n */\r\n abstract serialize(\r\n snapshot: SerializerSnapshot,\r\n options?: { includeId?: boolean; clientGeneratedIds?: boolean },\r\n ): Record<string, unknown>;\r\n\r\n // Per-operation normalization hooks — default to calling `normalizeResponse`.\r\n\r\n /** Called when normalizing a `findRecord` response. */\r\n normalizeFindRecordResponse(\r\n store: unknown,\r\n modelClass: ModelClassMeta,\r\n payload: unknown,\r\n id: string | null,\r\n requestType: NormalizeRequestType,\r\n ): NormalizedDocument {\r\n return this.normalizeResponse(store, modelClass, payload, id, requestType);\r\n }\r\n\r\n /** Called when normalizing a `findAll` response. */\r\n normalizeFindAllResponse(\r\n store: unknown,\r\n modelClass: ModelClassMeta,\r\n payload: unknown,\r\n id: string | null,\r\n requestType: NormalizeRequestType,\r\n ): NormalizedDocument {\r\n return this.normalizeResponse(store, modelClass, payload, id, requestType);\r\n }\r\n\r\n /** Called when normalizing a `query` response. */\r\n normalizeQueryResponse(\r\n store: unknown,\r\n modelClass: ModelClassMeta,\r\n payload: unknown,\r\n id: string | null,\r\n requestType: NormalizeRequestType,\r\n ): NormalizedDocument {\r\n return this.normalizeResponse(store, modelClass, payload, id, requestType);\r\n }\r\n\r\n /** Called when normalizing a `queryRecord` response. */\r\n normalizeQueryRecordResponse(\r\n store: unknown,\r\n modelClass: ModelClassMeta,\r\n payload: unknown,\r\n id: string | null,\r\n requestType: NormalizeRequestType,\r\n ): NormalizedDocument {\r\n return this.normalizeResponse(store, modelClass, payload, id, requestType);\r\n }\r\n\r\n /** Called when normalizing a `createRecord` response. */\r\n normalizeCreateRecordResponse(\r\n store: unknown,\r\n modelClass: ModelClassMeta,\r\n payload: unknown,\r\n id: string | null,\r\n requestType: NormalizeRequestType,\r\n ): NormalizedDocument {\r\n return this.normalizeResponse(store, modelClass, payload, id, requestType);\r\n }\r\n\r\n /** Called when normalizing an `updateRecord` response. */\r\n normalizeUpdateRecordResponse(\r\n store: unknown,\r\n modelClass: ModelClassMeta,\r\n payload: unknown,\r\n id: string | null,\r\n requestType: NormalizeRequestType,\r\n ): NormalizedDocument {\r\n return this.normalizeResponse(store, modelClass, payload, id, requestType);\r\n }\r\n\r\n /** Called when normalizing a `deleteRecord` response. */\r\n normalizeDeleteRecordResponse(\r\n store: unknown,\r\n modelClass: ModelClassMeta,\r\n payload: unknown,\r\n id: string | null,\r\n requestType: NormalizeRequestType,\r\n ): NormalizedDocument {\r\n return this.normalizeResponse(store, modelClass, payload, id, requestType);\r\n }\r\n\r\n /**\r\n * Writes a single attribute value into `json`.\r\n * Default: writes `snapshot.attr(key)` under the key returned by `keyForAttribute`.\r\n */\r\n serializeAttribute(\r\n snapshot: SerializerSnapshot,\r\n json: Record<string, unknown>,\r\n key: string,\r\n _attribute: AttributeDef,\r\n ): void {\r\n json[this.keyForAttribute(key)] = snapshot.attr(key);\r\n }\r\n\r\n /**\r\n * Writes a `belongsTo` relationship id into `json`.\r\n * Default: writes the related record's id (or `null`) under `keyForRelationship`.\r\n */\r\n serializeBelongsTo(\r\n snapshot: SerializerSnapshot,\r\n json: Record<string, unknown>,\r\n relationship: RelationshipDef,\r\n ): void {\r\n const id = snapshot.belongsTo(relationship.name, { id: true }) as\r\n | string\r\n | null;\r\n json[this.keyForRelationship(relationship.name)] = id ?? null;\r\n }\r\n\r\n /**\r\n * Writes a `hasMany` relationship id array into `json`.\r\n * Default: writes the array of related ids under `keyForRelationship`.\r\n */\r\n serializeHasMany(\r\n snapshot: SerializerSnapshot,\r\n json: Record<string, unknown>,\r\n relationship: RelationshipDef,\r\n ): void {\r\n const ids = snapshot.hasMany(relationship.name, { ids: true }) as string[];\r\n json[this.keyForRelationship(relationship.name)] = ids ?? [];\r\n }\r\n\r\n /**\r\n * Extracts attribute values from a raw resource hash.\r\n * Returns a map of `{ propertyName: value }` using `keyForAttribute` to\r\n * locate the payload key.\r\n */\r\n extractAttributes(\r\n modelClass: ModelClassMeta,\r\n resourceHash: Record<string, unknown>,\r\n ): Record<string, unknown> {\r\n const attributes: Record<string, unknown> = {};\r\n for (const [name] of modelClass.attributes) {\r\n const payloadKey = this.keyForAttribute(name);\r\n if (payloadKey in resourceHash) {\r\n attributes[name] = resourceHash[payloadKey];\r\n }\r\n }\r\n return attributes;\r\n }\r\n\r\n /**\r\n * Extracts all non-id, non-relationship fields from a raw payload.\r\n * Used for polymorphic models where the concrete child may have attributes\r\n * not declared on the abstract parent.\r\n */\r\n extractAllAttributes(\r\n modelClass: ModelClassMeta,\r\n resourceHash: Record<string, unknown>,\r\n ): Record<string, unknown> {\r\n const relationshipKeys = new Set<string>();\r\n for (const [name] of modelClass.relationships) {\r\n relationshipKeys.add(this.keyForRelationship(name));\r\n }\r\n const attributes: Record<string, unknown> = {};\r\n for (const [key, value] of Object.entries(resourceHash)) {\r\n if (key === this.primaryKey || relationshipKeys.has(key)) continue;\r\n attributes[key] = value;\r\n }\r\n return attributes;\r\n }\r\n\r\n /**\r\n * Extracts relationship references from a raw resource hash.\r\n *\r\n * - `belongsTo`: raw id (string or number) → `{ data: { type, id } }`\r\n * - `hasMany`: array of raw ids → `{ data: [{ type, id }, …] }`\r\n *\r\n * Returns only the relationships whose payload keys are present in `resourceHash`.\r\n */\r\n extractRelationships(\r\n modelClass: ModelClassMeta,\r\n resourceHash: Record<string, unknown>,\r\n ): NormalizedResource['relationships'] {\r\n const relationships: NonNullable<NormalizedResource['relationships']> = {};\r\n for (const [name, rel] of modelClass.relationships) {\r\n const payloadKey = this.keyForRelationship(name);\r\n if (!(payloadKey in resourceHash)) {\r\n continue;\r\n }\r\n const raw = resourceHash[payloadKey];\r\n if (rel.kind === 'belongsTo') {\r\n if (raw === null || raw === undefined) {\r\n relationships[name] = { data: null };\r\n } else if (typeof raw === 'string' || typeof raw === 'number') {\r\n relationships[name] = {\r\n data: { type: rel.type, id: String(raw) },\r\n };\r\n }\r\n } else if (Array.isArray(raw)) {\r\n const ids = raw\r\n .filter((entry) => typeof entry === 'string' || typeof entry === 'number')\r\n .map((entry) => ({ type: rel.type, id: String(entry) }));\r\n if (ids.length === raw.length) {\r\n relationships[name] = { data: ids };\r\n }\r\n }\r\n }\r\n return relationships;\r\n }\r\n\r\n /**\r\n * Extracts the primary key from a raw resource hash.\r\n * Returns `null` when the key is absent.\r\n */\r\n extractId(\r\n _modelClass: ModelClassMeta,\r\n resourceHash: Record<string, unknown>,\r\n ): string | null {\r\n const raw = resourceHash[this.primaryKey];\r\n if (raw === null || raw === undefined) {\r\n return null;\r\n }\r\n return String(raw);\r\n }\r\n\r\n /**\r\n * Extracts field-level validation errors from a server error payload.\r\n * Default: looks for `{ errors: { field: string | string[] } }`.\r\n * Returns an empty object when no recognisable error structure is found.\r\n */\r\n extractErrors(\r\n _store: unknown,\r\n _modelClass: ModelClassMeta,\r\n payload: unknown,\r\n _id: string | null,\r\n ): Record<string, string[]> {\r\n if (payload && typeof payload === 'object' && 'errors' in payload) {\r\n const errs = (payload as { errors: unknown }).errors;\r\n if (errs && typeof errs === 'object' && !Array.isArray(errs)) {\r\n const out: Record<string, string[]> = {};\r\n for (const [attribute, value] of Object.entries(errs as Record<string, unknown>)) {\r\n out[attribute] = Array.isArray(value) ? value.map(String) : [String(value)];\r\n }\r\n return out;\r\n }\r\n }\r\n return {};\r\n }\r\n\r\n /**\r\n * Maps a camelCase property name to the payload key used by this format.\r\n * Default: identity (no transformation).\r\n */\r\n keyForAttribute(key: string): string {\r\n return key;\r\n }\r\n\r\n /**\r\n * Maps a camelCase relationship name to the payload key used by this format.\r\n * Default: identity (no transformation).\r\n */\r\n keyForRelationship(key: string): string {\r\n return key;\r\n }\r\n}\r\n"],"names":["Serializer","store","modelClass","payload","id","requestType","snapshot","json","key","_attribute","relationship","ids","resourceHash","attributes","name","payloadKey","relationshipKeys","value","relationships","rel","raw","entry","_modelClass","_store","_id","errs","out","attribute"],"mappings":"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"}
|
package/dist/adapter/index.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("../RestAdapter-
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("../RestAdapter-D7GSrsJo.cjs"),r=require("../MemoryAdapter-C8iXAa2v.cjs");exports.Adapter=e.Adapter;Object.defineProperty(exports,"RestAdapter",{enumerable:!0,get:()=>e.RestAdapter});Object.defineProperty(exports,"MemoryAdapter",{enumerable:!0,get:()=>r.MemoryAdapter});
|
|
2
2
|
//# sourceMappingURL=index.cjs.map
|
package/dist/adapter/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { A as a, R as t } from "../RestAdapter-
|
|
2
|
-
import { M as p } from "../MemoryAdapter-
|
|
1
|
+
import { A as a, R as t } from "../RestAdapter-DYUoyV5h.js";
|
|
2
|
+
import { M as p } from "../MemoryAdapter-BW1HKixm.js";
|
|
3
3
|
export {
|
|
4
4
|
a as Adapter,
|
|
5
5
|
p as MemoryAdapter,
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";require("reflect-metadata");const F=require("./SchemaService-DbJLoYb9.cjs"),v=require("tsyringe"),h=require("mobx"),b=require("./relationships-BgM0NKdb.cjs"),R=require("./RestAdapter-D7GSrsJo.cjs"),m=require("./MdqlMemoryExecutor-BUlsalKm.cjs"),T=require("./JsonSerializer-BzUCyUSf.cjs");class O{constructor(){this._buckets=new Map,h.makeObservable(this,{_buckets:h.observable.shallow,set:h.action,delete:h.action,clear:h.action})}bucket(t,e=!1){let s=this._buckets.get(t);return!s&&e&&(s=h.observable.map({},{deep:!1}),this._buckets.set(t,s)),s}set(t,e,s){this.bucket(t,!0).set(e,s)}get(t,e){var s;return((s=this.bucket(t))==null?void 0:s.get(e))??null}has(t,e){var s;return((s=this.bucket(t))==null?void 0:s.has(e))??!1}delete(t,e){var s;return((s=this.bucket(t))==null?void 0:s.delete(e))??!1}all(t){const e=this.bucket(t);return e?Array.from(e.values()):[]}clear(t){var e;if(t)(e=this.bucket(t))==null||e.clear();else for(const s of this._buckets.values())s.clear()}size(t){var s;if(t)return((s=this.bucket(t))==null?void 0:s.size)??0;let e=0;for(const i of this._buckets.values())e+=i.size;return e}}class w{constructor(t){this.updating=!1,this.opts=t,h.makeObservable(this,{resolved:t.keepAlive?h.computed({keepAlive:!0}):h.computed,updating:h.observable,length:h.computed,modelName:h.computed})}get resolved(){return this.opts.source()}get isLoading(){return this.updating}get isUpdating(){return this.updating}get length(){return this.resolved.length}get modelName(){return this.opts.modelName}at(t){return this.resolved[t]}toArray(){return[...this.resolved]}map(t){return this.resolved.map(t)}filter(t){return this.resolved.filter(t)}forEach(t){this.resolved.forEach(t)}includes(t){return this.resolved.includes(t)}async update(){if(!this.opts.update)return this;this.updating=!0;try{await this.opts.update()}finally{this.updating=!1}return this}[Symbol.iterator](){return this.resolved[Symbol.iterator]()}}class S extends w{constructor(t){super(t),this.queryParams=t.query,this.metaData=t.meta??{},this.linksData=t.links??{},h.makeObservable(this,{metaData:h.observable.ref,linksData:h.observable.ref,meta:h.computed,links:h.computed,query:h.computed})}get meta(){return this.metaData}get links(){return this.linksData}get query(){return this.queryParams}_setMeta(t){this.metaData=t}_setLinks(t){this.linksData=t}}const E=["equals","notEquals","in","notIn","isNull","isNotNull"],D=[...E,"contains","startsWith","endsWith"],_=[...E,"greaterThan","greaterThanOrEquals","lessThan","lessThanOrEquals","between"],z={string:new Set(D),number:new Set(_),date:new Set(_),boolean:new Set(["equals","notEquals","isNull","isNotNull"])},M=new Set(["equals","notEquals","in","notIn","isNull","isNotNull","contains","startsWith","endsWith","greaterThan","greaterThanOrEquals","lessThan","lessThanOrEquals","between"]);class q extends Error{constructor(t){const e=t.map(s=>`${s.path}: ${s.message}`);super(`MDQL validation failed: ${e.join("; ")}`),this.name="MdqlValidationException",this.errors=t}}class f{static validate(t,e){const s=f.validateQuiet(t,e);if(s.length>0)throw new q(s)}static validateQuiet(t,e){const s=[];if(!e.doesTypeExist(t.modelName))return s.push({path:"modelName",message:`Unknown model type "${t.modelName}".`}),s;const i=e.attributesDefinitionFor(t.modelName),r=e.relationshipsDefinitionFor(t.modelName);f.validateFilterNode(t.filters,"filters",s,e,t.modelName);for(let n=0;n<t.orderBy.length;n++){const o=t.orderBy[n];o.field.includes(".")?f.resolveFieldAttribute(o.field,t.modelName,e)||s.push({path:`orderBy[${n}]`,message:`Unknown attribute path "${o.field}".`}):o.field!=="id"&&!i.has(o.field)&&s.push({path:`orderBy[${n}]`,message:`Unknown attribute "${o.field}" on "${t.modelName}".`})}for(const n of t.includes)r.has(n)||s.push({path:"includes",message:`Unknown relationship "${n}" on "${t.modelName}".`});return t.limit!==null&&(!Number.isInteger(t.limit)||t.limit<1)&&s.push({path:"limit",message:"Limit must be a positive integer."}),t.offset!==null&&(!Number.isInteger(t.offset)||t.offset<0)&&s.push({path:"offset",message:"Offset must be a non-negative integer."}),s}static resolveFieldAttribute(t,e,s){const i=t.split(".");if(i.length===1)return t==="id"?{name:"id",type:"string"}:s.attributesDefinitionFor(e).get(t)??null;let r=e;for(let a=0;a<i.length-1;a++){const c=s.relationshipsDefinitionFor(r).get(i[a]);if(!c||(r=c.type,!s.doesTypeExist(r)))return null}const n=i[i.length-1];return n==="id"?{name:"id",type:"string"}:s.attributesDefinitionFor(r).get(n)??null}static validateFilterNode(t,e,s,i,r){if(t.kind==="condition"){const n=f.resolveFieldAttribute(t.field,r,i);if(!n){const a=t.field.includes(".")?`Unknown attribute path "${t.field}".`:`Unknown attribute "${t.field}".`;s.push({path:e,message:a});return}(n.type?z[n.type]??M:M).has(t.operator)||s.push({path:e,message:`Operator "${t.operator}" is not valid for type "${n.type}".`}),t.operator==="between"&&(!Array.isArray(t.value)||t.value.length!==2)&&s.push({path:e,message:'Operator "between" requires a value of [min, max].'}),(t.operator==="in"||t.operator==="notIn")&&(Array.isArray(t.value)||s.push({path:e,message:`Operator "${t.operator}" requires an array value.`}));return}for(let n=0;n<t.children.length;n++)f.validateFilterNode(t.children[n],`${e}.${t.kind}[${n}]`,s,i,r)}}class y{constructor(t,e){this.store=t,this.queryModelName=e,this.rootGroup={kind:"and",children:[]},this.orderByClauses=[],this.limitValue=null,this.offsetValue=null,this.includesList=[]}where(t,e,s){const i={kind:"condition",field:t,operator:e,value:s};return this.rootGroup.children.push(i),this}whereEquals(t,e){return this.where(t,"equals",e)}whereContains(t,e){return this.where(t,"contains",e)}and(t){const e=new y(this.store,this.queryModelName);t(e);const s={kind:"and",children:[...e.rootGroup.children]};return this.rootGroup.children.push(s),this}or(t){const e=new y(this.store,this.queryModelName);t(e);const s={kind:"or",children:[...e.rootGroup.children]};return this.rootGroup.children.push(s),this}not(t){const e=new y(this.store,this.queryModelName);t(e);const s={kind:"not",children:[...e.rootGroup.children]};return this.rootGroup.children.push(s),this}orderBy(t,e="asc"){return this.orderByClauses.push({field:t,direction:e}),this}limit(t){return this.limitValue=t,this}offset(t){return this.offsetValue=t,this}include(t){return this.includesList.includes(t)||this.includesList.push(t),this}toQueryObject(){return{modelName:this.queryModelName,filters:{kind:"and",children:[...this.rootGroup.children]},orderBy:[...this.orderByClauses],limit:this.limitValue,offset:this.offsetValue,includes:[...this.includesList]}}async toArray(){const t=this.toQueryObject();f.validate(t,this.store.schema);const e=this.store.peekAll(this.queryModelName).toArray();return m.MdqlMemoryExecutor.executeMany(e,t)}async first(){const t=this.toQueryObject();f.validate(t,this.store.schema);const e=this.store.peekAll(this.queryModelName).toArray();return m.MdqlMemoryExecutor.executeOne(e,t)}async count(){const t=this.toQueryObject();f.validate(t,this.store.schema);const e=this.store.peekAll(this.queryModelName).toArray();return m.MdqlMemoryExecutor.count(e,t)}async exists(){const t=this.toQueryObject();f.validate(t,this.store.schema);const e=this.store.peekAll(this.queryModelName).toArray();return m.MdqlMemoryExecutor.exists(e,t)}toLiveArray(){const t=this.toQueryObject();f.validate(t,this.store.schema);const e=m.MdqlMemoryExecutor.compilePredicate(t);return this.store.liveQuery(this.queryModelName,e)}}var C=Object.getOwnPropertyDescriptor,x=(p,t,e,s)=>{for(var i=s>1?void 0:s?C(t,e):t,r=p.length-1,n;r>=0;r--)(n=p[r])&&(i=n(i)||i);return i},P=(p,t)=>(e,s)=>t(e,s,p);exports.Store=class{constructor(t){this.identityMap=new O,this.adapters=new Map,this.serializers=new Map,this.newRecords=new Map,this.newRecordTypes=new WeakMap,this.relationshipCache=new WeakMap,this.pendingMembers=new WeakMap,this._cache=null,this.coalescePending=new Map,this.coalesceScheduled=new Set,this.schema=t}static refEquals(t,e){return t.id===e.id&&t.type===e.type}registerAdapter(t,e){this.adapters.set(t,e)}registerSerializer(t,e){this.serializers.set(t,e)}registerCache(t){this._cache=t}adapterFor(t){const e=this.adapters.get(t)??this.adapters.get("application");if(!e)throw new Error(`No adapter registered for "${t}"`);return e}serializerFor(t){const e=this.serializers.get(t)??this.serializers.get("application");if(!e)throw new Error(`No serializer registered for "${t}"`);return e}createRecord(t,e={}){if(!this.schema.doesTypeExist(t))throw new Error(`Unknown model type: "${t}"`);const s=this.schema.modelFor(t),i=new s({id:null,data:e,store:this});return this.trackNewRecord(t,i),i}trackNewRecord(t,e){let s=this.newRecords.get(t);s||(s=new Set,this.newRecords.set(t,s)),s.add(e),this.newRecordTypes.set(e,t)}untrackNewRecord(t){var s;const e=this.newRecordTypes.get(t);e&&((s=this.newRecords.get(e))==null||s.delete(t),this.newRecordTypes.delete(t))}peekRecord(t,e){const s=e==null?null:String(e);if(s===null)return null;const i=this.identityMap.get(t,s);if(i)return i;const r=this.schema.polymorphicRootFor(t);if(r){const n=this.identityMap.get(r,s);if(n&&n instanceof this.schema.modelFor(t))return n}return null}peekAll(t){return new w({modelName:t,source:()=>{const e=this.identityMap.all(t),s=this.newRecords.get(t);return!s||s.size===0?e:[...e,...s]}})}push(t){const e=t;if(e.included)for(const s of e.included)this.pushResource(s);return e.data===null||e.data===void 0?null:Array.isArray(e.data)?e.data.map(s=>this.pushResource(s)):this.pushResource(e.data)}pushPayload(t,e){let s,i;typeof t=="string"?(s=t,i=e):(s=null,i=t);const r=s?this.serializerFor(s).normalizeResponse(this,this.schema.modelFor(s),i,null,"pushPayload"):i;this.push(r)}normalize(t,e){return this.serializerFor(t).normalizeResponse(this,this.schema.modelFor(t),e,null,"normalize")}pushResource(t){const{type:e,id:s}=t;if(!this.schema.doesTypeExist(e))throw new Error(`Unknown model type: "${e}"`);if(s===null)throw new Error(`Cannot push a resource of type "${e}" without an id`);let i=e,r=this.schema.modelFor(e);const n=this.schema.resolveConcreteModel(e,t.attributes??{});n&&(r=n.modelClass,i=e);const o=this.schema.polymorphicRootFor(e);o&&(i=o);const a=this.identityMap.get(i,s);if(a)return h.runInAction(()=>{a._applyServerData(null,t.attributes??{},t.relationships)}),this.trackInverseForResource(a,t),a;const l=r,c=b.Model.push.call(l,{id:s,data:t.attributes??{},relationships:t.relationships,store:this});return this.identityMap.set(i,s,c),this.trackInverseForResource(c,t),c}trackInverseForResource(t,e){if(e.relationships)for(const[s,i]of Object.entries(e.relationships)){const r=this.schema.relationshipsDefinitionFor(t.modelName).get(s);if(!r||!r.options.inverse||!i.data)continue;const n=Array.isArray(i.data)?i.data:[i.data];for(const o of n)this.addInverse(o.type,o.id,r.options.inverse,t)}}addInverse(t,e,s,i){const r=this.identityMap.get(t,e);if(!r)return;const o=this.schema.relationshipsDefinitionFor(t).get(s);if(!o)return;const a=r._getRelationshipRef(s),l={type:i.modelName,id:i.id};h.runInAction(()=>{if(o.kind==="hasMany"){const c=a!=null&&a.data&&Array.isArray(a.data)?a.data:[];c.some(u=>exports.Store.refEquals(u,l))||r._setRelationshipRef(s,{data:[...c,l]})}else r._setRelationshipRef(s,{data:l})})}removeInverse(t,e,s,i){const r=this.identityMap.get(t,e);if(!r)return;const o=this.schema.relationshipsDefinitionFor(t).get(s);if(!o)return;const a=r._getRelationshipRef(s);h.runInAction(()=>{if(o.kind==="hasMany"){const c=(a!=null&&a.data&&Array.isArray(a.data)?a.data:[]).filter(u=>!(u.id===i.id&&u.type===i.modelName));r._setRelationshipRef(s,{data:c})}else r._setRelationshipRef(s,{data:null})})}unloadRecord(t){t.id!==null&&this.identityMap.delete(t.modelName,t.id),this.untrackNewRecord(t),this.relationshipCache.delete(t)}unloadAll(t){var e;if(t){for(const s of this.identityMap.all(t))this.relationshipCache.delete(s);this.identityMap.clear(t),(e=this.newRecords.get(t))==null||e.clear()}else this.identityMap.clear(),this.newRecords.clear()}async findRecord(t,e,s={}){const i=this.peekRecord(t,e);if(i&&!s.reload&&!s.include)return i;if(!s.reload&&!s.include&&this._cache){const d=await this._cache.get(t,e);if(d)return this.push({data:{type:d.modelName,id:d.id,attributes:d.attributes,relationships:d.relationships}})}const r=this.adapterFor(t);if(r.coalesceFindRequests&&r.findMany&&!s.include)return this.scheduleCoalescedFind(t,e);const n=i?this.createSnapshot(i):this.createEmptySnapshot(t,e),o=s.include?{include:s.include,adapterOptions:s.adapterOptions}:s.adapterOptions?{adapterOptions:s.adapterOptions}:void 0,a=await r.findRecord(this,t,e,n,o),l=R.extractResponseHeaders(a),c=this.serializerFor(t).normalizeResponse(this,this.schema.modelFor(t),a,e,"findRecord"),u=this.push(c);if(this._cache){const d=l?R.parseCacheTTLFromHeaders(l):null;d!==0&&this.cacheNormalizedDocument(c,d??void 0)}return u}async findAll(t,e={}){const s=this.adapterFor(t),i=e.include?{include:e.include,adapterOptions:e.adapterOptions}:e.adapterOptions?{adapterOptions:e.adapterOptions}:void 0,r=await s.findAll(this,t,null,[],i),n=R.extractResponseHeaders(r),o=this.serializerFor(t).normalizeResponse(this,this.schema.modelFor(t),r,null,"findAll");if(this.push(o),this._cache){const a=n?R.parseCacheTTLFromHeaders(n):null;a!==0&&this.cacheNormalizedDocument(o,a??void 0)}return this.peekAll(t)}async query(t,e){const s=[],i=new S({modelName:t,query:e,source:()=>s.map(r=>this.peekRecord(t,r)).filter(r=>r!==null),update:async()=>{await this.runQuery(t,e,i,s)}});return await this.runQuery(t,e,i,s),i}async runQuery(t,e,s,i){const n=await this.adapterFor(t).query(this,t,e,s),o=this.serializerFor(t).normalizeResponse(this,this.schema.modelFor(t),n,null,"query");if(this.push(o),i.length=0,Array.isArray(o.data))for(const a of o.data)a.id&&i.push(a.id);o.meta&&s._setMeta(o.meta),o.links&&s._setLinks(o.links)}async queryRecord(t,e){const i=await this.adapterFor(t).queryRecord(this,t,e),r=this.serializerFor(t).normalizeResponse(this,this.schema.modelFor(t),i,null,"queryRecord"),n=this.push(r);return Array.isArray(n)?n[0]??null:n??null}async saveRecord(t,e={}){const s=this.adapterFor(t.modelName),{isNew:i}=t;i&&this.schema.hasClientGeneratedIds(t.modelName)&&t.id===null&&(t.id=t._clientId);const r=this.createSnapshot(t);let n;i?n=await s.createRecord(this,t.modelName,r):e.patch&&s.patchRecord?n=await s.patchRecord(this,t.modelName,r):n=await s.updateRecord(this,t.modelName,r);const o=this.serializerFor(t.modelName).normalizeResponse(this,this.schema.modelFor(t.modelName),n,t.id,i?"createRecord":"updateRecord"),a=o.data;if(a){const l=a.id??t.id;h.runInAction(()=>{t._applyServerData(l,a.attributes??{},a.relationships)}),i&&l&&(this.untrackNewRecord(t),this.identityMap.set(t.modelName,l,t))}if(o.included)for(const l of o.included)this.pushResource(l);if(this._cache&&t.id){const l=t,c={};for(const[u,d]of l._relationships)c[u]=d;this._cache.set(t.modelName,t.id,{...l._data},{relationships:Object.keys(c).length>0?c:void 0})}return t}async deleteRecord(t){const e=this.adapterFor(t.modelName),s=this.createSnapshot(t);return await e.deleteRecord(this,t.modelName,s),this._cache&&t.id&&this._cache.invalidate(t.modelName,t.id),this.unloadRecord(t),t}async reloadRecord(t){if(!t.id)throw new Error("Cannot reload a record without an id");const e=this.adapterFor(t.modelName),s=this.createSnapshot(t),i=await e.findRecord(this,t.modelName,t.id,s),r=this.serializerFor(t.modelName).normalizeResponse(this,this.schema.modelFor(t.modelName),i,t.id,"findRecord");return this.push(r),t}createSnapshot(t){const{modelName:e}=t,s=this.schema.attributesDefinitionFor(e),i=this.schema.relationshipsDefinitionFor(e),r=t;return{id:t.id,clientId:t._clientId,modelName:e,record:t,attr:n=>r._data[n],belongsTo:(n,o)=>{const a=r._getRelationshipRef(n);return!(a!=null&&a.data)||Array.isArray(a.data)?null:o!=null&&o.id?a.data.id:this.peekRecord(a.data.type,a.data.id)},hasMany:(n,o)=>{const a=r._getRelationshipRef(n),l=a!=null&&a.data&&Array.isArray(a.data)?a.data:[];return o!=null&&o.ids?l.map(c=>c.id):l.map(c=>this.peekRecord(c.type,c.id)).filter(c=>c!==null)},changedAttributes:()=>r.changedAttributes(),eachAttribute:n=>{for(const[o,a]of s)n(o,a)},eachRelationship:n=>{for(const[o,a]of i)n(o,a)}}}createEmptySnapshot(t,e){const s=this.schema.attributesDefinitionFor(t),i=this.schema.relationshipsDefinitionFor(t);return{id:e,clientId:"",modelName:t,record:null,attr:()=>{},belongsTo:()=>null,hasMany:()=>[],changedAttributes:()=>({}),eachAttribute:r=>{for(const[n,o]of s)r(n,o)},eachRelationship:r=>{for(const[n,o]of i)r(n,o)}}}getRelationshipCache(t,e){var s;return(s=this.relationshipCache.get(t))==null?void 0:s.get(e)}setRelationshipCache(t,e,s){let i=this.relationshipCache.get(t);i||(i=new Map,this.relationshipCache.set(t,i)),i.set(e,s)}resolveRelationship(t,e,s){const i=s.options.async===!0,r=this.getRelationshipCache(t,e);if(r)return r;const n={parent:t,name:e,meta:s,store:this};if(i){if(s.kind==="belongsTo"){const l=new b.AsyncBelongsTo(n);return this.setRelationshipCache(t,e,l),l}const a=new b.AsyncHasMany(n);return this.setRelationshipCache(t,e,a),a}if(s.kind==="belongsTo"){const a=t._getRelationshipRef(e);return!(a!=null&&a.data)||Array.isArray(a.data)?null:this.peekRecord(a.data.type,a.data.id)}const o=new b.ManyArray(n);return this.setRelationshipCache(t,e,o),o}setRelationshipValue(t,e,s,i){if(s.kind!=="belongsTo")return;const r=t._getRelationshipRef(e),n=r!=null&&r.data&&!Array.isArray(r.data)?r.data:null;if(i==null){h.runInAction(()=>{t._setRelationshipRef(e,{data:null})}),n&&s.options.inverse&&this.removeInverse(n.type,n.id,s.options.inverse,t);return}const o=i,a={type:o.modelName,id:o.id};h.runInAction(()=>{t._setRelationshipRef(e,{data:a})}),s.options.inverse&&(n&&!exports.Store.refEquals(n,a)&&this.removeInverse(n.type,n.id,s.options.inverse,t),this.addInverse(a.type,a.id,s.options.inverse,t))}_getRelationshipRefFor(t,e){return t._getRelationshipRef(e)}_getPendingMembers(t,e){var s;return((s=this.pendingMembers.get(t))==null?void 0:s.get(e))??[]}addPendingMember(t,e,s){let i=this.pendingMembers.get(t);i||(i=new Map,this.pendingMembers.set(t,i));let r=i.get(e);r||(r=h.observable.set(),i.set(e,r)),r.add(s)}removePendingMember(t,e,s){var i,r;(r=(i=this.pendingMembers.get(t))==null?void 0:i.get(e))==null||r.delete(s)}_hasManyAppend(t,e,s,i){if(i.id===null){if(this.addPendingMember(t,e,i),s.options.inverse){const a=this.schema.relationshipsDefinitionFor(i.modelName).get(s.options.inverse);(a==null?void 0:a.kind)==="belongsTo"&&h.runInAction(()=>{i._setRelationshipRef(s.options.inverse,{data:{type:t.modelName,id:t.id}})})}return}const r=this._getRelationshipRefFor(t,e),n=r!=null&&r.data&&Array.isArray(r.data)?r.data:[],o={type:i.modelName,id:i.id};n.some(a=>exports.Store.refEquals(a,o))||h.runInAction(()=>{t._setRelationshipRef(e,{data:[...n,o]})}),s.options.inverse&&this.addInverse(i.modelName,i.id,s.options.inverse,t)}_hasManyRemove(t,e,s,i){if(i.id===null){this.removePendingMember(t,e,i);return}const r=this._getRelationshipRefFor(t,e),o=(r!=null&&r.data&&Array.isArray(r.data)?r.data:[]).filter(a=>!(a.id===i.id&&a.type===i.modelName));h.runInAction(()=>{t._setRelationshipRef(e,{data:o})}),s.options.inverse&&this.removeInverse(i.modelName,i.id,s.options.inverse,t)}cacheNormalizedDocument(t,e){const s=[];t.data&&(Array.isArray(t.data)?s.push(...t.data):s.push(t.data)),t.included&&s.push(...t.included);for(const i of s)i.id&&this._cache.set(i.type,i.id,i.attributes??{},{relationships:i.relationships,ttl:e})}scheduleCoalescedFind(t,e){return new Promise((s,i)=>{let r=this.coalescePending.get(t);r||(r=new Map,this.coalescePending.set(t,r));let n=r.get(e);n||(n=[],r.set(e,n)),n.push({resolve:s,reject:i}),this.coalesceScheduled.has(t)||(this.coalesceScheduled.add(t),queueMicrotask(()=>this.flushCoalescedFind(t)))})}async flushCoalescedFind(t){this.coalesceScheduled.delete(t);const e=this.coalescePending.get(t),s=new Map(e);e.clear();const i=Array.from(s.keys()),r=this.adapterFor(t);try{const n=i.map(l=>{const c=this.peekRecord(t,l);return c?this.createSnapshot(c):this.createEmptySnapshot(t,l)}),o=await r.findMany(this,t,i,n),a=this.serializerFor(t).normalizeResponse(this,this.schema.modelFor(t),o,null,"findMany");this.push(a);for(const l of i){const c=this.peekRecord(t,l),u=s.get(l);if(u)for(const d of u)c?d.resolve(c):d.reject(new Error(`Record not found after findMany: ${t}:${l}`))}}catch(n){for(const o of s.values())for(const a of o)a.reject(n)}}liveQuery(t,e){return new w({modelName:t,keepAlive:!0,source:()=>{const s=this.identityMap.all(t),i=this.newRecords.get(t);return(i&&i.size>0?[...s,...i]:s).filter(e)}})}select(t){if(!this.schema.doesTypeExist(t))throw new Error(`Unknown model type: "${t}"`);return new y(this,t)}async optimisticUpdate(t,e,s){const i=t,r={...i._data};h.runInAction(()=>{for(const n of Object.keys(e))n==="__proto__"||n==="constructor"||n==="prototype"||(i._data[n]=e[n])});try{return await s(),t}catch(n){throw h.runInAction(()=>{for(const[o,a]of Object.entries(r))i._data[o]=a}),n}}runInTransaction(t){h.runInAction(t)}serialize(t={}){var i;const e={},s=this.identityMap._buckets;for(const[r,n]of s){const o=(i=t.exclude)==null?void 0:i[r],a=[];for(const[l,c]of n){const u=c;let d;if(o&&o.length>0){d={};for(const[g,A]of Object.entries(u._data))o.includes(g)||(d[g]=A)}else d={...u._data};const k={id:l,attributes:d};if(u._relationships&&u._relationships.size>0){const g={};for(const[A,I]of u._relationships)g[A]=I;k.relationships=g}a.push(k)}a.length>0&&(e[r]=a)}return{records:e}}hydrate(t){h.runInAction(()=>{for(const[e,s]of Object.entries(t.records))for(const i of s)this.pushResource({type:e,id:i.id,attributes:i.attributes,relationships:i.relationships})})}static hydrate(t,e){const s=new exports.Store(t);return s.hydrate(e),s}};exports.Store=x([v.singleton(),v.injectable(),P(0,v.inject(F.SchemaService))],exports.Store);function $(p){if(typeof Reflect.getMetadata!="function")throw new Error('mobx-data requires reflect-metadata. Did you forget to import "reflect-metadata" at the top of your entry point?');const t=new F.SchemaService;for(const r of p.models)t.registerModel(r.modelName,r);const e=new exports.Store(t),s=p.adapter??new R.RestAdapter,i=p.serializer??new T.JsonSerializer;for(const r of p.models)e.registerAdapter(r.modelName,s),e.registerSerializer(r.modelName,i);return e.registerAdapter("application",s),e.registerSerializer("application",i),e}exports.ALL_OPERATORS=M;exports.AdapterPopulatedRecordArray=S;exports.IdentityMap=O;exports.MdqlQueryBuilder=y;exports.MdqlValidationException=q;exports.MdqlValidator=f;exports.OPERATORS_FOR_TYPE=z;exports.RecordArray=w;exports.createStore=$;
|
|
2
|
+
//# sourceMappingURL=createStore-7PecKT54.cjs.map
|