UNPKG

@sprucelabs/spruce-cli

Version:

Command line interface for building Spruce skills.

247 lines 12.1 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const path_1 = __importDefault(require("path")); const spruce_skill_utils_1 = require("@sprucelabs/spruce-skill-utils"); const uniq_1 = __importDefault(require("lodash/uniq")); const syncSchemasOptions_schema_1 = __importDefault(require("./../../../.spruce/schemas/spruceCli/v2020_07_22/syncSchemasOptions.schema")); const SpruceError_1 = __importDefault(require("../../../errors/SpruceError")); const SchemaTemplateItemBuilder_1 = __importDefault(require("../../../templateItemBuilders/SchemaTemplateItemBuilder")); const action_utility_1 = __importDefault(require("../../../utilities/action.utility")); const AbstractAction_1 = __importDefault(require("../../AbstractAction")); const schemaDisk_utility_1 = __importDefault(require("../utilities/schemaDisk.utility")); const ValueTypeBuilder_1 = __importDefault(require("../ValueTypeBuilder")); class SyncAction extends AbstractAction_1.default { optionsSchema = syncSchemasOptions_schema_1.default; commandAliases = ['sync.schemas']; invocationMessage = 'Building schemas and generating types... 📃'; schemaWriter = this.Writer('schema'); schemaStore = this.Store('schema'); skillStore = this.Store('skill'); async execute(options) { const normalizedOptions = this.validateAndNormalizeOptions(options); let { schemaTypesDestinationDirOrFile, fieldTypesDestinationDir, schemaLookupDir, addonsLookupDir, shouldEnableVersioning, globalSchemaNamespace, shouldFetchRemoteSchemas, shouldGenerateCoreSchemaTypes, shouldFetchLocalSchemas, generateFieldTypes, generateStandaloneTypesFile, deleteDestinationDirIfNoSchemas, shouldFetchCoreSchemas, registerBuiltSchemas, syncingMessage, deleteOrphanedSchemas, moduleToImportFromWhenRemote, shouldInstallMissingDependencies, } = normalizedOptions; this.ui.startLoading('Loading details about your skill... 🧐'); let localNamespace = await this.skillStore.loadCurrentSkillsNamespace(); let shouldImportCoreSchemas = true; if (shouldGenerateCoreSchemaTypes) { shouldFetchRemoteSchemas = false; shouldFetchLocalSchemas = true; shouldFetchCoreSchemas = false; registerBuiltSchemas = true; generateStandaloneTypesFile = true; shouldImportCoreSchemas = false; localNamespace = spruce_skill_utils_1.CORE_NAMESPACE; } let coreSyncResults; const { resolvedFieldTypesDestination, resolvedSchemaTypesDestinationDirOrFile, resolvedSchemaTypesDestination, } = schemaDisk_utility_1.default.resolveTypeFilePaths({ cwd: this.cwd, generateStandaloneTypesFile, schemaTypesDestinationDirOrFile, fieldTypesDestinationDir, language: this.getProjectLanguage(), }); this.ui.startLoading('Generating field types...'); const { fieldTemplateItems, fieldErrors, generateFieldFiles } = await this.generateFieldTemplateItems({ addonsLookupDir, shouldGenerateFieldTypes: generateFieldTypes, resolvedFieldTypesDestination, }); this.ui.startLoading(syncingMessage); const schemaErrors = []; let schemaTemplateItems; let typeResults = []; try { const templateResults = await this.generateSchemaTemplateItems({ schemaLookupDir, shouldFetchLocalSchemas, moduleToImportFromWhenRemote, resolvedSchemaTypesDestinationDirOrFile, shouldEnableVersioning, shouldFetchRemoteSchemas, shouldFetchCoreSchemas, localNamespace, }); schemaErrors.push(...templateResults.schemaErrors); schemaTemplateItems = templateResults.schemaTemplateItems; } catch (err) { schemaErrors.push(err); } if (schemaErrors.length === 0 && schemaTemplateItems) { if (deleteDestinationDirIfNoSchemas && schemaTemplateItems.length === 0) { spruce_skill_utils_1.diskUtil.deleteDir(resolvedSchemaTypesDestinationDirOrFile); return {}; } if (deleteOrphanedSchemas) { this.ui.startLoading('Identifying orphaned schemas...'); await schemaDisk_utility_1.default.deleteOrphanedSchemas(resolvedSchemaTypesDestinationDirOrFile, schemaTemplateItems); } await this.optionallyInstallRemoteModules(schemaTemplateItems, shouldInstallMissingDependencies); let valueTypes; try { valueTypes = this.isInGoProject() ? undefined : await this.generateValueTypes({ resolvedDestination: resolvedFieldTypesDestination, fieldTemplateItems, schemaTemplateItems, globalSchemaNamespace: globalSchemaNamespace ?? undefined, }); } catch (err) { schemaErrors.push(err); } if (valueTypes || this.isInGoProject()) { try { this.ui.startLoading('Determining what changed... ⚡️'); let goModuleNameAndPath = undefined; if (this.isInGoProject()) { goModuleNameAndPath = this.skillStore.getGoModuleName({ shouldIncludePathFromCwd: true, }); } typeResults = await this.schemaWriter.writeSchemasAndTypes(resolvedSchemaTypesDestination, { registerBuiltSchemas, fieldTemplateItems, schemaTemplateItems, shouldImportCoreSchemas, valueTypes, goModuleNameAndPath, language: this.getProjectLanguage(), globalSchemaNamespace: globalSchemaNamespace ?? undefined, typesTemplate: this.resolveTypesTemplate(generateStandaloneTypesFile), }); } catch (err) { schemaErrors.push(err); } } } const p = resolvedSchemaTypesDestination; const dir = spruce_skill_utils_1.diskUtil.isDir(p) ? p : path_1.default.dirname(p); if (spruce_skill_utils_1.diskUtil.doesDirExist(dir)) { spruce_skill_utils_1.diskUtil.deleteEmptyDirs(dir); } this.ui.stopLoading(); const errors = [...schemaErrors, ...fieldErrors]; return action_utility_1.default.mergeActionResults(coreSyncResults || {}, { files: [...typeResults, ...generateFieldFiles], errors: errors.length > 0 ? errors : undefined, meta: { schemaTemplateItems, fieldTemplateItems, }, }); } resolveTypesTemplate(generateStandaloneTypesFile) { if (this.isInGoProject()) { return 'schema/schemas.go.hbs'; } return generateStandaloneTypesFile ? 'schema/core.schemas.types.ts.hbs' : undefined; } async optionallyInstallRemoteModules(schemaTemplateItems, forceInstall) { const modules = (0, uniq_1.default)(schemaTemplateItems .map((item) => item.importFrom) .filter((i) => !!i)); if (this.isInGoProject()) { return; } const notInstalled = []; const pkg = this.Service('pkg'); for (const m of modules) { if (!pkg.isInstalled(m) && notInstalled.indexOf(m) === -1) { notInstalled.push(m); } } if (notInstalled.length > 0) { if (!forceInstall) { this.ui.stopLoading(); this.ui.renderSection({ headline: `Missing ${notInstalled.length} module${notInstalled.length === 1 ? '' : 's'}`, lines: [ `Looks like I need to install the following modules to continue to sync schemas:`, '', ...notInstalled, ], }); const confirm = await this.ui.confirm('Should we do that now?'); if (!confirm) { throw new SpruceError_1.default({ code: 'ACTION_CANCELLED', friendlyMessage: `I can't sync schemas because of the missing modules.`, }); } } this.ui.startLoading(`Installing ${notInstalled.length} missing module${notInstalled.length === 1 ? '' : 's...'}`); const pkg = this.Service('pkg'); await pkg.install(notInstalled); this.ui.stopLoading(); } } async generateSchemaTemplateItems(options) { const { schemaLookupDir, resolvedSchemaTypesDestinationDirOrFile, shouldEnableVersioning, shouldFetchRemoteSchemas, shouldFetchCoreSchemas, shouldFetchLocalSchemas, localNamespace, moduleToImportFromWhenRemote, } = options; this.ui.startLoading('Loading builders...'); const { schemasByNamespace, errors: schemaErrors } = await this.schemaStore.fetchSchemas({ localSchemaLookupDir: schemaLookupDir, shouldFetchLocalSchemas, shouldFetchRemoteSchemas, shouldEnableVersioning, moduleToImportFromWhenRemote, localNamespace, shouldFetchCoreSchemas, didUpdateHandler: (message) => { this.ui.startLoading(message); }, }); const hashSpruceDestination = this.isInGoProject() ? this.cwd : resolvedSchemaTypesDestinationDirOrFile.replace(spruce_skill_utils_1.diskUtil.resolveHashSprucePath(this.cwd), '#spruce'); let total = 0; let totalNamespaces = 0; for (const namespace of Object.keys(schemasByNamespace)) { totalNamespaces++; total += schemasByNamespace[namespace].length; } this.ui.startLoading(`Building ${total} schemas from ${totalNamespaces} namespaces.`); const schemaTemplateItemBuilder = new SchemaTemplateItemBuilder_1.default(localNamespace); const schemaTemplateItems = schemaTemplateItemBuilder.buildTemplateItems(schemasByNamespace, hashSpruceDestination); return { schemaTemplateItems, schemaErrors }; } isInGoProject() { return this.getProjectLanguage() === 'go'; } async generateFieldTemplateItems(options) { if (this.isInGoProject()) { return { generateFieldFiles: [], fieldTemplateItems: [], fieldErrors: [], }; } const { addonsLookupDir, shouldGenerateFieldTypes: generateFieldTypes, resolvedFieldTypesDestination, } = options; const action = this.Action('schema', 'syncFields'); const results = await action.execute({ fieldTypesDestinationDir: resolvedFieldTypesDestination, addonsLookupDir, generateFieldTypes, }); return { generateFieldFiles: results.files ?? [], fieldTemplateItems: results.meta?.fieldTemplateItems ?? [], fieldErrors: results.errors ?? [], }; } async generateValueTypes(options) { this.ui.startLoading('Generating value types...'); const builder = new ValueTypeBuilder_1.default(this.schemaWriter, this.Service('import')); return builder.generateValueTypes(options); } } exports.default = SyncAction; //# sourceMappingURL=SyncAction.js.map