Join our webinar on Wednesday, June 26, at 1pm EDTHow Chia Mitigates Risk in the Crypto Industry.Register
Socket
Socket
Sign inDemoInstall

ts-japi

Package Overview
Dependencies
0
Maintainers
1
Versions
34
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 1.6.1 to 1.6.2

api-extractor.json

8

CHANGELOG.md
# Changelog
## 1.6.2
### Patch Changes
- c5a8201: Add customisable relationship names
## 1.6.1

@@ -27,3 +33,3 @@

- Fixes https://github.com/mu-io/ts-japi/issues/23
- Fixes https://github.com/mathematic-inc/ts-japi/issues/23

@@ -30,0 +36,0 @@ ## 1.4.0

4

lib/classes/cache.d.ts

@@ -21,5 +21,5 @@ import { SerializerOptions } from '../interfaces/serializer.interface';

/**
* Creates a {@linkcode Cache}
* Creates a {@link Cache}
*
* @param limit The maximum amount of documents that can be stored before erasure.
* @param limit - The maximum amount of documents that can be stored before erasure.
*/

@@ -26,0 +26,0 @@ constructor(options?: Partial<CacheOptions<PrimaryType>>);

"use strict";
var __read = (this && this.__read) || function (o, n) {
var m = typeof Symbol === "function" && o[Symbol.iterator];
if (!m) return o;
var i = m.call(o), r, ar = [], e;
try {
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
}
catch (error) { e = { error: error }; }
finally {
try {
if (r && !r.done && (m = i["return"])) m.call(i);
}
finally { if (e) throw e.error; }
}
return ar;
};
exports.__esModule = true;
var Cache = /** @class */ (function () {
Object.defineProperty(exports, "__esModule", { value: true });
class Cache {
/**
* Creates a {@linkcode Cache}
* The default max for document storage
*/
static defaultLimit = 10;
/** @internal The storage for the cache */
storage = [];
/**
* The maximum amount of documents that can be storage before erasure.
*/
limit = Cache.defaultLimit;
/**
* The method to use in determining data equality
*/
resolver = Object.is;
/**
* Creates a {@link Cache}
*
* @param limit The maximum amount of documents that can be stored before erasure.
* @param limit - The maximum amount of documents that can be stored before erasure.
*/
function Cache(options) {
if (options === void 0) { options = {}; }
/** @internal The storage for the cache */
this.storage = [];
/**
* The maximum amount of documents that can be storage before erasure.
*/
this.limit = Cache.defaultLimit;
/**
* The method to use in determining data equality
*/
this.resolver = Object.is;
constructor(options = {}) {
if (options.limit)

@@ -43,8 +30,4 @@ this.limit = options.limit;

/** @internal Gets a document in the cache */
Cache.prototype.get = function (data, options) {
var _this = this;
var document = this.storage.find(function (_a) {
var _b = __read(_a, 2), storedData = _b[0], storedOptions = _b[1];
return _this.resolver(storedData, data) && Object.is(storedOptions, options);
});
get(data, options) {
const document = this.storage.find(([storedData, storedOptions]) => this.resolver(storedData, data) && Object.is(storedOptions, options));
if (document)

@@ -54,5 +37,5 @@ return document[2];

return false;
};
}
/** @internal Sets a document in the cache */
Cache.prototype.set = function (data, document, options) {
set(data, document, options) {
if (this.storage.length > this.limit) {

@@ -63,10 +46,5 @@ this.storage.shift();

return document;
};
/**
* The default max for document storage
*/
Cache.defaultLimit = 10;
return Cache;
}());
exports["default"] = Cache;
}
}
exports.default = Cache;
//# sourceMappingURL=cache.js.map

@@ -5,3 +5,3 @@ import { ErrorSerializerOptions } from '../interfaces/error-serializer.interface';

/**
* The {@linkcode ErrorSerializer} class is used to serialize errors.
* The {@link ErrorSerializer} class is used to serialize errors.
*

@@ -38,6 +38,6 @@ * Example:

/**
* Creates a {@linkcode Serializer}.
* Creates a {@link Serializer}.
*
* @param collectionName The name of the collection of objects.
* @param options Options for the serializer.
* @param collectionName - The name of the collection of objects.
* @param options - Options for the serializer.
*/

@@ -48,4 +48,4 @@ constructor(options?: Partial<ErrorSerializerOptions<ErrorType>>);

*
* @param errors Errors to serialize.
* @param options Options to use at runtime.
* @param errors - Errors to serialize.
* @param options - Options to use at runtime.
*/

@@ -52,0 +52,0 @@ serialize(errors: SingleOrArray<ErrorType>, options?: Partial<ErrorSerializerOptions<ErrorType>>): ErrorDocument;

"use strict";
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
var __values = (this && this.__values) || function(o) {
var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
if (m) return m.call(o);
if (o && typeof o.length === "number") return {
next: function () {
if (o && i >= o.length) o = void 0;
return { value: o && o[i++], done: !o };
}
};
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
};
var __read = (this && this.__read) || function (o, n) {
var m = typeof Symbol === "function" && o[Symbol.iterator];
if (!m) return o;
var i = m.call(o), r, ar = [], e;
try {
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
}
catch (error) { e = { error: error }; }
finally {
try {
if (r && !r.done && (m = i["return"])) m.call(i);
}
finally { if (e) throw e.error; }
}
return ar;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
exports.__esModule = true;
var error_model_1 = __importDefault(require("../models/error.model"));
var merge_1 = __importDefault(require("../utils/merge"));
Object.defineProperty(exports, "__esModule", { value: true });
const error_model_1 = __importDefault(require("../models/error.model"));
const merge_1 = __importDefault(require("../utils/merge"));
/**
* The {@linkcode ErrorSerializer} class is used to serialize errors.
* The {@link ErrorSerializer} class is used to serialize errors.
*

@@ -54,13 +16,35 @@ * Example:

*/
var ErrorSerializer = /** @class */ (function () {
class ErrorSerializer {
/**
* Creates a {@linkcode Serializer}.
* Default options. Can be edited to change default options globally.
*/
static defaultOptions = {
version: '1.0',
attributes: {
id: 'id',
status: 'code',
code: 'name',
title: 'reason',
detail: 'message',
source: {
pointer: 'location',
parameter: undefined,
},
},
metaizers: {},
linkers: {},
};
/**
* The set of options for the serializer.
*/
options;
/**
* Creates a {@link Serializer}.
*
* @param collectionName The name of the collection of objects.
* @param options Options for the serializer.
* @param collectionName - The name of the collection of objects.
* @param options - Options for the serializer.
*/
function ErrorSerializer(options) {
if (options === void 0) { options = {}; }
constructor(options = {}) {
// Setting default options.
this.options = merge_1["default"]({}, ErrorSerializer.defaultOptions, options);
this.options = (0, merge_1.default)({}, ErrorSerializer.defaultOptions, options);
}

@@ -70,16 +54,15 @@ /**

*
* @param errors Errors to serialize.
* @param options Options to use at runtime.
* @param errors - Errors to serialize.
* @param options - Options to use at runtime.
*/
ErrorSerializer.prototype.serialize = function (errors, options) {
var e_1, _a, e_2, _b, e_3, _c, _d;
serialize(errors, options) {
// Get options.
var o = this.options;
let o = this.options;
if (options)
o = merge_1["default"]({}, this.options, options);
var attributes = o.attributes;
var linkers = o.linkers;
var metaizers = o.metaizers;
var version = o.version;
var document = { errors: [] };
o = (0, merge_1.default)({}, this.options, options);
const attributes = o.attributes;
const linkers = o.linkers;
const metaizers = o.metaizers;
const version = o.version;
const document = { errors: [] };
// Normalize error input

@@ -89,6 +72,6 @@ if (!Array.isArray(errors)) {

}
document.errors = errors.map(function (e) {
if (e instanceof error_model_1["default"])
document.errors = errors.map((e) => {
if (e instanceof error_model_1.default)
return e;
var eo = {};
const eo = {};
if (attributes.id && e[attributes.id]) {

@@ -121,11 +104,11 @@ eo.id = String(e[attributes.id]);

}
return new error_model_1["default"](eo);
return new error_model_1.default(eo);
});
// Constructing base document.
if (version) {
document.jsonapi = { version: version };
document.jsonapi = { version };
}
// Handling document metadata.
if (metaizers.jsonapi) {
document.jsonapi = __assign(__assign({}, document.jsonapi), { meta: metaizers.jsonapi.metaize() });
document.jsonapi = { ...document.jsonapi, meta: metaizers.jsonapi.metaize() };
}

@@ -136,70 +119,20 @@ if (metaizers.document) {

if (metaizers.error) {
try {
for (var _e = __values(document.errors), _f = _e.next(); !_f.done; _f = _e.next()) {
var error = _f.value;
error.meta = metaizers.error.metaize(error);
}
for (const error of document.errors) {
error.meta = metaizers.error.metaize(error);
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (_f && !_f.done && (_a = _e["return"])) _a.call(_e);
}
finally { if (e_1) throw e_1.error; }
}
}
// Handling links.
if (Object.keys(linkers).length > 0) {
try {
for (var _g = __values(Object.entries(linkers)), _h = _g.next(); !_h.done; _h = _g.next()) {
var _j = __read(_h.value, 2), key = _j[0], linker = _j[1];
if (linker) {
try {
for (var _k = (e_3 = void 0, __values(document.errors)), _l = _k.next(); !_l.done; _l = _k.next()) {
var error = _l.value;
error.links = __assign(__assign({}, error.links), (_d = {}, _d[key] = linker.link(error), _d));
}
}
catch (e_3_1) { e_3 = { error: e_3_1 }; }
finally {
try {
if (_l && !_l.done && (_c = _k["return"])) _c.call(_k);
}
finally { if (e_3) throw e_3.error; }
}
for (const [key, linker] of Object.entries(linkers)) {
if (linker) {
for (const error of document.errors) {
error.links = { ...error.links, [key]: linker.link(error) };
}
}
}
catch (e_2_1) { e_2 = { error: e_2_1 }; }
finally {
try {
if (_h && !_h.done && (_b = _g["return"])) _b.call(_g);
}
finally { if (e_2) throw e_2.error; }
}
}
return document;
};
/**
* Default options. Can be edited to change default options globally.
*/
ErrorSerializer.defaultOptions = {
version: '1.0',
attributes: {
id: 'id',
status: 'code',
code: 'name',
title: 'reason',
detail: 'message',
source: {
pointer: 'location',
parameter: undefined
}
},
metaizers: {},
linkers: {}
};
return ErrorSerializer;
}());
exports["default"] = ErrorSerializer;
}
}
exports.default = ErrorSerializer;
//# sourceMappingURL=error-serializer.js.map

@@ -5,3 +5,3 @@ import { LinkerOptions } from '../interfaces/linker.interface';

/**
* The {@linkcode Linker} class is used to construct a [link](https://jsonapi.org/format/#document-links).
* The {@link Linker} class is used to construct a [link](https://jsonapi.org/format/#document-links).
*

@@ -14,9 +14,9 @@ * Example:

export default class Linker<Dependencies extends any[]> {
/** @internal Generates a {@linkcode Link}. */
/** @internal Generates a {@link Link}. */
link: VariadicFunction<Dependencies, Link>;
/**
* Creates a {@linkcode Linker}.
* Creates a {@link Linker}.
*
* @param link A {@linkcode LinkFunction} used to generate a string URI from its arguments.
* @param options Options for the linker.
* @param link - A {@link LinkFunction} used to generate a string URI from its arguments.
* @param options - Options for the linker.
*/

@@ -23,0 +23,0 @@ constructor(link: VariadicFunction<Dependencies, string>, options?: LinkerOptions<Dependencies>);

"use strict";
var __read = (this && this.__read) || function (o, n) {
var m = typeof Symbol === "function" && o[Symbol.iterator];
if (!m) return o;
var i = m.call(o), r, ar = [], e;
try {
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
}
catch (error) { e = { error: error }; }
finally {
try {
if (r && !r.done && (m = i["return"])) m.call(i);
}
finally { if (e) throw e.error; }
}
return ar;
};
var __spreadArray = (this && this.__spreadArray) || function (to, from) {
for (var i = 0, il = from.length, j = to.length; i < il; i++, j++)
to[j] = from[i];
return to;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
exports.__esModule = true;
var link_model_1 = __importDefault(require("../models/link.model"));
Object.defineProperty(exports, "__esModule", { value: true });
const link_model_1 = __importDefault(require("../models/link.model"));
/**
* The {@linkcode Linker} class is used to construct a [link](https://jsonapi.org/format/#document-links).
* The {@link Linker} class is used to construct a [link](https://jsonapi.org/format/#document-links).
*

@@ -36,25 +15,20 @@ * Example:

*/
var Linker = /** @class */ (function () {
class Linker {
/** @internal Generates a {@link Link}. */
link;
/**
* Creates a {@linkcode Linker}.
* Creates a {@link Linker}.
*
* @param link A {@linkcode LinkFunction} used to generate a string URI from its arguments.
* @param options Options for the linker.
* @param link - A {@link LinkFunction} used to generate a string URI from its arguments.
* @param options - Options for the linker.
*/
function Linker(link, options) {
if (options === void 0) { options = {}; }
this.link = function () {
var _a;
var datas = [];
for (var _i = 0; _i < arguments.length; _i++) {
datas[_i] = arguments[_i];
}
constructor(link, options = {}) {
this.link = (...datas) => {
return options.metaizer
? new link_model_1["default"](link.apply(void 0, __spreadArray([], __read(datas))), (_a = options.metaizer).metaize.apply(_a, __spreadArray([], __read(datas))))
: new link_model_1["default"](link.apply(void 0, __spreadArray([], __read(datas))));
? new link_model_1.default(link(...datas), options.metaizer.metaize(...datas))
: new link_model_1.default(link(...datas));
};
}
return Linker;
}());
exports["default"] = Linker;
}
exports.default = Linker;
//# sourceMappingURL=linker.js.map
import Meta from '../models/meta.model';
import { Dictionary, VariadicFunction } from '../types/global.types';
/**
* The {@linkcode Metaizer} class is used to construct [meta information](https://jsonapi.org/format/#document-meta).
* The {@link Metaizer} class is used to construct [meta information](https://jsonapi.org/format/#document-meta).
*

@@ -12,8 +12,8 @@ * Example:

export default class Metaizer<Dependencies extends any[]> {
/** @internal Generates a {@linkcode Meta}. */
/** @internal Generates a {@link Meta}. */
metaize: VariadicFunction<Dependencies, Meta>;
/**
* Creates a {@linkcode Metaizer}.
* Creates a {@link Metaizer}.
*
* @param metaize A function to generate [meta information](https://jsonapi.org/format/#document-meta)
* @param metaize - A function to generate [meta information](https://jsonapi.org/format/#document-meta)
* from its arguments.

@@ -20,0 +20,0 @@ */

"use strict";
var __read = (this && this.__read) || function (o, n) {
var m = typeof Symbol === "function" && o[Symbol.iterator];
if (!m) return o;
var i = m.call(o), r, ar = [], e;
try {
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
}
catch (error) { e = { error: error }; }
finally {
try {
if (r && !r.done && (m = i["return"])) m.call(i);
}
finally { if (e) throw e.error; }
}
return ar;
};
var __spreadArray = (this && this.__spreadArray) || function (to, from) {
for (var i = 0, il = from.length, j = to.length; i < il; i++, j++)
to[j] = from[i];
return to;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
exports.__esModule = true;
var meta_model_1 = __importDefault(require("../models/meta.model"));
Object.defineProperty(exports, "__esModule", { value: true });
const meta_model_1 = __importDefault(require("../models/meta.model"));
/**
* The {@linkcode Metaizer} class is used to construct [meta information](https://jsonapi.org/format/#document-meta).
* The {@link Metaizer} class is used to construct [meta information](https://jsonapi.org/format/#document-meta).
*

@@ -36,21 +15,16 @@ * Example:

*/
var Metaizer = /** @class */ (function () {
class Metaizer {
/** @internal Generates a {@link Meta}. */
metaize;
/**
* Creates a {@linkcode Metaizer}.
* Creates a {@link Metaizer}.
*
* @param metaize A function to generate [meta information](https://jsonapi.org/format/#document-meta)
* @param metaize - A function to generate [meta information](https://jsonapi.org/format/#document-meta)
* from its arguments.
*/
function Metaizer(metaize) {
this.metaize = function () {
var datas = [];
for (var _i = 0; _i < arguments.length; _i++) {
datas[_i] = arguments[_i];
}
return new meta_model_1["default"](metaize.apply(void 0, __spreadArray([], __read(datas))));
};
constructor(metaize) {
this.metaize = (...datas) => new meta_model_1.default(metaize(...datas));
}
return Metaizer;
}());
exports["default"] = Metaizer;
}
exports.default = Metaizer;
//# sourceMappingURL=metaizer.js.map

@@ -5,3 +5,3 @@ import { PaginationOf } from '../interfaces/paginator.interface';

/**
* The {@linkcode Paginator} class is used to construct [pagination links](https://jsonapi.org/format/#fetching-pagination).
* The {@link Paginator} class is used to construct [pagination links](https://jsonapi.org/format/#fetching-pagination).
*

@@ -17,5 +17,5 @@ * Example:

/**
* Creates a {@linkcode Paginator}.
* Creates a {@link Paginator}.
*
* @param paginate A function to generate pagination links from data.
* @param paginate - A function to generate pagination links from data.
*/

@@ -22,0 +22,0 @@ constructor(paginate: (data: SingleOrArray<DataType>) => PaginationOf<string> | void);

@@ -5,6 +5,6 @@ "use strict";

};
exports.__esModule = true;
var link_model_1 = __importDefault(require("../models/link.model"));
Object.defineProperty(exports, "__esModule", { value: true });
const link_model_1 = __importDefault(require("../models/link.model"));
/**
* The {@linkcode Paginator} class is used to construct [pagination links](https://jsonapi.org/format/#fetching-pagination).
* The {@link Paginator} class is used to construct [pagination links](https://jsonapi.org/format/#fetching-pagination).
*

@@ -16,24 +16,25 @@ * Example:

*/
var Paginator = /** @class */ (function () {
class Paginator {
/** @internal Generates pagination links. */
paginate;
/**
* Creates a {@linkcode Paginator}.
* Creates a {@link Paginator}.
*
* @param paginate A function to generate pagination links from data.
* @param paginate - A function to generate pagination links from data.
*/
function Paginator(paginate) {
this.paginate = function (data) {
var links = paginate(data);
constructor(paginate) {
this.paginate = (data) => {
const links = paginate(data);
if (!links)
return;
return {
first: typeof links.first === 'string' ? new link_model_1["default"](links.first) : links.first,
last: typeof links.last === 'string' ? new link_model_1["default"](links.last) : links.last,
prev: typeof links.prev === 'string' ? new link_model_1["default"](links.prev) : links.prev,
next: typeof links.next === 'string' ? new link_model_1["default"](links.next) : links.next
first: typeof links.first === 'string' ? new link_model_1.default(links.first) : links.first,
last: typeof links.last === 'string' ? new link_model_1.default(links.last) : links.last,
prev: typeof links.prev === 'string' ? new link_model_1.default(links.prev) : links.prev,
next: typeof links.next === 'string' ? new link_model_1.default(links.next) : links.next,
};
};
}
return Paginator;
}());
exports["default"] = Paginator;
}
exports.default = Paginator;
//# sourceMappingURL=paginator.js.map

@@ -12,3 +12,3 @@ import { RelatorOptions } from '../interfaces/relator.interface';

/**
* The {@linkcode Relator} class is used to generate top-level [included data](https://jsonapi.org/format/#document-top-level)
* The {@link Relator} class is used to generate top-level [included data](https://jsonapi.org/format/#document-top-level)
* as well as resource-level [relationships](https://jsonapi.org/format/#document-resource-object-relationships).

@@ -34,7 +34,7 @@ *

/**
* Creates a {@linkcode Relator}.
* Creates a {@link Relator}.
*
* @param fetch Fetches related data from primary data.
* @param serializer The `Serializer` to use for related data.
* @param options Options for the relator.
* @param fetch - Fetches related data from primary data.
* @param serializer - The `Serializer` to use for related data.
* @param options - Options for the relator.
*/

@@ -54,5 +54,5 @@ constructor(fetch: (data: PrimaryType) => Promise<RelatedType | RelatedType[] | nullish>, serializer: Serializer<RelatedType>, options?: Partial<RelatorOptions<PrimaryType, RelatedType>>);

getRelatedMeta(data: PrimaryType, relatedData: RelatedType | RelatedType[] | nullish): Meta | undefined;
/** @internal Creates a {@linkcode Relationship}. */
/** @internal Creates a {@link Relationship}. */
getRelationship(data: PrimaryType, relatedDataCache?: Dictionary<any>[]): Promise<Relationship>;
}
//# sourceMappingURL=relator.d.ts.map
"use strict";
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
var __read = (this && this.__read) || function (o, n) {
var m = typeof Symbol === "function" && o[Symbol.iterator];
if (!m) return o;
var i = m.call(o), r, ar = [], e;
try {
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
}
catch (error) { e = { error: error }; }
finally {
try {
if (r && !r.done && (m = i["return"])) m.call(i);
}
finally { if (e) throw e.error; }
}
return ar;
};
var __spreadArray = (this && this.__spreadArray) || function (to, from) {
for (var i = 0, il = from.length, j = to.length; i < il; i++, j++)
to[j] = from[i];
return to;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
exports.__esModule = true;
var relationship_model_1 = __importDefault(require("../models/relationship.model"));
var merge_1 = __importDefault(require("../utils/merge"));
Object.defineProperty(exports, "__esModule", { value: true });
const relationship_model_1 = __importDefault(require("../models/relationship.model"));
const merge_1 = __importDefault(require("../utils/merge"));
/**
* The {@linkcode Relator} class is used to generate top-level [included data](https://jsonapi.org/format/#document-top-level)
* The {@link Relator} class is used to generate top-level [included data](https://jsonapi.org/format/#document-top-level)
* as well as resource-level [relationships](https://jsonapi.org/format/#document-resource-object-relationships).

@@ -85,15 +17,25 @@ *

*/
var Relator = /** @class */ (function () {
class Relator {
/**
* Creates a {@linkcode Relator}.
* Default options. Can be edited to change default options globally.
*/
static defaultOptions = {
linkers: {},
};
/**
* Options for relator.
*/
options;
relatedName;
/**
* Creates a {@link Relator}.
*
* @param fetch Fetches related data from primary data.
* @param serializer The `Serializer` to use for related data.
* @param options Options for the relator.
* @param fetch - Fetches related data from primary data.
* @param serializer - The `Serializer` to use for related data.
* @param options - Options for the relator.
*/
function Relator(fetch, serializer, options) {
if (options === void 0) { options = {}; }
constructor(fetch, serializer, options = {}) {
// Setting default options
this.relatedName = serializer.collectionName;
this.options = merge_1["default"]({}, Relator.defaultOptions, options);
this.options = (0, merge_1.default)({}, Relator.defaultOptions, options);
this.getRelatedData = fetch;

@@ -104,16 +46,24 @@ this.getRelatedResource = serializer.createResource.bind(serializer);

}
/** @internal Gets related data from primary data. */
getRelatedData;
/** @internal Gets related relators */
getRelatedRelators;
/** @internal Creates related identifiers */
getRelatedIdentifier;
/** @internal Creates related resources */
getRelatedResource;
/** @internal Gets related links from primary data and related data */
Relator.prototype.getRelatedLinks = function (data, relatedData) {
var links;
getRelatedLinks(data, relatedData) {
let links;
if (this.options.linkers.relationship) {
links = __assign(__assign({}, links), { self: this.options.linkers.relationship.link(data, relatedData) });
links = { ...links, self: this.options.linkers.relationship.link(data, relatedData) };
}
if (this.options.linkers.related) {
links = __assign(__assign({}, links), { related: this.options.linkers.related.link(data, relatedData) });
links = { ...links, related: this.options.linkers.related.link(data, relatedData) };
}
return links;
};
}
/** @internal Gets related meta from primary data and related data */
Relator.prototype.getRelatedMeta = function (data, relatedData) {
var meta;
getRelatedMeta(data, relatedData) {
let meta;
if (this.options.metaizer) {

@@ -123,49 +73,35 @@ meta = this.options.metaizer.metaize(data, relatedData);

return meta;
};
/** @internal Creates a {@linkcode Relationship}. */
Relator.prototype.getRelationship = function (data, relatedDataCache) {
return __awaiter(this, void 0, void 0, function () {
var relationshipOptions, relatedData, links, meta;
var _this = this;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
relationshipOptions = {};
return [4 /*yield*/, this.getRelatedData(data)];
case 1:
relatedData = _a.sent();
if (relatedData && relatedDataCache) {
relatedDataCache.push.apply(relatedDataCache, __spreadArray([], __read((Array.isArray(relatedData) ? relatedData : [relatedData]))));
}
links = this.getRelatedLinks(data, relatedData);
if (links)
relationshipOptions.links = links;
// Construct related resources.
if (relatedData !== undefined) {
if (relatedData === null) {
relationshipOptions.data = null;
}
else {
relationshipOptions.data = Array.isArray(relatedData)
? relatedData.map(function (data) { return _this.getRelatedIdentifier(data); })
: this.getRelatedIdentifier(relatedData);
}
}
meta = this.getRelatedMeta(data, relatedData);
if (meta)
relationshipOptions.meta = meta;
return [2 /*return*/, new relationship_model_1["default"](relationshipOptions)];
}
});
});
};
/**
* Default options. Can be edited to change default options globally.
*/
Relator.defaultOptions = {
linkers: {}
};
return Relator;
}());
exports["default"] = Relator;
}
/** @internal Creates a {@link Relationship}. */
async getRelationship(data, relatedDataCache) {
// Initialize options.
const relationshipOptions = {};
// Get related data.
const relatedData = await this.getRelatedData(data);
if (relatedData && relatedDataCache) {
relatedDataCache.push(...(Array.isArray(relatedData) ? relatedData : [relatedData]));
}
// Get related links.
const links = this.getRelatedLinks(data, relatedData);
if (links)
relationshipOptions.links = links;
// Construct related resources.
if (relatedData !== undefined) {
if (relatedData === null) {
relationshipOptions.data = null;
}
else {
relationshipOptions.data = Array.isArray(relatedData)
? relatedData.map((data) => this.getRelatedIdentifier(data))
: this.getRelatedIdentifier(relatedData);
}
}
// Get meta.
const meta = this.getRelatedMeta(data, relatedData);
if (meta)
relationshipOptions.meta = meta;
return new relationship_model_1.default(relationshipOptions);
}
}
exports.default = Relator;
//# sourceMappingURL=relator.js.map

@@ -10,4 +10,4 @@ import { DataDocument } from '../interfaces/json-api.interface';

/**
* The {@linkcode Serializer} class is the main class used to serializer data
* (you can use the {@linkcode ErrorSerializer} class to serialize errors).
* The {@link Serializer} class is the main class used to serializer data
* (you can use the {@link ErrorSerializer} class to serialize errors).
*

@@ -53,14 +53,14 @@ * Example:

/**
* Creates a {@linkcode Serializer}.
* Creates a {@link Serializer}.
*
* @param collectionName The name of the collection of objects.
* @param options Options for the serializer.
* @param collectionName - The name of the collection of objects.
* @param options - Options for the serializer.
*/
constructor(collectionName: string, options?: Partial<SerializerOptions<PrimaryType>>);
/**
* Gets the {@linkcode Relator}s associated with this serializer
* Gets the {@link Relator}s associated with this serializer
*/
getRelators(): Record<string, Relator<PrimaryType, any>> | undefined;
/**
* Sets the {@linkcode Relator}s associated with this serializer
* Sets the {@link Relator}s associated with this serializer
*/

@@ -75,4 +75,4 @@ setRelators(relators: SerializerOptions<PrimaryType>['relators']): void;

*
* @param data Data to serialize.
* @param options Options to use at runtime.
* @param data - Data to serialize.
* @param options - Options to use at runtime.
*/

@@ -79,0 +79,0 @@ serialize(data: SingleOrArray<PrimaryType> | nullish, options?: Partial<SerializerOptions<PrimaryType>>): Promise<Partial<DataDocument<PrimaryType>>>;

"use strict";
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
var __read = (this && this.__read) || function (o, n) {
var m = typeof Symbol === "function" && o[Symbol.iterator];
if (!m) return o;
var i = m.call(o), r, ar = [], e;
try {
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
}
catch (error) { e = { error: error }; }
finally {
try {
if (r && !r.done && (m = i["return"])) m.call(i);
}
finally { if (e) throw e.error; }
}
return ar;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
exports.__esModule = true;
var resource_identifier_model_1 = __importDefault(require("../models/resource-identifier.model"));
var resource_model_1 = __importDefault(require("../models/resource.model"));
var merge_1 = __importDefault(require("../utils/merge"));
var serializer_utils_1 = require("../utils/serializer.utils");
var cache_1 = __importDefault(require("./cache"));
Object.defineProperty(exports, "__esModule", { value: true });
const resource_identifier_model_1 = __importDefault(require("../models/resource-identifier.model"));
const resource_model_1 = __importDefault(require("../models/resource.model"));
const merge_1 = __importDefault(require("../utils/merge"));
const serializer_utils_1 = require("../utils/serializer.utils");
const cache_1 = __importDefault(require("./cache"));
/**
* The {@linkcode Serializer} class is the main class used to serializer data
* (you can use the {@linkcode ErrorSerializer} class to serialize errors).
* The {@link Serializer} class is the main class used to serializer data
* (you can use the {@link ErrorSerializer} class to serialize errors).
*

@@ -83,19 +20,46 @@ * Example:

*/
var Serializer = /** @class */ (function () {
class Serializer {
/**
* Creates a {@linkcode Serializer}.
* Default options. Can be edited to change default options globally.
*/
static defaultOptions = {
idKey: 'id',
version: '1.0',
onlyIdentifier: false,
nullData: false,
asIncluded: false,
onlyRelationship: false,
cache: false,
depth: 0,
projection: null,
linkers: {},
metaizers: {},
};
/**
* The name to use for the type.
*/
collectionName;
/**
* The set of options for the serializer.
*/
options;
/**
* The set of helper functions for the serializer
*/
helpers;
/**
* Caching
*/
cache = new cache_1.default();
/**
* Creates a {@link Serializer}.
*
* @param collectionName The name of the collection of objects.
* @param options Options for the serializer.
* @param collectionName - The name of the collection of objects.
* @param options - Options for the serializer.
*/
function Serializer(collectionName, options) {
if (options === void 0) { options = {}; }
/**
* Caching
*/
this.cache = new cache_1["default"]();
constructor(collectionName, options = {}) {
// Setting default options.
this.options = merge_1["default"]({}, Serializer.defaultOptions, options);
this.options = (0, merge_1.default)({}, Serializer.defaultOptions, options);
this.helpers = new serializer_utils_1.Helpers(this.options);
if (this.options.cache && this.options.cache instanceof cache_1["default"]) {
if (this.options.cache && this.options.cache instanceof cache_1.default) {
this.cache = this.options.cache;

@@ -107,255 +71,188 @@ }

/**
* Gets the {@linkcode Relator}s associated with this serializer
* Gets the {@link Relator}s associated with this serializer
*/
Serializer.prototype.getRelators = function () {
getRelators() {
return this.helpers.relators;
};
}
/**
* Sets the {@linkcode Relator}s associated with this serializer
* Sets the {@link Relator}s associated with this serializer
*/
Serializer.prototype.setRelators = function (relators) {
setRelators(relators) {
this.options.relators = relators;
this.helpers = new serializer_utils_1.Helpers(this.options);
};
}
/** @internal Generates a `ResourceIdentifier`. */
Serializer.prototype.createIdentifier = function (data, options) {
createIdentifier(data, options) {
// Get options
if (options === undefined)
options = this.options;
var identifierOptions = {};
const identifierOptions = {};
if (options.metaizers.resource) {
identifierOptions.meta = options.metaizers.resource.metaize(data);
}
return new resource_identifier_model_1["default"](data[options.idKey], this.collectionName, identifierOptions);
};
return new resource_identifier_model_1.default(data[options.idKey], this.collectionName, identifierOptions);
}
/** @internal Generates a `Resource`. */
Serializer.prototype.createResource = function (data, options, helpers, relatorDataCache) {
return __awaiter(this, void 0, void 0, function () {
var resourceOptions, id, type, relationships_1;
var _this = this;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
// Get options
if (options === undefined || helpers === undefined) {
options = this.options;
helpers = this.helpers;
}
resourceOptions = {};
id = data[options.idKey];
type = this.collectionName;
// Get attributes
resourceOptions.attributes = helpers.projectAttributes(data);
if (!helpers.relators) return [3 /*break*/, 2];
relationships_1 = {};
return [4 /*yield*/, Promise.all(Object.entries(helpers.relators).map(function (_a) {
var _b = __read(_a, 2), name = _b[0], relator = _b[1];
return __awaiter(_this, void 0, void 0, function () {
var relatedDataCache, _c, _d;
return __generator(this, function (_e) {
switch (_e.label) {
case 0:
if (relatorDataCache) {
relatedDataCache = relatorDataCache.get(relator) || [];
relatorDataCache.set(relator, relatedDataCache);
}
_c = relationships_1;
_d = name;
return [4 /*yield*/, relator.getRelationship(data, relatedDataCache)];
case 1:
_c[_d] = _e.sent();
return [2 /*return*/];
}
});
});
}))];
case 1:
_a.sent();
resourceOptions.relationships = relationships_1;
_a.label = 2;
case 2:
// Handling links
if (options.linkers.resource) {
resourceOptions.links = { self: options.linkers.resource.link(data) };
}
if (options.metaizers.resource) {
resourceOptions.meta = options.metaizers.resource.metaize(data);
}
return [2 /*return*/, new resource_model_1["default"](id, type, resourceOptions)];
async createResource(data, options, helpers, relatorDataCache) {
// Get options
if (options === undefined || helpers === undefined) {
options = this.options;
helpers = this.helpers;
}
const resourceOptions = {};
// Get ID before projections.
const id = data[options.idKey];
const type = this.collectionName;
// Get attributes
resourceOptions.attributes = helpers.projectAttributes(data);
// Handling relators
if (helpers.relators) {
const relationships = {};
await Promise.all(Object.entries(helpers.relators).map(async ([name, relator]) => {
let relatedDataCache;
if (relatorDataCache) {
relatedDataCache = relatorDataCache.get(relator) || [];
relatorDataCache.set(relator, relatedDataCache);
}
});
});
};
relationships[name] = await relator.getRelationship(data, relatedDataCache);
}));
resourceOptions.relationships = relationships;
}
// Handling links
if (options.linkers.resource) {
resourceOptions.links = { self: options.linkers.resource.link(data) };
}
if (options.metaizers.resource) {
resourceOptions.meta = options.metaizers.resource.metaize(data);
}
return new resource_model_1.default(id, type, resourceOptions);
}
/**
* The actual serialization function.
*
* @param data Data to serialize.
* @param options Options to use at runtime.
* @param data - Data to serialize.
* @param options - Options to use at runtime.
*/
Serializer.prototype.serialize = function (data, options) {
return __awaiter(this, void 0, void 0, function () {
var o, h, cache, storedDocument, document, relatorDataCache, keys, wasSingle, dto, createIdentifier, createResource, relators, relator_1, relatedData, links, meta, pagination, _a, _b, _c, _d, _e;
var _this = this;
return __generator(this, function (_f) {
switch (_f.label) {
case 0:
o = this.options;
h = this.helpers;
if (options !== undefined) {
o = merge_1["default"]({}, o, options);
h = new serializer_utils_1.Helpers(o);
}
cache = o.cache instanceof cache_1["default"] ? o.cache : this.cache;
if (o.cache) {
storedDocument = cache.get(data, options);
if (storedDocument) {
return [2 /*return*/, storedDocument];
}
}
document = {};
// Document versioning
if (o.version) {
document.jsonapi = __assign(__assign({}, document.jsonapi), { version: o.version });
}
if (o.metaizers.jsonapi) {
document.jsonapi = __assign(__assign({}, document.jsonapi), { meta: o.metaizers.jsonapi.metaize() });
}
relatorDataCache = new Map();
keys = [];
wasSingle = false;
if (!o.onlyRelationship) return [3 /*break*/, 2];
// Validate options.
if (h.relators === undefined) {
throw new TypeError("\"relators\" must be defined when using \"onlyRelationship\"");
}
if (!data || Array.isArray(data)) {
throw new TypeError("Cannot serialize multiple primary datum using \"onlyRelationship\"");
}
relator_1 = h.relators[o.onlyRelationship];
if (relator_1 === undefined) {
throw new TypeError("\"onlyRelationship\" is not the name of any collection name among the relators listed in \"relators\"");
}
return [4 /*yield*/, relator_1.getRelatedData(data)];
case 1:
relatedData = _f.sent();
links = relator_1.getRelatedLinks(data, relatedData);
if (links)
document.links = links;
meta = relator_1.getRelatedMeta(data, relatedData);
if (meta)
document.meta = meta;
createIdentifier = function (datum) { return relator_1.getRelatedIdentifier(datum); };
createResource = function (datum) { return __awaiter(_this, void 0, void 0, function () {
var resource;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, relator_1.getRelatedResource(datum)];
case 1:
resource = _a.sent();
keys.push(resource.getKey());
return [2 /*return*/, resource];
}
});
}); };
relators = relator_1.getRelatedRelators();
dto = relatedData;
return [3 /*break*/, 3];
case 2:
// Handle meta
if (o.metaizers.document) {
document.meta = o.metaizers.document.metaize(data);
}
// Handle links
if (o.linkers.document) {
document.links = __assign(__assign({}, document.links), { self: o.linkers.document.link(data) });
}
// Handle pagination links
if (o.linkers.paginator) {
pagination = o.linkers.paginator.paginate(data);
if (pagination) {
document.links = __assign(__assign({}, document.links), pagination);
}
}
createIdentifier = function (datum) { return _this.createIdentifier(datum, o); };
createResource = function (datum) { return __awaiter(_this, void 0, void 0, function () {
var resource;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, this.createResource(datum, o, h, relatorDataCache)];
case 1:
resource = _a.sent();
keys.push(resource.getKey());
return [2 /*return*/, resource];
}
});
}); };
relators = h.relators;
dto = data;
_f.label = 3;
case 3:
if (dto === undefined) {
return [2 /*return*/, cache.set(data, document, options)];
}
if (o.nullData || dto === null) {
document.data = null;
return [2 /*return*/, cache.set(data, document, options)];
}
// Handle `onlyIdentifier` option
if (o.onlyIdentifier) {
document.data = Array.isArray(dto) ? dto.map(createIdentifier) : createIdentifier(dto);
return [2 /*return*/, cache.set(data, document, options)];
}
if (!Array.isArray(dto)) {
wasSingle = true;
dto = [dto];
}
if (!o.asIncluded) return [3 /*break*/, 5];
document.data = dto.map(createIdentifier);
_a = document;
return [4 /*yield*/, Promise.all(dto.map(createResource))];
case 4:
_a.included = _f.sent();
return [3 /*break*/, 7];
case 5:
_b = document;
return [4 /*yield*/, Promise.all(dto.map(createResource))];
case 6:
_b.data = _f.sent();
_f.label = 7;
case 7:
if (!(relators && o.depth > 0)) return [3 /*break*/, 9];
_c = document;
_e = (_d = (document.included || [])).concat;
return [4 /*yield*/, serializer_utils_1.recurseRelators(dto, relators, o.depth, keys, relatorDataCache)];
case 8:
_c.included = _e.apply(_d, [_f.sent()]);
_f.label = 9;
case 9:
if (wasSingle) {
document.data = document.data[0];
}
return [2 /*return*/, cache.set(data, document, options)];
async serialize(data, options) {
// Merge options.
let o = this.options;
let h = this.helpers;
if (options !== undefined) {
o = (0, merge_1.default)({}, o, options);
h = new serializer_utils_1.Helpers(o);
}
const cache = o.cache instanceof cache_1.default ? o.cache : this.cache;
if (o.cache) {
const storedDocument = cache.get(data, options);
if (storedDocument) {
return storedDocument;
}
}
// Construct initial document and included data
const document = {};
// Document versioning
if (o.version) {
document.jsonapi = { ...document.jsonapi, version: o.version };
}
if (o.metaizers.jsonapi) {
document.jsonapi = { ...document.jsonapi, meta: o.metaizers.jsonapi.metaize() };
}
// Cache data fetched during resource creation
const relatorDataCache = new Map();
const keys = [];
let wasSingle = false;
let dto;
let createIdentifier;
let createResource;
let relators;
// Check if only a relationship is desired
if (o.onlyRelationship) {
// Validate options.
if (h.relators === undefined) {
throw new TypeError(`"relators" must be defined when using "onlyRelationship"`);
}
if (!data || Array.isArray(data)) {
throw new TypeError(`Cannot serialize multiple primary datum using "onlyRelationship"`);
}
const relator = h.relators[o.onlyRelationship];
if (relator === undefined) {
throw new TypeError(`"onlyRelationship" is not the name of any collection name among the relators listed in "relators"`);
}
// Handle related data
const relatedData = await relator.getRelatedData(data);
// Handle related links
const links = relator.getRelatedLinks(data, relatedData);
if (links)
document.links = links;
// Handle related meta
const meta = relator.getRelatedMeta(data, relatedData);
if (meta)
document.meta = meta;
createIdentifier = (datum) => relator.getRelatedIdentifier(datum);
createResource = async (datum) => {
const resource = await relator.getRelatedResource(datum);
keys.push(resource.getKey());
return resource;
};
relators = relator.getRelatedRelators();
dto = relatedData;
}
else {
// Handle meta
if (o.metaizers.document) {
document.meta = o.metaizers.document.metaize(data);
}
// Handle links
if (o.linkers.document) {
document.links = { ...document.links, self: o.linkers.document.link(data) };
}
// Handle pagination links
if (o.linkers.paginator) {
const pagination = o.linkers.paginator.paginate(data);
if (pagination) {
document.links = { ...document.links, ...pagination };
}
});
});
};
/**
* Default options. Can be edited to change default options globally.
*/
Serializer.defaultOptions = {
idKey: 'id',
version: '1.0',
onlyIdentifier: false,
nullData: false,
asIncluded: false,
onlyRelationship: false,
cache: false,
depth: 0,
projection: null,
linkers: {},
metaizers: {}
};
return Serializer;
}());
exports["default"] = Serializer;
}
createIdentifier = (datum) => this.createIdentifier(datum, o);
createResource = async (datum) => {
const resource = await this.createResource(datum, o, h, relatorDataCache);
keys.push(resource.getKey());
return resource;
};
relators = h.relators;
dto = data;
}
if (dto === undefined) {
return cache.set(data, document, options);
}
if (o.nullData || dto === null) {
document.data = null;
return cache.set(data, document, options);
}
// Handle `onlyIdentifier` option
if (o.onlyIdentifier) {
document.data = Array.isArray(dto) ? dto.map(createIdentifier) : createIdentifier(dto);
return cache.set(data, document, options);
}
if (!Array.isArray(dto)) {
wasSingle = true;
dto = [dto];
}
if (o.asIncluded) {
document.data = dto.map(createIdentifier);
document.included = await Promise.all(dto.map(createResource));
}
else {
document.data = await Promise.all(dto.map(createResource));
}
if (relators && o.depth > 0) {
document.included = (document.included || []).concat(await (0, serializer_utils_1.recurseRelators)(dto, relators, o.depth, keys, relatorDataCache));
}
if (wasSingle) {
document.data = document.data[0];
}
return cache.set(data, document, options);
}
}
exports.default = Serializer;
//# sourceMappingURL=serializer.js.map
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {

@@ -12,20 +16,23 @@ if (k2 === undefined) k2 = k;

};
exports.__esModule = true;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Serializer = exports.ErrorSerializer = exports.JapiError = exports.Relator = exports.Paginator = exports.Metaizer = exports.Linker = exports.Cache = void 0;
var cache_1 = require("./classes/cache");
__createBinding(exports, cache_1, "default", "Cache");
Object.defineProperty(exports, "Cache", { enumerable: true, get: function () { return __importDefault(cache_1).default; } });
var linker_1 = require("./classes/linker");
__createBinding(exports, linker_1, "default", "Linker");
Object.defineProperty(exports, "Linker", { enumerable: true, get: function () { return __importDefault(linker_1).default; } });
var metaizer_1 = require("./classes/metaizer");
__createBinding(exports, metaizer_1, "default", "Metaizer");
Object.defineProperty(exports, "Metaizer", { enumerable: true, get: function () { return __importDefault(metaizer_1).default; } });
var paginator_1 = require("./classes/paginator");
__createBinding(exports, paginator_1, "default", "Paginator");
Object.defineProperty(exports, "Paginator", { enumerable: true, get: function () { return __importDefault(paginator_1).default; } });
var relator_1 = require("./classes/relator");
__createBinding(exports, relator_1, "default", "Relator");
Object.defineProperty(exports, "Relator", { enumerable: true, get: function () { return __importDefault(relator_1).default; } });
var error_model_1 = require("./models/error.model");
__createBinding(exports, error_model_1, "default", "JapiError");
Object.defineProperty(exports, "JapiError", { enumerable: true, get: function () { return __importDefault(error_model_1).default; } });
var error_serializer_1 = require("./classes/error-serializer");
__createBinding(exports, error_serializer_1, "default", "ErrorSerializer");
Object.defineProperty(exports, "ErrorSerializer", { enumerable: true, get: function () { return __importDefault(error_serializer_1).default; } });
var serializer_1 = require("./classes/serializer");
__createBinding(exports, serializer_1, "default", "Serializer");
Object.defineProperty(exports, "Serializer", { enumerable: true, get: function () { return __importDefault(serializer_1).default; } });
__exportStar(require("./interfaces/cache.interface"), exports);

@@ -32,0 +39,0 @@ __exportStar(require("./interfaces/error-serializer.interface"), exports);

@@ -6,3 +6,3 @@ import { SingleOrArray, nullish } from '../types/global.types';

*
* @default `10`
* @defaultValue `10`
*/

@@ -13,3 +13,3 @@ limit: number;

*
* @default `Object.is`
* @defaultValue `Object.is`
*/

@@ -16,0 +16,0 @@ resolver(storedData: SingleOrArray<DataType> | nullish, newData: SingleOrArray<DataType> | nullish): boolean;

"use strict";
exports.__esModule = true;
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=cache.interface.js.map

@@ -9,3 +9,3 @@ import Linker from '../classes/linker';

*
* @default `"id"`
* @defaultValue `"id"`
*/

@@ -16,3 +16,3 @@ id: keyof T;

*
* @default `"code"`
* @defaultValue `"code"`
*/

@@ -23,3 +23,3 @@ status: keyof T;

*
* @default `"name"`
* @defaultValue `"name"`
*/

@@ -32,3 +32,3 @@ code: keyof T;

*
* @default `"reason"`
* @defaultValue `"reason"`
*/

@@ -40,3 +40,3 @@ title: keyof T;

*
* @default `"message"`
* @defaultValue `"message"`
*/

@@ -56,3 +56,3 @@ detail: keyof T;

*
* @default `"location"`
* @defaultValue `"location"`
*/

@@ -63,3 +63,3 @@ pointer: keyof T;

*
* @default `undefined`
* @defaultValue `undefined`
*/

@@ -72,3 +72,3 @@ parameter: keyof T;

*
* @default `1.0`
* @defaultValue `1.0`
*/

@@ -78,3 +78,3 @@ version: string | null;

* An object of attribute names to use in place of the
* {@linkcode ErrorAttributeOption | default ones}.
* {@link ErrorAttributeOption | default ones}.
*/

@@ -87,3 +87,3 @@ attributes: Partial<ErrorAttributeOption<T>>;

/**
* A {@linkcode Linker} that gets the [about link](https://jsonapi.org/format/#errors) for an error.
* A {@link Linker} that gets the [about link](https://jsonapi.org/format/#errors) for an error.
*/

@@ -93,3 +93,3 @@ about?: Linker<[JapiError]>;

/**
* A dictionary of {@linkcode Metaizer}s to use in different locations of the document.
* A dictionary of {@link Metaizer}s to use in different locations of the document.
*/

@@ -96,0 +96,0 @@ metaizers: {

"use strict";
exports.__esModule = true;
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=error-serializer.interface.js.map
"use strict";
exports.__esModule = true;
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=error.interface.js.map
"use strict";
exports.__esModule = true;
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=json-api.interface.js.map
import Metaizer from '../classes/metaizer';
export interface LinkerOptions<Dependencies extends any[]> {
/**
* A {@linkcode Metaizer} that gets the
* A {@link Metaizer} that gets the
* [meta](https://jsonapi.org/format/#document-resource-object-relationships)

@@ -6,0 +6,0 @@ * about the link.

"use strict";
exports.__esModule = true;
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=linker.interface.js.map
"use strict";
exports.__esModule = true;
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=paginator.interface.js.map

@@ -6,3 +6,3 @@ import Linker from '../classes/linker';

/**
* A dictionary of {@linkcode Linker}s to use for constructing links.
* A dictionary of {@link Linker}s to use for constructing links.
*

@@ -13,3 +13,3 @@ * @see {@link https://jsonapi.org/format/#document-resource-object-relationships | Resource object relationships} for more information.

/**
* A {@linkcode Linker} that gets the [self link](https://jsonapi.org/format/#document-resource-object-relationships)
* A {@link Linker} that gets the [self link](https://jsonapi.org/format/#document-resource-object-relationships)
* between the primary data and the (array of) related data.

@@ -19,3 +19,3 @@ */

/**
* A {@linkcode Linker} that gets the [related link](https://jsonapi.org/format/#document-resource-object-relationships)
* A {@link Linker} that gets the [related link](https://jsonapi.org/format/#document-resource-object-relationships)
* between the primary data and the (array of) related data.

@@ -26,3 +26,3 @@ */

/**
* A {@linkcode Metaizer} that gets the
* A {@link Metaizer} that gets the
* [meta](https://jsonapi.org/format/#document-resource-object-relationships)

@@ -29,0 +29,0 @@ * about the relationship.

"use strict";
exports.__esModule = true;
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=relator.interface.js.map

@@ -11,3 +11,3 @@ import Linker from '../classes/linker';

*
* @default `"id"`
* @defaultValue `"id"`
*/

@@ -18,10 +18,10 @@ idKey: keyof PrimaryType;

*
* @default `1.0`
* @defaultValue `1.0`
*/
version: string | null;
/**
* Enables caching of documents. If a {@linkcode Cache} is given, then the
* given {@linkcode Cache} will be used.
* Enables caching of documents. If a {@link Cache} is given, then the
* given {@link Cache} will be used.
*
* @default `false`
* @defaultValue `false`
*/

@@ -33,8 +33,8 @@ cache: boolean | Cache<PrimaryType>;

* This option will ignore options
* {@linkcode SerializerOptions.onlyIdentifier | onlyIdentifier},
* {@linkcode SerializerOptions.linkers | linkers.resource}, and
* {@linkcode SerializerOptions.metaizers | metaizers.resource}
* {@link SerializerOptions.onlyIdentifier | onlyIdentifier},
* {@link SerializerOptions.linkers | linkers.resource}, and
* {@link SerializerOptions.metaizers | metaizers.resource}
* (and all options they ignores).
*
* @default `false`
* @defaultValue `false`
*/

@@ -46,5 +46,5 @@ nullData: boolean;

* This option will ignore the options
* {@linkcode SerializerOptions.depth | depth}
* {@link SerializerOptions.depth | depth}
*
* @default `false`
* @defaultValue `false`
*/

@@ -55,3 +55,3 @@ onlyIdentifier: boolean;

* only. The value must be the name of a collection for a relator in the
* {@linkcode SerializerOptions.relators | relators} option.
* {@link SerializerOptions.relators | relators} option.
*

@@ -62,5 +62,5 @@ * Only a single primary datum (as opposed to an array) **MUST**

* This option will ignore the options
* {@linkcode SerializerOptions.projection | projection},
* {@linkcode SerializerOptions.linkers | linkers.resource}, and
* {@linkcode SerializerOptions.metaizers | metaizers.resource}.
* {@link SerializerOptions.projection | projection},
* {@link SerializerOptions.linkers | linkers.resource}, and
* {@link SerializerOptions.metaizers | metaizers.resource}.
*/

@@ -73,3 +73,3 @@ onlyRelationship: string;

*
* @default `false`
* @defaultValue `false`
*/

@@ -87,3 +87,3 @@ asIncluded: boolean;

*
* @default `0`
* @defaultValue `0`
*/

@@ -98,9 +98,9 @@ depth: number;

*
* @default `null`
* @defaultValue `null`
*/
projection: Partial<Record<keyof PrimaryType, 0 | 1>> | null | undefined;
/**
* A {@linkcode Relator} that generates `relationships` for a given primary resource.
* A {@link Relator} that generates `relationships` for a given primary resource.
*
* *Note*: You can add more relators by using {@linkcode Serializer.setRelators}. This is useful in
* *Note*: You can add more relators by using {@link Serializer.setRelators}. This is useful in
* case you have a cycle of relators among serializers.

@@ -117,11 +117,11 @@ *

/**
* A {@linkcode Linker} that gets represents a [top-level self link](https://jsonapi.org/format/#document-top-level).
* A {@link Linker} that gets represents a [top-level self link](https://jsonapi.org/format/#document-top-level).
*/
document?: Linker<[SingleOrArray<PrimaryType> | nullish]>;
/**
* A {@linkcode Linker} that represents a [resource-level self link](https://jsonapi.org/format/#document-resource-objects).
* A {@link Linker} that represents a [resource-level self link](https://jsonapi.org/format/#document-resource-objects).
*/
resource?: Linker<[PrimaryType]>;
/**
* A {@linkcode Paginator} to use for [pagination links](https://jsonapi.org/format/#fetching-pagination).
* A {@link Paginator} to use for [pagination links](https://jsonapi.org/format/#fetching-pagination).
*/

@@ -131,3 +131,3 @@ paginator?: Paginator<PrimaryType>;

/**
* A dictionary of {@linkcode Metaizer}s to use in different locations of the document.
* A dictionary of {@link Metaizer}s to use in different locations of the document.
*/

@@ -134,0 +134,0 @@ metaizers: {

"use strict";
exports.__esModule = true;
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=serializer.interface.js.map

@@ -9,3 +9,3 @@ import { Dictionary, nullish } from '..';

*
* @param error An unknown object
* @param error - An unknown object
*/

@@ -12,0 +12,0 @@ static isLikeJapiError(error: unknown): error is Partial<JapiError>;

"use strict";
exports.__esModule = true;
var is_object_1 = require("../utils/is-object");
var JapiError = /** @class */ (function () {
function JapiError(options) {
if (options === void 0) { options = {}; }
Object.defineProperty(exports, "__esModule", { value: true });
const is_object_1 = require("../utils/is-object");
class JapiError {
/**
* Tests whether `error` has similar attributes to a JapiError
*
* @param error - An unknown object
*/
static isLikeJapiError(error) {
if (!(0, is_object_1.isObject)(error))
return false;
return (['id', 'status', 'code', 'title', 'detail', 'source', 'links', 'meta'].some((attrName) => attrName in error) &&
[
['id', 'status', 'code', 'title', 'detail'].every((attrName) => !(attrName in error) || typeof error[attrName] === 'string'),
['source', 'links', 'meta'].every((attrName) => !(attrName in error) || (0, is_object_1.isObject)(error[attrName])),
].every((v) => v));
}
/** @internal */
stack;
/**
* A unique identifier for this particular occurrence of the problem.
*/
id;
/**
* The HTTP status code applicable to this problem, expressed as a string
* value.
*/
status;
/**
* An application-specific error code, expressed as a string value.
*/
code;
/**
* A short, human-readable summary of the problem that SHOULD NOT change from
* occurrence to occurrence of the problem, except for purposes of
* localization.
*/
title;
/**
* A human-readable explanation specific to this occurrence of the problem.
* Like title, this field’s value can be localized.
*/
detail;
/**
* An object containing references to the source of the error, optionally
* including any of the following members.
*/
source;
/**
* A links object
*/
links;
/**
* A meta object containing non-standard meta information about the error.
*/
meta;
constructor(options = {}) {
if (options.id)

@@ -21,19 +73,4 @@ this.id = options.id;

}
/**
* Tests whether `error` has similar attributes to a JapiError
*
* @param error An unknown object
*/
JapiError.isLikeJapiError = function (error) {
if (!is_object_1.isObject(error))
return false;
return (['id', 'status', 'code', 'title', 'detail', 'source', 'links', 'meta'].some(function (attrName) { return attrName in error; }) &&
[
['id', 'status', 'code', 'title', 'detail'].every(function (attrName) { return !(attrName in error) || typeof error[attrName] === 'string'; }),
['source', 'links', 'meta'].every(function (attrName) { return !(attrName in error) || is_object_1.isObject(error[attrName]); }),
].every(function (v) { return v; }));
};
return JapiError;
}());
exports["default"] = JapiError;
}
exports.default = JapiError;
//# sourceMappingURL=error.model.js.map
"use strict";
exports.__esModule = true;
var url_1 = require("url");
var Link = /** @class */ (function () {
function Link(href, meta) {
this.toJSON = this.toString.bind(this);
Object.defineProperty(exports, "__esModule", { value: true });
const url_1 = require("url");
class Link {
url;
meta;
constructor(href, meta) {
this.url = new url_1.URL(href);
this.meta = meta;
}
Link.prototype.toString = function () {
toJSON = this.toString.bind(this);
toString() {
return this.meta ? { href: this.url.href, meta: this.meta } : this.url.href;
};
return Link;
}());
exports["default"] = Link;
}
}
exports.default = Link;
//# sourceMappingURL=link.model.js.map
"use strict";
exports.__esModule = true;
var Meta = /** @class */ (function () {
function Meta(meta) {
Object.defineProperty(exports, "__esModule", { value: true });
class Meta {
constructor(meta) {
Object.assign(this, meta);
}
return Meta;
}());
exports["default"] = Meta;
}
exports.default = Meta;
//# sourceMappingURL=meta.model.js.map
"use strict";
exports.__esModule = true;
var Relationship = /** @class */ (function () {
function Relationship(options) {
Object.defineProperty(exports, "__esModule", { value: true });
class Relationship {
links;
data;
meta;
constructor(options) {
// data can be explicitly set to null for empty to-one relationships

@@ -16,5 +19,4 @@ if (typeof options.data !== 'undefined')

}
return Relationship;
}());
exports["default"] = Relationship;
}
exports.default = Relationship;
//# sourceMappingURL=relationship.model.js.map
"use strict";
exports.__esModule = true;
var ResourceIdentifier = /** @class */ (function () {
function ResourceIdentifier(id, type, options) {
Object.defineProperty(exports, "__esModule", { value: true });
class ResourceIdentifier {
type;
id;
meta;
constructor(id, type, options) {
this.type = type;

@@ -10,8 +13,7 @@ this.id = id;

}
ResourceIdentifier.prototype.getKey = function () {
return "[" + this.type + ":" + this.id + "]";
};
return ResourceIdentifier;
}());
exports["default"] = ResourceIdentifier;
getKey() {
return `[${this.type}:${this.id}]`;
}
}
exports.default = ResourceIdentifier;
//# sourceMappingURL=resource-identifier.model.js.map
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
exports.__esModule = true;
var resource_identifier_model_1 = __importDefault(require("./resource-identifier.model"));
var Resource = /** @class */ (function (_super) {
__extends(Resource, _super);
function Resource(id, type, options) {
var _this = _super.call(this, id, type, options) || this;
Object.defineProperty(exports, "__esModule", { value: true });
const resource_identifier_model_1 = __importDefault(require("./resource-identifier.model"));
class Resource extends resource_identifier_model_1.default {
attributes;
links;
relationships;
constructor(id, type, options) {
super(id, type, options);
if (options.attributes)
_this.attributes = options.attributes;
this.attributes = options.attributes;
if (options.relationships)
_this.relationships = options.relationships;
this.relationships = options.relationships;
if (options.links)
_this.links = options.links;
return _this;
this.links = options.links;
}
return Resource;
}(resource_identifier_model_1["default"]));
exports["default"] = Resource;
}
exports.default = Resource;
//# sourceMappingURL=resource.model.js.map
"use strict";
exports.__esModule = true;
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=global.types.js.map

@@ -5,5 +5,5 @@ import { ErrorDocument } from '../interfaces/json-api.interface';

*
* @param document An unknown object
* @param document - An unknown object
*/
export declare function isErrorDocument(document: unknown): document is ErrorDocument;
//# sourceMappingURL=is-error-document.d.ts.map

@@ -5,20 +5,18 @@ "use strict";

};
exports.__esModule = true;
Object.defineProperty(exports, "__esModule", { value: true });
exports.isErrorDocument = void 0;
var is_plain_object_1 = require("./is-plain-object");
var error_model_1 = __importDefault(require("../models/error.model"));
const is_plain_object_1 = require("./is-plain-object");
const error_model_1 = __importDefault(require("../models/error.model"));
/**
* Detects an `ErrorDocument` like object
*
* @param document An unknown object
* @param document - An unknown object
*/
function isErrorDocument(document) {
return (is_plain_object_1.isPlainObject(document) &&
return ((0, is_plain_object_1.isPlainObject)(document) &&
Array.isArray(document.errors) &&
('jsonapi' in document ||
document.errors.every(function (error) {
return error instanceof error_model_1["default"] ? true : error_model_1["default"].isLikeJapiError(error);
})));
document.errors.every((error) => error instanceof error_model_1.default ? true : error_model_1.default.isLikeJapiError(error))));
}
exports.isErrorDocument = isErrorDocument;
//# sourceMappingURL=is-error-document.js.map
"use strict";
exports.__esModule = true;
Object.defineProperty(exports, "__esModule", { value: true });
exports.isObject = void 0;

@@ -4,0 +4,0 @@ function isObject(o) {

"use strict";
exports.__esModule = true;
Object.defineProperty(exports, "__esModule", { value: true });
exports.isPlainObject = void 0;
var is_object_1 = require("./is-object");
const is_object_1 = require("./is-object");
function isPlainObject(o) {
if (!is_object_1.isObject(o))
if (!(0, is_object_1.isObject)(o))
return false;

@@ -12,3 +12,3 @@ // If constructor was modified

// If prototype was modified
if (!is_object_1.isObject(o.constructor.prototype))
if (!(0, is_object_1.isObject)(o.constructor.prototype))
return false;

@@ -15,0 +15,0 @@ // eslint-disable-next-line no-prototype-builtins

@@ -5,6 +5,6 @@ import { Dictionary, UnionToIntersection } from '../types/global.types';

*
* @param target The object to merge into
* @param source The objects to use for merging
* @param target - The object to merge into
* @param source - The objects to use for merging
*/
export default function merge<T extends Dictionary<any>, U extends Dictionary<any>[]>(target: T, ...sources: U): T & UnionToIntersection<U[number]>;
//# sourceMappingURL=merge.d.ts.map
"use strict";
var __values = (this && this.__values) || function(o) {
var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
if (m) return m.call(o);
if (o && typeof o.length === "number") return {
next: function () {
if (o && i >= o.length) o = void 0;
return { value: o && o[i++], done: !o };
}
};
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
};
var __read = (this && this.__read) || function (o, n) {
var m = typeof Symbol === "function" && o[Symbol.iterator];
if (!m) return o;
var i = m.call(o), r, ar = [], e;
try {
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
}
catch (error) { e = { error: error }; }
finally {
try {
if (r && !r.done && (m = i["return"])) m.call(i);
}
finally { if (e) throw e.error; }
}
return ar;
};
var __spreadArray = (this && this.__spreadArray) || function (to, from) {
for (var i = 0, il = from.length, j = to.length; i < il; i++, j++)
to[j] = from[i];
return to;
};
exports.__esModule = true;
var is_plain_object_1 = require("./is-plain-object");
Object.defineProperty(exports, "__esModule", { value: true });
const is_plain_object_1 = require("./is-plain-object");
/**
* Deep merge two objects over their enumerable properties.
*
* @param target The object to merge into
* @param source The objects to use for merging
* @param target - The object to merge into
* @param source - The objects to use for merging
*/
function merge(target) {
var e_1, _a, _b, _c;
var sources = [];
for (var _i = 1; _i < arguments.length; _i++) {
sources[_i - 1] = arguments[_i];
}
function merge(target, ...sources) {
if (!sources.length)
return target;
var source = sources.shift();
if (is_plain_object_1.isPlainObject(target) && is_plain_object_1.isPlainObject(source)) {
try {
for (var _d = __values(Object.keys(source)), _e = _d.next(); !_e.done; _e = _d.next()) {
var key = _e.value;
if (is_plain_object_1.isPlainObject(source[key])) {
if (!target[key])
Object.assign(target, (_b = {}, _b[key] = {}, _b));
merge(target[key], source[key]);
}
else {
Object.assign(target, (_c = {}, _c[key] = source[key], _c));
}
const source = sources.shift();
if ((0, is_plain_object_1.isPlainObject)(target) && (0, is_plain_object_1.isPlainObject)(source)) {
for (const key of Object.keys(source)) {
if ((0, is_plain_object_1.isPlainObject)(source[key])) {
if (!target[key])
Object.assign(target, { [key]: {} });
merge(target[key], source[key]);
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (_e && !_e.done && (_a = _d["return"])) _a.call(_d);
else {
Object.assign(target, { [key]: source[key] });
}
finally { if (e_1) throw e_1.error; }
}
}
return merge.apply(void 0, __spreadArray([target], __read(sources)));
return merge(target, ...sources);
}
exports["default"] = merge;
exports.default = merge;
//# sourceMappingURL=merge.js.map
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
Object.defineProperty(exports, "__esModule", { value: true });
exports.Helpers = exports.normalizeRelators = exports.recurseRelators = void 0;
const relator_1 = __importDefault(require("../classes/relator"));
async function recurseRelators(data, relators, depth, keys, relatorDataCache) {
const included = [];
let curRelatorDataCache = relatorDataCache || new Map();
// Required to support backwards compatability where the first dataCache may
// not be passed in. All subsequent iterations will contain a dataCache
if (!relatorDataCache && depth > 0) {
for (const name in relators) {
const cache = curRelatorDataCache.get(relators[name]) || [];
curRelatorDataCache.set(relators[name], cache);
for (const datum of data) {
const relatedData = await relators[name].getRelatedData(datum);
if (relatedData !== null) {
cache.push(...(Array.isArray(relatedData) ? relatedData : [relatedData]));
}
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
var __values = (this && this.__values) || function(o) {
var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
if (m) return m.call(o);
if (o && typeof o.length === "number") return {
next: function () {
if (o && i >= o.length) o = void 0;
return { value: o && o[i++], done: !o };
}
};
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
};
var __read = (this && this.__read) || function (o, n) {
var m = typeof Symbol === "function" && o[Symbol.iterator];
if (!m) return o;
var i = m.call(o), r, ar = [], e;
try {
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
}
catch (error) { e = { error: error }; }
finally {
try {
if (r && !r.done && (m = i["return"])) m.call(i);
while (depth-- > 0 && curRelatorDataCache.size > 0) {
const newRelatorDataCache = new Map();
for (const [relator, cache] of curRelatorDataCache) {
for (let i = 0; i < cache.length; i++) {
const resource = await relator.getRelatedResource(cache[i], undefined, undefined, newRelatorDataCache);
const key = resource.getKey();
if (!keys.includes(key)) {
keys.push(key);
included.push(resource);
}
}
}
finally { if (e) throw e.error; }
curRelatorDataCache = newRelatorDataCache;
}
return ar;
};
var __spreadArray = (this && this.__spreadArray) || function (to, from) {
for (var i = 0, il = from.length, j = to.length; i < il; i++, j++)
to[j] = from[i];
return to;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
exports.__esModule = true;
exports.Helpers = exports.normalizeRelators = exports.recurseRelators = void 0;
var relator_1 = __importDefault(require("../classes/relator"));
function recurseRelators(data, relators, depth, keys, relatorDataCache) {
return __awaiter(this, void 0, void 0, function () {
var included, curRelatorDataCache, _a, _b, _i, name_1, cache, data_1, data_1_1, datum, relatedData, e_1_1, newRelatorDataCache, curRelatorDataCache_1, curRelatorDataCache_1_1, _c, relator, cache, i, resource, key, e_2_1;
var e_1, _d, e_2, _e;
return __generator(this, function (_f) {
switch (_f.label) {
case 0:
included = [];
curRelatorDataCache = relatorDataCache || new Map();
if (!(!relatorDataCache && depth > 0)) return [3 /*break*/, 10];
_a = [];
for (_b in relators)
_a.push(_b);
_i = 0;
_f.label = 1;
case 1:
if (!(_i < _a.length)) return [3 /*break*/, 10];
name_1 = _a[_i];
cache = curRelatorDataCache.get(relators[name_1]) || [];
curRelatorDataCache.set(relators[name_1], cache);
_f.label = 2;
case 2:
_f.trys.push([2, 7, 8, 9]);
data_1 = (e_1 = void 0, __values(data)), data_1_1 = data_1.next();
_f.label = 3;
case 3:
if (!!data_1_1.done) return [3 /*break*/, 6];
datum = data_1_1.value;
return [4 /*yield*/, relators[name_1].getRelatedData(datum)];
case 4:
relatedData = _f.sent();
if (relatedData !== null) {
cache.push.apply(cache, __spreadArray([], __read((Array.isArray(relatedData) ? relatedData : [relatedData]))));
}
_f.label = 5;
case 5:
data_1_1 = data_1.next();
return [3 /*break*/, 3];
case 6: return [3 /*break*/, 9];
case 7:
e_1_1 = _f.sent();
e_1 = { error: e_1_1 };
return [3 /*break*/, 9];
case 8:
try {
if (data_1_1 && !data_1_1.done && (_d = data_1["return"])) _d.call(data_1);
}
finally { if (e_1) throw e_1.error; }
return [7 /*endfinally*/];
case 9:
_i++;
return [3 /*break*/, 1];
case 10:
if (!(depth-- > 0 && curRelatorDataCache.size > 0)) return [3 /*break*/, 21];
newRelatorDataCache = new Map();
_f.label = 11;
case 11:
_f.trys.push([11, 18, 19, 20]);
curRelatorDataCache_1 = (e_2 = void 0, __values(curRelatorDataCache)), curRelatorDataCache_1_1 = curRelatorDataCache_1.next();
_f.label = 12;
case 12:
if (!!curRelatorDataCache_1_1.done) return [3 /*break*/, 17];
_c = __read(curRelatorDataCache_1_1.value, 2), relator = _c[0], cache = _c[1];
i = 0;
_f.label = 13;
case 13:
if (!(i < cache.length)) return [3 /*break*/, 16];
return [4 /*yield*/, relator.getRelatedResource(cache[i], undefined, undefined, newRelatorDataCache)];
case 14:
resource = _f.sent();
key = resource.getKey();
if (!keys.includes(key)) {
keys.push(key);
included.push(resource);
}
_f.label = 15;
case 15:
i++;
return [3 /*break*/, 13];
case 16:
curRelatorDataCache_1_1 = curRelatorDataCache_1.next();
return [3 /*break*/, 12];
case 17: return [3 /*break*/, 20];
case 18:
e_2_1 = _f.sent();
e_2 = { error: e_2_1 };
return [3 /*break*/, 20];
case 19:
try {
if (curRelatorDataCache_1_1 && !curRelatorDataCache_1_1.done && (_e = curRelatorDataCache_1["return"])) _e.call(curRelatorDataCache_1);
}
finally { if (e_2) throw e_2.error; }
return [7 /*endfinally*/];
case 20:
curRelatorDataCache = newRelatorDataCache;
return [3 /*break*/, 10];
case 21: return [2 /*return*/, included];
}
});
});
return included;
}
exports.recurseRelators = recurseRelators;
function normalizeRelators(relators) {
var e_3, _a;
var normalizedRelators = {};
const normalizedRelators = {};
if (relators) {
if (relators instanceof relator_1["default"]) {
if (relators instanceof relator_1.default) {
normalizedRelators[relators.relatedName] = relators;

@@ -187,15 +50,5 @@ return normalizedRelators;

else if (relators instanceof Array) {
try {
for (var relators_1 = __values(relators), relators_1_1 = relators_1.next(); !relators_1_1.done; relators_1_1 = relators_1.next()) {
var relator = relators_1_1.value;
normalizedRelators[relator.relatedName] = relator;
}
for (const relator of relators) {
normalizedRelators[relator.relatedName] = relator;
}
catch (e_3_1) { e_3 = { error: e_3_1 }; }
finally {
try {
if (relators_1_1 && !relators_1_1.done && (_a = relators_1["return"])) _a.call(relators_1);
}
finally { if (e_3) throw e_3.error; }
}
return normalizedRelators;

@@ -210,4 +63,6 @@ }

exports.normalizeRelators = normalizeRelators;
var Helpers = /** @class */ (function () {
function Helpers(options) {
class Helpers {
projectAttributes;
relators;
constructor(options) {
// Relators

@@ -217,7 +72,7 @@ this.relators = normalizeRelators(options.relators);

if (options.projection === undefined) {
this.projectAttributes = function () { return undefined; };
this.projectAttributes = () => undefined;
}
else if (options.projection === null) {
this.projectAttributes = function (data) {
var attributes = Object.assign({}, data);
this.projectAttributes = (data) => {
const attributes = Object.assign({}, data);
delete attributes[options.idKey];

@@ -228,10 +83,10 @@ return attributes;

else {
var projection_1 = options.projection;
var type = Object.values(projection_1)[0];
const projection = options.projection;
const type = Object.values(projection)[0];
if (type === 0) {
this.projectAttributes = function (data) {
var keys = Object.keys(data);
var attributes = {};
for (var i = 0, len = keys.length; i < len; i++) {
if (!(keys[i] in projection_1)) {
this.projectAttributes = (data) => {
const keys = Object.keys(data);
const attributes = {};
for (let i = 0, len = keys.length; i < len; i++) {
if (!(keys[i] in projection)) {
attributes[keys[i]] = data[keys[i]];

@@ -245,7 +100,7 @@ }

else {
var keys_1 = Object.keys(projection_1);
this.projectAttributes = function (data) {
var attributes = {};
for (var i = 0, len = keys_1.length; i < len; i++) {
attributes[keys_1[i]] = data[keys_1[i]];
const keys = Object.keys(projection);
this.projectAttributes = (data) => {
const attributes = {};
for (let i = 0, len = keys.length; i < len; i++) {
attributes[keys[i]] = data[keys[i]];
}

@@ -258,5 +113,4 @@ delete attributes[options.idKey];

}
return Helpers;
}());
}
exports.Helpers = Helpers;
//# sourceMappingURL=serializer.utils.js.map
{
"name": "ts-japi",
"version": "1.6.1",
"version": "1.6.2",
"description": "A highly-modular (typescript-friendly)-framework agnostic library for serializing data to the JSON:API specification",
"main": "lib/index.js",
"scripts": {
"test": " jest --runInBand --verbose --coverage",
"playground": "ts-node ./benchmarks/playground.benchmark",
"lint": "eslint .",
"examples": "ts-node ./examples/",
"docs": "npm run api-extractor && ts-node tools/generate_docs.ts",
"clean": "make clean",
"build": "tsc",
"benchmark": "ts-node ./benchmarks/serializer.benchmark",
"playground": "ts-node ./benchmarks/playground.benchmark",
"clean": "make clean",
"build": "make",
"test": " jest --runInBand --verbose --coverage"
"api-extractor": "api-extractor run"
},

@@ -33,3 +36,3 @@ "publishConfig": {

],
"repository": "mu-io/ts-japi",
"repository": "mathematic-inc/ts-japi",
"engines": {

@@ -39,30 +42,33 @@ "node": ">=10"

"devDependencies": {
"@babel/cli": "^7.14.8",
"@babel/core": "^7.14.8",
"@babel/plugin-proposal-class-properties": "^7.14.5",
"@babel/plugin-proposal-export-namespace-from": "^7.14.5",
"@babel/plugin-proposal-object-rest-spread": "^7.14.7",
"@babel/preset-env": "^7.14.8",
"@babel/preset-typescript": "^7.14.5",
"@changesets/cli": "^2.16.0",
"@babel/cli": "^7.18.6",
"@babel/core": "^7.18.6",
"@babel/plugin-proposal-class-properties": "^7.18.6",
"@babel/plugin-proposal-export-namespace-from": "^7.18.6",
"@babel/plugin-proposal-object-rest-spread": "^7.18.6",
"@babel/preset-env": "^7.18.6",
"@babel/preset-typescript": "^7.18.6",
"@changesets/cli": "^2.23.0",
"@microsoft/api-documenter": "^7.18.0",
"@microsoft/api-extractor": "^7.28.2",
"@types/benchmark": "^2.1.1",
"@types/jest": "^26.0.24",
"@types/lodash": "^4.14.171",
"@types/uuid": "^8.3.1",
"@typescript-eslint/eslint-plugin": "^4.28.5",
"@typescript-eslint/parser": "^4.28.5",
"babel-jest": "^27.0.6",
"@types/jest": "^28.1.4",
"@types/lodash": "^4.14.182",
"@types/uuid": "^8.3.4",
"@typescript-eslint/eslint-plugin": "^5.30.3",
"@typescript-eslint/parser": "^5.30.3",
"babel-jest": "^28.1.2",
"benchmark": "^2.1.4",
"core-js": "^3.16.0",
"eslint": "^7.32.0",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-prettier": "^3.4.0",
"jest": "^27.0.6",
"core-js": "^3.23.3",
"eslint": "^8.19.0",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-prettier": "^4.2.1",
"eslint-plugin-tsdoc": "^0.2.16",
"jest": "^28.1.2",
"lodash": "^4.17.21",
"prettier": "^2.3.2",
"prettier": "^2.7.1",
"regenerator-runtime": "^0.13.9",
"ts-node": "^10.1.0",
"typedoc": "^0.21.4",
"typedoc-plugin-markdown": "^3.10.4",
"typescript": "^4.3.5",
"ts-node": "^10.8.2",
"typedoc": "^0.23.5",
"typedoc-plugin-markdown": "^3.13.2",
"typescript": "^4.7.4",
"uuid": "^8.3.2"

@@ -69,0 +75,0 @@ },

@@ -1,6 +0,6 @@

ts-japi / [Exports](modules.html)
# ts:japi
<br />
<img src="https://raw.githubusercontent.com/mu-io/ts-japi/master/docs/assets/images/logo.svg" alt="{ts:japi}" width="350"/>
<br/><br/>
<br/>
<img src="https://raw.githubusercontent.com/mathematic-inc/ts-japi/master/docs/assets/images/logo.svg" alt="{ts:japi}" width="350"/>
<br/>

@@ -10,36 +10,41 @@ ![node-current](https://img.shields.io/node/v/ts-japi)

> A highly-modular (typescript-friendly)-framework agnostic library for serializing data to the JSON:API specification
> A highly-modular (typescript-friendly)-framework agnostic library for serializing data to the
> JSON:API specification
- [Features](#features)
- [Documentation](#documentation)
- [Installation](#installation)
- [Getting Started](#getting-started)
- [Examples](#examples)
- [Serialization](#serialization)
- [Links](#links)
- [Pagination](#pagination)
- [Relationships](#relationships)
- [Metadata](#metadata)
- [Serializing Errors](#serializing-errors)
- [Caching](#caching)
- [Deserialization](#deserialization)
- [Remarks](#remarks)
- [FAQ](#faq)
- [For Developers](#for-developers)
- [Contributing](#contributing)
- [License](#license)
- [ts:japi](#tsjapi)
- [Features](#features)
- [Documentation](#documentation)
- [Installation](#installation)
- [Getting Started](#getting-started)
- [Examples](#examples)
- [Serialization](#serialization)
- [Links](#links)
- [Pagination](#pagination)
- [Relationships](#relationships)
- [Metadata](#metadata)
- [Serializing Errors](#serializing-errors)
- [Caching](#caching)
- [Deserialization](#deserialization)
- [Remarks](#remarks)
- [FAQ](#faq)
- [For Developers](#for-developers)
- [Contributing](#contributing)
- [License](#license)
## Features
- This is the **only** typescript-compatible library that fully types the JSON:API specification and performs *proper* serialization.
- This is the **only** typescript-compatible library that fully types the JSON:API specification and
performs _proper_ serialization.
- [**Zero dependencies**](#zdg).
- This is the **only** library with [resource recursion](#wirr).
- The modular framework laid out here *highly promotes* the specifications intentions:
- The modular framework laid out here _highly promotes_ the specifications intentions:
- Using links is no longer obfuscated.
- Meta can truly be placed anywhere with possible dependencies laid out visibly.
- This library is designed to adhere to the specifications "never remove, only add" policy, so we will remain backwards-compatible.
- This library is designed to adhere to the specifications "never remove, only add" policy, so we
will remain backwards-compatible.
## Documentation
The [documentation](https://mu-io.github.io/ts-japi) has everything that is covered here and more.
The [documentation](https://mathematic-inc.github.io/ts-japi/) has everything that is covered here
and more.

@@ -58,21 +63,34 @@ ## Installation

- [`Serializer`](https://mu-io.github.io/ts-japi/classes/serializer.html) with [`SerializerOptions`](https://mu-io.github.io/ts-japi/interfaces/serializeroptions.html)
- [`Relator`](https://mu-io.github.io/ts-japi/classes/relator.html) with [`RelatorOptions`](https://mu-io.github.io/ts-japi/interfaces/relatoroptions.html)
- [`Linker`](https://mu-io.github.io/ts-japi/classes/linker.html) with [`LinkerOptions`](https://mu-io.github.io/ts-japi/interfaces/linkeroptions.html)
- [`Metaizer`](https://mu-io.github.io/ts-japi/classes/metaizer.html)
- [`Paginator`](https://mu-io.github.io/ts-japi/classes/paginator.html)
- [`ErrorSerializer`](https://mu-io.github.io/ts-japi/classes/errorserializer.html) with [`ErrorSerializerOptions`](https://mu-io.github.io/ts-japi/interfaces/errorserializeroptions.html)
- **NEW** [`Cache`](https://mu-io.github.io/ts-japi/classes/cache.html) with [`CacheOptions`](https://mu-io.github.io/ts-japi/interfaces/cacheoptions.html)
- [`Serializer`](https://mathematic-inc.github.io/ts-japi/classes/serializer.html) with
[`SerializerOptions`](https://mathematic-inc.github.io/ts-japi/interfaces/serializeroptions.html)
- [`Relator`](https://mathematic-inc.github.io/ts-japi/classes/relator.html) with
[`RelatorOptions`](https://mathematic-inc.github.io/ts-japi/interfaces/relatoroptions.html)
- [`Linker`](https://mathematic-inc.github.io/ts-japi/classes/linker.html) with
[`LinkerOptions`](https://mathematic-inc.github.io/ts-japi/interfaces/linkeroptions.html)
- [`Metaizer`](https://mathematic-inc.github.io/ts-japi/classes/metaizer.html)
- [`Paginator`](https://mathematic-inc.github.io/ts-japi/classes/paginator.html)
- [`ErrorSerializer`](https://mathematic-inc.github.io/ts-japi/classes/errorserializer.html) with
[`ErrorSerializerOptions`](https://mathematic-inc.github.io/ts-japi/interfaces/errorserializeroptions.html)
- [`Cache`](https://mathematic-inc.github.io/ts-japi/classes/cache.html) with
[`CacheOptions`](https://mathematic-inc.github.io/ts-japi/interfaces/cacheoptions.html)
You can check the [documentation](https://mu-io.github.io/ts-japi) for a deeper insight into the usage.
You can check the [documentation](https://mathematic-inc.github.io/ts-japi) for a deeper insight
into the usage.
### Examples
You can check the [examples](https://github.com/mu-io/ts-japi/tree/master/examples) and the [test](https://github.com/mu-io/ts-japi/tree/master/test) folders to see some examples (such as the ones below). You can check [this example](https://github.com/mu-io/ts-japi/blob/master/examples/full.example.ts) to see almost every option of [`Serializer`](https://mu-io.github.io/ts-japi/classes/serializer.html) exhausted.
You can check the [examples](https://github.com/mathematic-inc/ts-japi/tree/master/examples) and the
[test](https://github.com/mathematic-inc/ts-japi/tree/master/test) folders to see some examples
(such as the ones below). You can check
[this example](https://github.com/mathematic-inc/ts-japi/blob/master/examples/full.example.ts) to
see almost every option of
[`Serializer`](https://mathematic-inc.github.io/ts-japi/classes/serializer.html) exhausted.
## Serialization
The [`Serializer`](https://mu-io.github.io/ts-japi/classes/serializer.html) class is the only class required for basic serialization.
The [`Serializer`](https://mathematic-inc.github.io/ts-japi/classes/serializer.html) class is the
only class required for basic serialization.
The following example constructs the most basic [`Serializer`](https://mu-io.github.io/ts-japi/classes/serializer.html): (Note the `await`)
The following example constructs the most basic
[`Serializer`](https://mathematic-inc.github.io/ts-japi/classes/serializer.html): (Note the `await`)

@@ -104,3 +122,2 @@ ```typescript

})();
```

@@ -110,5 +127,8 @@

The [`Linker`](https://mu-io.github.io/ts-japi/classes/linker.html) class is used to generate a normalized [document link](https://jsonapi.org/format/#document-links). Its methods are not meant to be called. See the [FAQ](#faq) for reasons.
The [`Linker`](https://mathematic-inc.github.io/ts-japi/classes/linker.html) class is used to
generate a normalized [document link](https://jsonapi.org/format/#document-links). Its methods are
not meant to be called. See the [FAQ](#faq) for reasons.
The following example constructs a [`Linker`](https://mu-io.github.io/ts-japi/classes/linker.html) for `User`s and `Article`s:
The following example constructs a
[`Linker`](https://mathematic-inc.github.io/ts-japi/classes/linker.html) for `User`s and `Article`s:

@@ -137,3 +157,2 @@ ```typescript

})();
```

@@ -143,5 +162,8 @@

The [`Paginator`](https://mu-io.github.io/ts-japi/classes/paginator.html) class is used to generate [pagination links](https://jsonapi.org/format/#fetching-pagination). Its methods are not meant to be called.
The [`Paginator`](https://mathematic-inc.github.io/ts-japi/classes/paginator.html) class is used to
generate [pagination links](https://jsonapi.org/format/#fetching-pagination). Its methods are not
meant to be called.
The following example constructs a [`Paginator`](https://mu-io.github.io/ts-japi/classes/paginator.html):
The following example constructs a
[`Paginator`](https://mathematic-inc.github.io/ts-japi/classes/paginator.html):

@@ -181,3 +203,2 @@ ```typescript

})();
```

@@ -187,7 +208,17 @@

The [`Relator`](https://mu-io.github.io/ts-japi/classes/relator.html) class is used to generate top-level [included data](https://jsonapi.org/format/#document-top-level) as well as resource-level [relationships](https://jsonapi.org/format/#document-resource-object-relationships). Its methods are not meant to be called.
The [`Relator`](https://mathematic-inc.github.io/ts-japi/classes/relator.html) class is used to
generate top-level [included data](https://jsonapi.org/format/#document-top-level) as well as
resource-level [relationships](https://jsonapi.org/format/#document-resource-object-relationships).
Its methods are not meant to be called.
[`Relator`](https://mu-io.github.io/ts-japi/classes/relator.html)s may also take optional [`Linker`](https://mu-io.github.io/ts-japi/classes/linker.html)s (using the [`linker`](https://mu-io.github.io/ts-japi/interfaces/relatoroptions.html#linkers) option) to define [relationship links](https://jsonapi.org/format/#document-resource-object-relationships) and [related resource links](https://jsonapi.org/format/#document-resource-object-related-resource-links).
[`Relator`](https://mathematic-inc.github.io/ts-japi/classes/relator.html)s may also take optional
[`Linker`](https://mathematic-inc.github.io/ts-japi/classes/linker.html)s (using the
[`linker`](https://mathematic-inc.github.io/ts-japi/interfaces/relatoroptions.html#linkers) option)
to define [relationship links](https://jsonapi.org/format/#document-resource-object-relationships)
and
[related resource links](https://jsonapi.org/format/#document-resource-object-related-resource-links).
The following example constructs a [`Relator`](https://mu-io.github.io/ts-japi/classes/relator.html) for `User`s and `Article`s:
The following example constructs a
[`Relator`](https://mathematic-inc.github.io/ts-japi/classes/relator.html) for `User`s and
`Article`s:

@@ -216,3 +247,2 @@ ```typescript

})();
```

@@ -222,12 +252,16 @@

The [`Metaizer`](https://mu-io.github.io/ts-japi/classes/metaizer.html) class is used to construct generate metadata given some dependencies. There are several locations [`Metaizer`](https://mu-io.github.io/ts-japi/classes/metaizer.html) can be used:
The [`Metaizer`](https://mathematic-inc.github.io/ts-japi/classes/metaizer.html) class is used to
construct generate metadata given some dependencies. There are several locations
[`Metaizer`](https://mathematic-inc.github.io/ts-japi/classes/metaizer.html) can be used:
- [`ErrorSerializerOptions.metaizers`](https://mu-io.github.io/ts-japi/interfaces/errorserializeroptions.html#metaizers)
- [`RelatorOptions.metaizer`](https://mu-io.github.io/ts-japi/interfaces/relatoroptions.html#metaizer)
- [`SerializerOptions.metaizers`](https://mu-io.github.io/ts-japi/interfaces/serializeroptions.html#metaizers)
- [`LinkerOptions.metaizer`](https://mu-io.github.io/ts-japi/interfaces/linkeroptions.html#metaizer)
- [`ErrorSerializerOptions.metaizers`](https://mathematic-inc.github.io/ts-japi/interfaces/errorserializeroptions.html#metaizers)
- [`RelatorOptions.metaizer`](https://mathematic-inc.github.io/ts-japi/interfaces/relatoroptions.html#metaizer)
- [`SerializerOptions.metaizers`](https://mathematic-inc.github.io/ts-japi/interfaces/serializeroptions.html#metaizers)
- [`LinkerOptions.metaizer`](https://mathematic-inc.github.io/ts-japi/interfaces/linkeroptions.html#metaizer)
Like [`Linker`](https://mu-io.github.io/ts-japi/classes/linker.html), its methods are not meant to be called.
Like [`Linker`](https://mathematic-inc.github.io/ts-japi/classes/linker.html), its methods are not
meant to be called.
The following example constructs a [`Metaizer`](https://mu-io.github.io/ts-japi/classes/metaizer.html):
The following example constructs a
[`Metaizer`](https://mathematic-inc.github.io/ts-japi/classes/metaizer.html):

@@ -259,3 +293,2 @@ ```typescript

})();
```

@@ -265,7 +298,17 @@

The [`ErrorSerializer`](https://mu-io.github.io/ts-japi/classes/errorserializer.html) class is used to serialize any object considered an error (the [`attributes`](https://mu-io.github.io/ts-japi/interfaces/errorserializeroptions.html#attributes) option allows you to choose what attributes to use during serialization). *Alternatively* (**recommended**), you can construct custom errors by extending the [`JapiError`](https://mu-io.github.io/ts-japi/classes/japierror.html) class and use those for all server-to-client errors.
The [`ErrorSerializer`](https://mathematic-inc.github.io/ts-japi/classes/errorserializer.html) class
is used to serialize any object considered an error (the
[`attributes`](https://mathematic-inc.github.io/ts-japi/interfaces/errorserializeroptions.html#attributes)
option allows you to choose what attributes to use during serialization). _Alternatively_
(**recommended**), you can construct custom errors by extending the
[`JapiError`](https://mathematic-inc.github.io/ts-japi/classes/japierror.html) class and use those
for all server-to-client errors.
The [error serializer test](https://github.com/mu-io/ts-japi/tree/master/test/error-serializer.test.ts) includes an example of the alternative solution.
The
[error serializer test](https://github.com/mathematic-inc/ts-japi/tree/master/test/error-serializer.test.ts)
includes an example of the alternative solution.
The following example constructs the most basic [`ErrorSerializer`](https://mu-io.github.io/ts-japi/classes/errorserializer.html): (Note the lack of `await`)
The following example constructs the most basic
[`ErrorSerializer`](https://mathematic-inc.github.io/ts-japi/classes/errorserializer.html): (Note
the lack of `await`)

@@ -288,3 +331,2 @@ ```typescript

})();
```

@@ -294,19 +336,37 @@

The [`Cache`](https://mu-io.github.io/ts-japi/classes/cache.html) class can be placed in a [`Serializer`](https://mu-io.github.io/ts-japi/classes/serializer.html)'s [`cache`](https://mu-io.github.io/ts-japi/interfaces/serializeroptions.html#cache) option. Alternatively, setting that option to `true` will provide a default [`Cache`](https://mu-io.github.io/ts-japi/classes/cache.html).
The [`Cache`](https://mathematic-inc.github.io/ts-japi/classes/cache.html) class can be placed in a
[`Serializer`](https://mathematic-inc.github.io/ts-japi/classes/serializer.html)'s
[`cache`](https://mathematic-inc.github.io/ts-japi/interfaces/serializeroptions.html#cache) option.
Alternatively, setting that option to `true` will provide a default
[`Cache`](https://mathematic-inc.github.io/ts-japi/classes/cache.html).
The default [`Cache`](https://mu-io.github.io/ts-japi/classes/cache.html) uses the basic [`Object.is`](https://mu-io.github.io/ts-japi/https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is) function to determine if input data are the same. If you want to adjust this, instantiate a new [`Cache`](https://mu-io.github.io/ts-japi/classes/cache.html) with a [`resolver`](https://mu-io.github.io/ts-japi/interfaces/cacheoptions.html#resolver).
The default [`Cache`](https://mathematic-inc.github.io/ts-japi/classes/cache.html) uses the basic
[`Object.is`](https://mathematic-inc.github.io/ts-japi/https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is)
function to determine if input data are the same. If you want to adjust this, instantiate a new
[`Cache`](https://mathematic-inc.github.io/ts-japi/classes/cache.html) with a
[`resolver`](https://mathematic-inc.github.io/ts-japi/interfaces/cacheoptions.html#resolver).
## Deserialization
We stress the following: Given that there are many clients readily built to consume JSON:API endpoints (see [here](https://jsonapi.org/implementations/)), we do not provide deserialization. In particular, since unmarshalling data is strongly related to the code it will be used in (e.g. React), tighter integration is recommended over an unnecessary abstraction.
We stress the following: Given that there are many clients readily built to consume JSON:API
endpoints (see [here](https://jsonapi.org/implementations/)), we do not provide deserialization. In
particular, since unmarshalling data is strongly related to the code it will be used in (e.g.
React), tighter integration is recommended over an unnecessary abstraction.
## Remarks
There are several model classes used inside TS:JAPI such as `Resource` and `Relationships`. These models are used for normalization as well as traversing a JSON:API document. If you plan to fork this repo, you can extend these models and reimplement them to create your own custom (non-standard, extended) serializer.
There are several model classes used inside TS:JAPI such as `Resource` and `Relationships`. These
models are used for normalization as well as traversing a JSON:API document. If you plan to fork
this repo, you can extend these models and reimplement them to create your own custom (non-standard,
extended) serializer.
## FAQ
> Why not just allow optional functions that return the internal `Link` Class (or just a URI `string`)?
> Why not just allow optional functions that return the internal `Link` Class (or just a URI
> `string`)?
The `Link` class is defined to be as general as possible in case of changes in the specification. In particular, the implementation of metadata and the types in our library rely on the generality of the `Link` class. Relying on user arguments will generate a lot of overhead for both us and users whenever the specs change.
The `Link` class is defined to be as general as possible in case of changes in the specification. In
particular, the implementation of metadata and the types in our library rely on the generality of
the `Link` class. Relying on user arguments will generate a lot of overhead for both us and users
whenever the specs change.

@@ -319,20 +379,30 @@ > Why does the `Meta` class exist if it is essentially just a plain object?

Due to [compound documents](https://jsonapi.org/format/#document-compound-documents), it is possible to recurse through related resources via their [resource linkages](https://jsonapi.org/format/#document-resource-object-linkage) and obtain [included resources](https://jsonapi.org/format/#document-top-level) beyond primary data relations. This is should be done with caution (see [`SerializerOptions.depth`](https://mu-io.github.io/ts-japi/interfaces/serializeroptions.html#depth) and [this example](https://github.com/mu-io/ts-japi/blob/master/examples/resource-recursion.example.ts))
Due to [compound documents](https://jsonapi.org/format/#document-compound-documents), it is possible
to recurse through related resources via their
[resource linkages](https://jsonapi.org/format/#document-resource-object-linkage) and obtain
[included resources](https://jsonapi.org/format/#document-top-level) beyond primary data relations.
This is should be done with caution (see
[`SerializerOptions.depth`](https://mathematic-inc.github.io/ts-japi/interfaces/serializeroptions.html#depth)
and
[this example](https://github.com/mathematic-inc/ts-japi/blob/master/examples/resource-recursion.example.ts))
## For Developers
To get started in developing this library, run `yarn install`, `yarn build` and `yarn test` (in this precise order) to assure everything is in working order.
To get started in developing this library, run `yarn install`, `yarn build` and `yarn test` (in this
precise order) to assure everything is in working order.
## Contributing
This project is maintained by the author, however contributions are welcome and appreciated.
You can find TS:JAPI on GitHub: [https://github.com/mu-io/ts-japi](https://github.com/mu-io/ts-japi)
This project is maintained by the author, however contributions are welcome and appreciated. You can
find TS:JAPI on GitHub:
[https://github.com/mathematic-inc/ts-japi](https://github.com/mathematic-inc/ts-japi)
Feel free to submit an issue, but please do not submit pull requests unless it is to fix some issue.
For more information, read the [contribution guide](https://github.com/mu-io/ts-japi/blob/master/CONTRIBUTING.html).
For more information, read the
[contribution guide](https://github.com/mathematic-inc/ts-japi/blob/master/CONTRIBUTING.html).
## License
Copyright © 2020 [mu-io](https://github.com/mu-io).
Copyright © 2020 [mathematic-inc](https://github.com/mathematic-inc).
Licensed under [Apache 2.0](https://www.apache.org/licenses/LICENSE-2.0).
{
"compilerOptions": {
/* Basic Options */
// "incremental": true, /* Enable incremental compilation */
// "target": "es3", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */
"module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */
"lib": [
"es2020",
"dom"
], /* Specify library files to be included in the compilation. */
// "allowJs": true, /* Allow javascript files to be compiled. */
// "checkJs": true, /* Report errors in .js files. */
// "jsx": "react", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */
"declaration": true, /* Generates corresponding '.d.ts' file. */
"declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */
"sourceMap": true, /* Generates corresponding '.map' file. */
// "outFile": "./", /* Concatenate and emit output to single file. */
"outDir": "./lib/", /* Redirect output structure to the directory. */
"rootDir": "./src/", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
// "composite": true, /* Enable project compilation */
// "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */
// "removeComments": true, /* Do not emit comments to output. */
// "noEmit": true, /* Do not emit outputs. */
// "importHelpers": true, /* Import emit helpers from 'tslib'. */
"downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
// "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
/* Strict Type-Checking Options */
"strict": true, /* Enable all strict type-checking options. */
"noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
"strictNullChecks": true, /* Enable strict null checks. */
"strictFunctionTypes": true, /* Enable strict checking of function types. */
"strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */
"strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */
"noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
"alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
/* Additional Checks */
// "noUnusedLocals": true, /* Report errors on unused locals. */
// "noUnusedParameters": true, /* Report errors on unused parameters. */
"noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
"noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
/* Module Resolution Options */
// "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
// "baseUrl": "./", /* Base directory to resolve non-absolute module names. */
// "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
// "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */
// "typeRoots": [], /* List of folders to include type definitions from. */
// "types": [], /* Type declaration files to be included in compilation. */
// "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
"esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
"resolveJsonModule": true,
// "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
/* Source Map Options */
// "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */
// "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
// "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */
// "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */
/* Experimental Options */
// "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */
// "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
/* Advanced Options */
"forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */
},
"include": [
"src"
],
"typedocOptions": {
"out": "docs",
"entryPoints": [
"./src/index.ts"
],
"includes": [
"./examples"
],
"plugin": "none",
"exclude": "**/*+(.spec|.e2e|.test).ts",
"readme": "src/docs/README.md",
"categorizeByGroup": true,
"gitRevision": "master"
}
"compilerOptions": {
"target": "esnext",
"module": "commonjs",
"lib": [
"es2020",
"dom"
],
"declaration": true, /* Generates corresponding '.d.ts' file. */
"declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */
"sourceMap": true, /* Generates corresponding '.map' file. */
// "outFile": "./", /* Concatenate and emit output to single file. */
"outDir": "./lib/", /* Redirect output structure to the directory. */
"rootDir": "./src/", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
// "composite": true, /* Enable project compilation */
// "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */
// "removeComments": true, /* Do not emit comments to output. */
// "noEmit": true, /* Do not emit outputs. */
// "importHelpers": true, /* Import emit helpers from 'tslib'. */
"downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
// "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
/* Strict Type-Checking Options */
"strict": true, /* Enable all strict type-checking options. */
"noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
"strictNullChecks": true, /* Enable strict null checks. */
"strictFunctionTypes": true, /* Enable strict checking of function types. */
"strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */
"strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */
"noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
"alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
/* Additional Checks */
// "noUnusedLocals": true, /* Report errors on unused locals. */
// "noUnusedParameters": true, /* Report errors on unused parameters. */
"noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
"noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
/* Module Resolution Options */
// "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
// "baseUrl": "./", /* Base directory to resolve non-absolute module names. */
// "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
// "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */
// "typeRoots": [], /* List of folders to include type definitions from. */
// "types": [], /* Type declaration files to be included in compilation. */
// "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
"esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
"resolveJsonModule": true,
// "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
/* Source Map Options */
// "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */
// "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
// "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */
// "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */
/* Experimental Options */
// "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */
// "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
/* Advanced Options */
"forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */
},
"include": [
"src"
]
}

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc