UNPKG

@sprucelabs/spruce-cli

Version:

Command line interface for building Spruce skills.

223 lines • 9.9 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.coreSchemas = void 0; const path_1 = __importDefault(require("path")); const globby_1 = __importDefault(require("@sprucelabs/globby")); const schema_1 = require("@sprucelabs/schema"); const spruce_core_schemas_1 = require("@sprucelabs/spruce-core-schemas"); const spruce_event_utils_1 = require("@sprucelabs/spruce-event-utils"); const spruce_skill_utils_1 = require("@sprucelabs/spruce-skill-utils"); const spruce_skill_utils_2 = require("@sprucelabs/spruce-skill-utils"); const spruce_skill_utils_3 = require("@sprucelabs/spruce-skill-utils"); const lodash_1 = require("lodash"); const SpruceError_1 = __importDefault(require("../../../errors/SpruceError")); const AbstractStore_1 = __importDefault(require("../../../stores/AbstractStore")); exports.coreSchemas = { personSchema: spruce_core_schemas_1.personSchema, skillSchema: spruce_core_schemas_1.skillSchema, skillCreatorSchema: spruce_core_schemas_1.skillCreatorSchema, locationSchema: spruce_core_schemas_1.locationSchema, organizationSchema: spruce_core_schemas_1.organizationSchema, personOrganizationSchema: spruce_core_schemas_1.personOrganizationSchema, personLocationSchema: spruce_core_schemas_1.personLocationSchema, roleSchema: spruce_core_schemas_1.roleSchema, messageSchema: spruce_core_schemas_1.messageSchema, messageSourceSchema: spruce_core_schemas_1.messageSourceSchema, messageTargetSchema: spruce_core_schemas_1.messageTargetSchema, sendMessageSchema: spruce_core_schemas_1.sendMessageSchema, choiceSchema: spruce_core_schemas_1.choiceSchema, linkSchema: spruce_core_schemas_1.linkSchema, }; const DEFAULT_LOCAL_SCHEMA_DIR = 'src/schemas'; class SchemaStore extends AbstractStore_1.default { name = 'schema'; async fetchSchemas(options) { const { localSchemaLookupDir: localSchemaDir = DEFAULT_LOCAL_SCHEMA_DIR, shouldFetchLocalSchemas = true, shouldFetchRemoteSchemas = true, shouldEnableVersioning = true, localNamespace, shouldFetchCoreSchemas = true, didUpdateHandler, moduleToImportFromWhenRemote, } = options || {}; const results = { errors: [], schemasByNamespace: {}, }; if (shouldFetchCoreSchemas) { results.schemasByNamespace[spruce_skill_utils_3.CORE_NAMESPACE] = Object.values(exports.coreSchemas).map((schema) => ({ ...schema, namespace: spruce_skill_utils_3.CORE_NAMESPACE, })); } if (shouldFetchLocalSchemas) { const locals = await this.loadLocalSchemas(localSchemaDir, localNamespace, shouldEnableVersioning, didUpdateHandler); if (moduleToImportFromWhenRemote) { locals.schemas.forEach((local) => { local.moduleToImportFromWhenRemote = moduleToImportFromWhenRemote; }); } results.schemasByNamespace[localNamespace] = locals.schemas; results.errors.push(...locals.errors); } if (shouldFetchRemoteSchemas) { await this.emitDidFetchSchemasAndMixinResults(localNamespace, results); } return results; } async emitDidFetchSchemasAndMixinResults(localNamespace, results) { const schemas = []; for (const namespace in results.schemasByNamespace) { schemas.push(...results.schemasByNamespace[namespace]); } const remoteResults = await this.emitter.emit('schema.did-fetch-schemas', { schemas, }); const { payloads, errors } = spruce_event_utils_1.eventResponseUtil.getAllResponsePayloadsAndErrors(remoteResults, SpruceError_1.default); if (errors && errors.length > 0) { results.errors.push(...errors); } else { payloads.forEach((payload) => { payload?.schemas?.forEach((schema) => { this.mixinSchemaOrThrowIfExists(schema, localNamespace, results); }); }); } } mixinSchemaOrThrowIfExists(schema, localNamespace, results) { const namespace = schema.namespace ?? localNamespace; if (!results.schemasByNamespace[namespace]) { results.schemasByNamespace[namespace] = []; } const idWithVersion = (0, schema_1.normalizeSchemaToIdWithVersion)(schema); const match = results.schemasByNamespace[namespace].find((s) => (0, lodash_1.isEqual)((0, schema_1.normalizeSchemaToIdWithVersion)(s), idWithVersion)); if (!match) { results.schemasByNamespace[namespace].push(schema); } } async hasLocalSchemas() { const matches = await this.globbyLocalBuilders(DEFAULT_LOCAL_SCHEMA_DIR); return matches.length > 0; } async loadLocalSchemas(localLookupDir, localNamespace, shouldEnableVersioning, didUpdateHandler) { const localMatches = await this.globbyLocalBuilders(localLookupDir); const errors = []; const schemas = []; didUpdateHandler?.(`Starting import of ${localMatches.length} schema builders...`); try { const importer = this.Service('import'); const imported = await importer.bulkImport(localMatches); for (let c = 0; c < localMatches.length; c++) { try { const local = localMatches[c]; let schema = imported[c]; let version = this.resolveLocalVersion(shouldEnableVersioning, local, errors); if (version || shouldEnableVersioning === false) { schema = this.prepareLocalSchema(schema, localNamespace, version, didUpdateHandler); schemas.push(schema); } } catch (err) { errors.push(new SpruceError_1.default({ code: 'SCHEMA_FAILED_TO_IMPORT', file: err?.options?.file ?? '**UNKNOWN**', originalError: err?.originalError ?? err, })); } } } catch (err) { throw new SpruceError_1.default({ code: 'SCHEMA_FAILED_TO_IMPORT', file: err?.options?.file ?? '**UNKNOWN**', originalError: err?.originalError ?? err, }); } return { schemas, errors, }; } async globbyLocalBuilders(localLookupDir) { return await (0, globby_1.default)(spruce_skill_utils_2.diskUtil.resolvePath(this.cwd, localLookupDir, '**/*.builder.[t|j]s')); } resolveLocalVersion(shouldEnableVersioning, local, errors) { let version; try { version = shouldEnableVersioning === false ? undefined : spruce_skill_utils_1.versionUtil.extractVersion(this.cwd, local).constValue; } catch (err) { errors.push(new SpruceError_1.default({ // @ts-ignore code: 'VERSION_MISSING', friendlyMessage: `It looks like your schema's are not versioned. Make sure schemas are in a directory like src/schemas/${spruce_skill_utils_1.versionUtil.generateVersion().dirValue}/*.ts`, })); } return version; } prepareLocalSchema(schema, localNamespace, version, didUpdateHandler) { let errors = []; if (schema.version) { errors.push('version_should_not_be_set'); } if (schema.namespace) { errors.push('namespace_should_not_be_set'); } schema.namespace = localNamespace; if (errors.length > 0) { throw new schema_1.SchemaError({ code: 'INVALID_SCHEMA', schemaId: schema.id, errors, friendlyMessage: 'You should not set a namespace nor version in your schema builder.', }); } schema.version = version; didUpdateHandler?.(`Imported ${schema.id} builder.`); return schema; } async fetchFields(options) { const { localAddonsDir } = options || {}; const coreAddons = schema_1.fieldRegistrations.map((registration) => { return { registration, isLocal: false, }; }); const localErrors = []; const localAddons = !localAddonsDir ? [] : await Promise.all((await (0, globby_1.default)([ path_1.default.join(localAddonsDir, '/*Field.addon.[t|j]s'), ])).map(async (file) => { try { const importService = this.Service('import'); const registration = await importService.importDefault(file); return { path: file, registration, isLocal: true, }; } catch (err) { localErrors.push(new SpruceError_1.default({ code: 'FAILED_TO_IMPORT', file, originalError: err, })); return false; } })); const allFields = (0, lodash_1.uniqBy)([ ...coreAddons, ...localAddons.filter((addon) => !!addon), ], 'registration.type'); return { fields: allFields, errors: localErrors, }; } } exports.default = SchemaStore; //# sourceMappingURL=SchemaStore.js.map