ts-japi
Version:
A highly-modular (typescript-friendly)-framework agnostic library for serializing data to the JSON:API specification
120 lines • 4.58 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const relationship_model_1 = __importDefault(require("../models/relationship.model"));
const merge_1 = __importDefault(require("../utils/merge"));
const serializer_1 = __importDefault(require("./serializer"));
/**
* 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).
*
* Example:
* ```typescript
* [[include:relator.example.ts]]
* ```
*/
class Relator {
/**
* Default options. Can be edited to change default options globally.
*/
static defaultOptions = {
linkers: {},
};
/**
* Options for relator.
*/
options;
relatedName;
internalSerializer;
_serializer;
constructor(fetch, serializer, options) {
// Setting default options
this.relatedName =
options?.relatedName ||
(serializer instanceof serializer_1.default ? serializer : serializer()).collectionName;
this.internalSerializer = serializer;
this.options = (0, merge_1.default)({}, Relator.defaultOptions, options ?? {});
this.getRelatedData = fetch;
}
get serializer() {
// Instantiate _serializer if not already instantiated
if (!this._serializer) {
this._serializer =
this.internalSerializer instanceof serializer_1.default
? this.internalSerializer
: this.internalSerializer();
}
return this._serializer;
}
/** @internal Gets related data from primary data. */
getRelatedData;
/** @internal Gets related relators */
getRelatedRelators() {
return this.serializer.getRelators();
}
/** @internal Creates related identifiers */
getRelatedIdentifier(data, options) {
return this.serializer.createIdentifier(data, options);
}
/** @internal Creates related resources */
async getRelatedResource(data, options, helpers, relatorDataCache) {
return this.serializer.createResource(data, options, helpers, relatorDataCache);
}
/** @internal Gets related links from primary data and related data */
getRelatedLinks(data, relatedData) {
let links;
if (this.options.linkers.relationship) {
links = { ...links, self: this.options.linkers.relationship.link(data, relatedData) };
}
if (this.options.linkers.related) {
links = { ...links, related: this.options.linkers.related.link(data, relatedData) };
}
return links;
}
/** @internal Gets related meta from primary data and related data */
getRelatedMeta(data, relatedData) {
let meta;
if (this.options.metaizer) {
meta = this.options.metaizer.metaize(data, relatedData);
}
return meta;
}
/** @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;
let relationship;
if (relatedData !== undefined || meta || links) {
relationship = new relationship_model_1.default(relationshipOptions);
}
return relationship;
}
}
exports.default = Relator;
//# sourceMappingURL=relator.js.map