UNPKG

@sprucelabs/spruce-cli

Version:

Command line interface for building Spruce skills.

244 lines • 12.7 kB
"use strict"; var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; 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 mercury_core_events_1 = require("@sprucelabs/mercury-core-events"); const mercury_types_1 = require("@sprucelabs/mercury-types"); const schema_1 = require("@sprucelabs/schema"); const spruce_event_utils_1 = require("@sprucelabs/spruce-event-utils"); const spruce_skill_utils_1 = require("@sprucelabs/spruce-skill-utils"); const test_utils_1 = require("@sprucelabs/test-utils"); const AbstractEventTest_1 = __importDefault(require("../../../tests/AbstractEventTest")); const coreContract = spruce_event_utils_1.eventContractUtil.unifyContracts(mercury_core_events_1.coreEventContracts); class KeepingEventsInSyncTest extends AbstractEventTest_1.default { static get eventContractPath() { return this.resolveHashSprucePath('events', 'events.contract.ts'); } static async hasSyncEventsAction() { await this.Cli(); test_utils_1.assert.isFunction(this.Action('event', 'sync').execute); } static async syncsWithoutSavingCoreEventsByDefault() { await this.FeatureFixture().installCachedFeatures('eventsInNodeModule'); const results = await this.skipInstallSkillPrompts(() => this.Action('event', 'sync').execute({})); await this.assertValidSyncEventsResults(results); } static async mergesGlobalEvents() { await this.FeatureFixture().installCachedFeatures('events'); const skills = this.getSkillFixture(); await skills.registerCurrentSkill({ name: 'events in sync skill', }); const skill2 = await skills.seedDemoSkill({ name: 'a temp skill' }); await this.Service('dependency').add({ id: skill2.id, namespace: skill2.slug, }); await skills.registerEventContract(skill2, { eventSignatures: { 'test-sync::v2021_01_01': { isGlobal: true, }, }, }); const results = await this.Action('event', 'sync').execute({}); await this.assertValidSyncEventsResults(results); const fqen = spruce_event_utils_1.eventNameUtil.join({ eventName: 'test-sync', version: 'v2021_01_01', eventNamespace: skill2.slug, }); await this.assertGlobalEventsAreTyped(fqen); } static async canSetSkillEventContractTypesFile() { await this.FeatureFixture().installCachedFeatures('eventsInNodeModule'); await this.skipInstallSkillPrompts(() => this.Action('event', 'sync').execute({ skillEventContractTypesFile: 'testy test', })); const contents = spruce_skill_utils_1.diskUtil.readFile(this.eventContractPath); test_utils_1.assert.doesInclude(contents, `declare module 'testy test'`); } static async canSyncOnlyCoreEvents() { await this.FeatureFixture().installCachedFeatures('eventsInNodeModule'); const promise = this.syncCoreEventsPretendingToBeMercuryTypes(); await this.skipInstallSkillPrompts(); const results = await promise; await this.assertValidSyncEventsResults(results, true); } static async syncingSchemasDoesNotSyncEventSchemasIfEventsHaveNeverBeenSynced() { const cli = await this.FeatureFixture().installCachedFeatures('events'); const event = cli.getFeature('event'); let wasHit = false; //@ts-ignore event.getEventContractBuilder = () => { wasHit = true; }; const results = await this.Action('schema', 'sync').execute({}); this.assertCoreEventContractsSavedToDisk(false); this.assertCorePayloadSchemasAreCreated(results, false); test_utils_1.assert.isFalse(wasHit); test_utils_1.assert.isFalse(spruce_skill_utils_1.diskUtil.doesFileExist(this.eventContractPath)); } static async syncingSchemaAfterSyncEventsSyncsSchemasAndDoesNotWriteCoreEvents() { const cli = await this.FeatureFixture().installCachedFeatures('events'); await this.Action('event', 'sync').execute({}); const event = cli.getFeature('event'); let wasHit = false; const oldGetter = event.getEventContractBuilder.bind(event); //@ts-ignore event.getEventContractBuilder = () => { wasHit = true; return oldGetter(); }; const results = await this.Action('schema', 'sync').execute({}); test_utils_1.assert.isTrue(wasHit); await this.assertValidSyncSchemasResults(results, false); } static async syncingSchemasAfterSyncingCoreEventsSavesCoreEvents() { await this.FeatureFixture().installCachedFeatures('events'); await this.syncCoreEventsPretendingToBeMercuryTypes(); const results = await this.Action('schema', 'sync').execute({}); await this.assertValidSyncSchemasResults(results, true); } static async syncCoreEventsPretendingToBeMercuryTypes() { const results = await this.Action('event', 'sync').execute({ shouldSyncOnlyCoreEvents: true, eventBuilderFile: '../../../builder', skillEventContractTypesFile: '../../builder', }); const builder = ` export function buildEventContract(..._: any[]):any { return _[0] } export function buildPermissionContract(..._: any[]):any { return _[0] } `; spruce_skill_utils_1.diskUtil.writeFile(this.resolvePath('src', 'builder.ts'), builder); await this.Service('pkg').uninstall([ '@sprucelabs/mercury-types', '@sprucelabs/mercury-client', '@sprucelabs/spruce-event-plugin', ]); return results; } static async assertValidSyncEventsResults(results, shouldSyncOnlyCoreEvents = false) { test_utils_1.assert.isFalsy(results.errors); await this.assertValidSyncSchemasResults(results, shouldSyncOnlyCoreEvents); } static async assertGlobalEventsAreTyped(eventName) { const contents = spruce_skill_utils_1.diskUtil.readFile(this.eventContractPath); test_utils_1.assert.doesInclude(contents, `'${eventName}':`); } static async assertValidSyncSchemasResults(results, shouldSyncOnlyCoreEvents) { test_utils_1.assert.isFalsy(results.errors); this.assertCoreEventContractsSavedToDisk(shouldSyncOnlyCoreEvents); this.assertCorePayloadSchemasAreCreated(results, shouldSyncOnlyCoreEvents); await this.assertEventsHavePayloads(results); await this.assertCombinedContractContents(); const coreContractContents = spruce_skill_utils_1.diskUtil.readFile(this.eventContractPath); const search = `did-message::v2020_12_25': MercuryDidMessageEventContract_v2020_12_25['eventSignatures']['did-message::v2020_12_25']`; if (shouldSyncOnlyCoreEvents) { test_utils_1.assert.doesInclude(coreContractContents, search); } else { test_utils_1.assert.doesNotInclude(coreContractContents, search); } } static async assertCombinedContractContents() { const imported = await this.importCombinedContractsFile(); test_utils_1.assert.isTruthy(imported); test_utils_1.assert.isArray(imported); const localContract = spruce_event_utils_1.eventContractUtil.unifyContracts(imported); test_utils_1.assert.isTruthy(localContract); const sigs = spruce_event_utils_1.eventContractUtil.getNamedEventSignatures(coreContract); for (const sig of sigs) { spruce_event_utils_1.eventContractUtil.getSignatureByName(localContract, sig.fullyQualifiedEventName); } } static async importCombinedContractsFile() { const eventContractsFile = this.eventContractPath; // hack import to bring types in when importing contract file if (spruce_skill_utils_1.diskUtil.doesDirExist(this.resolvePath('node_modules/@sprucelabs/mercury-types'))) { const contents = spruce_skill_utils_1.diskUtil.readFile(eventContractsFile); spruce_skill_utils_1.diskUtil.writeFile(eventContractsFile, `import '@sprucelabs/mercury-types'\n${contents}`); } const imported = await this.Service('import').importDefault(eventContractsFile); return imported; } static async assertEventsHavePayloads(results, eventName = 'authenticate') { const imported = await this.importCombinedContractsFile(); const contract = spruce_event_utils_1.eventContractUtil.unifyContracts(imported); test_utils_1.assert.isTruthy(contract); (0, mercury_types_1.validateEventContract)(contract); const signature = spruce_event_utils_1.eventContractUtil.getSignatureByName(contract, eventName); test_utils_1.assert.isTruthy(signature.emitPayloadSchema); (0, schema_1.validateSchema)(signature.emitPayloadSchema); test_utils_1.assert.isTruthy(signature.responsePayloadSchema); (0, schema_1.validateSchema)(signature.responsePayloadSchema); } static assertCorePayloadSchemasAreCreated(results, shouldHaveWritten = true) { const filesToCheck = [ { name: `unregisterListenersEmitTargetAndPayload.schema.ts`, path: `schemas${path_1.default.sep}${spruce_skill_utils_1.MERCURY_API_NAMESPACE}`, }, ]; this.assertFilesWereGenerated(filesToCheck, results, shouldHaveWritten); } static assertFilesWereGenerated(filesToCheck, results, shouldHaveWritten = true) { for (const file of filesToCheck) { const expected = this.resolveHashSprucePath('schemas/mercury/v2020_12_25', file.name); const doesExist = spruce_skill_utils_1.diskUtil.doesFileExist(expected); if (shouldHaveWritten) { test_utils_1.assert.isTrue(doesExist, `Expected to find ${file} on the filesystem.`); } else { test_utils_1.assert.isFalse(doesExist, `Should not have written ${file}.`); } } } static assertCoreEventContractsSavedToDisk(shouldHaveWritten = true) { const sigs = spruce_event_utils_1.eventContractUtil.getNamedEventSignatures(coreContract); for (const sig of sigs) { const expected = this.resolveHashSprucePath(`events/mercury/${spruce_skill_utils_1.namesUtil.toCamel(sig.eventName)}.v2020_12_25.contract.ts`); const doesExist = spruce_skill_utils_1.diskUtil.doesFileExist(expected); if (shouldHaveWritten) { test_utils_1.assert.isTrue(doesExist, `Expected to write a file ${expected}.`); } else { test_utils_1.assert.isFalse(doesExist, `Generated contract for ${sig.fullyQualifiedEventName} and it should not have because it's a core contract.`); } } } } exports.default = KeepingEventsInSyncTest; __decorate([ (0, test_utils_1.test)() ], KeepingEventsInSyncTest, "hasSyncEventsAction", null); __decorate([ (0, test_utils_1.test)() ], KeepingEventsInSyncTest, "syncsWithoutSavingCoreEventsByDefault", null); __decorate([ (0, test_utils_1.test)() ], KeepingEventsInSyncTest, "mergesGlobalEvents", null); __decorate([ (0, test_utils_1.test)() ], KeepingEventsInSyncTest, "canSetSkillEventContractTypesFile", null); __decorate([ (0, test_utils_1.test)() ], KeepingEventsInSyncTest, "canSyncOnlyCoreEvents", null); __decorate([ (0, test_utils_1.test)() ], KeepingEventsInSyncTest, "syncingSchemasDoesNotSyncEventSchemasIfEventsHaveNeverBeenSynced", null); __decorate([ (0, test_utils_1.test)() ], KeepingEventsInSyncTest, "syncingSchemaAfterSyncEventsSyncsSchemasAndDoesNotWriteCoreEvents", null); __decorate([ (0, test_utils_1.test)() ], KeepingEventsInSyncTest, "syncingSchemasAfterSyncingCoreEventsSavesCoreEvents", null); //# sourceMappingURL=KeepingEventsInSync.test.js.map