@sprucelabs/spruce-cli
Version:
Command line interface for building Spruce skills.
181 lines • 7.62 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const schema_1 = require("@sprucelabs/schema");
const spruce_skill_utils_1 = require("@sprucelabs/spruce-skill-utils");
const cloneDeep_1 = __importDefault(require("lodash/cloneDeep"));
const isEqual_1 = __importDefault(require("lodash/isEqual"));
const merge_1 = __importDefault(require("lodash/merge"));
const SpruceError_1 = __importDefault(require("../errors/SpruceError"));
const schema_utility_1 = __importDefault(require("../features/schema/utilities/schema.utility"));
class SchemaTemplateItemBuilder {
schemasByKey = {};
localNamespace;
constructor(localNamespace) {
this.localNamespace = localNamespace;
}
buildTemplateItems(schemasByNamespace, destinationDir = '#spruce/schemas') {
const schemas = [];
const namespaces = Object.keys(schemasByNamespace);
for (const namespace of namespaces) {
schemas.push(...schemasByNamespace[namespace].map((s) => ({
namespace,
...s,
})));
}
this.flattenSchemas(schemas);
const flattened = Object.values(this.schemasByKey);
const sorted = flattened
.sort((a, b) => {
if (this.doesADependOnB(a, b)) {
return -1;
}
else if (this.doesADependOnB(b, a)) {
return 1;
}
return 0;
})
.reverse();
const schemaTemplateItems = sorted.map((s) => this.buildTemplateItem({
...s,
destinationDir,
}));
return schemaTemplateItems;
}
doesADependOnB(a, b) {
const { dependencies } = a;
const idWithVersion = (0, schema_1.normalizeSchemaToIdWithVersion)(b.schema);
if (dependencies.find((dep) => (0, isEqual_1.default)(dep, idWithVersion))) {
return true;
}
return false;
}
flattenSchemas(schemas) {
schemas.forEach((def) => {
this.flattenSchema(def);
});
}
flattenSchema(schema, isNested = false) {
const localSchema = (0, cloneDeep_1.default)(schema);
const namedFields = this.pluckFields(localSchema);
const dependencies = [];
namedFields.forEach(({ field, name }) => {
if (field.type === 'schema') {
const schemasOrIdsWithVersion = schema_1.SchemaField.mapFieldDefinitionToSchemasOrIdsWithVersion(field);
const { ...originalOptions } = field.options;
delete field.options.schema;
delete field.options.schemaId;
delete field.options.schemaIds;
delete field.options.schemas;
field.options.schemaIds = [];
schemasOrIdsWithVersion.forEach((schemaOrId) => {
const related = { ...schemaOrId };
if (localSchema.version && !related.version) {
related.version = localSchema.version;
}
if (!related.namespace) {
related.namespace = schema.namespace;
}
if (localSchema.moduleToImportFromWhenRemote &&
//@ts-ignore
!related.moduleToImportFromWhenRemote &&
!(0, schema_1.isIdWithVersion)(related)) {
//@ts-ignore
related.moduleToImportFromWhenRemote =
localSchema.moduleToImportFromWhenRemote;
}
const relatedIdWithVersion = (0, schema_1.normalizeSchemaToIdWithVersion)(related);
field.options.schemaIds?.push(relatedIdWithVersion);
dependencies.push(relatedIdWithVersion);
this.flattenSchema(related, true);
});
if (field.options.schemaIds.length === 0) {
throw new SpruceError_1.default({
code: 'SCHEMA_TEMPLATE_ITEM_BUILDING_FAILED',
schemaId: schema.id,
schemaNamespace: schema.namespace,
fieldName: name,
fieldOptions: originalOptions,
});
}
}
});
const key = schema_utility_1.default.generateCacheKey(localSchema);
this.schemasByKey[key] = (0, merge_1.default)(this.schemasByKey[key] ?? {}, {
schema: localSchema,
dependencies,
isNested: this.schemasByKey[key]?.isNested === false ? false : isNested,
});
}
pluckFields(localSchema) {
const fields = localSchema.dynamicFieldSignature
? { dynamicField: localSchema.dynamicFieldSignature }
: (localSchema.fields ?? {});
const namedFields = Object.keys(fields).map((name) => ({
name,
field: fields[name],
}));
return namedFields;
}
buildTemplateItem(options) {
const { schema, isNested, destinationDir } = options;
const namespace = schema.namespace ?? this.localNamespace;
const importFrom = this.getImportFromForSchema(schema);
const item = {
id: schema.id,
namespace,
schema,
...schema_utility_1.default.generateNamesForSchema(schema),
isNested,
destinationDir,
};
if (importFrom) {
item.importFrom = importFrom;
}
if (namespace.toLowerCase() === this.localNamespace.toLowerCase() &&
schema.importsWhenLocal) {
item.imports = [...schema.importsWhenLocal];
}
else if (namespace.toLowerCase() !== this.localNamespace.toLowerCase() &&
schema.importsWhenRemote) {
item.imports = [...schema.importsWhenRemote];
}
const namedFields = this.pluckFields(schema);
for (const { field } of namedFields) {
if (field.type === 'schema') {
field.options.schemaIds?.forEach((idWithVersion) => {
const key = schema_utility_1.default.generateCacheKey(idWithVersion);
const match = this.schemasByKey[key];
if (match.schema.importsWhenRemote &&
match.schema.namespace &&
match.schema.namespace.toLowerCase() !==
this.localNamespace.toLowerCase()) {
if (!item.imports) {
item.imports = [];
}
item.imports.push(...match.schema.importsWhenRemote);
}
});
}
}
return item;
}
getImportFromForSchema(schema) {
if (schema.moduleToImportFromWhenRemote &&
schema.namespace !== this.localNamespace) {
return schema.moduleToImportFromWhenRemote;
}
switch (schema.namespace) {
case spruce_skill_utils_1.CORE_NAMESPACE:
if (this.localNamespace !== spruce_skill_utils_1.CORE_NAMESPACE) {
return '@sprucelabs/spruce-core-schemas';
}
break;
}
return undefined;
}
}
exports.default = SchemaTemplateItemBuilder;
//# sourceMappingURL=SchemaTemplateItemBuilder.js.map