@oada/oadaify
Version:
Make OADA data nicer to work with in JS/TS
138 lines • 4.22 kB
JavaScript
;
/**
* @license
* Copyright 2022 Alex Layton
*
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE file or at
* https://opensource.org/licenses/MIT.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.deoadaify = exports.oadaify = exports._meta = exports._type = exports._rev = exports._id = void 0;
// TS is dumb about symbol keys
/**
* Symbol to access OADA `_id` key
*/
exports._id = Symbol('_id');
/**
* Symbol to access OADA `_rev` key
*/
exports._rev = Symbol('_rev');
/**
* Symbol to access OADA `_type` key
*/
exports._type = Symbol('_type');
/**
* Symbol to access OADA `_meta` key
*/
exports._meta = Symbol('_meta');
/**
* @todo just declare symbols in here if TS stops being dumb about symbol keys
*/
// eslint-disable-next-line @typescript-eslint/naming-convention
const Symbols = {
_id: exports._id,
_rev: exports._rev,
_type: exports._type,
_meta: exports._meta,
};
function isArray(value) {
return Array.isArray(value);
}
function oadaify(value, deep = true) {
if (!value || typeof value !== 'object') {
// Nothing to OADAify
return value;
}
if (isArray(value)) {
// Map ourself over arrays
return deep
? value.map((v) => oadaify(v))
: Array.from(value);
}
const out = deep
? Object.fromEntries(Object.entries(value).map(([k, v]) => [k, oadaify(v)]))
: { ...value };
// OADAify any OADA keys
// Have to explicitly handle each symbol for TS to understand...
if ('_id' in value) {
// eslint-disable-next-line security/detect-object-injection
out[exports._id] = `${value._id}`;
Object.defineProperty(out, '_id', {
value: value._id,
enumerable: false,
});
}
if ('_rev' in value) {
// eslint-disable-next-line security/detect-object-injection
out[exports._rev] = Number(value._rev);
Object.defineProperty(out, '_rev', {
value: value._rev,
enumerable: false,
});
}
if ('_type' in value) {
// eslint-disable-next-line security/detect-object-injection
out[exports._type] = `${value._type}`;
Object.defineProperty(out, '_type', {
value: value._type,
enumerable: false,
});
}
// TODO: Should _meta be OADAified?
if ('_meta' in value) {
// eslint-disable-next-line security/detect-object-injection
out[exports._meta] = value._meta;
Object.defineProperty(out, '_meta', {
value: value._meta,
enumerable: false,
});
}
// Make the JSON still right
Object.defineProperty(out, 'toJSON', { enumerable: false, value: toJSON });
return out;
}
exports.oadaify = oadaify;
/**
* Inverse of oadaify
*
* Makes OADA keys normal object properties again.
*
* @see oadaify
*/
function deoadaify(value) {
if (!value || typeof value !== 'object') {
return value;
}
if (Array.isArray(value)) {
return value.map((v) => deoadaify(v));
}
const out = Object.fromEntries(Object.entries(value).map(([k, v]) => [k, deoadaify(v)]));
// Add OADA keys
if (Object.prototype.hasOwnProperty.call(value, exports._id)) {
// eslint-disable-next-line security/detect-object-injection
out._id = value[exports._id];
}
if (Object.prototype.hasOwnProperty.call(value, exports._rev)) {
// eslint-disable-next-line security/detect-object-injection
out._rev = value[exports._rev];
}
if (Object.prototype.hasOwnProperty.call(value, exports._type)) {
// eslint-disable-next-line security/detect-object-injection
out._type = value[exports._type];
}
if (Object.prototype.hasOwnProperty.call(value, exports._meta)) {
// eslint-disable-next-line security/detect-object-injection
out._meta = value[exports._meta];
}
return out;
}
exports.deoadaify = deoadaify;
/**
* Makes the OADA keys reappear for JSON.stringify
*/
function toJSON() {
return deoadaify(this);
}
exports.default = oadaify;
//# sourceMappingURL=index.js.map