@23blocks/jsonapi-codec 1.0.3 → 1.0.4
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/dist/index.d.ts +1 -0
- package/dist/index.esm.js +182 -0
- package/dist/src/index.d.ts +5 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/lib/decode.d.ts +28 -0
- package/dist/src/lib/decode.d.ts.map +1 -0
- package/dist/src/lib/errors.d.ts +24 -0
- package/dist/src/lib/errors.d.ts.map +1 -0
- package/dist/src/lib/mapper.d.ts +40 -0
- package/dist/src/lib/mapper.d.ts.map +1 -0
- package/dist/src/lib/types.d.ts +154 -0
- package/dist/src/lib/types.d.ts.map +1 -0
- package/package.json +10 -8
- package/dist/index.js +0 -10
- package/dist/index.js.map +0 -1
- package/dist/lib/decode.js +0 -57
- package/dist/lib/decode.js.map +0 -1
- package/dist/lib/errors.js +0 -54
- package/dist/lib/errors.js.map +0 -1
- package/dist/lib/mapper.js +0 -59
- package/dist/lib/mapper.js.map +0 -1
- package/dist/lib/types.js +0 -20
- package/dist/lib/types.js.map +0 -1
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./src/index";
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import { _ } from '@swc/helpers/_/_extends';
|
|
2
|
+
import { BlockErrorException } from '@23blocks/contracts';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Type guard for single resource document
|
|
6
|
+
*/ function isSingleResourceDocument(doc) {
|
|
7
|
+
return doc.data !== null && doc.data !== undefined && !Array.isArray(doc.data);
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Type guard for collection resource document
|
|
11
|
+
*/ function isCollectionDocument(doc) {
|
|
12
|
+
return Array.isArray(doc.data);
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Type guard for error document
|
|
16
|
+
*/ function isErrorDocument(doc) {
|
|
17
|
+
return Array.isArray(doc.errors) && doc.errors.length > 0;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Create a key for the included map
|
|
22
|
+
*/ function resourceKey(type, id) {
|
|
23
|
+
return `${type}:${id}`;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Build an included map from an array of resources
|
|
27
|
+
*/ function buildIncludedMap(included = []) {
|
|
28
|
+
const map = new Map();
|
|
29
|
+
for (const resource of included){
|
|
30
|
+
map.set(resourceKey(resource.type, resource.id), resource);
|
|
31
|
+
}
|
|
32
|
+
return map;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Get a resource from the included map
|
|
36
|
+
*/ function getIncluded(included, type, id) {
|
|
37
|
+
return included.get(resourceKey(type, id));
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Resolve a relationship from included resources
|
|
41
|
+
*/ function resolveRelationship(resource, relationshipName, included, mapper) {
|
|
42
|
+
var _resource_relationships;
|
|
43
|
+
const relationship = (_resource_relationships = resource.relationships) == null ? void 0 : _resource_relationships[relationshipName];
|
|
44
|
+
if (!(relationship == null ? void 0 : relationship.data)) {
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
const data = relationship.data;
|
|
48
|
+
if (Array.isArray(data)) {
|
|
49
|
+
throw new Error(`Expected single relationship for '${relationshipName}', got array. Use resolveRelationshipMany instead.`);
|
|
50
|
+
}
|
|
51
|
+
const related = getIncluded(included, data.type, data.id);
|
|
52
|
+
if (!related) {
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
return mapper.map(related, included);
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Resolve a has-many relationship from included resources
|
|
59
|
+
*/ function resolveRelationshipMany(resource, relationshipName, included, mapper) {
|
|
60
|
+
var _resource_relationships;
|
|
61
|
+
const relationship = (_resource_relationships = resource.relationships) == null ? void 0 : _resource_relationships[relationshipName];
|
|
62
|
+
if (!(relationship == null ? void 0 : relationship.data)) {
|
|
63
|
+
return [];
|
|
64
|
+
}
|
|
65
|
+
const data = relationship.data;
|
|
66
|
+
if (!Array.isArray(data)) {
|
|
67
|
+
throw new Error(`Expected array relationship for '${relationshipName}', got single. Use resolveRelationship instead.`);
|
|
68
|
+
}
|
|
69
|
+
return data.map((identifier)=>{
|
|
70
|
+
const related = getIncluded(included, identifier.type, identifier.id);
|
|
71
|
+
if (!related) {
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
return mapper.map(related, included);
|
|
75
|
+
}).filter((item)=>item !== null);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Decode a single resource from a JSON:API document
|
|
80
|
+
*/ function decodeOne(document, mapper) {
|
|
81
|
+
if (!isSingleResourceDocument(document)) {
|
|
82
|
+
throw new Error('Expected single resource document');
|
|
83
|
+
}
|
|
84
|
+
const included = buildIncludedMap(document.included);
|
|
85
|
+
return mapper.map(document.data, included);
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Decode a single resource from a JSON:API document, returning null if not found
|
|
89
|
+
*/ function decodeOneOrNull(document, mapper) {
|
|
90
|
+
if (!document.data || Array.isArray(document.data)) {
|
|
91
|
+
return null;
|
|
92
|
+
}
|
|
93
|
+
const included = buildIncludedMap(document.included);
|
|
94
|
+
return mapper.map(document.data, included);
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Decode multiple resources from a JSON:API document
|
|
98
|
+
*/ function decodeMany(document, mapper) {
|
|
99
|
+
if (!isCollectionDocument(document)) {
|
|
100
|
+
throw new Error('Expected collection document');
|
|
101
|
+
}
|
|
102
|
+
const included = buildIncludedMap(document.included);
|
|
103
|
+
return document.data.map((resource)=>mapper.map(resource, included));
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Extract pagination metadata from JSON:API meta
|
|
107
|
+
*/ function extractPageMeta(meta) {
|
|
108
|
+
var _meta_current_page, _meta_total_pages, _meta_total_count, _meta_per_page;
|
|
109
|
+
return {
|
|
110
|
+
currentPage: (_meta_current_page = meta == null ? void 0 : meta.current_page) != null ? _meta_current_page : 1,
|
|
111
|
+
totalPages: (_meta_total_pages = meta == null ? void 0 : meta.total_pages) != null ? _meta_total_pages : 1,
|
|
112
|
+
totalCount: (_meta_total_count = meta == null ? void 0 : meta.total_count) != null ? _meta_total_count : 0,
|
|
113
|
+
perPage: (_meta_per_page = meta == null ? void 0 : meta.per_page) != null ? _meta_per_page : 0
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Decode a paginated collection from a JSON:API document
|
|
118
|
+
*/ function decodePageResult(document, mapper) {
|
|
119
|
+
const data = isCollectionDocument(document) ? decodeMany(document, mapper) : [];
|
|
120
|
+
return {
|
|
121
|
+
data,
|
|
122
|
+
meta: extractPageMeta(document.meta)
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Decode with a custom decoder function
|
|
127
|
+
*/ function decodeWith(document, decoder) {
|
|
128
|
+
const included = buildIncludedMap(document.included);
|
|
129
|
+
return decoder(document, included);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Convert a JSON:API error to a BlockError
|
|
134
|
+
*/ function jsonApiErrorToBlockError(error) {
|
|
135
|
+
var _error_source, _error_source1;
|
|
136
|
+
var _error_code, _error_detail, _ref, _error_source_pointer;
|
|
137
|
+
return {
|
|
138
|
+
code: (_error_code = error.code) != null ? _error_code : 'unknown_error',
|
|
139
|
+
message: (_ref = (_error_detail = error.detail) != null ? _error_detail : error.title) != null ? _ref : 'An unknown error occurred',
|
|
140
|
+
status: error.status ? parseInt(error.status, 10) : 500,
|
|
141
|
+
source: (_error_source_pointer = (_error_source = error.source) == null ? void 0 : _error_source.pointer) != null ? _error_source_pointer : (_error_source1 = error.source) == null ? void 0 : _error_source1.parameter,
|
|
142
|
+
meta: error.meta
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Convert multiple JSON:API errors to a single BlockError
|
|
147
|
+
* Uses the first error as the primary error, includes others in meta
|
|
148
|
+
*/ function jsonApiErrorsToBlockError(errors) {
|
|
149
|
+
if (errors.length === 0) {
|
|
150
|
+
return {
|
|
151
|
+
code: 'unknown_error',
|
|
152
|
+
message: 'An unknown error occurred',
|
|
153
|
+
status: 500
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
const primary = jsonApiErrorToBlockError(errors[0]);
|
|
157
|
+
if (errors.length > 1) {
|
|
158
|
+
primary.meta = _({}, primary.meta, {
|
|
159
|
+
additionalErrors: errors.slice(1).map(jsonApiErrorToBlockError)
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
return primary;
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Create a BlockErrorException from JSON:API errors
|
|
166
|
+
*/ function blockErrorFromJsonApi(errors) {
|
|
167
|
+
return new BlockErrorException(jsonApiErrorsToBlockError(errors));
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Check if a document is an error document and throw if so
|
|
171
|
+
*/ function throwIfError(document) {
|
|
172
|
+
if (isErrorDocument(document)) {
|
|
173
|
+
throw blockErrorFromJsonApi(document.errors);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Assert that a document is not an error document
|
|
178
|
+
*/ function assertNotError(document) {
|
|
179
|
+
throwIfError(document);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
export { assertNotError, blockErrorFromJsonApi, buildIncludedMap, decodeMany, decodeOne, decodeOneOrNull, decodePageResult, decodeWith, extractPageMeta, getIncluded, isCollectionDocument, isErrorDocument, isSingleResourceDocument, jsonApiErrorToBlockError, jsonApiErrorsToBlockError, resolveRelationship, resolveRelationshipMany, resourceKey, throwIfError };
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { type JsonApiResource, type JsonApiRelationship, type JsonApiResourceIdentifier, type JsonApiLinks, type JsonApiLink, type JsonApiError, type JsonApiDocument, type JsonApiMeta, isSingleResourceDocument, isCollectionDocument, isErrorDocument, } from './lib/types.js';
|
|
2
|
+
export { type IncludedMap, type ResourceMapper, resourceKey, buildIncludedMap, getIncluded, resolveRelationship, resolveRelationshipMany, } from './lib/mapper.js';
|
|
3
|
+
export { decodeOne, decodeOneOrNull, decodeMany, extractPageMeta, decodePageResult, decodeWith, } from './lib/decode.js';
|
|
4
|
+
export { jsonApiErrorToBlockError, jsonApiErrorsToBlockError, blockErrorFromJsonApi, throwIfError, assertNotError, } from './lib/errors.js';
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EACL,KAAK,eAAe,EACpB,KAAK,mBAAmB,EACxB,KAAK,yBAAyB,EAC9B,KAAK,YAAY,EACjB,KAAK,WAAW,EAChB,KAAK,YAAY,EACjB,KAAK,eAAe,EACpB,KAAK,WAAW,EAChB,wBAAwB,EACxB,oBAAoB,EACpB,eAAe,GAChB,MAAM,gBAAgB,CAAC;AAGxB,OAAO,EACL,KAAK,WAAW,EAChB,KAAK,cAAc,EACnB,WAAW,EACX,gBAAgB,EAChB,WAAW,EACX,mBAAmB,EACnB,uBAAuB,GACxB,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EACL,SAAS,EACT,eAAe,EACf,UAAU,EACV,eAAe,EACf,gBAAgB,EAChB,UAAU,GACX,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EACL,wBAAwB,EACxB,yBAAyB,EACzB,qBAAqB,EACrB,YAAY,EACZ,cAAc,GACf,MAAM,iBAAiB,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { PageResult, PageMeta } from '@23blocks/contracts';
|
|
2
|
+
import type { JsonApiDocument, JsonApiMeta } from './types.js';
|
|
3
|
+
import type { ResourceMapper, IncludedMap } from './mapper.js';
|
|
4
|
+
/**
|
|
5
|
+
* Decode a single resource from a JSON:API document
|
|
6
|
+
*/
|
|
7
|
+
export declare function decodeOne<T>(document: JsonApiDocument, mapper: ResourceMapper<T>): T;
|
|
8
|
+
/**
|
|
9
|
+
* Decode a single resource from a JSON:API document, returning null if not found
|
|
10
|
+
*/
|
|
11
|
+
export declare function decodeOneOrNull<T>(document: JsonApiDocument, mapper: ResourceMapper<T>): T | null;
|
|
12
|
+
/**
|
|
13
|
+
* Decode multiple resources from a JSON:API document
|
|
14
|
+
*/
|
|
15
|
+
export declare function decodeMany<T>(document: JsonApiDocument, mapper: ResourceMapper<T>): T[];
|
|
16
|
+
/**
|
|
17
|
+
* Extract pagination metadata from JSON:API meta
|
|
18
|
+
*/
|
|
19
|
+
export declare function extractPageMeta(meta?: JsonApiMeta): PageMeta;
|
|
20
|
+
/**
|
|
21
|
+
* Decode a paginated collection from a JSON:API document
|
|
22
|
+
*/
|
|
23
|
+
export declare function decodePageResult<T>(document: JsonApiDocument, mapper: ResourceMapper<T>): PageResult<T>;
|
|
24
|
+
/**
|
|
25
|
+
* Decode with a custom decoder function
|
|
26
|
+
*/
|
|
27
|
+
export declare function decodeWith<T>(document: JsonApiDocument, decoder: (doc: JsonApiDocument, included: IncludedMap) => T): T;
|
|
28
|
+
//# sourceMappingURL=decode.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"decode.d.ts","sourceRoot":"","sources":["../../../src/lib/decode.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAChE,OAAO,KAAK,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE/D,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAG/D;;GAEG;AACH,wBAAgB,SAAS,CAAC,CAAC,EACzB,QAAQ,EAAE,eAAe,EACzB,MAAM,EAAE,cAAc,CAAC,CAAC,CAAC,GACxB,CAAC,CAOH;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAC/B,QAAQ,EAAE,eAAe,EACzB,MAAM,EAAE,cAAc,CAAC,CAAC,CAAC,GACxB,CAAC,GAAG,IAAI,CAOV;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAC1B,QAAQ,EAAE,eAAe,EACzB,MAAM,EAAE,cAAc,CAAC,CAAC,CAAC,GACxB,CAAC,EAAE,CAOL;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,IAAI,CAAC,EAAE,WAAW,GAAG,QAAQ,CAO5D;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,EAChC,QAAQ,EAAE,eAAe,EACzB,MAAM,EAAE,cAAc,CAAC,CAAC,CAAC,GACxB,UAAU,CAAC,CAAC,CAAC,CASf;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAC1B,QAAQ,EAAE,eAAe,EACzB,OAAO,EAAE,CAAC,GAAG,EAAE,eAAe,EAAE,QAAQ,EAAE,WAAW,KAAK,CAAC,GAC1D,CAAC,CAGH"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { BlockErrorException, type BlockError } from '@23blocks/contracts';
|
|
2
|
+
import type { JsonApiDocument, JsonApiError } from './types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Convert a JSON:API error to a BlockError
|
|
5
|
+
*/
|
|
6
|
+
export declare function jsonApiErrorToBlockError(error: JsonApiError): BlockError;
|
|
7
|
+
/**
|
|
8
|
+
* Convert multiple JSON:API errors to a single BlockError
|
|
9
|
+
* Uses the first error as the primary error, includes others in meta
|
|
10
|
+
*/
|
|
11
|
+
export declare function jsonApiErrorsToBlockError(errors: JsonApiError[]): BlockError;
|
|
12
|
+
/**
|
|
13
|
+
* Create a BlockErrorException from JSON:API errors
|
|
14
|
+
*/
|
|
15
|
+
export declare function blockErrorFromJsonApi(errors: JsonApiError[]): BlockErrorException;
|
|
16
|
+
/**
|
|
17
|
+
* Check if a document is an error document and throw if so
|
|
18
|
+
*/
|
|
19
|
+
export declare function throwIfError(document: JsonApiDocument): void;
|
|
20
|
+
/**
|
|
21
|
+
* Assert that a document is not an error document
|
|
22
|
+
*/
|
|
23
|
+
export declare function assertNotError<T extends JsonApiDocument>(document: T): asserts document is T;
|
|
24
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../../src/lib/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,KAAK,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAC3E,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAGhE;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,YAAY,GAAG,UAAU,CAQxE;AAED;;;GAGG;AACH,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,YAAY,EAAE,GAAG,UAAU,CAmB5E;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,YAAY,EAAE,GAAG,mBAAmB,CAEjF;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,eAAe,GAAG,IAAI,CAI5D;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,CAAC,SAAS,eAAe,EAAE,QAAQ,EAAE,CAAC,GAAG,OAAO,CAAC,QAAQ,IAAI,CAAC,CAE5F"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { JsonApiResource } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Included resources map for efficient relationship resolution
|
|
4
|
+
*/
|
|
5
|
+
export type IncludedMap = Map<string, JsonApiResource>;
|
|
6
|
+
/**
|
|
7
|
+
* Resource mapper interface
|
|
8
|
+
* Each block provides mappers for its resource types
|
|
9
|
+
*/
|
|
10
|
+
export interface ResourceMapper<T> {
|
|
11
|
+
/** JSON:API resource type this mapper handles */
|
|
12
|
+
type: string;
|
|
13
|
+
/**
|
|
14
|
+
* Map a JSON:API resource to a domain object
|
|
15
|
+
* @param resource - The JSON:API resource to map
|
|
16
|
+
* @param included - Map of included resources for relationship resolution
|
|
17
|
+
*/
|
|
18
|
+
map(resource: JsonApiResource, included: IncludedMap): T;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Create a key for the included map
|
|
22
|
+
*/
|
|
23
|
+
export declare function resourceKey(type: string, id: string): string;
|
|
24
|
+
/**
|
|
25
|
+
* Build an included map from an array of resources
|
|
26
|
+
*/
|
|
27
|
+
export declare function buildIncludedMap(included?: JsonApiResource[]): IncludedMap;
|
|
28
|
+
/**
|
|
29
|
+
* Get a resource from the included map
|
|
30
|
+
*/
|
|
31
|
+
export declare function getIncluded(included: IncludedMap, type: string, id: string): JsonApiResource | undefined;
|
|
32
|
+
/**
|
|
33
|
+
* Resolve a relationship from included resources
|
|
34
|
+
*/
|
|
35
|
+
export declare function resolveRelationship<T>(resource: JsonApiResource, relationshipName: string, included: IncludedMap, mapper: ResourceMapper<T>): T | null;
|
|
36
|
+
/**
|
|
37
|
+
* Resolve a has-many relationship from included resources
|
|
38
|
+
*/
|
|
39
|
+
export declare function resolveRelationshipMany<T>(resource: JsonApiResource, relationshipName: string, included: IncludedMap, mapper: ResourceMapper<T>): T[];
|
|
40
|
+
//# sourceMappingURL=mapper.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mapper.d.ts","sourceRoot":"","sources":["../../../src/lib/mapper.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElD;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;AAEvD;;;GAGG;AACH,MAAM,WAAW,cAAc,CAAC,CAAC;IAC/B,iDAAiD;IACjD,IAAI,EAAE,MAAM,CAAC;IAEb;;;;OAIG;IACH,GAAG,CAAC,QAAQ,EAAE,eAAe,EAAE,QAAQ,EAAE,WAAW,GAAG,CAAC,CAAC;CAC1D;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,CAE5D;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,GAAE,eAAe,EAAO,GAAG,WAAW,CAM9E;AAED;;GAEG;AACH,wBAAgB,WAAW,CACzB,QAAQ,EAAE,WAAW,EACrB,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,MAAM,GACT,eAAe,GAAG,SAAS,CAE7B;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,CAAC,EACnC,QAAQ,EAAE,eAAe,EACzB,gBAAgB,EAAE,MAAM,EACxB,QAAQ,EAAE,WAAW,EACrB,MAAM,EAAE,cAAc,CAAC,CAAC,CAAC,GACxB,CAAC,GAAG,IAAI,CAmBV;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,CAAC,EACvC,QAAQ,EAAE,eAAe,EACzB,gBAAgB,EAAE,MAAM,EACxB,QAAQ,EAAE,WAAW,EACrB,MAAM,EAAE,cAAc,CAAC,CAAC,CAAC,GACxB,CAAC,EAAE,CAsBL"}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JSON:API Resource Object
|
|
3
|
+
* @see https://jsonapi.org/format/#document-resource-objects
|
|
4
|
+
*/
|
|
5
|
+
export interface JsonApiResource<TAttributes = Record<string, unknown>> {
|
|
6
|
+
/** Resource type */
|
|
7
|
+
type: string;
|
|
8
|
+
/** Resource ID */
|
|
9
|
+
id: string;
|
|
10
|
+
/** Resource attributes */
|
|
11
|
+
attributes?: TAttributes;
|
|
12
|
+
/** Resource relationships */
|
|
13
|
+
relationships?: Record<string, JsonApiRelationship>;
|
|
14
|
+
/** Resource links */
|
|
15
|
+
links?: JsonApiLinks;
|
|
16
|
+
/** Resource meta */
|
|
17
|
+
meta?: Record<string, unknown>;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* JSON:API Relationship Object
|
|
21
|
+
* @see https://jsonapi.org/format/#document-resource-object-relationships
|
|
22
|
+
*/
|
|
23
|
+
export interface JsonApiRelationship {
|
|
24
|
+
/** Relationship data */
|
|
25
|
+
data: JsonApiResourceIdentifier | JsonApiResourceIdentifier[] | null;
|
|
26
|
+
/** Relationship links */
|
|
27
|
+
links?: JsonApiLinks;
|
|
28
|
+
/** Relationship meta */
|
|
29
|
+
meta?: Record<string, unknown>;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* JSON:API Resource Identifier Object
|
|
33
|
+
* @see https://jsonapi.org/format/#document-resource-identifier-objects
|
|
34
|
+
*/
|
|
35
|
+
export interface JsonApiResourceIdentifier {
|
|
36
|
+
/** Resource type */
|
|
37
|
+
type: string;
|
|
38
|
+
/** Resource ID */
|
|
39
|
+
id: string;
|
|
40
|
+
/** Identifier meta */
|
|
41
|
+
meta?: Record<string, unknown>;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* JSON:API Links Object
|
|
45
|
+
* @see https://jsonapi.org/format/#document-links
|
|
46
|
+
*/
|
|
47
|
+
export interface JsonApiLinks {
|
|
48
|
+
self?: string | JsonApiLink;
|
|
49
|
+
related?: string | JsonApiLink;
|
|
50
|
+
first?: string | JsonApiLink | null;
|
|
51
|
+
last?: string | JsonApiLink | null;
|
|
52
|
+
prev?: string | JsonApiLink | null;
|
|
53
|
+
next?: string | JsonApiLink | null;
|
|
54
|
+
[key: string]: string | JsonApiLink | null | undefined;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* JSON:API Link Object
|
|
58
|
+
* @see https://jsonapi.org/format/#document-links
|
|
59
|
+
*/
|
|
60
|
+
export interface JsonApiLink {
|
|
61
|
+
href: string;
|
|
62
|
+
rel?: string;
|
|
63
|
+
describedby?: string;
|
|
64
|
+
title?: string;
|
|
65
|
+
type?: string;
|
|
66
|
+
hreflang?: string | string[];
|
|
67
|
+
meta?: Record<string, unknown>;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* JSON:API Error Object
|
|
71
|
+
* @see https://jsonapi.org/format/#error-objects
|
|
72
|
+
*/
|
|
73
|
+
export interface JsonApiError {
|
|
74
|
+
/** Unique identifier for this error */
|
|
75
|
+
id?: string;
|
|
76
|
+
/** Links related to the error */
|
|
77
|
+
links?: {
|
|
78
|
+
about?: string | JsonApiLink;
|
|
79
|
+
type?: string | JsonApiLink;
|
|
80
|
+
};
|
|
81
|
+
/** HTTP status code */
|
|
82
|
+
status?: string;
|
|
83
|
+
/** Application-specific error code */
|
|
84
|
+
code?: string;
|
|
85
|
+
/** Short summary of the error */
|
|
86
|
+
title?: string;
|
|
87
|
+
/** Detailed explanation of the error */
|
|
88
|
+
detail?: string;
|
|
89
|
+
/** Source of the error */
|
|
90
|
+
source?: {
|
|
91
|
+
pointer?: string;
|
|
92
|
+
parameter?: string;
|
|
93
|
+
header?: string;
|
|
94
|
+
};
|
|
95
|
+
/** Error meta */
|
|
96
|
+
meta?: Record<string, unknown>;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* JSON:API Document
|
|
100
|
+
* @see https://jsonapi.org/format/#document-structure
|
|
101
|
+
*/
|
|
102
|
+
export interface JsonApiDocument<TAttributes = Record<string, unknown>> {
|
|
103
|
+
/** Primary data */
|
|
104
|
+
data?: JsonApiResource<TAttributes> | JsonApiResource<TAttributes>[] | null;
|
|
105
|
+
/** Included resources */
|
|
106
|
+
included?: JsonApiResource[];
|
|
107
|
+
/** Errors */
|
|
108
|
+
errors?: JsonApiError[];
|
|
109
|
+
/** Top-level meta */
|
|
110
|
+
meta?: JsonApiMeta;
|
|
111
|
+
/** Top-level links */
|
|
112
|
+
links?: JsonApiLinks;
|
|
113
|
+
/** JSON:API version info */
|
|
114
|
+
jsonapi?: {
|
|
115
|
+
version?: string;
|
|
116
|
+
ext?: string[];
|
|
117
|
+
profile?: string[];
|
|
118
|
+
meta?: Record<string, unknown>;
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* JSON:API Meta Object (commonly used for pagination)
|
|
123
|
+
*/
|
|
124
|
+
export interface JsonApiMeta {
|
|
125
|
+
/** Current page number */
|
|
126
|
+
current_page?: number;
|
|
127
|
+
/** Total number of pages */
|
|
128
|
+
total_pages?: number;
|
|
129
|
+
/** Total count of items */
|
|
130
|
+
total_count?: number;
|
|
131
|
+
/** Items per page */
|
|
132
|
+
per_page?: number;
|
|
133
|
+
/** Any additional meta fields */
|
|
134
|
+
[key: string]: unknown;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Type guard for single resource document
|
|
138
|
+
*/
|
|
139
|
+
export declare function isSingleResourceDocument<T>(doc: JsonApiDocument<T>): doc is JsonApiDocument<T> & {
|
|
140
|
+
data: JsonApiResource<T>;
|
|
141
|
+
};
|
|
142
|
+
/**
|
|
143
|
+
* Type guard for collection resource document
|
|
144
|
+
*/
|
|
145
|
+
export declare function isCollectionDocument<T>(doc: JsonApiDocument<T>): doc is JsonApiDocument<T> & {
|
|
146
|
+
data: JsonApiResource<T>[];
|
|
147
|
+
};
|
|
148
|
+
/**
|
|
149
|
+
* Type guard for error document
|
|
150
|
+
*/
|
|
151
|
+
export declare function isErrorDocument(doc: JsonApiDocument): doc is JsonApiDocument & {
|
|
152
|
+
errors: JsonApiError[];
|
|
153
|
+
};
|
|
154
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/lib/types.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@23blocks/jsonapi-codec",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.4",
|
|
4
4
|
"description": "JSON:API v1.0 codec for encoding/decoding API responses",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "23blocks <hello@23blocks.com>",
|
|
@@ -22,15 +22,15 @@
|
|
|
22
22
|
"parser"
|
|
23
23
|
],
|
|
24
24
|
"type": "module",
|
|
25
|
-
"main": "./dist/index.js",
|
|
26
|
-
"module": "./dist/index.js",
|
|
25
|
+
"main": "./dist/index.esm.js",
|
|
26
|
+
"module": "./dist/index.esm.js",
|
|
27
27
|
"types": "./dist/index.d.ts",
|
|
28
28
|
"exports": {
|
|
29
29
|
"./package.json": "./package.json",
|
|
30
30
|
".": {
|
|
31
31
|
"types": "./dist/index.d.ts",
|
|
32
|
-
"import": "./dist/index.js",
|
|
33
|
-
"default": "./dist/index.js"
|
|
32
|
+
"import": "./dist/index.esm.js",
|
|
33
|
+
"default": "./dist/index.esm.js"
|
|
34
34
|
}
|
|
35
35
|
},
|
|
36
36
|
"files": [
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"sourceRoot": "packages/jsonapi-codec/src",
|
|
42
42
|
"targets": {
|
|
43
43
|
"build": {
|
|
44
|
-
"executor": "@nx/
|
|
44
|
+
"executor": "@nx/rollup:rollup",
|
|
45
45
|
"outputs": [
|
|
46
46
|
"{options.outputPath}"
|
|
47
47
|
],
|
|
@@ -49,8 +49,10 @@
|
|
|
49
49
|
"outputPath": "packages/jsonapi-codec/dist",
|
|
50
50
|
"main": "packages/jsonapi-codec/src/index.ts",
|
|
51
51
|
"tsConfig": "packages/jsonapi-codec/tsconfig.lib.json",
|
|
52
|
-
"
|
|
53
|
-
"
|
|
52
|
+
"compiler": "swc",
|
|
53
|
+
"format": [
|
|
54
|
+
"esm"
|
|
55
|
+
]
|
|
54
56
|
}
|
|
55
57
|
}
|
|
56
58
|
}
|
package/dist/index.js
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
// JSON:API Types
|
|
2
|
-
export { isSingleResourceDocument, isCollectionDocument, isErrorDocument } from './lib/types.js';
|
|
3
|
-
// Resource Mapper
|
|
4
|
-
export { resourceKey, buildIncludedMap, getIncluded, resolveRelationship, resolveRelationshipMany } from './lib/mapper.js';
|
|
5
|
-
// Decoding
|
|
6
|
-
export { decodeOne, decodeOneOrNull, decodeMany, extractPageMeta, decodePageResult, decodeWith } from './lib/decode.js';
|
|
7
|
-
// Error Handling
|
|
8
|
-
export { jsonApiErrorToBlockError, jsonApiErrorsToBlockError, blockErrorFromJsonApi, throwIfError, assertNotError } from './lib/errors.js';
|
|
9
|
-
|
|
10
|
-
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["// JSON:API Types\nexport {\n type JsonApiResource,\n type JsonApiRelationship,\n type JsonApiResourceIdentifier,\n type JsonApiLinks,\n type JsonApiLink,\n type JsonApiError,\n type JsonApiDocument,\n type JsonApiMeta,\n isSingleResourceDocument,\n isCollectionDocument,\n isErrorDocument,\n} from './lib/types.js';\n\n// Resource Mapper\nexport {\n type IncludedMap,\n type ResourceMapper,\n resourceKey,\n buildIncludedMap,\n getIncluded,\n resolveRelationship,\n resolveRelationshipMany,\n} from './lib/mapper.js';\n\n// Decoding\nexport {\n decodeOne,\n decodeOneOrNull,\n decodeMany,\n extractPageMeta,\n decodePageResult,\n decodeWith,\n} from './lib/decode.js';\n\n// Error Handling\nexport {\n jsonApiErrorToBlockError,\n jsonApiErrorsToBlockError,\n blockErrorFromJsonApi,\n throwIfError,\n assertNotError,\n} from './lib/errors.js';\n"],"names":["isSingleResourceDocument","isCollectionDocument","isErrorDocument","resourceKey","buildIncludedMap","getIncluded","resolveRelationship","resolveRelationshipMany","decodeOne","decodeOneOrNull","decodeMany","extractPageMeta","decodePageResult","decodeWith","jsonApiErrorToBlockError","jsonApiErrorsToBlockError","blockErrorFromJsonApi","throwIfError","assertNotError"],"rangeMappings":";;;;;;;","mappings":"AAAA,iBAAiB;AACjB,SASEA,wBAAwB,EACxBC,oBAAoB,EACpBC,eAAe,QACV,iBAAiB;AAExB,kBAAkB;AAClB,SAGEC,WAAW,EACXC,gBAAgB,EAChBC,WAAW,EACXC,mBAAmB,EACnBC,uBAAuB,QAClB,kBAAkB;AAEzB,WAAW;AACX,SACEC,SAAS,EACTC,eAAe,EACfC,UAAU,EACVC,eAAe,EACfC,gBAAgB,EAChBC,UAAU,QACL,kBAAkB;AAEzB,iBAAiB;AACjB,SACEC,wBAAwB,EACxBC,yBAAyB,EACzBC,qBAAqB,EACrBC,YAAY,EACZC,cAAc,QACT,kBAAkB"}
|
package/dist/lib/decode.js
DELETED
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
import { isSingleResourceDocument, isCollectionDocument } from './types.js';
|
|
2
|
-
import { buildIncludedMap } from './mapper.js';
|
|
3
|
-
/**
|
|
4
|
-
* Decode a single resource from a JSON:API document
|
|
5
|
-
*/ export function decodeOne(document, mapper) {
|
|
6
|
-
if (!isSingleResourceDocument(document)) {
|
|
7
|
-
throw new Error('Expected single resource document');
|
|
8
|
-
}
|
|
9
|
-
const included = buildIncludedMap(document.included);
|
|
10
|
-
return mapper.map(document.data, included);
|
|
11
|
-
}
|
|
12
|
-
/**
|
|
13
|
-
* Decode a single resource from a JSON:API document, returning null if not found
|
|
14
|
-
*/ export function decodeOneOrNull(document, mapper) {
|
|
15
|
-
if (!document.data || Array.isArray(document.data)) {
|
|
16
|
-
return null;
|
|
17
|
-
}
|
|
18
|
-
const included = buildIncludedMap(document.included);
|
|
19
|
-
return mapper.map(document.data, included);
|
|
20
|
-
}
|
|
21
|
-
/**
|
|
22
|
-
* Decode multiple resources from a JSON:API document
|
|
23
|
-
*/ export function decodeMany(document, mapper) {
|
|
24
|
-
if (!isCollectionDocument(document)) {
|
|
25
|
-
throw new Error('Expected collection document');
|
|
26
|
-
}
|
|
27
|
-
const included = buildIncludedMap(document.included);
|
|
28
|
-
return document.data.map((resource)=>mapper.map(resource, included));
|
|
29
|
-
}
|
|
30
|
-
/**
|
|
31
|
-
* Extract pagination metadata from JSON:API meta
|
|
32
|
-
*/ export function extractPageMeta(meta) {
|
|
33
|
-
var _meta_current_page, _meta_total_pages, _meta_total_count, _meta_per_page;
|
|
34
|
-
return {
|
|
35
|
-
currentPage: (_meta_current_page = meta == null ? void 0 : meta.current_page) != null ? _meta_current_page : 1,
|
|
36
|
-
totalPages: (_meta_total_pages = meta == null ? void 0 : meta.total_pages) != null ? _meta_total_pages : 1,
|
|
37
|
-
totalCount: (_meta_total_count = meta == null ? void 0 : meta.total_count) != null ? _meta_total_count : 0,
|
|
38
|
-
perPage: (_meta_per_page = meta == null ? void 0 : meta.per_page) != null ? _meta_per_page : 0
|
|
39
|
-
};
|
|
40
|
-
}
|
|
41
|
-
/**
|
|
42
|
-
* Decode a paginated collection from a JSON:API document
|
|
43
|
-
*/ export function decodePageResult(document, mapper) {
|
|
44
|
-
const data = isCollectionDocument(document) ? decodeMany(document, mapper) : [];
|
|
45
|
-
return {
|
|
46
|
-
data,
|
|
47
|
-
meta: extractPageMeta(document.meta)
|
|
48
|
-
};
|
|
49
|
-
}
|
|
50
|
-
/**
|
|
51
|
-
* Decode with a custom decoder function
|
|
52
|
-
*/ export function decodeWith(document, decoder) {
|
|
53
|
-
const included = buildIncludedMap(document.included);
|
|
54
|
-
return decoder(document, included);
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
//# sourceMappingURL=decode.js.map
|
package/dist/lib/decode.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/lib/decode.ts"],"sourcesContent":["import type { PageResult, PageMeta } from '@23blocks/contracts';\nimport type { JsonApiDocument, JsonApiMeta } from './types.js';\nimport { isSingleResourceDocument, isCollectionDocument } from './types.js';\nimport type { ResourceMapper, IncludedMap } from './mapper.js';\nimport { buildIncludedMap } from './mapper.js';\n\n/**\n * Decode a single resource from a JSON:API document\n */\nexport function decodeOne<T>(\n document: JsonApiDocument,\n mapper: ResourceMapper<T>\n): T {\n if (!isSingleResourceDocument(document)) {\n throw new Error('Expected single resource document');\n }\n\n const included = buildIncludedMap(document.included);\n return mapper.map(document.data, included);\n}\n\n/**\n * Decode a single resource from a JSON:API document, returning null if not found\n */\nexport function decodeOneOrNull<T>(\n document: JsonApiDocument,\n mapper: ResourceMapper<T>\n): T | null {\n if (!document.data || Array.isArray(document.data)) {\n return null;\n }\n\n const included = buildIncludedMap(document.included);\n return mapper.map(document.data, included);\n}\n\n/**\n * Decode multiple resources from a JSON:API document\n */\nexport function decodeMany<T>(\n document: JsonApiDocument,\n mapper: ResourceMapper<T>\n): T[] {\n if (!isCollectionDocument(document)) {\n throw new Error('Expected collection document');\n }\n\n const included = buildIncludedMap(document.included);\n return document.data.map((resource) => mapper.map(resource, included));\n}\n\n/**\n * Extract pagination metadata from JSON:API meta\n */\nexport function extractPageMeta(meta?: JsonApiMeta): PageMeta {\n return {\n currentPage: meta?.current_page ?? 1,\n totalPages: meta?.total_pages ?? 1,\n totalCount: meta?.total_count ?? 0,\n perPage: meta?.per_page ?? 0,\n };\n}\n\n/**\n * Decode a paginated collection from a JSON:API document\n */\nexport function decodePageResult<T>(\n document: JsonApiDocument,\n mapper: ResourceMapper<T>\n): PageResult<T> {\n const data = isCollectionDocument(document)\n ? decodeMany(document, mapper)\n : [];\n\n return {\n data,\n meta: extractPageMeta(document.meta),\n };\n}\n\n/**\n * Decode with a custom decoder function\n */\nexport function decodeWith<T>(\n document: JsonApiDocument,\n decoder: (doc: JsonApiDocument, included: IncludedMap) => T\n): T {\n const included = buildIncludedMap(document.included);\n return decoder(document, included);\n}\n"],"names":["isSingleResourceDocument","isCollectionDocument","buildIncludedMap","decodeOne","document","mapper","Error","included","map","data","decodeOneOrNull","Array","isArray","decodeMany","resource","extractPageMeta","meta","currentPage","current_page","totalPages","total_pages","totalCount","total_count","perPage","per_page","decodePageResult","decodeWith","decoder"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"AAEA,SAASA,wBAAwB,EAAEC,oBAAoB,QAAQ,aAAa;AAE5E,SAASC,gBAAgB,QAAQ,cAAc;AAE/C;;CAEC,GACD,OAAO,SAASC,UACdC,QAAyB,EACzBC,MAAyB;IAEzB,IAAI,CAACL,yBAAyBI,WAAW;QACvC,MAAM,IAAIE,MAAM;IAClB;IAEA,MAAMC,WAAWL,iBAAiBE,SAASG,QAAQ;IACnD,OAAOF,OAAOG,GAAG,CAACJ,SAASK,IAAI,EAAEF;AACnC;AAEA;;CAEC,GACD,OAAO,SAASG,gBACdN,QAAyB,EACzBC,MAAyB;IAEzB,IAAI,CAACD,SAASK,IAAI,IAAIE,MAAMC,OAAO,CAACR,SAASK,IAAI,GAAG;QAClD,OAAO;IACT;IAEA,MAAMF,WAAWL,iBAAiBE,SAASG,QAAQ;IACnD,OAAOF,OAAOG,GAAG,CAACJ,SAASK,IAAI,EAAEF;AACnC;AAEA;;CAEC,GACD,OAAO,SAASM,WACdT,QAAyB,EACzBC,MAAyB;IAEzB,IAAI,CAACJ,qBAAqBG,WAAW;QACnC,MAAM,IAAIE,MAAM;IAClB;IAEA,MAAMC,WAAWL,iBAAiBE,SAASG,QAAQ;IACnD,OAAOH,SAASK,IAAI,CAACD,GAAG,CAAC,CAACM,WAAaT,OAAOG,GAAG,CAACM,UAAUP;AAC9D;AAEA;;CAEC,GACD,OAAO,SAASQ,gBAAgBC,IAAkB;QAEjCA,oBACDA,mBACAA,mBACHA;IAJX,OAAO;QACLC,aAAaD,CAAAA,qBAAAA,wBAAAA,KAAME,YAAY,YAAlBF,qBAAsB;QACnCG,YAAYH,CAAAA,oBAAAA,wBAAAA,KAAMI,WAAW,YAAjBJ,oBAAqB;QACjCK,YAAYL,CAAAA,oBAAAA,wBAAAA,KAAMM,WAAW,YAAjBN,oBAAqB;QACjCO,SAASP,CAAAA,iBAAAA,wBAAAA,KAAMQ,QAAQ,YAAdR,iBAAkB;IAC7B;AACF;AAEA;;CAEC,GACD,OAAO,SAASS,iBACdrB,QAAyB,EACzBC,MAAyB;IAEzB,MAAMI,OAAOR,qBAAqBG,YAC9BS,WAAWT,UAAUC,UACrB,EAAE;IAEN,OAAO;QACLI;QACAO,MAAMD,gBAAgBX,SAASY,IAAI;IACrC;AACF;AAEA;;CAEC,GACD,OAAO,SAASU,WACdtB,QAAyB,EACzBuB,OAA2D;IAE3D,MAAMpB,WAAWL,iBAAiBE,SAASG,QAAQ;IACnD,OAAOoB,QAAQvB,UAAUG;AAC3B"}
|
package/dist/lib/errors.js
DELETED
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
import { _ as _extends } from "@swc/helpers/_/_extends";
|
|
2
|
-
import { BlockErrorException } from '@23blocks/contracts';
|
|
3
|
-
import { isErrorDocument } from './types.js';
|
|
4
|
-
/**
|
|
5
|
-
* Convert a JSON:API error to a BlockError
|
|
6
|
-
*/ export function jsonApiErrorToBlockError(error) {
|
|
7
|
-
var _error_source, _error_source1;
|
|
8
|
-
var _error_code, _error_detail, _ref, _error_source_pointer;
|
|
9
|
-
return {
|
|
10
|
-
code: (_error_code = error.code) != null ? _error_code : 'unknown_error',
|
|
11
|
-
message: (_ref = (_error_detail = error.detail) != null ? _error_detail : error.title) != null ? _ref : 'An unknown error occurred',
|
|
12
|
-
status: error.status ? parseInt(error.status, 10) : 500,
|
|
13
|
-
source: (_error_source_pointer = (_error_source = error.source) == null ? void 0 : _error_source.pointer) != null ? _error_source_pointer : (_error_source1 = error.source) == null ? void 0 : _error_source1.parameter,
|
|
14
|
-
meta: error.meta
|
|
15
|
-
};
|
|
16
|
-
}
|
|
17
|
-
/**
|
|
18
|
-
* Convert multiple JSON:API errors to a single BlockError
|
|
19
|
-
* Uses the first error as the primary error, includes others in meta
|
|
20
|
-
*/ export function jsonApiErrorsToBlockError(errors) {
|
|
21
|
-
if (errors.length === 0) {
|
|
22
|
-
return {
|
|
23
|
-
code: 'unknown_error',
|
|
24
|
-
message: 'An unknown error occurred',
|
|
25
|
-
status: 500
|
|
26
|
-
};
|
|
27
|
-
}
|
|
28
|
-
const primary = jsonApiErrorToBlockError(errors[0]);
|
|
29
|
-
if (errors.length > 1) {
|
|
30
|
-
primary.meta = _extends({}, primary.meta, {
|
|
31
|
-
additionalErrors: errors.slice(1).map(jsonApiErrorToBlockError)
|
|
32
|
-
});
|
|
33
|
-
}
|
|
34
|
-
return primary;
|
|
35
|
-
}
|
|
36
|
-
/**
|
|
37
|
-
* Create a BlockErrorException from JSON:API errors
|
|
38
|
-
*/ export function blockErrorFromJsonApi(errors) {
|
|
39
|
-
return new BlockErrorException(jsonApiErrorsToBlockError(errors));
|
|
40
|
-
}
|
|
41
|
-
/**
|
|
42
|
-
* Check if a document is an error document and throw if so
|
|
43
|
-
*/ export function throwIfError(document) {
|
|
44
|
-
if (isErrorDocument(document)) {
|
|
45
|
-
throw blockErrorFromJsonApi(document.errors);
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
/**
|
|
49
|
-
* Assert that a document is not an error document
|
|
50
|
-
*/ export function assertNotError(document) {
|
|
51
|
-
throwIfError(document);
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
//# sourceMappingURL=errors.js.map
|
package/dist/lib/errors.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/lib/errors.ts"],"sourcesContent":["import { BlockErrorException, type BlockError } from '@23blocks/contracts';\nimport type { JsonApiDocument, JsonApiError } from './types.js';\nimport { isErrorDocument } from './types.js';\n\n/**\n * Convert a JSON:API error to a BlockError\n */\nexport function jsonApiErrorToBlockError(error: JsonApiError): BlockError {\n return {\n code: error.code ?? 'unknown_error',\n message: error.detail ?? error.title ?? 'An unknown error occurred',\n status: error.status ? parseInt(error.status, 10) : 500,\n source: error.source?.pointer ?? error.source?.parameter,\n meta: error.meta,\n };\n}\n\n/**\n * Convert multiple JSON:API errors to a single BlockError\n * Uses the first error as the primary error, includes others in meta\n */\nexport function jsonApiErrorsToBlockError(errors: JsonApiError[]): BlockError {\n if (errors.length === 0) {\n return {\n code: 'unknown_error',\n message: 'An unknown error occurred',\n status: 500,\n };\n }\n\n const primary = jsonApiErrorToBlockError(errors[0]);\n\n if (errors.length > 1) {\n primary.meta = {\n ...primary.meta,\n additionalErrors: errors.slice(1).map(jsonApiErrorToBlockError),\n };\n }\n\n return primary;\n}\n\n/**\n * Create a BlockErrorException from JSON:API errors\n */\nexport function blockErrorFromJsonApi(errors: JsonApiError[]): BlockErrorException {\n return new BlockErrorException(jsonApiErrorsToBlockError(errors));\n}\n\n/**\n * Check if a document is an error document and throw if so\n */\nexport function throwIfError(document: JsonApiDocument): void {\n if (isErrorDocument(document)) {\n throw blockErrorFromJsonApi(document.errors);\n }\n}\n\n/**\n * Assert that a document is not an error document\n */\nexport function assertNotError<T extends JsonApiDocument>(document: T): asserts document is T {\n throwIfError(document);\n}\n"],"names":["BlockErrorException","isErrorDocument","jsonApiErrorToBlockError","error","code","message","detail","title","status","parseInt","source","pointer","parameter","meta","jsonApiErrorsToBlockError","errors","length","primary","additionalErrors","slice","map","blockErrorFromJsonApi","throwIfError","document","assertNotError"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":";AAAA,SAASA,mBAAmB,QAAyB,sBAAsB;AAE3E,SAASC,eAAe,QAAQ,aAAa;AAE7C;;CAEC,GACD,OAAO,SAASC,yBAAyBC,KAAmB;QAKhDA,eAAyBA;QAH3BA,aACGA,eAAAA,MAEDA;IAJV,OAAO;QACLC,MAAMD,CAAAA,cAAAA,MAAMC,IAAI,YAAVD,cAAc;QACpBE,SAASF,CAAAA,OAAAA,CAAAA,gBAAAA,MAAMG,MAAM,YAAZH,gBAAgBA,MAAMI,KAAK,YAA3BJ,OAA+B;QACxCK,QAAQL,MAAMK,MAAM,GAAGC,SAASN,MAAMK,MAAM,EAAE,MAAM;QACpDE,QAAQP,CAAAA,yBAAAA,gBAAAA,MAAMO,MAAM,qBAAZP,cAAcQ,OAAO,YAArBR,yBAAyBA,iBAAAA,MAAMO,MAAM,qBAAZP,eAAcS,SAAS;QACxDC,MAAMV,MAAMU,IAAI;IAClB;AACF;AAEA;;;CAGC,GACD,OAAO,SAASC,0BAA0BC,MAAsB;IAC9D,IAAIA,OAAOC,MAAM,KAAK,GAAG;QACvB,OAAO;YACLZ,MAAM;YACNC,SAAS;YACTG,QAAQ;QACV;IACF;IAEA,MAAMS,UAAUf,yBAAyBa,MAAM,CAAC,EAAE;IAElD,IAAIA,OAAOC,MAAM,GAAG,GAAG;QACrBC,QAAQJ,IAAI,GAAG,aACVI,QAAQJ,IAAI;YACfK,kBAAkBH,OAAOI,KAAK,CAAC,GAAGC,GAAG,CAAClB;;IAE1C;IAEA,OAAOe;AACT;AAEA;;CAEC,GACD,OAAO,SAASI,sBAAsBN,MAAsB;IAC1D,OAAO,IAAIf,oBAAoBc,0BAA0BC;AAC3D;AAEA;;CAEC,GACD,OAAO,SAASO,aAAaC,QAAyB;IACpD,IAAItB,gBAAgBsB,WAAW;QAC7B,MAAMF,sBAAsBE,SAASR,MAAM;IAC7C;AACF;AAEA;;CAEC,GACD,OAAO,SAASS,eAA0CD,QAAW;IACnED,aAAaC;AACf"}
|
package/dist/lib/mapper.js
DELETED
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Create a key for the included map
|
|
3
|
-
*/ export function resourceKey(type, id) {
|
|
4
|
-
return `${type}:${id}`;
|
|
5
|
-
}
|
|
6
|
-
/**
|
|
7
|
-
* Build an included map from an array of resources
|
|
8
|
-
*/ export function buildIncludedMap(included = []) {
|
|
9
|
-
const map = new Map();
|
|
10
|
-
for (const resource of included){
|
|
11
|
-
map.set(resourceKey(resource.type, resource.id), resource);
|
|
12
|
-
}
|
|
13
|
-
return map;
|
|
14
|
-
}
|
|
15
|
-
/**
|
|
16
|
-
* Get a resource from the included map
|
|
17
|
-
*/ export function getIncluded(included, type, id) {
|
|
18
|
-
return included.get(resourceKey(type, id));
|
|
19
|
-
}
|
|
20
|
-
/**
|
|
21
|
-
* Resolve a relationship from included resources
|
|
22
|
-
*/ export function resolveRelationship(resource, relationshipName, included, mapper) {
|
|
23
|
-
var _resource_relationships;
|
|
24
|
-
const relationship = (_resource_relationships = resource.relationships) == null ? void 0 : _resource_relationships[relationshipName];
|
|
25
|
-
if (!(relationship == null ? void 0 : relationship.data)) {
|
|
26
|
-
return null;
|
|
27
|
-
}
|
|
28
|
-
const data = relationship.data;
|
|
29
|
-
if (Array.isArray(data)) {
|
|
30
|
-
throw new Error(`Expected single relationship for '${relationshipName}', got array. Use resolveRelationshipMany instead.`);
|
|
31
|
-
}
|
|
32
|
-
const related = getIncluded(included, data.type, data.id);
|
|
33
|
-
if (!related) {
|
|
34
|
-
return null;
|
|
35
|
-
}
|
|
36
|
-
return mapper.map(related, included);
|
|
37
|
-
}
|
|
38
|
-
/**
|
|
39
|
-
* Resolve a has-many relationship from included resources
|
|
40
|
-
*/ export function resolveRelationshipMany(resource, relationshipName, included, mapper) {
|
|
41
|
-
var _resource_relationships;
|
|
42
|
-
const relationship = (_resource_relationships = resource.relationships) == null ? void 0 : _resource_relationships[relationshipName];
|
|
43
|
-
if (!(relationship == null ? void 0 : relationship.data)) {
|
|
44
|
-
return [];
|
|
45
|
-
}
|
|
46
|
-
const data = relationship.data;
|
|
47
|
-
if (!Array.isArray(data)) {
|
|
48
|
-
throw new Error(`Expected array relationship for '${relationshipName}', got single. Use resolveRelationship instead.`);
|
|
49
|
-
}
|
|
50
|
-
return data.map((identifier)=>{
|
|
51
|
-
const related = getIncluded(included, identifier.type, identifier.id);
|
|
52
|
-
if (!related) {
|
|
53
|
-
return null;
|
|
54
|
-
}
|
|
55
|
-
return mapper.map(related, included);
|
|
56
|
-
}).filter((item)=>item !== null);
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
//# sourceMappingURL=mapper.js.map
|
package/dist/lib/mapper.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/lib/mapper.ts"],"sourcesContent":["import type { JsonApiResource } from './types.js';\n\n/**\n * Included resources map for efficient relationship resolution\n */\nexport type IncludedMap = Map<string, JsonApiResource>;\n\n/**\n * Resource mapper interface\n * Each block provides mappers for its resource types\n */\nexport interface ResourceMapper<T> {\n /** JSON:API resource type this mapper handles */\n type: string;\n\n /**\n * Map a JSON:API resource to a domain object\n * @param resource - The JSON:API resource to map\n * @param included - Map of included resources for relationship resolution\n */\n map(resource: JsonApiResource, included: IncludedMap): T;\n}\n\n/**\n * Create a key for the included map\n */\nexport function resourceKey(type: string, id: string): string {\n return `${type}:${id}`;\n}\n\n/**\n * Build an included map from an array of resources\n */\nexport function buildIncludedMap(included: JsonApiResource[] = []): IncludedMap {\n const map = new Map<string, JsonApiResource>();\n for (const resource of included) {\n map.set(resourceKey(resource.type, resource.id), resource);\n }\n return map;\n}\n\n/**\n * Get a resource from the included map\n */\nexport function getIncluded(\n included: IncludedMap,\n type: string,\n id: string\n): JsonApiResource | undefined {\n return included.get(resourceKey(type, id));\n}\n\n/**\n * Resolve a relationship from included resources\n */\nexport function resolveRelationship<T>(\n resource: JsonApiResource,\n relationshipName: string,\n included: IncludedMap,\n mapper: ResourceMapper<T>\n): T | null {\n const relationship = resource.relationships?.[relationshipName];\n if (!relationship?.data) {\n return null;\n }\n\n const data = relationship.data;\n if (Array.isArray(data)) {\n throw new Error(\n `Expected single relationship for '${relationshipName}', got array. Use resolveRelationshipMany instead.`\n );\n }\n\n const related = getIncluded(included, data.type, data.id);\n if (!related) {\n return null;\n }\n\n return mapper.map(related, included);\n}\n\n/**\n * Resolve a has-many relationship from included resources\n */\nexport function resolveRelationshipMany<T>(\n resource: JsonApiResource,\n relationshipName: string,\n included: IncludedMap,\n mapper: ResourceMapper<T>\n): T[] {\n const relationship = resource.relationships?.[relationshipName];\n if (!relationship?.data) {\n return [];\n }\n\n const data = relationship.data;\n if (!Array.isArray(data)) {\n throw new Error(\n `Expected array relationship for '${relationshipName}', got single. Use resolveRelationship instead.`\n );\n }\n\n return data\n .map((identifier) => {\n const related = getIncluded(included, identifier.type, identifier.id);\n if (!related) {\n return null;\n }\n return mapper.map(related, included);\n })\n .filter((item): item is T => item !== null);\n}\n"],"names":["resourceKey","type","id","buildIncludedMap","included","map","Map","resource","set","getIncluded","get","resolveRelationship","relationshipName","mapper","relationship","relationships","data","Array","isArray","Error","related","resolveRelationshipMany","identifier","filter","item"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"AAuBA;;CAEC,GACD,OAAO,SAASA,YAAYC,IAAY,EAAEC,EAAU;IAClD,OAAO,CAAC,EAAED,KAAK,CAAC,EAAEC,GAAG,CAAC;AACxB;AAEA;;CAEC,GACD,OAAO,SAASC,iBAAiBC,WAA8B,EAAE;IAC/D,MAAMC,MAAM,IAAIC;IAChB,KAAK,MAAMC,YAAYH,SAAU;QAC/BC,IAAIG,GAAG,CAACR,YAAYO,SAASN,IAAI,EAAEM,SAASL,EAAE,GAAGK;IACnD;IACA,OAAOF;AACT;AAEA;;CAEC,GACD,OAAO,SAASI,YACdL,QAAqB,EACrBH,IAAY,EACZC,EAAU;IAEV,OAAOE,SAASM,GAAG,CAACV,YAAYC,MAAMC;AACxC;AAEA;;CAEC,GACD,OAAO,SAASS,oBACdJ,QAAyB,EACzBK,gBAAwB,EACxBR,QAAqB,EACrBS,MAAyB;QAEJN;IAArB,MAAMO,gBAAeP,0BAAAA,SAASQ,aAAa,qBAAtBR,uBAAwB,CAACK,iBAAiB;IAC/D,IAAI,EAACE,gCAAAA,aAAcE,IAAI,GAAE;QACvB,OAAO;IACT;IAEA,MAAMA,OAAOF,aAAaE,IAAI;IAC9B,IAAIC,MAAMC,OAAO,CAACF,OAAO;QACvB,MAAM,IAAIG,MACR,CAAC,kCAAkC,EAAEP,iBAAiB,kDAAkD,CAAC;IAE7G;IAEA,MAAMQ,UAAUX,YAAYL,UAAUY,KAAKf,IAAI,EAAEe,KAAKd,EAAE;IACxD,IAAI,CAACkB,SAAS;QACZ,OAAO;IACT;IAEA,OAAOP,OAAOR,GAAG,CAACe,SAAShB;AAC7B;AAEA;;CAEC,GACD,OAAO,SAASiB,wBACdd,QAAyB,EACzBK,gBAAwB,EACxBR,QAAqB,EACrBS,MAAyB;QAEJN;IAArB,MAAMO,gBAAeP,0BAAAA,SAASQ,aAAa,qBAAtBR,uBAAwB,CAACK,iBAAiB;IAC/D,IAAI,EAACE,gCAAAA,aAAcE,IAAI,GAAE;QACvB,OAAO,EAAE;IACX;IAEA,MAAMA,OAAOF,aAAaE,IAAI;IAC9B,IAAI,CAACC,MAAMC,OAAO,CAACF,OAAO;QACxB,MAAM,IAAIG,MACR,CAAC,iCAAiC,EAAEP,iBAAiB,+CAA+C,CAAC;IAEzG;IAEA,OAAOI,KACJX,GAAG,CAAC,CAACiB;QACJ,MAAMF,UAAUX,YAAYL,UAAUkB,WAAWrB,IAAI,EAAEqB,WAAWpB,EAAE;QACpE,IAAI,CAACkB,SAAS;YACZ,OAAO;QACT;QACA,OAAOP,OAAOR,GAAG,CAACe,SAAShB;IAC7B,GACCmB,MAAM,CAAC,CAACC,OAAoBA,SAAS;AAC1C"}
|
package/dist/lib/types.js
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* JSON:API Resource Object
|
|
3
|
-
* @see https://jsonapi.org/format/#document-resource-objects
|
|
4
|
-
*/ /**
|
|
5
|
-
* Type guard for single resource document
|
|
6
|
-
*/ export function isSingleResourceDocument(doc) {
|
|
7
|
-
return doc.data !== null && doc.data !== undefined && !Array.isArray(doc.data);
|
|
8
|
-
}
|
|
9
|
-
/**
|
|
10
|
-
* Type guard for collection resource document
|
|
11
|
-
*/ export function isCollectionDocument(doc) {
|
|
12
|
-
return Array.isArray(doc.data);
|
|
13
|
-
}
|
|
14
|
-
/**
|
|
15
|
-
* Type guard for error document
|
|
16
|
-
*/ export function isErrorDocument(doc) {
|
|
17
|
-
return Array.isArray(doc.errors) && doc.errors.length > 0;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
//# sourceMappingURL=types.js.map
|
package/dist/lib/types.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/lib/types.ts"],"sourcesContent":["/**\n * JSON:API Resource Object\n * @see https://jsonapi.org/format/#document-resource-objects\n */\nexport interface JsonApiResource<TAttributes = Record<string, unknown>> {\n /** Resource type */\n type: string;\n /** Resource ID */\n id: string;\n /** Resource attributes */\n attributes?: TAttributes;\n /** Resource relationships */\n relationships?: Record<string, JsonApiRelationship>;\n /** Resource links */\n links?: JsonApiLinks;\n /** Resource meta */\n meta?: Record<string, unknown>;\n}\n\n/**\n * JSON:API Relationship Object\n * @see https://jsonapi.org/format/#document-resource-object-relationships\n */\nexport interface JsonApiRelationship {\n /** Relationship data */\n data: JsonApiResourceIdentifier | JsonApiResourceIdentifier[] | null;\n /** Relationship links */\n links?: JsonApiLinks;\n /** Relationship meta */\n meta?: Record<string, unknown>;\n}\n\n/**\n * JSON:API Resource Identifier Object\n * @see https://jsonapi.org/format/#document-resource-identifier-objects\n */\nexport interface JsonApiResourceIdentifier {\n /** Resource type */\n type: string;\n /** Resource ID */\n id: string;\n /** Identifier meta */\n meta?: Record<string, unknown>;\n}\n\n/**\n * JSON:API Links Object\n * @see https://jsonapi.org/format/#document-links\n */\nexport interface JsonApiLinks {\n self?: string | JsonApiLink;\n related?: string | JsonApiLink;\n first?: string | JsonApiLink | null;\n last?: string | JsonApiLink | null;\n prev?: string | JsonApiLink | null;\n next?: string | JsonApiLink | null;\n [key: string]: string | JsonApiLink | null | undefined;\n}\n\n/**\n * JSON:API Link Object\n * @see https://jsonapi.org/format/#document-links\n */\nexport interface JsonApiLink {\n href: string;\n rel?: string;\n describedby?: string;\n title?: string;\n type?: string;\n hreflang?: string | string[];\n meta?: Record<string, unknown>;\n}\n\n/**\n * JSON:API Error Object\n * @see https://jsonapi.org/format/#error-objects\n */\nexport interface JsonApiError {\n /** Unique identifier for this error */\n id?: string;\n /** Links related to the error */\n links?: {\n about?: string | JsonApiLink;\n type?: string | JsonApiLink;\n };\n /** HTTP status code */\n status?: string;\n /** Application-specific error code */\n code?: string;\n /** Short summary of the error */\n title?: string;\n /** Detailed explanation of the error */\n detail?: string;\n /** Source of the error */\n source?: {\n pointer?: string;\n parameter?: string;\n header?: string;\n };\n /** Error meta */\n meta?: Record<string, unknown>;\n}\n\n/**\n * JSON:API Document\n * @see https://jsonapi.org/format/#document-structure\n */\nexport interface JsonApiDocument<TAttributes = Record<string, unknown>> {\n /** Primary data */\n data?: JsonApiResource<TAttributes> | JsonApiResource<TAttributes>[] | null;\n /** Included resources */\n included?: JsonApiResource[];\n /** Errors */\n errors?: JsonApiError[];\n /** Top-level meta */\n meta?: JsonApiMeta;\n /** Top-level links */\n links?: JsonApiLinks;\n /** JSON:API version info */\n jsonapi?: {\n version?: string;\n ext?: string[];\n profile?: string[];\n meta?: Record<string, unknown>;\n };\n}\n\n/**\n * JSON:API Meta Object (commonly used for pagination)\n */\nexport interface JsonApiMeta {\n /** Current page number */\n current_page?: number;\n /** Total number of pages */\n total_pages?: number;\n /** Total count of items */\n total_count?: number;\n /** Items per page */\n per_page?: number;\n /** Any additional meta fields */\n [key: string]: unknown;\n}\n\n/**\n * Type guard for single resource document\n */\nexport function isSingleResourceDocument<T>(\n doc: JsonApiDocument<T>\n): doc is JsonApiDocument<T> & { data: JsonApiResource<T> } {\n return doc.data !== null && doc.data !== undefined && !Array.isArray(doc.data);\n}\n\n/**\n * Type guard for collection resource document\n */\nexport function isCollectionDocument<T>(\n doc: JsonApiDocument<T>\n): doc is JsonApiDocument<T> & { data: JsonApiResource<T>[] } {\n return Array.isArray(doc.data);\n}\n\n/**\n * Type guard for error document\n */\nexport function isErrorDocument(\n doc: JsonApiDocument\n): doc is JsonApiDocument & { errors: JsonApiError[] } {\n return Array.isArray(doc.errors) && doc.errors.length > 0;\n}\n"],"names":["isSingleResourceDocument","doc","data","undefined","Array","isArray","isCollectionDocument","isErrorDocument","errors","length"],"rangeMappings":";;;;;;;;;;;;;;;;;","mappings":"AAAA;;;CAGC,GA4ID;;CAEC,GACD,OAAO,SAASA,yBACdC,GAAuB;IAEvB,OAAOA,IAAIC,IAAI,KAAK,QAAQD,IAAIC,IAAI,KAAKC,aAAa,CAACC,MAAMC,OAAO,CAACJ,IAAIC,IAAI;AAC/E;AAEA;;CAEC,GACD,OAAO,SAASI,qBACdL,GAAuB;IAEvB,OAAOG,MAAMC,OAAO,CAACJ,IAAIC,IAAI;AAC/B;AAEA;;CAEC,GACD,OAAO,SAASK,gBACdN,GAAoB;IAEpB,OAAOG,MAAMC,OAAO,CAACJ,IAAIO,MAAM,KAAKP,IAAIO,MAAM,CAACC,MAAM,GAAG;AAC1D"}
|