@tryghost/jsonapi-mapper 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/LICENSE +25 -0
  2. package/README.md +103 -0
  3. package/cjs/bookshelf/extras.js +30 -0
  4. package/cjs/bookshelf/index.js +74 -0
  5. package/cjs/bookshelf/links.js +112 -0
  6. package/cjs/bookshelf/utils.js +168 -0
  7. package/cjs/index.js +20 -0
  8. package/cjs/interfaces/common.js +16 -0
  9. package/cjs/interfaces/index.js +20 -0
  10. package/cjs/interfaces/links.js +16 -0
  11. package/cjs/interfaces/relations.js +16 -0
  12. package/cjs/serializer/index.js +35 -0
  13. package/cjs/serializer/jsonapi-serializer.skel.d.js +1 -0
  14. package/es/bookshelf/extras.js +10 -0
  15. package/es/bookshelf/index.js +55 -0
  16. package/es/bookshelf/links.js +92 -0
  17. package/es/bookshelf/utils.js +171 -0
  18. package/es/index.js +3 -0
  19. package/es/interfaces/common.js +0 -0
  20. package/es/interfaces/index.js +3 -0
  21. package/es/interfaces/links.js +0 -0
  22. package/es/interfaces/relations.js +0 -0
  23. package/es/serializer/index.js +5 -0
  24. package/es/serializer/jsonapi-serializer.skel.d.js +0 -0
  25. package/package.json +88 -0
  26. package/src/bookshelf/extras.ts +77 -0
  27. package/src/bookshelf/index.ts +64 -0
  28. package/src/bookshelf/links.ts +139 -0
  29. package/src/bookshelf/utils.ts +279 -0
  30. package/src/index.ts +3 -0
  31. package/src/interfaces/common.ts +38 -0
  32. package/src/interfaces/index.ts +3 -0
  33. package/src/interfaces/links.ts +26 -0
  34. package/src/interfaces/relations.ts +24 -0
  35. package/src/serializer/index.ts +50 -0
  36. package/src/serializer/jsonapi-serializer.skel.d.ts +4 -0
  37. package/types/bookshelf/extras.d.ts +52 -0
  38. package/types/bookshelf/extras.d.ts.map +1 -0
  39. package/types/bookshelf/index.d.ts +22 -0
  40. package/types/bookshelf/index.d.ts.map +1 -0
  41. package/types/bookshelf/links.d.ts +19 -0
  42. package/types/bookshelf/links.d.ts.map +1 -0
  43. package/types/bookshelf/utils.d.ts +26 -0
  44. package/types/bookshelf/utils.d.ts.map +1 -0
  45. package/types/index.d.ts +4 -0
  46. package/types/index.d.ts.map +1 -0
  47. package/types/interfaces/common.d.ts +24 -0
  48. package/types/interfaces/common.d.ts.map +1 -0
  49. package/types/interfaces/index.d.ts +4 -0
  50. package/types/interfaces/index.d.ts.map +1 -0
  51. package/types/interfaces/links.d.ts +25 -0
  52. package/types/interfaces/links.d.ts.map +1 -0
  53. package/types/interfaces/relations.d.ts +22 -0
  54. package/types/interfaces/relations.d.ts.map +1 -0
  55. package/types/serializer/index.d.ts +34 -0
  56. package/types/serializer/index.d.ts.map +1 -0
@@ -0,0 +1,139 @@
1
+ import { assign, omit, isEmpty, isNil } from 'lodash';
2
+ import { pluralize as plural } from 'inflection';
3
+ import { stringify as queryParams } from 'qs';
4
+
5
+ import { Model } from './extras';
6
+ import { LinkOpts, PagOpts, QueryOpts } from '../interfaces';
7
+ import { LinkObj } from '../serializer';
8
+
9
+ function urlConcat(...parts: string[]): string {
10
+ return parts.join('/');
11
+ }
12
+
13
+ /**
14
+ * Creates top level links object, for primary data and pagination links.
15
+ */
16
+ export function topLinks(linkOpts: LinkOpts): LinkObj {
17
+ let { baseUrl, type, pag }: LinkOpts = linkOpts;
18
+
19
+ let obj: LinkObj = {
20
+ self: urlConcat(baseUrl, plural(type))
21
+ };
22
+
23
+ // Build pagination if available
24
+ if (!isNil(pag)) {
25
+
26
+ // Support Bookshelf's built-in paging parameters
27
+ if (!isNil(pag.rowCount)) {
28
+ pag.total = pag.rowCount;
29
+ }
30
+
31
+ // Only add pagination links when more than 1 page
32
+ if (!isNil(pag.total) && pag.total > 0 && pag.total > pag.limit) {
33
+ assign(obj, pagLinks(linkOpts));
34
+ }
35
+ }
36
+
37
+ return obj;
38
+ }
39
+
40
+ /**
41
+ * Create links object, for pagination links.
42
+ * Since its used only inside other functions in this model, its not exported
43
+ */
44
+ function pagLinks(linkOpts: LinkOpts): LinkObj | undefined {
45
+ let { baseUrl, type, pag, query = {} }: LinkOpts = linkOpts;
46
+
47
+ if (pag === undefined) {
48
+ return undefined;
49
+ }
50
+
51
+ const { offset, limit, total}: PagOpts = pag;
52
+ // All links are based on the resource type
53
+ let baseLink: string = urlConcat(baseUrl, plural(type));
54
+
55
+ // Stringify the query string without page element
56
+ query = omit(query, ['page', 'page[limit]', 'page[offset]']) as QueryOpts;
57
+ baseLink = baseLink + '?' + queryParams(query, {encode: false});
58
+
59
+ let obj: LinkObj = {} as LinkObj;
60
+
61
+ // Add leading pag links if not at the first page
62
+ if (offset > 0) {
63
+ obj.first = () => {
64
+ let page: any = {page: {limit, offset: 0}};
65
+ return baseLink + queryParams(page, {encode: false});
66
+ };
67
+
68
+ obj.prev = () => {
69
+ let page: any = {page: {limit, offset: offset - limit}};
70
+ return baseLink + queryParams(page, {encode: false});
71
+ };
72
+ }
73
+
74
+ // Add trailing pag links if not at the last page
75
+ if (total && (offset + limit < total)) {
76
+ obj.next = () => {
77
+ let page: any = {page: {limit, offset: offset + limit}};
78
+ return baseLink + queryParams(page, {encode: false});
79
+ };
80
+
81
+ obj.last = () => {
82
+ // Avoiding overlapping with the penultimate page
83
+ let lastLimit: number = (total - (offset % limit)) % limit;
84
+ // If the limit fits perfectly in the total, reset it to the original
85
+ lastLimit = lastLimit === 0 ? limit : lastLimit;
86
+
87
+ let lastOffset: number = total - lastLimit;
88
+ let page: any = {page: {limit: lastLimit, offset: lastOffset }};
89
+ return baseLink + queryParams(page, {encode: false});
90
+ };
91
+ }
92
+
93
+ return !isEmpty(obj) ? obj : undefined;
94
+ }
95
+
96
+ /**
97
+ * Creates links object for a resource
98
+ */
99
+ export function dataLinks(linkOpts: LinkOpts): LinkObj {
100
+ let { baseUrl, type }: LinkOpts = linkOpts;
101
+ let baseLink: string = urlConcat(baseUrl, plural(type));
102
+
103
+ return {
104
+ self: function(resource: Model): string {
105
+ return urlConcat(baseLink, resource.id);
106
+ }
107
+ };
108
+ }
109
+
110
+ /**
111
+ * Creates links object for a relationship
112
+ */
113
+ export function relationshipLinks(linkOpts: LinkOpts, related: string): LinkObj {
114
+ let { baseUrl, type }: LinkOpts = linkOpts;
115
+ let baseLink: string = urlConcat(baseUrl, plural(type));
116
+
117
+ return {
118
+ self: function(resource: any, current: any, parent: Model): string {
119
+ return urlConcat(baseLink, parent.id, 'relationships', related);
120
+ },
121
+ related: function(resource: any, current: any, parent: Model): string {
122
+ return urlConcat(baseLink, parent.id, related);
123
+ }
124
+ };
125
+ }
126
+
127
+ /**
128
+ * Creates links object for a related resource, to be used for the included's array
129
+ */
130
+ export function includedLinks(linkOpts: LinkOpts): LinkObj {
131
+ let { baseUrl, type }: LinkOpts = linkOpts;
132
+ let baseLink: string = urlConcat(baseUrl, plural(type));
133
+
134
+ return {
135
+ self: function(primary: Model, current: Model): string {
136
+ return urlConcat(baseLink, current.id);
137
+ }
138
+ };
139
+ }
@@ -0,0 +1,279 @@
1
+ /**
2
+ * The main purpose of this module is to provide utility functions
3
+ * that follows the restrictions of the Bookshelf/Mapper/Serializer APIs
4
+ * with the goal of simplifying the logic of the main 'map' method.
5
+ */
6
+
7
+ import {
8
+ assign,
9
+ clone,
10
+ cloneDeep,
11
+ filter,
12
+ includes,
13
+ intersection,
14
+ isArray,
15
+ isNil,
16
+ isString,
17
+ isUndefined,
18
+ escapeRegExp,
19
+ forOwn,
20
+ has,
21
+ keys,
22
+ map,
23
+ mapValues,
24
+ merge,
25
+ omit,
26
+ reduce,
27
+ some,
28
+ toString,
29
+ update
30
+ } from 'lodash';
31
+
32
+ import { LinkOpts, RelationOpts } from '../interfaces';
33
+ import { SerialOpts } from '../serializer';
34
+ import { AttrMatcher, AttributesOpt } from '../interfaces';
35
+ import { topLinks, dataLinks, relationshipLinks, includedLinks } from './links';
36
+ import { BookOpts, Data, Model, isModel, isCollection } from './extras';
37
+
38
+ /**
39
+ * Main structure used through most utility and recursive functions
40
+ */
41
+ export interface Information {
42
+ bookOpts: BookOpts;
43
+ linkOpts: LinkOpts;
44
+ }
45
+
46
+ /**
47
+ * Start the data processing with top level information,
48
+ * then handle resources recursively in processSample
49
+ */
50
+ export function processData(info: Information, data: Data): SerialOpts {
51
+ let { bookOpts: { enableLinks }, linkOpts }: Information = info;
52
+
53
+ let template: SerialOpts = processSample(info, sample(data));
54
+
55
+ if (enableLinks) {
56
+ template.dataLinks = dataLinks(linkOpts);
57
+ template.topLevelLinks = topLinks(linkOpts);
58
+ }
59
+
60
+ return template;
61
+ }
62
+
63
+ /**
64
+ * Recursively adds data-related properties to the
65
+ * template to be sent to the serializer
66
+ */
67
+ function processSample(info: Information, sample: Sample): SerialOpts {
68
+ let { bookOpts, linkOpts }: Information = info;
69
+ let { enableLinks }: BookOpts = bookOpts;
70
+
71
+ let template: SerialOpts = {
72
+ // Add list of valid attributes
73
+ attributes: getAttrsList(sample, bookOpts)
74
+ };
75
+
76
+ // Nested relations (recursive) template generation
77
+ forOwn(sample.relations, (relSample: Sample, relName: string): void => {
78
+ if (!relationAllowed(bookOpts, relName)) { return; }
79
+
80
+ let relLinkOpts: LinkOpts = assign(clone(linkOpts), {type: relName});
81
+ let relTemplate: SerialOpts = processSample({bookOpts, linkOpts: relLinkOpts}, relSample);
82
+ relTemplate.ref = 'id'; // Add reference in nested resources
83
+
84
+ // Related links
85
+ if (enableLinks) {
86
+ relTemplate.relationshipLinks = relationshipLinks(linkOpts, relName);
87
+ relTemplate.includedLinks = includedLinks(relLinkOpts);
88
+ }
89
+
90
+ // Include links as compound document
91
+ if (!includeAllowed(bookOpts, relName)) {
92
+ relTemplate.included = false;
93
+ }
94
+
95
+ template[relName] = relTemplate;
96
+ (template.attributes as string[]).push(relName);
97
+ });
98
+
99
+ return template;
100
+ }
101
+
102
+ /**
103
+ * Representation of a sample, a model with only models in the relations,
104
+ * no collections
105
+ */
106
+ interface Sample extends Model {
107
+ relations: {
108
+ [relationName: string]: Sample
109
+ };
110
+ }
111
+
112
+ /**
113
+ * Convert any data into a model representing
114
+ * a complete sample to be used in the template generation
115
+ */
116
+ function sample(data: Data): Sample {
117
+ if (isModel(data)) {
118
+ // Override type because we will overwrite relations
119
+ const sampled: Sample = cloneDeep(omit(data, 'relations')) as Sample;
120
+ sampled.relations = mapValues(data.relations, sample);
121
+
122
+ return sampled;
123
+ } else if (isCollection(data)) {
124
+ const first: Model = data.first();
125
+ const rest: Model[] = (<Model[]><unknown> data).slice(1);
126
+ return reduce(rest, mergeSample, sample(first));
127
+ } else {
128
+ return {} as Sample;
129
+ }
130
+ }
131
+
132
+ /**
133
+ * Merge two models into a representation of both
134
+ */
135
+ function mergeSample(main: Sample, toMerge: Model): Sample {
136
+ const sampled: Sample = sample(toMerge);
137
+ main.attributes = merge(main.attributes, sampled.attributes);
138
+ main.relations = merge(main.relations, sampled.relations);
139
+ return main;
140
+ }
141
+
142
+ function matches(matcher: AttrMatcher, str: string): boolean {
143
+ let reg: RegExp;
144
+
145
+ if (typeof matcher === 'string') {
146
+ reg = RegExp(`^${escapeRegExp(matcher)}$`);
147
+ } else {
148
+ reg = matcher;
149
+ }
150
+
151
+ return reg.test(str);
152
+ }
153
+ /**
154
+ * Retrieve model's attribute names
155
+ * following filtering rules
156
+ */
157
+ function getAttrsList(data: Model, bookOpts: BookOpts): string[] {
158
+ let idAttr: undefined | string | string[] = data.idAttribute;
159
+ if (isString(idAttr)) {
160
+ idAttr = [ idAttr ];
161
+ } else if (isUndefined(idAttr)) {
162
+ idAttr = [];
163
+ }
164
+
165
+ let attrs: string[] = keys(data.attributes);
166
+ let outputVirtuals = data.outputVirtuals;
167
+
168
+ if (!isNil(bookOpts.outputVirtuals)) {
169
+ outputVirtuals = bookOpts.outputVirtuals
170
+ }
171
+
172
+ if (data.virtuals && outputVirtuals) {
173
+ attrs = attrs.concat(keys(data.virtuals))
174
+ }
175
+
176
+ let { attributes = { omit: idAttr } }: BookOpts = bookOpts;
177
+
178
+ // cast it to the object version of the option
179
+ if (attributes instanceof Array) {
180
+ attributes = { include : attributes };
181
+ }
182
+ let { omit, include }: AttributesOpt = attributes;
183
+
184
+ return filter(attrs, (attr: string) => {
185
+ let included: boolean = true;
186
+ let omitted: boolean = false;
187
+
188
+ if (include) {
189
+ included = some(include, (m: AttrMatcher) => matches(m, attr));
190
+ }
191
+
192
+ if (omit) {
193
+ omitted = some(omit, (m: AttrMatcher) => matches(m, attr));
194
+ }
195
+
196
+ // `omit` has more precedence than `include` option
197
+ return ! omitted && included;
198
+ });
199
+ }
200
+
201
+ /**
202
+ * Based on Bookshelf options, determine if a relation must be included
203
+ */
204
+ function relationAllowed(bookOpts: BookOpts, relName: string): boolean {
205
+ let { relations }: BookOpts = bookOpts;
206
+
207
+ if (typeof relations === 'boolean') {
208
+ return relations;
209
+ } else {
210
+ let { fields }: RelationOpts = relations;
211
+ return ! fields || includes(fields, relName);
212
+ }
213
+ }
214
+
215
+ /**
216
+ * Based on Bookshelf options, determine if a relation must be included
217
+ */
218
+ function includeAllowed(bookOpts: BookOpts, relName: string): boolean {
219
+ let { relations }: BookOpts = bookOpts;
220
+
221
+ if (typeof relations === 'boolean') {
222
+ return relations;
223
+ } else {
224
+ let { fields, included }: RelationOpts = relations;
225
+
226
+ if (typeof included === 'boolean') {
227
+ return included;
228
+ } else {
229
+ // If included is an array, only allow relations that are in that array
230
+ let allowed: string[] = included;
231
+
232
+ if (fields) {
233
+ // If fields specified, ensure that the included relations
234
+ // are listed as one of the relations to be serialized
235
+ allowed = intersection(fields, included);
236
+ }
237
+
238
+ return includes(allowed, relName);
239
+ }
240
+ }
241
+ }
242
+
243
+ /**
244
+ * Convert a bookshelf model or collection to
245
+ * json adding the id attribute if missing
246
+ */
247
+ export function toJSON(data: Data): any {
248
+
249
+ let json: any = null;
250
+
251
+ if (isModel(data)) {
252
+ json = data.toJSON({shallow: true}); // serialize without the relations
253
+
254
+ // When idAttribute is a composite id, calling .id returns `undefined`
255
+ const idAttr: undefined | string | string[] = data.idAttribute;
256
+ if (isArray(idAttr)) {
257
+ // the id will be the values in order separated by comma
258
+ data.id = map(idAttr, (attr: string) => data.attributes[attr]).join(',');
259
+ }
260
+
261
+ // Assign the id for the model if it's not present already
262
+ if (! has(json, 'id')) {
263
+ json.id = data.id;
264
+ }
265
+
266
+ update(json, 'id', toString);
267
+
268
+ // Loop over model relations to call toJSON recursively on them
269
+ forOwn(data.relations, function (relData: Data, relName: string): void {
270
+ json[relName] = toJSON(relData);
271
+ });
272
+
273
+ } else if (isCollection(data)) {
274
+ // Run a recursive toJSON on each model of the collection
275
+ json = data.map(toJSON);
276
+ }
277
+
278
+ return json;
279
+ }
package/src/index.ts ADDED
@@ -0,0 +1,3 @@
1
+ export * from './bookshelf';
2
+ export * from './interfaces';
3
+ export * from './serializer';
@@ -0,0 +1,38 @@
1
+ import { PagOpts, QueryOpts } from './links';
2
+ import { RelationTypeOpt, RelationOpts } from './relations';
3
+
4
+ //// GENERAL INTERFACES FOR MAPPERS
5
+
6
+ // Mapper
7
+ export interface Mapper {
8
+ map(data: any, type: string, mapOpts?: MapOpts): any;
9
+ }
10
+
11
+ export type AttrMatcher = RegExp | string;
12
+
13
+ export type AttributesOpt = {
14
+ omit?: AttrMatcher[],
15
+ include?: AttrMatcher[]
16
+ };
17
+
18
+ // Mapper Options
19
+ export interface MapOpts {
20
+ // Attributes-related
21
+ attributes?: AttrMatcher[] | AttributesOpt;
22
+ keyForAttr?: (attr: string) => string;
23
+
24
+ // Relations-related
25
+ relations?: boolean | RelationOpts;
26
+ typeForModel?: RelationTypeOpt;
27
+
28
+ // Links-related
29
+ enableLinks?: boolean;
30
+ pagination?: PagOpts;
31
+ query?: QueryOpts;
32
+
33
+ // Meta-related
34
+ meta?: { [key:string]: any };
35
+
36
+ // Virtuals-related
37
+ outputVirtuals?: boolean;
38
+ }
@@ -0,0 +1,3 @@
1
+ export * from './common';
2
+ export * from './links';
3
+ export * from './relations';
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Query Parameters map
3
+ */
4
+ export interface QueryOpts {
5
+ [key: string]: string;
6
+ }
7
+
8
+ /**
9
+ * Pagination variables
10
+ */
11
+ export interface PagOpts {
12
+ offset: number;
13
+ limit: number;
14
+ total?: number;
15
+ rowCount?: number;
16
+ }
17
+
18
+ /**
19
+ * Data required to form links
20
+ */
21
+ export interface LinkOpts {
22
+ baseUrl: string;
23
+ type: string;
24
+ pag?: PagOpts;
25
+ query?: QueryOpts;
26
+ }
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Map to specify type for the passed relations
3
+ */
4
+ export interface RelationTypeMap {
5
+ [relationName: string]: string;
6
+ }
7
+
8
+ /**
9
+ * Function to pass directly as the typeForAttributes option to the serializer
10
+ */
11
+ export type RelationTypeFunction = (attribute: string) => string;
12
+
13
+ /**
14
+ * The relationTypes option can be a function or an object
15
+ */
16
+ export type RelationTypeOpt = RelationTypeMap | RelationTypeFunction;
17
+
18
+ /**
19
+ * Relationship options
20
+ */
21
+ export interface RelationOpts {
22
+ included: boolean | string[];
23
+ fields?: string[];
24
+ }
@@ -0,0 +1,50 @@
1
+ import * as jas from 'jsonapi-serializer';
2
+
3
+ export type LinkFunc = (primary: any, related?: any, parent?: any) => string;
4
+
5
+ export type Link = string | LinkFunc;
6
+
7
+ export interface LinkObj {
8
+ self?: Link;
9
+ related?: Link;
10
+
11
+ first?: Link;
12
+ last?: Link;
13
+
14
+ prev?: Link;
15
+ next?: Link;
16
+ }
17
+
18
+ export interface SerialOpts {
19
+ attributes?: string[];
20
+ ref?: string;
21
+ included?: boolean;
22
+
23
+ topLevelLinks?: LinkObj;
24
+ dataLinks?: LinkObj;
25
+ relationshipLinks?: LinkObj;
26
+ includedLinks?: LinkObj;
27
+
28
+ relationshipMeta?: any;
29
+ ignoreRelationshipData?: boolean;
30
+
31
+ keyForAttribute?: (attribute: any) => string;
32
+ typeForAttribute?: (attribute: any) => any;
33
+ pluralizeType?: boolean;
34
+
35
+ meta?: any;
36
+
37
+ // TODO improve type-checking of relationship options
38
+ [relationships: string]: any;
39
+ }
40
+
41
+ export interface SerializerCtor {
42
+ new(type: string, opts: SerialOpts): Serializer;
43
+ }
44
+
45
+ export interface Serializer {
46
+ serialize(data: any): any;
47
+ }
48
+
49
+ // tslint:disable-next-line variable-name
50
+ export let Serializer: SerializerCtor = jas.Serializer;
@@ -0,0 +1,4 @@
1
+ declare module 'jsonapi-serializer' {
2
+ const content: any;
3
+ export = content;
4
+ }
@@ -0,0 +1,52 @@
1
+ /**
2
+ * The purpose of this module is to extend the initially defined properties,
3
+ * behaviors and characteristics of the bookshelf API
4
+ */
5
+ import { Model as BModel, Collection as BCollection } from 'bookshelf';
6
+ import { MapOpts, RelationTypeOpt, RelationOpts } from '../interfaces';
7
+ export interface BookOpts extends MapOpts {
8
+ keyForAttr: (attr: string) => string;
9
+ relations: boolean | RelationOpts;
10
+ typeForModel: RelationTypeOpt;
11
+ enableLinks: boolean;
12
+ outputVirtuals?: boolean;
13
+ }
14
+ /**
15
+ * Internal form of the relations property of bookshelf objects
16
+ */
17
+ export interface RelationsObject {
18
+ [relationName: string]: Data;
19
+ }
20
+ export interface Attributes {
21
+ [attrName: string]: any;
22
+ }
23
+ /**
24
+ * Bookshelf Model including some private properties
25
+ */
26
+ export interface Model extends BModel<any> {
27
+ id: any;
28
+ idAttribute: any;
29
+ attributes: Attributes;
30
+ relations: RelationsObject;
31
+ virtuals?: any;
32
+ outputVirtuals?: boolean;
33
+ }
34
+ /**
35
+ * Bookshelf Collection including some private properties
36
+ */
37
+ export interface Collection extends BCollection<any> {
38
+ models: Model[];
39
+ length: number;
40
+ }
41
+ export type Data = Model | Collection;
42
+ /**
43
+ * Bookshelf Model Type Guard
44
+ * https://basarat.gitbooks.io/typescript/content/docs/types/typeGuard.html
45
+ */
46
+ export declare function isModel(data: Data): data is Model;
47
+ /**
48
+ * Bookshelf Collection Type Guard
49
+ * https://basarat.gitbooks.io/typescript/content/docs/types/typeGuard.html
50
+ */
51
+ export declare function isCollection(data: Data): data is Collection;
52
+ //# sourceMappingURL=extras.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extras.d.ts","sourceRoot":"","sources":["../../src/bookshelf/extras.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,KAAK,IAAI,MAAM,EAAE,UAAU,IAAI,WAAW,EAAE,MAAM,WAAW,CAAC;AACvE,OAAO,EAAE,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAGvE,MAAM,WAAW,QAAS,SAAQ,OAAO;IAEvC,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;IAGrC,SAAS,EAAE,OAAO,GAAG,YAAY,CAAC;IAClC,YAAY,EAAE,eAAe,CAAC;IAG9B,WAAW,EAAE,OAAO,CAAC;IAGrB,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B;AAED,MAAM,WAAW,UAAU;IACzB,CAAC,QAAQ,EAAE,MAAM,GAAG,GAAG,CAAC;CACzB;AAED;;GAEG;AACH,MAAM,WAAW,KAAM,SAAQ,MAAM,CAAC,GAAG,CAAC;IACxC,EAAE,EAAE,GAAG,CAAC;IAIR,WAAW,EAAE,GAAG,CAAC;IAEjB,UAAU,EAAE,UAAU,CAAC;IACvB,SAAS,EAAE,eAAe,CAAC;IAC3B,QAAQ,CAAC,EAAE,GAAG,CAAC;IACf,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED;;GAEG;AACH,MAAM,WAAW,UAAW,SAAQ,WAAW,CAAC,GAAG,CAAC;IAClD,MAAM,EAAE,KAAK,EAAE,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,MAAM,IAAI,GAAG,KAAK,GAAG,UAAU,CAAC;AAEtC;;;GAGG;AACH,wBAAgB,OAAO,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,IAAI,KAAK,CAEjD;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,IAAI,UAAU,CAG3D"}
@@ -0,0 +1,22 @@
1
+ import { SerialOpts } from '../serializer';
2
+ import { Mapper, MapOpts } from '../interfaces';
3
+ import { Data } from './extras';
4
+ /**
5
+ * Mapper class for Bookshelf sources
6
+ */
7
+ export declare class Bookshelf implements Mapper {
8
+ baseUrl: string;
9
+ serialOpts?: SerialOpts | undefined;
10
+ /**
11
+ * Standard constructor
12
+ */
13
+ constructor(baseUrl: string, serialOpts?: SerialOpts | undefined);
14
+ /**
15
+ * Maps bookshelf data to a JSON-API 1.0 compliant object
16
+ *
17
+ * The `any` type data source is set for typing compatibility, but must be removed if possible
18
+ * TODO fix data any type
19
+ */
20
+ map(data: Data | any, type: string, mapOpts?: MapOpts): any;
21
+ }
22
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/bookshelf/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,UAAU,EAAc,MAAM,eAAe,CAAC;AACvD,OAAO,EAAE,MAAM,EAAE,OAAO,EAAY,MAAM,eAAe,CAAC;AAC1D,OAAO,EAAE,IAAI,EAAY,MAAM,UAAU,CAAC;AAG1C;;GAEG;AACH,qBAAa,SAAU,YAAW,MAAM;IAKnB,OAAO,EAAE,MAAM;IAAS,UAAU,CAAC,EAAE,UAAU;IAHlE;;OAEG;gBACgB,OAAO,EAAE,MAAM,EAAS,UAAU,CAAC,EAAE,UAAU,YAAA;IAElE;;;;;OAKG;IACH,GAAG,CAAC,IAAI,EAAE,IAAI,GAAG,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,OAAY,GAAG,GAAG;CAuChE"}
@@ -0,0 +1,19 @@
1
+ import { LinkOpts } from '../interfaces';
2
+ import { LinkObj } from '../serializer';
3
+ /**
4
+ * Creates top level links object, for primary data and pagination links.
5
+ */
6
+ export declare function topLinks(linkOpts: LinkOpts): LinkObj;
7
+ /**
8
+ * Creates links object for a resource
9
+ */
10
+ export declare function dataLinks(linkOpts: LinkOpts): LinkObj;
11
+ /**
12
+ * Creates links object for a relationship
13
+ */
14
+ export declare function relationshipLinks(linkOpts: LinkOpts, related: string): LinkObj;
15
+ /**
16
+ * Creates links object for a related resource, to be used for the included's array
17
+ */
18
+ export declare function includedLinks(linkOpts: LinkOpts): LinkObj;
19
+ //# sourceMappingURL=links.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"links.d.ts","sourceRoot":"","sources":["../../src/bookshelf/links.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,QAAQ,EAAsB,MAAM,eAAe,CAAC;AAC7D,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAMxC;;GAEG;AACH,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAsBpD;AA0DD;;GAEG;AACH,wBAAgB,SAAS,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CASrD;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAY9E;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CASzD"}