@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
package/LICENSE ADDED
@@ -0,0 +1,25 @@
1
+ This is free and unencumbered software released into the public domain.
2
+
3
+ Anyone is free to copy, modify, publish, use, compile, sell, or
4
+ distribute this software, either in source code form or as a compiled
5
+ binary, for any purpose, commercial or non-commercial, and by any
6
+ means.
7
+
8
+ In jurisdictions that recognize copyright laws, the author or authors
9
+ of this software dedicate any and all copyright interest in the
10
+ software to the public domain. We make this dedication for the benefit
11
+ of the public at large and to the detriment of our heirs and
12
+ successors. We intend this dedication to be an overt act of
13
+ relinquishment in perpetuity of all present and future rights to this
14
+ software under copyright law.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19
+ IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22
+ OTHER DEALINGS IN THE SOFTWARE.
23
+
24
+ For more information, please refer to <http://unlicense.org>
25
+
package/README.md ADDED
@@ -0,0 +1,103 @@
1
+ # JSON API Mapper
2
+
3
+ This is Ghost's Fork of JSON API Mapper, with minor changes to support the latest releases of Bookshelf.js. The rest of this README file is from upstream:
4
+
5
+ JSON API Mapper (_formerly Oh My JSON API_) is a wrapper around [@Seyz](https://github.com/SeyZ/)'s excellent [JSON API](http://jsonapi.org/)-compliant serializer, [jsonapi-serializer](https://github.com/SeyZ/jsonapi-serializer), that removes the pain of generating the necessary options needed to serialize each of your ORM models.
6
+
7
+ [![Join the chat at https://gitter.im/scoutforpets/oh-my-jsonapi](https://badges.gitter.im/scoutforpets/jsonapi-mapper.svg)](https://gitter.im/scoutforpets/jsonapi-mapper?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
8
+
9
+ ## _Breaking Changes_
10
+ This project has recently been renamed and rewritten using Typescript. While most functionality is generally the same, there have been a few deprecations and changes to how the Mapper is initialized. Please see the [migration guide](#migrating-from-ohmyjsonapi) below.
11
+
12
+ ## How does it work?
13
+ A serializer requires some sort of 'template' to understand how to convert what you're passing in to whatever you want to come out. When you're dealing with an ORM, such as [Bookshelf](https://github.com/tgriesser/bookshelf), it would be a real pain to have to generate the 'template' for every one of your Bookshelf models in order to convert them to JSON API. JSON API Mapper handles this by dynamically analyzing your models and automatically generating the necessary 'template' to pass to the serializer.
14
+
15
+ ## What ORMs do you support?
16
+ Initially, we only provide a mapper for [Bookshelf](https://github.com/tgriesser/bookshelf). However, the library can be easily extended with new mappers to support other ORMs. PR's are more than welcome!
17
+
18
+ ## How do I install it?
19
+ `npm install jsonapi-mapper --save`
20
+
21
+ ## How do I use it?
22
+ It's pretty simple. You only need to configure the mapper and then use it as many times you need.
23
+
24
+ ```javascript
25
+ import Mapper = require('jsonapi-mapper');
26
+
27
+ // Create the mapper
28
+ var mapper = new Mapper.Bookshelf('https://api.hotapp.com');
29
+
30
+ // Use the mapper to output JSON API-compliant using your ORM-provided data
31
+ return mapper.map(myData, 'appointment');
32
+ ```
33
+
34
+ ## How can I contribute?
35
+ God bless you if you're reading this! Check out our [Contributing page](https://github.com/scoutforpets/jsonapi-mapper/blob/master/CONTRIBUTING.md)
36
+
37
+ ## Migrating from OhMyJSONAPI
38
+ The migration process is painless:
39
+ - Remove `oh-my-jsonapi` from your project.
40
+ - Run `npm install jsonapi-mapper --save`
41
+ - Convert any instances of the constructor:
42
+
43
+ ```javascript
44
+ new OhMyJSONAPI('bookshelf', 'https://api.hotapp.com');
45
+ ```
46
+
47
+ to
48
+
49
+ ```javascript
50
+ new Mapper.Bookshelf('https://api.hotapp.com');
51
+ ```
52
+ - Convert any instances of:
53
+
54
+ ```javascript
55
+ jsonApi.toJSONAPI(myData, 'appointment');
56
+ ```
57
+
58
+ to
59
+
60
+ ```javascript
61
+ mapper.map(myData, 'appointment');
62
+ ```
63
+
64
+ ## API
65
+ ```javascript
66
+ new Mapper.Bookshelf(baseUrl, serializerOptions)
67
+ ```
68
+ - _(optional)_ `baseUrl` _(string)_: the base URL to be used in all `links` objects returned.
69
+ - _(optional)_ `serializerOptions` _(string)_: options to be passed to the serializer. These options will override any options generated by the mapper. For more information on the raw serializer, please [see the documentation here](https://github.com/SeyZ/jsonapi-serializer#documentation).
70
+
71
+ ```javascript
72
+ mapper#map(data, type, mapperOptions)
73
+ ```
74
+ - `data` _(object)_: The data object from Bookshelf (either a Model or a Collection) to be serialized.
75
+ - `type` _(string)_: The type of the resource being returned. For example, if you passed in an `Appointment` model, your `type` might be `appointment`.
76
+ - _(optional)_ `mapperOptions` _(object)_:
77
+ - _(optional)_ `attributes` (object):
78
+ - _(optional)_ `omit` _(RegExp | string)[]_: List of model attributes to omit from the resulting payload. For example, you may wish to exclude any foreign keys (as recommended by the JSON API-spec). Note: the model's `idAttribute` is automatically excluded by default.
79
+ - _(optional)_ `include` _(RegExp | string)[]_: List of model attributes to explicitly include from the resulting payload.
80
+ - _(optional)_ `keyForAttr` _(function (string => string))_: Function to customize the attributes keys. The function is passed as input the attribute key (`string`) and output the new attribute key (`string`).
81
+ - _(optional)_ `relations` _(boolean | object)_: Flag to enable (`true`) or disable (`false`) serializing of related models on the response. Alternatively, you can provide an object containing the following options:
82
+ - `included` _(boolean | string[])_ (default: `true`) - includes data for all relations in the response. You may optionally specify an array containing the names of specific relations to be included.
83
+ - `fields` _string[]_ - an array of relation names that should be included in the response.
84
+ - _(optional)_ `typeForModel` _(object | function)_: To customize the type of a relation. If the value returned is _falsy_, then it's automatically pluralized. This function **also affects** the type passed as the second parameter of the `map` function.
85
+ - _object_: The object should have the structure `{"<relation-name>": "<type-to-use>"}` (e.g. `{"best-friend": "people"}`).
86
+ - _function (string => string)_: The function is passed as input the relation name (`string`) and output the type for that relation (`string`) (e.g. `(x) => x + '-resources'`).
87
+ - _(optional)_ `enableLinks` _(boolean)_: Flag to enable (`true`) or disable (`false`) the generation of links in the payload. This may be useful if the consuming system doesn't take advantage of links and you want to save on payload size and maybe a bit of performance. Defaults to `true`.
88
+ - _(optional)_ `query` _(object)_: An object containing the original query parameters. These will be appended to `self` and pagination links. Developer Note: This is not fully implemented yet, but following releases will fix that.
89
+ - _(optional)_ `pagination` _(object)_: Pagination-related parameters for building pagination links for collections.
90
+ - _(required)_ `offset` _(integer)_
91
+ - _(required)_ `limit` _(integer)_
92
+ - _(optional)_ `total` or `rowCount` _(integer)_
93
+ - _(optional)_ `meta` _(object)_: Top-level meta object to include in the document
94
+ - _(optional)_ `outputVirtuals` _(boolean)_: Flag to include/omit the virtuals if the `virtuals` plugin is used, overrides the default `outputVirtuals` value.
95
+
96
+ # How can I contribute?
97
+ The project is very open to collaboration from the public, especially on providing the groundwork for other ORM's (like [Sequelize](http://docs.sequelizejs.com/) or [Mongoose](http://mongoosejs.com/)). Just open a PR!
98
+
99
+ The project source has been recently rewritten using [Typescript](http://www.typescriptlang.org/), which has been proven useful for static checks and overall development.
100
+
101
+ # Credits
102
+ - Thanks to [@Seyz](https://github.com/SeyZ/). Without his work, the project would not be possible.
103
+ - Thanks to the [zomoz team](https://github.com/zomoz) (especially [@ShadowManu](https://github.com/shadowmanu)) for their hard work in migrating the codebase to Typescript and writing a comprehensive test suite.
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var extras_exports = {};
20
+ __export(extras_exports, {
21
+ isCollection: () => isCollection,
22
+ isModel: () => isModel
23
+ });
24
+ module.exports = __toCommonJS(extras_exports);
25
+ function isModel(data) {
26
+ return data ? !isCollection(data) : false;
27
+ }
28
+ function isCollection(data) {
29
+ return data ? data.models !== void 0 : false;
30
+ }
@@ -0,0 +1,74 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, { get: all[name], enumerable: true });
10
+ };
11
+ var __copyProps = (to, from, except, desc) => {
12
+ if (from && typeof from === "object" || typeof from === "function") {
13
+ for (let key of __getOwnPropNames(from))
14
+ if (!__hasOwnProp.call(to, key) && key !== except)
15
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
+ }
17
+ return to;
18
+ };
19
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
20
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
21
+ var bookshelf_exports = {};
22
+ __export(bookshelf_exports, {
23
+ Bookshelf: () => Bookshelf
24
+ });
25
+ module.exports = __toCommonJS(bookshelf_exports);
26
+ var import_lodash = require("lodash");
27
+ var import_inflection = require("inflection");
28
+ var import_serializer = require("../serializer");
29
+ var import_utils = require("./utils");
30
+ class Bookshelf {
31
+ /**
32
+ * Standard constructor
33
+ */
34
+ constructor(baseUrl, serialOpts) {
35
+ __publicField(this, "baseUrl", baseUrl);
36
+ __publicField(this, "serialOpts", serialOpts);
37
+ }
38
+ /**
39
+ * Maps bookshelf data to a JSON-API 1.0 compliant object
40
+ *
41
+ * The `any` type data source is set for typing compatibility, but must be removed if possible
42
+ * TODO fix data any type
43
+ */
44
+ map(data, type, mapOpts = {}) {
45
+ const {
46
+ attributes,
47
+ keyForAttr = import_lodash.identity,
48
+ relations = true,
49
+ typeForModel = (attr) => (0, import_inflection.pluralize)(attr),
50
+ enableLinks = true,
51
+ pagination,
52
+ query,
53
+ meta,
54
+ outputVirtuals
55
+ } = mapOpts;
56
+ const bookOpts = {
57
+ attributes,
58
+ keyForAttr,
59
+ relations,
60
+ typeForModel,
61
+ enableLinks,
62
+ pagination,
63
+ query,
64
+ outputVirtuals
65
+ };
66
+ const linkOpts = { baseUrl: this.baseUrl, type, pag: pagination };
67
+ const info = { bookOpts, linkOpts };
68
+ const template = (0, import_utils.processData)(info, data);
69
+ const typeForAttribute = typeof typeForModel === "function" ? typeForModel : (attr) => typeForModel[attr] || (0, import_inflection.pluralize)(attr);
70
+ (0, import_lodash.assign)(template, { typeForAttribute, keyForAttribute: keyForAttr, meta }, this.serialOpts);
71
+ const json = (0, import_utils.toJSON)(data);
72
+ return new import_serializer.Serializer(type, template).serialize(json);
73
+ }
74
+ }
@@ -0,0 +1,112 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var links_exports = {};
20
+ __export(links_exports, {
21
+ dataLinks: () => dataLinks,
22
+ includedLinks: () => includedLinks,
23
+ relationshipLinks: () => relationshipLinks,
24
+ topLinks: () => topLinks
25
+ });
26
+ module.exports = __toCommonJS(links_exports);
27
+ var import_lodash = require("lodash");
28
+ var import_inflection = require("inflection");
29
+ var import_qs = require("qs");
30
+ function urlConcat(...parts) {
31
+ return parts.join("/");
32
+ }
33
+ function topLinks(linkOpts) {
34
+ let { baseUrl, type, pag } = linkOpts;
35
+ let obj = {
36
+ self: urlConcat(baseUrl, (0, import_inflection.pluralize)(type))
37
+ };
38
+ if (!(0, import_lodash.isNil)(pag)) {
39
+ if (!(0, import_lodash.isNil)(pag.rowCount)) {
40
+ pag.total = pag.rowCount;
41
+ }
42
+ if (!(0, import_lodash.isNil)(pag.total) && pag.total > 0 && pag.total > pag.limit) {
43
+ (0, import_lodash.assign)(obj, pagLinks(linkOpts));
44
+ }
45
+ }
46
+ return obj;
47
+ }
48
+ function pagLinks(linkOpts) {
49
+ let { baseUrl, type, pag, query = {} } = linkOpts;
50
+ if (pag === void 0) {
51
+ return void 0;
52
+ }
53
+ const { offset, limit, total } = pag;
54
+ let baseLink = urlConcat(baseUrl, (0, import_inflection.pluralize)(type));
55
+ query = (0, import_lodash.omit)(query, ["page", "page[limit]", "page[offset]"]);
56
+ baseLink = baseLink + "?" + (0, import_qs.stringify)(query, { encode: false });
57
+ let obj = {};
58
+ if (offset > 0) {
59
+ obj.first = () => {
60
+ let page = { page: { limit, offset: 0 } };
61
+ return baseLink + (0, import_qs.stringify)(page, { encode: false });
62
+ };
63
+ obj.prev = () => {
64
+ let page = { page: { limit, offset: offset - limit } };
65
+ return baseLink + (0, import_qs.stringify)(page, { encode: false });
66
+ };
67
+ }
68
+ if (total && offset + limit < total) {
69
+ obj.next = () => {
70
+ let page = { page: { limit, offset: offset + limit } };
71
+ return baseLink + (0, import_qs.stringify)(page, { encode: false });
72
+ };
73
+ obj.last = () => {
74
+ let lastLimit = (total - offset % limit) % limit;
75
+ lastLimit = lastLimit === 0 ? limit : lastLimit;
76
+ let lastOffset = total - lastLimit;
77
+ let page = { page: { limit: lastLimit, offset: lastOffset } };
78
+ return baseLink + (0, import_qs.stringify)(page, { encode: false });
79
+ };
80
+ }
81
+ return !(0, import_lodash.isEmpty)(obj) ? obj : void 0;
82
+ }
83
+ function dataLinks(linkOpts) {
84
+ let { baseUrl, type } = linkOpts;
85
+ let baseLink = urlConcat(baseUrl, (0, import_inflection.pluralize)(type));
86
+ return {
87
+ self: function(resource) {
88
+ return urlConcat(baseLink, resource.id);
89
+ }
90
+ };
91
+ }
92
+ function relationshipLinks(linkOpts, related) {
93
+ let { baseUrl, type } = linkOpts;
94
+ let baseLink = urlConcat(baseUrl, (0, import_inflection.pluralize)(type));
95
+ return {
96
+ self: function(resource, current, parent) {
97
+ return urlConcat(baseLink, parent.id, "relationships", related);
98
+ },
99
+ related: function(resource, current, parent) {
100
+ return urlConcat(baseLink, parent.id, related);
101
+ }
102
+ };
103
+ }
104
+ function includedLinks(linkOpts) {
105
+ let { baseUrl, type } = linkOpts;
106
+ let baseLink = urlConcat(baseUrl, (0, import_inflection.pluralize)(type));
107
+ return {
108
+ self: function(primary, current) {
109
+ return urlConcat(baseLink, current.id);
110
+ }
111
+ };
112
+ }
@@ -0,0 +1,168 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var utils_exports = {};
20
+ __export(utils_exports, {
21
+ processData: () => processData,
22
+ toJSON: () => toJSON
23
+ });
24
+ module.exports = __toCommonJS(utils_exports);
25
+ var import_lodash = require("lodash");
26
+ var import_links = require("./links");
27
+ var import_extras = require("./extras");
28
+ function processData(info, data) {
29
+ let { bookOpts: { enableLinks }, linkOpts } = info;
30
+ let template = processSample(info, sample(data));
31
+ if (enableLinks) {
32
+ template.dataLinks = (0, import_links.dataLinks)(linkOpts);
33
+ template.topLevelLinks = (0, import_links.topLinks)(linkOpts);
34
+ }
35
+ return template;
36
+ }
37
+ function processSample(info, sample2) {
38
+ let { bookOpts, linkOpts } = info;
39
+ let { enableLinks } = bookOpts;
40
+ let template = {
41
+ // Add list of valid attributes
42
+ attributes: getAttrsList(sample2, bookOpts)
43
+ };
44
+ (0, import_lodash.forOwn)(sample2.relations, (relSample, relName) => {
45
+ if (!relationAllowed(bookOpts, relName)) {
46
+ return;
47
+ }
48
+ let relLinkOpts = (0, import_lodash.assign)((0, import_lodash.clone)(linkOpts), { type: relName });
49
+ let relTemplate = processSample({ bookOpts, linkOpts: relLinkOpts }, relSample);
50
+ relTemplate.ref = "id";
51
+ if (enableLinks) {
52
+ relTemplate.relationshipLinks = (0, import_links.relationshipLinks)(linkOpts, relName);
53
+ relTemplate.includedLinks = (0, import_links.includedLinks)(relLinkOpts);
54
+ }
55
+ if (!includeAllowed(bookOpts, relName)) {
56
+ relTemplate.included = false;
57
+ }
58
+ template[relName] = relTemplate;
59
+ template.attributes.push(relName);
60
+ });
61
+ return template;
62
+ }
63
+ function sample(data) {
64
+ if ((0, import_extras.isModel)(data)) {
65
+ const sampled = (0, import_lodash.cloneDeep)((0, import_lodash.omit)(data, "relations"));
66
+ sampled.relations = (0, import_lodash.mapValues)(data.relations, sample);
67
+ return sampled;
68
+ } else if ((0, import_extras.isCollection)(data)) {
69
+ const first = data.first();
70
+ const rest = data.slice(1);
71
+ return (0, import_lodash.reduce)(rest, mergeSample, sample(first));
72
+ } else {
73
+ return {};
74
+ }
75
+ }
76
+ function mergeSample(main, toMerge) {
77
+ const sampled = sample(toMerge);
78
+ main.attributes = (0, import_lodash.merge)(main.attributes, sampled.attributes);
79
+ main.relations = (0, import_lodash.merge)(main.relations, sampled.relations);
80
+ return main;
81
+ }
82
+ function matches(matcher, str) {
83
+ let reg;
84
+ if (typeof matcher === "string") {
85
+ reg = RegExp(`^${(0, import_lodash.escapeRegExp)(matcher)}$`);
86
+ } else {
87
+ reg = matcher;
88
+ }
89
+ return reg.test(str);
90
+ }
91
+ function getAttrsList(data, bookOpts) {
92
+ let idAttr = data.idAttribute;
93
+ if ((0, import_lodash.isString)(idAttr)) {
94
+ idAttr = [idAttr];
95
+ } else if ((0, import_lodash.isUndefined)(idAttr)) {
96
+ idAttr = [];
97
+ }
98
+ let attrs = (0, import_lodash.keys)(data.attributes);
99
+ let outputVirtuals = data.outputVirtuals;
100
+ if (!(0, import_lodash.isNil)(bookOpts.outputVirtuals)) {
101
+ outputVirtuals = bookOpts.outputVirtuals;
102
+ }
103
+ if (data.virtuals && outputVirtuals) {
104
+ attrs = attrs.concat((0, import_lodash.keys)(data.virtuals));
105
+ }
106
+ let { attributes = { omit: idAttr } } = bookOpts;
107
+ if (attributes instanceof Array) {
108
+ attributes = { include: attributes };
109
+ }
110
+ let { omit: omit2, include } = attributes;
111
+ return (0, import_lodash.filter)(attrs, (attr) => {
112
+ let included = true;
113
+ let omitted = false;
114
+ if (include) {
115
+ included = (0, import_lodash.some)(include, (m) => matches(m, attr));
116
+ }
117
+ if (omit2) {
118
+ omitted = (0, import_lodash.some)(omit2, (m) => matches(m, attr));
119
+ }
120
+ return !omitted && included;
121
+ });
122
+ }
123
+ function relationAllowed(bookOpts, relName) {
124
+ let { relations } = bookOpts;
125
+ if (typeof relations === "boolean") {
126
+ return relations;
127
+ } else {
128
+ let { fields } = relations;
129
+ return !fields || (0, import_lodash.includes)(fields, relName);
130
+ }
131
+ }
132
+ function includeAllowed(bookOpts, relName) {
133
+ let { relations } = bookOpts;
134
+ if (typeof relations === "boolean") {
135
+ return relations;
136
+ } else {
137
+ let { fields, included } = relations;
138
+ if (typeof included === "boolean") {
139
+ return included;
140
+ } else {
141
+ let allowed = included;
142
+ if (fields) {
143
+ allowed = (0, import_lodash.intersection)(fields, included);
144
+ }
145
+ return (0, import_lodash.includes)(allowed, relName);
146
+ }
147
+ }
148
+ }
149
+ function toJSON(data) {
150
+ let json = null;
151
+ if ((0, import_extras.isModel)(data)) {
152
+ json = data.toJSON({ shallow: true });
153
+ const idAttr = data.idAttribute;
154
+ if ((0, import_lodash.isArray)(idAttr)) {
155
+ data.id = (0, import_lodash.map)(idAttr, (attr) => data.attributes[attr]).join(",");
156
+ }
157
+ if (!(0, import_lodash.has)(json, "id")) {
158
+ json.id = data.id;
159
+ }
160
+ (0, import_lodash.update)(json, "id", import_lodash.toString);
161
+ (0, import_lodash.forOwn)(data.relations, function(relData, relName) {
162
+ json[relName] = toJSON(relData);
163
+ });
164
+ } else if ((0, import_extras.isCollection)(data)) {
165
+ json = data.map(toJSON);
166
+ }
167
+ return json;
168
+ }
package/cjs/index.js ADDED
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __copyProps = (to, from, except, desc) => {
7
+ if (from && typeof from === "object" || typeof from === "function") {
8
+ for (let key of __getOwnPropNames(from))
9
+ if (!__hasOwnProp.call(to, key) && key !== except)
10
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
11
+ }
12
+ return to;
13
+ };
14
+ var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
15
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
16
+ var index_exports = {};
17
+ module.exports = __toCommonJS(index_exports);
18
+ __reExport(index_exports, require("./bookshelf"), module.exports);
19
+ __reExport(index_exports, require("./interfaces"), module.exports);
20
+ __reExport(index_exports, require("./serializer"), module.exports);
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __copyProps = (to, from, except, desc) => {
7
+ if (from && typeof from === "object" || typeof from === "function") {
8
+ for (let key of __getOwnPropNames(from))
9
+ if (!__hasOwnProp.call(to, key) && key !== except)
10
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
11
+ }
12
+ return to;
13
+ };
14
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
15
+ var common_exports = {};
16
+ module.exports = __toCommonJS(common_exports);
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __copyProps = (to, from, except, desc) => {
7
+ if (from && typeof from === "object" || typeof from === "function") {
8
+ for (let key of __getOwnPropNames(from))
9
+ if (!__hasOwnProp.call(to, key) && key !== except)
10
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
11
+ }
12
+ return to;
13
+ };
14
+ var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
15
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
16
+ var interfaces_exports = {};
17
+ module.exports = __toCommonJS(interfaces_exports);
18
+ __reExport(interfaces_exports, require("./common"), module.exports);
19
+ __reExport(interfaces_exports, require("./links"), module.exports);
20
+ __reExport(interfaces_exports, require("./relations"), module.exports);
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __copyProps = (to, from, except, desc) => {
7
+ if (from && typeof from === "object" || typeof from === "function") {
8
+ for (let key of __getOwnPropNames(from))
9
+ if (!__hasOwnProp.call(to, key) && key !== except)
10
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
11
+ }
12
+ return to;
13
+ };
14
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
15
+ var links_exports = {};
16
+ module.exports = __toCommonJS(links_exports);
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __copyProps = (to, from, except, desc) => {
7
+ if (from && typeof from === "object" || typeof from === "function") {
8
+ for (let key of __getOwnPropNames(from))
9
+ if (!__hasOwnProp.call(to, key) && key !== except)
10
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
11
+ }
12
+ return to;
13
+ };
14
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
15
+ var relations_exports = {};
16
+ module.exports = __toCommonJS(relations_exports);
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+ var serializer_exports = {};
30
+ __export(serializer_exports, {
31
+ Serializer: () => Serializer
32
+ });
33
+ module.exports = __toCommonJS(serializer_exports);
34
+ var jas = __toESM(require("jsonapi-serializer"));
35
+ let Serializer = jas.Serializer;
@@ -0,0 +1 @@
1
+ "use strict";
@@ -0,0 +1,10 @@
1
+ function isModel(data) {
2
+ return data ? !isCollection(data) : false;
3
+ }
4
+ function isCollection(data) {
5
+ return data ? data.models !== void 0 : false;
6
+ }
7
+ export {
8
+ isCollection,
9
+ isModel
10
+ };