yayson 4.0.0 → 4.2.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 +272 -82
- package/build/legacy.cjs +88 -35
- package/build/legacy.d.cts +44 -8
- package/build/legacy.d.cts.map +1 -1
- package/build/legacy.d.mts +44 -8
- package/build/legacy.d.mts.map +1 -1
- package/build/legacy.mjs +88 -35
- package/build/legacy.mjs.map +1 -1
- package/build/{symbols-nFs99aEX.cjs → symbols-B--FS78o.cjs} +3 -0
- package/build/{symbols-DSjKJ8vh.mjs → symbols-BfU4k1el.mjs} +4 -1
- package/build/symbols-BfU4k1el.mjs.map +1 -0
- package/build/{types-DbMIe8E2.d.cts → types-KZiF6x7A.d.mts} +21 -2
- package/build/types-KZiF6x7A.d.mts.map +1 -0
- package/build/{types-BsfPiPEw.d.mts → types-iC38_iCI.d.cts} +21 -2
- package/build/types-iC38_iCI.d.cts.map +1 -0
- package/build/utils.cjs +1 -1
- package/build/utils.d.cts +1 -1
- package/build/utils.d.mts +1 -1
- package/build/utils.mjs +1 -1
- package/build/{yayson-BKEyEcGk.d.cts → yayson-BvwMr4Ad.d.mts} +18 -4
- package/build/yayson-BvwMr4Ad.d.mts.map +1 -0
- package/build/{yayson-CUfrxK9d.cjs → yayson-C4P8J4sn.cjs} +127 -51
- package/build/{yayson-BJv2Z0Z6.mjs → yayson-DIQ_olLX.mjs} +128 -52
- package/build/yayson-DIQ_olLX.mjs.map +1 -0
- package/build/{yayson-CRbukIqr.d.mts → yayson-DTMLeA5k.d.cts} +18 -4
- package/build/yayson-DTMLeA5k.d.cts.map +1 -0
- package/build/yayson.cjs +1 -1
- package/build/yayson.d.cts +2 -2
- package/build/yayson.d.mts +2 -2
- package/build/yayson.mjs +1 -1
- package/package.json +1 -1
- package/skill/yayson/SKILL.md +20 -0
- package/skill/yayson/references/api.md +27 -2
- package/build/symbols-DSjKJ8vh.mjs.map +0 -1
- package/build/types-BsfPiPEw.d.mts.map +0 -1
- package/build/types-DbMIe8E2.d.cts.map +0 -1
- package/build/yayson-BJv2Z0Z6.mjs.map +0 -1
- package/build/yayson-BKEyEcGk.d.cts.map +0 -1
- package/build/yayson-CRbukIqr.d.mts.map +0 -1
|
@@ -4,6 +4,7 @@ declare class Adapter {
|
|
|
4
4
|
static get(model: ModelLike): Record<string, unknown>;
|
|
5
5
|
static get(model: ModelLike, key: string): unknown;
|
|
6
6
|
static id(model: ModelLike): string | undefined;
|
|
7
|
+
static has(model: ModelLike, key: string): boolean;
|
|
7
8
|
}
|
|
8
9
|
//#endregion
|
|
9
10
|
//#region src/yayson/symbols.d.ts
|
|
@@ -46,6 +47,17 @@ interface JsonApiRelationship {
|
|
|
46
47
|
links?: JsonApiLink;
|
|
47
48
|
meta?: Record<string, unknown>;
|
|
48
49
|
}
|
|
50
|
+
/**
|
|
51
|
+
* Extended relationship descriptor for `relationships()` return values.
|
|
52
|
+
* `hasMany: true` renders empty/missing as `data: []` (spec-compliant to-many).
|
|
53
|
+
* `optional: true` omits the relationship when its key is absent on the instance
|
|
54
|
+
* (or renders `links` only); explicit `null`/`[]` still render normally.
|
|
55
|
+
*/
|
|
56
|
+
interface RelationshipConfig<P> {
|
|
57
|
+
presenter: P;
|
|
58
|
+
hasMany?: boolean;
|
|
59
|
+
optional?: boolean;
|
|
60
|
+
}
|
|
49
61
|
interface JsonApiRelationships {
|
|
50
62
|
[key: string]: JsonApiRelationship;
|
|
51
63
|
}
|
|
@@ -87,6 +99,13 @@ interface StoreModel extends Record<string, unknown> {
|
|
|
87
99
|
[REL_LINKS]?: JsonApiLink;
|
|
88
100
|
[REL_META]?: Record<string, unknown>;
|
|
89
101
|
}
|
|
102
|
+
/** Model type for create payloads where id may be absent */
|
|
103
|
+
interface StoreModelWithOptionalId extends Record<string, unknown> {
|
|
104
|
+
id?: string | number;
|
|
105
|
+
[TYPE]?: string;
|
|
106
|
+
[LINKS]?: JsonApiLink;
|
|
107
|
+
[META]?: Record<string, unknown>;
|
|
108
|
+
}
|
|
90
109
|
interface StoreModels {
|
|
91
110
|
[type: string]: {
|
|
92
111
|
[id: string]: StoreModel;
|
|
@@ -118,5 +137,5 @@ interface LegacyStoreOptions<S extends SchemaRegistry = SchemaRegistry> {
|
|
|
118
137
|
strict?: boolean;
|
|
119
138
|
}
|
|
120
139
|
//#endregion
|
|
121
|
-
export {
|
|
122
|
-
//# sourceMappingURL=types-
|
|
140
|
+
export { REL_LINKS as C, ModelLike as D, Adapter as E, META as S, TYPE as T, StoreRecord as _, JsonApiRelationship as a, ZodLikeSchema as b, LegacyPresenterOptions as c, RelationshipConfig as d, SchemaRegistry as f, StoreOptions as g, StoreModels as h, JsonApiLinks as i, LegacyStoreOptions as l, StoreModelWithOptionalId as m, JsonApiDocument as n, JsonApiRelationships as o, StoreModel as p, JsonApiLink as r, JsonApiResource as s, InferModelType as t, PresenterOptions as u, StoreResult as v, REL_META as w, LINKS as x, ValidationError as y };
|
|
141
|
+
//# sourceMappingURL=types-KZiF6x7A.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types-KZiF6x7A.d.mts","names":[],"sources":["../../../../../../yayson/adapter.ts","../../../../../../yayson/symbols.ts","../../../../../../yayson/schema.ts","../../../../../../yayson/types.ts"],"mappings":"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"}
|
|
@@ -4,6 +4,7 @@ declare class Adapter {
|
|
|
4
4
|
static get(model: ModelLike): Record<string, unknown>;
|
|
5
5
|
static get(model: ModelLike, key: string): unknown;
|
|
6
6
|
static id(model: ModelLike): string | undefined;
|
|
7
|
+
static has(model: ModelLike, key: string): boolean;
|
|
7
8
|
}
|
|
8
9
|
//#endregion
|
|
9
10
|
//#region src/yayson/symbols.d.ts
|
|
@@ -46,6 +47,17 @@ interface JsonApiRelationship {
|
|
|
46
47
|
links?: JsonApiLink;
|
|
47
48
|
meta?: Record<string, unknown>;
|
|
48
49
|
}
|
|
50
|
+
/**
|
|
51
|
+
* Extended relationship descriptor for `relationships()` return values.
|
|
52
|
+
* `hasMany: true` renders empty/missing as `data: []` (spec-compliant to-many).
|
|
53
|
+
* `optional: true` omits the relationship when its key is absent on the instance
|
|
54
|
+
* (or renders `links` only); explicit `null`/`[]` still render normally.
|
|
55
|
+
*/
|
|
56
|
+
interface RelationshipConfig<P> {
|
|
57
|
+
presenter: P;
|
|
58
|
+
hasMany?: boolean;
|
|
59
|
+
optional?: boolean;
|
|
60
|
+
}
|
|
49
61
|
interface JsonApiRelationships {
|
|
50
62
|
[key: string]: JsonApiRelationship;
|
|
51
63
|
}
|
|
@@ -87,6 +99,13 @@ interface StoreModel extends Record<string, unknown> {
|
|
|
87
99
|
[REL_LINKS]?: JsonApiLink;
|
|
88
100
|
[REL_META]?: Record<string, unknown>;
|
|
89
101
|
}
|
|
102
|
+
/** Model type for create payloads where id may be absent */
|
|
103
|
+
interface StoreModelWithOptionalId extends Record<string, unknown> {
|
|
104
|
+
id?: string | number;
|
|
105
|
+
[TYPE]?: string;
|
|
106
|
+
[LINKS]?: JsonApiLink;
|
|
107
|
+
[META]?: Record<string, unknown>;
|
|
108
|
+
}
|
|
90
109
|
interface StoreModels {
|
|
91
110
|
[type: string]: {
|
|
92
111
|
[id: string]: StoreModel;
|
|
@@ -118,5 +137,5 @@ interface LegacyStoreOptions<S extends SchemaRegistry = SchemaRegistry> {
|
|
|
118
137
|
strict?: boolean;
|
|
119
138
|
}
|
|
120
139
|
//#endregion
|
|
121
|
-
export {
|
|
122
|
-
//# sourceMappingURL=types-
|
|
140
|
+
export { REL_LINKS as C, ModelLike as D, Adapter as E, META as S, TYPE as T, StoreRecord as _, JsonApiRelationship as a, ZodLikeSchema as b, LegacyPresenterOptions as c, RelationshipConfig as d, SchemaRegistry as f, StoreOptions as g, StoreModels as h, JsonApiLinks as i, LegacyStoreOptions as l, StoreModelWithOptionalId as m, JsonApiDocument as n, JsonApiRelationships as o, StoreModel as p, JsonApiLink as r, JsonApiResource as s, InferModelType as t, PresenterOptions as u, StoreResult as v, REL_META as w, LINKS as x, ValidationError as y };
|
|
141
|
+
//# sourceMappingURL=types-iC38_iCI.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types-iC38_iCI.d.cts","names":[],"sources":["../../../../../../yayson/adapter.ts","../../../../../../yayson/symbols.ts","../../../../../../yayson/schema.ts","../../../../../../yayson/types.ts"],"mappings":"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"}
|
package/build/utils.cjs
CHANGED
package/build/utils.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { C as
|
|
1
|
+
import { C as REL_LINKS, D as ModelLike, E as Adapter, S as META, T as TYPE, p as StoreModel, r as JsonApiLink, w as REL_META, x as LINKS } from "./types-iC38_iCI.cjs";
|
|
2
2
|
|
|
3
3
|
//#region src/utils.d.ts
|
|
4
4
|
declare function getType(model: StoreModel): string | undefined;
|
package/build/utils.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { C as
|
|
1
|
+
import { C as REL_LINKS, D as ModelLike, E as Adapter, S as META, T as TYPE, p as StoreModel, r as JsonApiLink, w as REL_META, x as LINKS } from "./types-KZiF6x7A.mjs";
|
|
2
2
|
|
|
3
3
|
//#region src/utils.d.ts
|
|
4
4
|
declare function getType(model: StoreModel): string | undefined;
|
package/build/utils.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as TYPE, i as REL_META, n as META, o as adapter_default, r as REL_LINKS, t as LINKS } from "./symbols-
|
|
1
|
+
import { a as TYPE, i as REL_META, n as META, o as adapter_default, r as REL_LINKS, t as LINKS } from "./symbols-BfU4k1el.mjs";
|
|
2
2
|
|
|
3
3
|
//#region src/utils.ts
|
|
4
4
|
function getType(model) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { D as ModelLike, E as Adapter, _ as StoreRecord$1, d as RelationshipConfig, f as SchemaRegistry, g as StoreOptions, h as StoreModels, i as JsonApiLinks, m as StoreModelWithOptionalId, n as JsonApiDocument, o as JsonApiRelationships, p as StoreModel, r as JsonApiLink, t as InferModelType, u as PresenterOptions, v as StoreResult, y as ValidationError } from "./types-KZiF6x7A.mjs";
|
|
2
2
|
|
|
3
3
|
//#region src/yayson/presenter.d.ts
|
|
4
4
|
declare function createPresenter(adapter: typeof Adapter): {
|
|
@@ -8,12 +8,15 @@ declare function createPresenter(adapter: typeof Adapter): {
|
|
|
8
8
|
id(instance: ModelLike): string | undefined;
|
|
9
9
|
selfLinks(_instance: ModelLike): JsonApiLink | string | undefined;
|
|
10
10
|
links(_instance?: ModelLike): JsonApiLinks | undefined;
|
|
11
|
-
relationships(): Record<string, /*elided*/any
|
|
11
|
+
relationships(): Record<string, /*elided*/any | RelationshipConfig< /*elided*/any>>;
|
|
12
12
|
attributes(instance: ModelLike | null): Record<string, unknown>;
|
|
13
13
|
includeRelationships(scope: JsonApiDocument, instance: ModelLike): unknown[];
|
|
14
|
-
buildRelationships(instance: ModelLike | null
|
|
14
|
+
buildRelationships(instance: ModelLike | null, options?: {
|
|
15
|
+
payload?: boolean;
|
|
16
|
+
}): JsonApiRelationships | null;
|
|
15
17
|
buildSelfLink(instance: ModelLike): JsonApiLink | undefined;
|
|
16
18
|
toJSON(instanceOrCollection: ModelLike | ModelLike[] | null | undefined, options?: PresenterOptions): JsonApiDocument;
|
|
19
|
+
payload(instance: ModelLike, options?: PresenterOptions): JsonApiDocument;
|
|
17
20
|
render(instanceOrCollection: ModelLike | ModelLike[] | null, options?: PresenterOptions): JsonApiDocument;
|
|
18
21
|
};
|
|
19
22
|
adapter: typeof Adapter;
|
|
@@ -21,6 +24,7 @@ declare function createPresenter(adapter: typeof Adapter): {
|
|
|
21
24
|
fields?: string[];
|
|
22
25
|
toJSON(instanceOrCollection: ModelLike | ModelLike[] | null, options?: PresenterOptions): JsonApiDocument;
|
|
23
26
|
render(instanceOrCollection: ModelLike | ModelLike[] | null, options?: PresenterOptions): JsonApiDocument;
|
|
27
|
+
payload(instance: ModelLike, options?: PresenterOptions): JsonApiDocument;
|
|
24
28
|
};
|
|
25
29
|
type Presenter = ReturnType<typeof createPresenter>;
|
|
26
30
|
//#endregion
|
|
@@ -35,6 +39,7 @@ declare class StoreRecord implements StoreRecord$1 {
|
|
|
35
39
|
constructor(options: StoreRecord$1);
|
|
36
40
|
}
|
|
37
41
|
declare class Store<S extends SchemaRegistry = SchemaRegistry> {
|
|
42
|
+
#private;
|
|
38
43
|
records: StoreRecord[];
|
|
39
44
|
schemas?: S;
|
|
40
45
|
strict: boolean;
|
|
@@ -49,6 +54,15 @@ declare class Store<S extends SchemaRegistry = SchemaRegistry> {
|
|
|
49
54
|
remove(type: string, id?: string | number): void;
|
|
50
55
|
syncAll(body: JsonApiDocument): StoreResult;
|
|
51
56
|
sync(body: JsonApiDocument): StoreModel | StoreResult;
|
|
57
|
+
/**
|
|
58
|
+
* Build a model from a JSON:API document without storing it.
|
|
59
|
+
* Useful for create payloads where id may be absent.
|
|
60
|
+
*
|
|
61
|
+
* Per JSON:API spec: "The id member is not required when the resource object
|
|
62
|
+
* originates at the client and represents a new resource to be created on the server."
|
|
63
|
+
*/
|
|
64
|
+
static build(body: JsonApiDocument): StoreModelWithOptionalId;
|
|
65
|
+
build(body: JsonApiDocument): StoreModelWithOptionalId;
|
|
52
66
|
retrieve<T extends string>(type: T, body: JsonApiDocument): InferModelType<S, T> | null;
|
|
53
67
|
retrieveAll<T extends string>(type: T, body: JsonApiDocument): StoreResult<InferModelType<S, T>>;
|
|
54
68
|
}
|
|
@@ -66,4 +80,4 @@ interface YaysonResult {
|
|
|
66
80
|
declare function yayson(options?: YaysonOptions): YaysonResult;
|
|
67
81
|
//#endregion
|
|
68
82
|
export { Presenter as i, YaysonResult as n, yayson as r, YaysonOptions as t };
|
|
69
|
-
//# sourceMappingURL=yayson-
|
|
83
|
+
//# sourceMappingURL=yayson-BvwMr4Ad.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"yayson-BvwMr4Ad.d.mts","names":[],"sources":["../../../../../../yayson/presenter.ts","../../../../../../yayson/store.ts","../../../../../../yayson.ts"],"mappings":";;;iBA0BwB,eAAA,CAAgB,OAAA,SAAgB,OAAA;EAAA,aAUhC,eAAA;iBAVe;WAQ5B,eAAA;iBAMM,SAAA;yBAIQ,SAAA,GAAY,WAAA;sBAIf,SAAA,GAAY,YAAA;qBAIb,MAAA,SAZJ,gBAYsC,kBAAA,EAZtC;yBAgBQ,SAAA,UAAmB,MAAA;gCAiBZ,eAAA,EAAe,QAAA,EAAY,SAAA;iCAqB1B,SAAA,SAAgB,OAAA;MAAa,OAAA;IAAA,IAA2B,oBAAA;4BAuE7D,SAAA,GAAY,WAAA;iCAKZ,SAAA,GAAY,SAAA,uBAA8B,OAAA,GACtD,gBAAA,GACT,eAAA;sBA8Ee,SAAA,EAAS,OAAA,GAAY,gBAAA,GAAmB,eAAA;iCA0B7B,SAAA,GAAY,SAAA,WAAkB,OAAA,GAAY,gBAAA,GAAmB,eAAA;EAAA;;;;+BAItD,SAAA,GAAY,SAAA,WAAkB,OAAA,GAAY,gBAAA,GAAmB,eAAA;+BAI7D,SAAA,GAAY,SAAA,WAAkB,OAAA,GAAY,gBAAA,GAAmB,eAAA;oBAIxE,SAAA,EAAS,OAAA,GAAY,gBAAA,GAAmB,eAAA;AAAA;AAAA,KAQzD,SAAA,GAAY,UAAA,QAAkB,eAAA;;;cClRpC,WAAA,YAAuB,aAAA;EAC3B,EAAA;EACA,IAAA;EACA,UAAA,GAAa,MAAA;EACb,aAAA,GAAgB,oBAAA;EAChB,KAAA,GAAQ,WAAA;EACR,IAAA,GAAO,MAAA;cAEK,OAAA,EAAS,aAAA;AAAA;AAAA,cAUF,KAAA,WAAgB,cAAA,GAAiB,cAAA;EAAA;EACpD,OAAA,EAAS,WAAA;EACT,OAAA,GAAU,CAAA;EACV,MAAA;EACA,gBAAA,EAAkB,eAAA;cAEN,OAAA,GAAU,YAAA,CAAa,CAAA;EAMnC,KAAA,CAAA;EAmGA,OAAA,CAAQ,GAAA,EAAK,WAAA,EAAa,IAAA,UAAc,MAAA,EAAQ,WAAA,GAAc,UAAA;EA+B9D,UAAA,CAAW,IAAA,UAAc,EAAA,oBAAsB,WAAA;EAK/C,WAAA,CAAY,IAAA,WAAe,WAAA;EAiB3B,IAAA,kBAAA,CAAuB,IAAA,EAAM,CAAA,EAAG,EAAA,mBAAqB,MAAA,GAAS,WAAA,GAAc,cAAA,CAAe,CAAA,EAAG,CAAA;EAM9F,OAAA,kBAAA,CAA0B,IAAA,EAAM,CAAA,EAAG,MAAA,GAAS,WAAA,GAAc,cAAA,CAAe,CAAA,EAAG,CAAA;EAgB5E,MAAA,CAAO,IAAA,UAAc,EAAA;EAkBrB,OAAA,CAAQ,IAAA,EAAM,eAAA,GAAkB,WAAA;EA8DhC,IAAA,CAAK,IAAA,EAAM,eAAA,GAAkB,UAAA,GAAa,WAAA;EDvI5B;;;;;;;EAAA,OC0JP,KAAA,CAAM,IAAA,EAAM,eAAA,GAAkB,wBAAA;EAIrC,KAAA,CAAM,IAAA,EAAM,eAAA,GAAkB,wBAAA;EAQ9B,QAAA,kBAAA,CAA2B,IAAA,EAAM,CAAA,EAAG,IAAA,EAAM,eAAA,GAAkB,cAAA,CAAe,CAAA,EAAG,CAAA;EAW9E,WAAA,kBAAA,CAA8B,IAAA,EAAM,CAAA,EAAG,IAAA,EAAM,eAAA,GAAkB,WAAA,CAAY,cAAA,CAAe,CAAA,EAAG,CAAA;AAAA;;;KCzU1F,aAAA,mBAAgC,OAAA;AAAA,UAE3B,aAAA;EACR,OAAA,GAAU,aAAA;AAAA;AAAA,UAGF,YAAA;EACR,KAAA,SAAc,KAAA;EACd,SAAA,EAAW,SAAA;EACX,OAAA,SAAgB,OAAA;AAAA;AAAA,iBAgBT,MAAA,CAAO,OAAA,GAAU,aAAA,GAAgB,YAAA"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const require_symbols = require('./symbols-
|
|
1
|
+
const require_symbols = require('./symbols-B--FS78o.cjs');
|
|
2
2
|
|
|
3
3
|
//#region src/yayson/adapters/sequelize.ts
|
|
4
4
|
function isSequelizeModel(model) {
|
|
@@ -8,12 +8,16 @@ var SequelizeAdapter = class extends require_symbols.adapter_default {
|
|
|
8
8
|
static get(model, key) {
|
|
9
9
|
if (isSequelizeModel(model)) return model.get(key);
|
|
10
10
|
}
|
|
11
|
+
static has(model, key) {
|
|
12
|
+
if (isSequelizeModel(model)) return model.get(key) !== void 0;
|
|
13
|
+
return false;
|
|
14
|
+
}
|
|
11
15
|
static id(model) {
|
|
12
16
|
const pkFields = model.constructor && "primaryKeys" in model.constructor ? Object.keys(model.constructor.primaryKeys) : ["id"];
|
|
13
17
|
if (pkFields.length > 1) throw new Error("YAYSON does not support Sequelize models with composite primary keys. You can only use one column for your primary key. Currently using: " + pkFields.join(","));
|
|
14
18
|
else if (pkFields.length < 1) throw new Error("YAYSON can only serialize Sequelize models which have a primary key. This is used for the JSON:API model id.");
|
|
15
19
|
const id = this.get(model, pkFields[0]);
|
|
16
|
-
if (id
|
|
20
|
+
if (id == null) return;
|
|
17
21
|
return `${id}`;
|
|
18
22
|
}
|
|
19
23
|
};
|
|
@@ -69,23 +73,32 @@ function createPresenter(adapter) {
|
|
|
69
73
|
const result = [];
|
|
70
74
|
if (!relationships) return result;
|
|
71
75
|
for (const key in relationships) {
|
|
72
|
-
const
|
|
73
|
-
if (!
|
|
74
|
-
const presenter = new
|
|
76
|
+
const entry = relationships[key];
|
|
77
|
+
if (!entry) throw new Error(`Presenter for ${key} in ${this.constructor.type} is not defined`);
|
|
78
|
+
const presenter = new (typeof entry === "function" ? entry : entry.presenter)(scope);
|
|
75
79
|
const data = this.constructor.adapter.get(instance, key);
|
|
76
80
|
result.push(presenter.toJSON(data, { include: true }));
|
|
77
81
|
}
|
|
78
82
|
return result;
|
|
79
83
|
}
|
|
80
|
-
buildRelationships(instance) {
|
|
84
|
+
buildRelationships(instance, options = {}) {
|
|
81
85
|
if (instance == null) return null;
|
|
82
86
|
const rels = this.relationships();
|
|
83
87
|
const links = this.links(instance) || {};
|
|
88
|
+
const isPayload = options.payload === true;
|
|
84
89
|
let relationships = null;
|
|
85
90
|
if (!rels) return null;
|
|
86
91
|
for (const key in rels) {
|
|
92
|
+
const entry = rels[key];
|
|
93
|
+
if (!entry) continue;
|
|
94
|
+
const isConfig = typeof entry !== "function";
|
|
95
|
+
const presenter = isConfig ? entry.presenter : entry;
|
|
96
|
+
const hasMany = isConfig ? entry.hasMany : void 0;
|
|
97
|
+
const optional = isConfig ? entry.optional ?? false : false;
|
|
98
|
+
const linkValue = links[key];
|
|
99
|
+
const hasLinks = linkValue != null;
|
|
87
100
|
const data = this.constructor.adapter.get(instance, key);
|
|
88
|
-
const
|
|
101
|
+
const keyPresent = this.constructor.adapter.has(instance, key);
|
|
89
102
|
const buildData = (d) => {
|
|
90
103
|
const id = this.constructor.adapter.id(d);
|
|
91
104
|
if (!id) throw new Error(`Model of type ${presenter.type} is missing an id (relationship '${key}' of ${this.constructor.type})`);
|
|
@@ -94,19 +107,21 @@ function createPresenter(adapter) {
|
|
|
94
107
|
type: presenter.type
|
|
95
108
|
};
|
|
96
109
|
};
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
}
|
|
110
|
+
if (optional && !keyPresent && !isPayload) {
|
|
111
|
+
if (hasLinks) {
|
|
112
|
+
if (!relationships) relationships = {};
|
|
113
|
+
relationships[key] = { links: buildLinks(linkValue) };
|
|
114
|
+
}
|
|
115
|
+
continue;
|
|
116
|
+
}
|
|
104
117
|
if (!relationships) relationships = {};
|
|
105
|
-
|
|
106
|
-
if (Array.isArray(data))
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
118
|
+
const rel = {};
|
|
119
|
+
if (Array.isArray(data)) rel.data = data.map(buildData);
|
|
120
|
+
else if (data != null) rel.data = buildData(data);
|
|
121
|
+
else if (hasMany === true) rel.data = [];
|
|
122
|
+
else if (!hasLinks) rel.data = null;
|
|
123
|
+
if (hasLinks) rel.links = buildLinks(linkValue);
|
|
124
|
+
relationships[key] = rel;
|
|
110
125
|
}
|
|
111
126
|
return relationships;
|
|
112
127
|
}
|
|
@@ -150,6 +165,23 @@ function createPresenter(adapter) {
|
|
|
150
165
|
}
|
|
151
166
|
return this.scope;
|
|
152
167
|
}
|
|
168
|
+
payload(instance, options) {
|
|
169
|
+
if (Array.isArray(instance)) throw new Error("payload() expects a single resource, not an array");
|
|
170
|
+
if (instance == null) throw new Error("payload() requires a resource, got null");
|
|
171
|
+
const model = {
|
|
172
|
+
type: this.constructor.type,
|
|
173
|
+
attributes: this.attributes(instance)
|
|
174
|
+
};
|
|
175
|
+
const id = this.id(instance);
|
|
176
|
+
if (id != null) model.id = id;
|
|
177
|
+
const relationships = this.buildRelationships(instance, { payload: true });
|
|
178
|
+
if (relationships != null) model.relationships = relationships;
|
|
179
|
+
const result = { data: model };
|
|
180
|
+
const opts = options ?? {};
|
|
181
|
+
if (opts.meta != null) result.meta = opts.meta;
|
|
182
|
+
if (opts.links != null) result.links = opts.links;
|
|
183
|
+
return result;
|
|
184
|
+
}
|
|
153
185
|
render(instanceOrCollection, options) {
|
|
154
186
|
return this.toJSON(instanceOrCollection, options);
|
|
155
187
|
}
|
|
@@ -159,6 +191,9 @@ function createPresenter(adapter) {
|
|
|
159
191
|
static render(instanceOrCollection, options) {
|
|
160
192
|
return new this().render(instanceOrCollection, options);
|
|
161
193
|
}
|
|
194
|
+
static payload(instance, options) {
|
|
195
|
+
return new this().payload(instance, options);
|
|
196
|
+
}
|
|
162
197
|
}
|
|
163
198
|
return Presenter;
|
|
164
199
|
}
|
|
@@ -190,6 +225,9 @@ function validate(schema, data, strict) {
|
|
|
190
225
|
|
|
191
226
|
//#endregion
|
|
192
227
|
//#region src/yayson/store.ts
|
|
228
|
+
function hasId(model) {
|
|
229
|
+
return model.id != null;
|
|
230
|
+
}
|
|
193
231
|
var StoreRecord = class {
|
|
194
232
|
id;
|
|
195
233
|
type;
|
|
@@ -206,7 +244,7 @@ var StoreRecord = class {
|
|
|
206
244
|
this.meta = options.meta;
|
|
207
245
|
}
|
|
208
246
|
};
|
|
209
|
-
var Store = class {
|
|
247
|
+
var Store = class Store {
|
|
210
248
|
records = [];
|
|
211
249
|
schemas;
|
|
212
250
|
strict;
|
|
@@ -220,37 +258,57 @@ var Store = class {
|
|
|
220
258
|
this.records = [];
|
|
221
259
|
this.validationErrors = [];
|
|
222
260
|
}
|
|
223
|
-
|
|
224
|
-
const
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
const
|
|
230
|
-
|
|
231
|
-
if (
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
if (
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
const
|
|
238
|
-
|
|
261
|
+
#createStub(type, id) {
|
|
262
|
+
const stub = { id };
|
|
263
|
+
stub[require_symbols.TYPE] = type;
|
|
264
|
+
return stub;
|
|
265
|
+
}
|
|
266
|
+
#createModel(resource, options) {
|
|
267
|
+
const models = options?.models ?? {};
|
|
268
|
+
const model = { ...resource.attributes || {} };
|
|
269
|
+
if (resource.id != null) model.id = resource.id;
|
|
270
|
+
const type = resource.type;
|
|
271
|
+
model[require_symbols.TYPE] = type;
|
|
272
|
+
if (resource.meta != null) model[require_symbols.META] = resource.meta;
|
|
273
|
+
if (resource.links != null) model[require_symbols.LINKS] = resource.links;
|
|
274
|
+
if (hasId(model)) {
|
|
275
|
+
const idStr = String(model.id);
|
|
276
|
+
if (!models[type]) models[type] = {};
|
|
277
|
+
if (!models[type][idStr]) models[type][idStr] = model;
|
|
278
|
+
}
|
|
279
|
+
if (resource.relationships != null) {
|
|
280
|
+
const resolver = (ref) => {
|
|
281
|
+
return this.#findModel(ref.type, ref.id, models) ?? this.#createStub(ref.type, ref.id);
|
|
282
|
+
};
|
|
283
|
+
this.#resolveRelationships(model, resource.relationships, resolver, { includeRelMeta: options?.includeRelMeta });
|
|
284
|
+
}
|
|
285
|
+
return model;
|
|
286
|
+
}
|
|
287
|
+
#resolveRelationships(model, relationships, resolver, options) {
|
|
288
|
+
const includeRelMeta = options?.includeRelMeta ?? true;
|
|
289
|
+
for (const key in relationships) {
|
|
290
|
+
const { data, links, meta } = relationships[key];
|
|
239
291
|
model[key] = null;
|
|
240
292
|
if (data == null && links == null) continue;
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
relModel[require_symbols.REL_LINKS] = links || {};
|
|
249
|
-
relModel[require_symbols.REL_META] = meta || {};
|
|
250
|
-
model[key] = relModel;
|
|
293
|
+
if (Array.isArray(data)) model[key] = data.filter((item) => item.id != null).map(resolver);
|
|
294
|
+
else if (data != null && data.id != null) {
|
|
295
|
+
const relModel = resolver(data);
|
|
296
|
+
if (includeRelMeta) {
|
|
297
|
+
const modelWithMeta = relModel;
|
|
298
|
+
modelWithMeta[require_symbols.REL_LINKS] = links || {};
|
|
299
|
+
modelWithMeta[require_symbols.REL_META] = meta || {};
|
|
251
300
|
}
|
|
301
|
+
model[key] = relModel;
|
|
302
|
+
} else if (data == null && (links != null || meta != null) && includeRelMeta) {
|
|
303
|
+
const relModel = { id: "" };
|
|
304
|
+
relModel[require_symbols.REL_LINKS] = links || {};
|
|
305
|
+
relModel[require_symbols.REL_META] = meta || {};
|
|
306
|
+
model[key] = relModel;
|
|
252
307
|
}
|
|
253
308
|
}
|
|
309
|
+
}
|
|
310
|
+
toModel(rec, type, models) {
|
|
311
|
+
const model = this.#createModel(rec, { models });
|
|
254
312
|
if (this.schemas && this.schemas[rec.type]) {
|
|
255
313
|
const schema = this.schemas[rec.type];
|
|
256
314
|
const result = validate(schema, model, this.strict);
|
|
@@ -274,13 +332,16 @@ var Store = class {
|
|
|
274
332
|
findRecords(type) {
|
|
275
333
|
return this.records.filter((r) => r.type === type);
|
|
276
334
|
}
|
|
277
|
-
|
|
278
|
-
const modelsObj = models ?? {};
|
|
335
|
+
#findModel(type, id, models) {
|
|
279
336
|
const idStr = String(id);
|
|
280
|
-
const
|
|
337
|
+
const cached = models[type]?.[idStr];
|
|
338
|
+
if (cached) return cached;
|
|
339
|
+
const rec = this.findRecord(type, id);
|
|
281
340
|
if (rec == null) return null;
|
|
282
|
-
|
|
283
|
-
|
|
341
|
+
return this.toModel(rec, type, models);
|
|
342
|
+
}
|
|
343
|
+
find(type, id, models) {
|
|
344
|
+
return this.#findModel(type, id, models ?? {});
|
|
284
345
|
}
|
|
285
346
|
findAll(type, models) {
|
|
286
347
|
const modelsObj = models ?? {};
|
|
@@ -354,6 +415,21 @@ var Store = class {
|
|
|
354
415
|
}
|
|
355
416
|
return result;
|
|
356
417
|
}
|
|
418
|
+
/**
|
|
419
|
+
* Build a model from a JSON:API document without storing it.
|
|
420
|
+
* Useful for create payloads where id may be absent.
|
|
421
|
+
*
|
|
422
|
+
* Per JSON:API spec: "The id member is not required when the resource object
|
|
423
|
+
* originates at the client and represents a new resource to be created on the server."
|
|
424
|
+
*/
|
|
425
|
+
static build(body) {
|
|
426
|
+
return new Store().build(body);
|
|
427
|
+
}
|
|
428
|
+
build(body) {
|
|
429
|
+
const { data } = body;
|
|
430
|
+
if (data == null || Array.isArray(data)) throw new Error("build() expects a single resource in data, not null or an array");
|
|
431
|
+
return this.#createModel(data);
|
|
432
|
+
}
|
|
357
433
|
retrieve(type, body) {
|
|
358
434
|
const synced = this.syncAll(body);
|
|
359
435
|
const model = synced.find((m) => m[require_symbols.TYPE] === type);
|