@jsonjoy.com/json-type
Version:
High-performance JSON Pointer implementation
96 lines • 3.4 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.ModuleType = void 0;
const printTree_1 = require("tree-dump/lib/printTree");
const Walker_1 = require("../../../schema/Walker");
const TypeBuilder_1 = require("../../TypeBuilder");
const AliasType_1 = require("../AliasType");
class ModuleType {
constructor() {
this.t = new TypeBuilder_1.TypeBuilder(this);
this.aliases = new Map();
/**
* @todo Add ability fetch object of given type by its ID, analogous to
* GraphQL "nodes".
*/
this.alias = (id, type) => {
const existingAlias = this.aliases.get(id);
if (existingAlias)
return existingAlias;
const alias = new AliasType_1.AliasType(this, id, type);
this.aliases.set(id, alias);
return alias;
};
this.unalias = (id) => {
const alias = this.aliases.get(id);
if (!alias)
throw new Error(`Alias [id = ${id}] not found.`);
return alias;
};
this.hasAlias = (id) => this.aliases.has(id);
this.resolve = (id) => {
const alias = this.unalias(id);
return alias.type.kind() === 'ref' ? this.resolve(alias.type.ref()) : alias;
};
}
exportTypes() {
const result = {};
for (const [id, alias] of this.aliases.entries()) {
result[id] = alias.getType().getSchema();
}
return result;
}
import(module) {
const map = {};
for (const alias of module.keys) {
map[alias.key] = alias.value;
}
const expandObjFields = (aliasOfObj) => {
const obj = typeof aliasOfObj === 'string' ? map[aliasOfObj] : aliasOfObj;
if (!obj || obj.kind !== 'obj')
throw new Error('NO_OBJ');
if (obj.extends) {
const uniqueFields = new Map();
for (const parent of obj.extends) {
const parentFields = expandObjFields(parent);
for (const field of parentFields)
uniqueFields.set(field.key, field);
}
delete obj.extends;
for (const field of obj.keys)
uniqueFields.set(field.key, field);
obj.keys = [...uniqueFields.values()];
}
return obj.keys;
};
Walker_1.Walker.walk(module, {
onType: (type) => {
if (type.kind !== 'obj')
return;
if (type.extends)
expandObjFields(type);
},
});
this.importTypes(map);
}
importTypes(aliases) {
const result = {};
for (const id in aliases)
result[id] = this.alias(id, this.t.import(aliases[id]));
return result;
}
toString(tab = '') {
return ('Module' +
(0, printTree_1.printTree)(tab, [
(tab) => 'aliases' +
(0, printTree_1.printTree)(tab, [...this.aliases.values()].map((alias) => (tab) => alias.toString(tab))),
]));
}
}
exports.ModuleType = ModuleType;
ModuleType.from = (module) => {
const type = new ModuleType();
type.import(module);
return type;
};
//# sourceMappingURL=index.js.map