@sprucelabs/spruce-cli 18.0.0 → 18.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +10 -0
- package/build/__tests__/behavioral/EnablingAndDisablingCache.test.js +1 -1
- package/build/__tests__/behavioral/EnablingAndDisablingCache.test.js.map +1 -1
- package/build/__tests__/behavioral/RememberingUpgradeSelections.test.js +1 -1
- package/build/__tests__/behavioral/RememberingUpgradeSelections.test.js.map +1 -1
- package/build/__tests__/behavioral/SettingUpSchemasForModuleDistribution.test.js +4 -4
- package/build/__tests__/behavioral/SettingUpSchemasForModuleDistribution.test.js.map +1 -1
- package/build/__tests__/behavioral/WatchingSkillViews.test.js +3 -3
- package/build/__tests__/behavioral/WatchingSkillViews.test.js.map +1 -1
- package/build/__tests__/behavioral/errors/SettingUpErrors.test.js +1 -1
- package/build/__tests__/behavioral/errors/SettingUpErrors.test.js.map +1 -1
- package/build/__tests__/behavioral/events/CreatingAListener.test.d.ts +2 -0
- package/build/__tests__/behavioral/events/CreatingAListener.test.js +118 -59
- package/build/__tests__/behavioral/events/CreatingAListener.test.js.map +1 -1
- package/build/__tests__/behavioral/events/EverythingInstalledInstaller.d.ts +17 -0
- package/build/__tests__/behavioral/events/EverythingInstalledInstaller.js +137 -0
- package/build/__tests__/behavioral/events/EverythingInstalledInstaller.js.map +1 -0
- package/build/__tests__/behavioral/onboard/StartingOnboarding.test.js +46 -45
- package/build/__tests__/behavioral/onboard/StartingOnboarding.test.js.map +1 -1
- package/build/__tests__/behavioral/tests/CreatingATest.test.js +1 -1
- package/build/__tests__/behavioral/tests/CreatingATest.test.js.map +1 -1
- package/build/__tests__/behavioral/tests/SelectingAnAbstractTestClass.test.js +4 -4
- package/build/__tests__/behavioral/tests/SelectingAnAbstractTestClass.test.js.map +1 -1
- package/build/__tests__/behavioral/upgrading/UpdatingDependencies2.test.js +2 -2
- package/build/__tests__/behavioral/upgrading/UpdatingDependencies2.test.js.map +1 -1
- package/build/__tests__/behavioral/upgrading/UpgradingANodeModule.test.js +2 -2
- package/build/__tests__/behavioral/upgrading/UpgradingANodeModule.test.js.map +1 -1
- package/build/__tests__/behavioral/upgrading/UpgradingASkill5.test.js +2 -2
- package/build/__tests__/behavioral/upgrading/UpgradingASkill5.test.js.map +1 -1
- package/build/__tests__/behavioral/upgrading/UpgradingWithListeners.test.js +2 -2
- package/build/__tests__/behavioral/upgrading/UpgradingWithListeners.test.js.map +1 -1
- package/build/__tests__/behavioral/views/CreatingASkillView.test.js +1 -1
- package/build/__tests__/behavioral/views/CreatingASkillView.test.js.map +1 -1
- package/build/__tests__/behavioral/views/CreatingATheme.test.js +1 -1
- package/build/__tests__/behavioral/views/CreatingATheme.test.js.map +1 -1
- package/build/__tests__/behavioral/watchers/WatchingForChanges.test.d.ts +3 -3
- package/build/__tests__/behavioral/watchers/WatchingForChanges.test.js +153 -156
- package/build/__tests__/behavioral/watchers/WatchingForChanges.test.js.map +1 -1
- package/build/__tests__/implementation/ActionExecuter.test.js +2 -2
- package/build/__tests__/implementation/ActionExecuter.test.js.map +1 -1
- package/build/__tests__/implementation/ActionExecuter2.test.js +1 -1
- package/build/__tests__/implementation/ActionExecuter2.test.js.map +1 -1
- package/build/__tests__/implementation/ActionExecuter4.test.js +1 -1
- package/build/__tests__/implementation/ActionExecuter4.test.js.map +1 -1
- package/build/__tests__/implementation/FeatureInstaller.test.js +8 -4
- package/build/__tests__/implementation/FeatureInstaller.test.js.map +1 -1
- package/build/__tests__/implementation/GlobalEmitter.d.ts +1 -1
- package/build/__tests__/implementation/GlobalEmitter.js +9 -10
- package/build/__tests__/implementation/GlobalEmitter.js.map +1 -1
- package/build/__tests__/implementation/SettingUpANodeModule.test.js +1 -1
- package/build/__tests__/implementation/SettingUpANodeModule.test.js.map +1 -1
- package/build/__tests__/implementation/SkillStore.test.d.ts +3 -1
- package/build/__tests__/implementation/SkillStore.test.js +67 -50
- package/build/__tests__/implementation/SkillStore.test.js.map +1 -1
- package/build/__tests__/implementation/StoreFeature.test.js +1 -1
- package/build/__tests__/implementation/StoreFeature.test.js.map +1 -1
- package/build/cli.js +3 -3
- package/build/cli.js.map +1 -1
- package/build/features/AbstractAction.d.ts +2 -2
- package/build/features/AbstractAction.js.map +1 -1
- package/build/features/AbstractFeature.d.ts +22 -22
- package/build/features/AbstractFeature.js.map +1 -1
- package/build/features/ActionExecuter.d.ts +8 -8
- package/build/features/ActionExecuter.js.map +1 -1
- package/build/features/FeatureInstaller.d.ts +15 -2
- package/build/features/FeatureInstaller.js +36 -36
- package/build/features/FeatureInstaller.js.map +1 -1
- package/build/features/FeatureInstallerFactory.d.ts +12 -10
- package/build/features/FeatureInstallerFactory.js +2 -2
- package/build/features/FeatureInstallerFactory.js.map +1 -1
- package/build/features/OverrideActionDecorator.js +4 -5
- package/build/features/OverrideActionDecorator.js.map +1 -1
- package/build/features/event/actions/ListenAction.js.map +1 -1
- package/build/features/event/actions/SetRemoteAction.d.ts +1 -0
- package/build/features/event/actions/SetRemoteAction.js +2 -1
- package/build/features/event/actions/SetRemoteAction.js.map +1 -1
- package/build/features/event/actions/SyncListenersAction.js.map +1 -1
- package/build/features/node/NodeFeature.js.map +1 -1
- package/build/features/skill/SkillFeature.js.map +1 -1
- package/build/features/skill/stores/SkillStore.d.ts +4 -1
- package/build/features/skill/stores/SkillStore.js +127 -100
- package/build/features/skill/stores/SkillStore.js.map +1 -1
- package/build/features/watch/WatchFeature.js +1 -1
- package/build/features/watch/WatchFeature.js.map +1 -1
- package/build/interfaces/SpyInterface.d.ts +2 -0
- package/build/interfaces/SpyInterface.js +16 -4
- package/build/interfaces/SpyInterface.js.map +1 -1
- package/build/stores/AbstractStore.d.ts +9 -7
- package/build/stores/AbstractStore.js.map +1 -1
- package/build/stores/StoreFactory.d.ts +19 -13
- package/build/stores/StoreFactory.js +15 -13
- package/build/stores/StoreFactory.js.map +1 -1
- package/build/tests/AbstractCliTest.d.ts +9 -6
- package/build/tests/AbstractCliTest.js +53 -45
- package/build/tests/AbstractCliTest.js.map +1 -1
- package/build/tests/AbstractSchemaTest.js +18 -20
- package/build/tests/AbstractSchemaTest.js.map +1 -1
- package/build/utilities/action.utility.js +3 -1
- package/build/utilities/action.utility.js.map +1 -1
- package/node_modules/@typescript-eslint/parser/package.json +5 -5
- package/node_modules/@typescript-eslint/scope-manager/package.json +5 -5
- package/node_modules/@typescript-eslint/types/package.json +2 -2
- package/node_modules/@typescript-eslint/typescript-estree/package.json +5 -5
- package/node_modules/@typescript-eslint/visitor-keys/package.json +3 -3
- package/package.json +32 -90
- package/src/__tests__/behavioral/EnablingAndDisablingCache.test.ts +1 -1
- package/src/__tests__/behavioral/RememberingUpgradeSelections.test.ts +1 -1
- package/src/__tests__/behavioral/SettingUpSchemasForModuleDistribution.test.ts +4 -4
- package/src/__tests__/behavioral/WatchingSkillViews.test.ts +3 -3
- package/src/__tests__/behavioral/errors/SettingUpErrors.test.ts +1 -1
- package/src/__tests__/behavioral/events/CreatingAListener.test.ts +41 -14
- package/src/__tests__/behavioral/events/EverythingInstalledInstaller.ts +46 -0
- package/src/__tests__/behavioral/onboard/StartingOnboarding.test.ts +10 -5
- package/src/__tests__/behavioral/tests/CreatingATest.test.ts +1 -1
- package/src/__tests__/behavioral/tests/SelectingAnAbstractTestClass.test.ts +4 -4
- package/src/__tests__/behavioral/upgrading/UpdatingDependencies2.test.ts +2 -2
- package/src/__tests__/behavioral/upgrading/UpgradingANodeModule.test.ts +2 -2
- package/src/__tests__/behavioral/upgrading/UpgradingASkill5.test.ts +2 -2
- package/src/__tests__/behavioral/upgrading/UpgradingWithListeners.test.ts +2 -2
- package/src/__tests__/behavioral/views/CreatingASkillView.test.ts +1 -1
- package/src/__tests__/behavioral/views/CreatingATheme.test.ts +1 -1
- package/src/__tests__/behavioral/watchers/WatchingForChanges.test.ts +35 -35
- package/src/__tests__/implementation/ActionExecuter.test.ts +2 -2
- package/src/__tests__/implementation/ActionExecuter2.test.ts +1 -1
- package/src/__tests__/implementation/ActionExecuter4.test.ts +1 -1
- package/src/__tests__/implementation/FeatureInstaller.test.ts +8 -1
- package/src/__tests__/implementation/GlobalEmitter.ts +2 -4
- package/src/__tests__/implementation/SettingUpANodeModule.test.ts +1 -1
- package/src/__tests__/implementation/SkillStore.test.ts +23 -24
- package/src/__tests__/implementation/StoreFeature.test.ts +1 -1
- package/src/cli.ts +7 -3
- package/src/features/AbstractAction.ts +3 -3
- package/src/features/AbstractFeature.ts +26 -26
- package/src/features/ActionExecuter.ts +9 -9
- package/src/features/FeatureInstaller.ts +32 -12
- package/src/features/FeatureInstallerFactory.ts +17 -13
- package/src/features/OverrideActionDecorator.ts +2 -5
- package/src/features/event/actions/ListenAction.ts +1 -0
- package/src/features/event/actions/SetRemoteAction.ts +2 -1
- package/src/features/event/actions/SyncListenersAction.ts +0 -1
- package/src/features/node/NodeFeature.ts +3 -1
- package/src/features/skill/SkillFeature.ts +3 -3
- package/src/features/skill/stores/SkillStore.ts +18 -11
- package/src/features/watch/WatchFeature.ts +1 -1
- package/src/interfaces/SpyInterface.ts +10 -0
- package/src/stores/AbstractStore.ts +14 -8
- package/src/stores/StoreFactory.ts +56 -44
- package/src/tests/AbstractCliTest.ts +53 -45
- package/src/tests/AbstractSchemaTest.ts +1 -3
- package/src/utilities/action.utility.ts +3 -1
- package/.DS_Store +0 -0
- package/.env +0 -25
- package/.eslintcache +0 -1
- package/build/.spruce/tmp/cached-skills.json +0 -3
- package/junit.xml +0 -7
- package/src/.DS_Store +0 -0
- package/src/.spruce/tmp/cached-skills.json +0 -3
- package/yarn-error.log +0 -12174
|
@@ -1,22 +1,25 @@
|
|
|
1
1
|
import { test, assert } from '@sprucelabs/test-utils'
|
|
2
2
|
import { errorAssert } from '@sprucelabs/test-utils'
|
|
3
|
+
import SkillStore from '../../features/skill/stores/SkillStore'
|
|
3
4
|
import AbstractCliTest from '../../tests/AbstractCliTest'
|
|
4
5
|
|
|
5
6
|
export default class SkillStoreTest extends AbstractCliTest {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
private static store: SkillStore
|
|
8
|
+
|
|
9
|
+
protected static async beforeEach() {
|
|
10
|
+
await super.beforeEach()
|
|
11
|
+
this.store = this.SkillStore()
|
|
9
12
|
}
|
|
10
13
|
|
|
11
14
|
@test()
|
|
12
15
|
protected static async hasRegisterMethod() {
|
|
13
|
-
assert.isFunction(this.
|
|
16
|
+
assert.isFunction(this.store.register)
|
|
14
17
|
}
|
|
15
18
|
|
|
16
19
|
@test()
|
|
17
20
|
protected static async cantRegisterIfNotInSkill() {
|
|
18
21
|
const err = await assert.doesThrowAsync(() =>
|
|
19
|
-
this.
|
|
22
|
+
this.store.register({
|
|
20
23
|
name: 'awesome skill',
|
|
21
24
|
slug: 'awesome-skill',
|
|
22
25
|
})
|
|
@@ -26,16 +29,14 @@ export default class SkillStoreTest extends AbstractCliTest {
|
|
|
26
29
|
|
|
27
30
|
@test()
|
|
28
31
|
protected static async cantLoadcurrentSkillIfNotInSkill() {
|
|
29
|
-
const err = await assert.doesThrowAsync(() =>
|
|
30
|
-
this.Store('skill').loadCurrentSkill()
|
|
31
|
-
)
|
|
32
|
+
const err = await assert.doesThrowAsync(() => this.store.loadCurrentSkill())
|
|
32
33
|
errorAssert.assertError(err, 'DIRECTORY_NOT_SKILL')
|
|
33
34
|
}
|
|
34
35
|
|
|
35
36
|
@test()
|
|
36
37
|
protected static async cantCheckIfSkillIsRegisteredNotInSkill() {
|
|
37
38
|
const err = await assert.doesThrowAsync(() =>
|
|
38
|
-
this.
|
|
39
|
+
this.store.isCurrentSkillRegistered()
|
|
39
40
|
)
|
|
40
41
|
errorAssert.assertError(err, 'DIRECTORY_NOT_SKILL')
|
|
41
42
|
}
|
|
@@ -43,8 +44,7 @@ export default class SkillStoreTest extends AbstractCliTest {
|
|
|
43
44
|
@test()
|
|
44
45
|
protected static async canGetNamespace() {
|
|
45
46
|
await this.FeatureFixture().installCachedFeatures('skills')
|
|
46
|
-
|
|
47
|
-
const namespace = await this.Store('skill').loadCurrentSkillsNamespace()
|
|
47
|
+
const namespace = await this.store.loadCurrentSkillsNamespace()
|
|
48
48
|
assert.isEqual(namespace, 'TestSkill')
|
|
49
49
|
}
|
|
50
50
|
|
|
@@ -52,12 +52,9 @@ export default class SkillStoreTest extends AbstractCliTest {
|
|
|
52
52
|
protected static async canSetNamespace() {
|
|
53
53
|
await this.FeatureFixture().installCachedFeatures('skills')
|
|
54
54
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
await this.Store('skill').setCurrentSkillsNamespace('new-namespace')
|
|
59
|
-
|
|
60
|
-
namespace = await store.loadCurrentSkillsNamespace()
|
|
55
|
+
let namespace = await this.store.loadCurrentSkillsNamespace()
|
|
56
|
+
await this.store.setCurrentSkillsNamespace('new-namespace')
|
|
57
|
+
namespace = await this.store.loadCurrentSkillsNamespace()
|
|
61
58
|
assert.isEqual(namespace, 'NewNamespace')
|
|
62
59
|
}
|
|
63
60
|
|
|
@@ -68,12 +65,10 @@ export default class SkillStoreTest extends AbstractCliTest {
|
|
|
68
65
|
const slug = `awesome-skill-${new Date().getTime()}`
|
|
69
66
|
await this.people.loginAsDemoPerson()
|
|
70
67
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
let isRegistered = await skillStore.isCurrentSkillRegistered()
|
|
68
|
+
let isRegistered = await this.store.isCurrentSkillRegistered()
|
|
74
69
|
assert.isFalse(isRegistered)
|
|
75
70
|
|
|
76
|
-
const skill = await
|
|
71
|
+
const skill = await this.store.register({
|
|
77
72
|
name: 'awesome skill',
|
|
78
73
|
slug,
|
|
79
74
|
})
|
|
@@ -92,10 +87,10 @@ export default class SkillStoreTest extends AbstractCliTest {
|
|
|
92
87
|
|
|
93
88
|
assert.isEqual(results.skill?.id, skill.id)
|
|
94
89
|
|
|
95
|
-
isRegistered = await
|
|
90
|
+
isRegistered = await this.store.isCurrentSkillRegistered()
|
|
96
91
|
assert.isTrue(isRegistered)
|
|
97
92
|
|
|
98
|
-
const currentSkill = await
|
|
93
|
+
const currentSkill = await this.store.loadCurrentSkill()
|
|
99
94
|
|
|
100
95
|
assert.isEqual(currentSkill.id, skill.id)
|
|
101
96
|
assert.isTrue(currentSkill.isRegistered)
|
|
@@ -109,7 +104,7 @@ export default class SkillStoreTest extends AbstractCliTest {
|
|
|
109
104
|
assert.isEqual(env.get('SKILL_API_KEY'), skill.apiKey)
|
|
110
105
|
|
|
111
106
|
const err = await assert.doesThrowAsync(() =>
|
|
112
|
-
|
|
107
|
+
this.store.setCurrentSkillsNamespace('test')
|
|
113
108
|
)
|
|
114
109
|
|
|
115
110
|
errorAssert.assertError(err, 'GENERIC')
|
|
@@ -118,4 +113,8 @@ export default class SkillStoreTest extends AbstractCliTest {
|
|
|
118
113
|
const namespace = pkg.get('skill.namespace')
|
|
119
114
|
assert.isEqual(namespace, slug)
|
|
120
115
|
}
|
|
116
|
+
|
|
117
|
+
private static SkillStore(): SkillStore {
|
|
118
|
+
return this.Store('skill', {})
|
|
119
|
+
}
|
|
121
120
|
}
|
package/src/cli.ts
CHANGED
|
@@ -20,7 +20,9 @@ import FeatureCommandAttacher, {
|
|
|
20
20
|
BlockedCommands,
|
|
21
21
|
OptionOverrides,
|
|
22
22
|
} from './features/FeatureCommandAttacher'
|
|
23
|
-
import FeatureInstaller
|
|
23
|
+
import FeatureInstaller, {
|
|
24
|
+
FeatureInstallerImpl,
|
|
25
|
+
} from './features/FeatureInstaller'
|
|
24
26
|
import FeatureInstallerFactory from './features/FeatureInstallerFactory'
|
|
25
27
|
import { FeatureCode, InstallFeatureOptions } from './features/features.types'
|
|
26
28
|
import CliGlobalEmitter, {
|
|
@@ -471,14 +473,16 @@ async function setupInFlightEntertainment(ui: TerminalInterface) {
|
|
|
471
473
|
const command = new CommandService(diskUtil.resolvePath(__dirname, '../'))
|
|
472
474
|
InFlightEntertainment.setup({ command, ui })
|
|
473
475
|
|
|
474
|
-
|
|
476
|
+
FeatureInstallerImpl.startInFlightIntertainmentHandler = (
|
|
477
|
+
didUpdateHandler
|
|
478
|
+
) => {
|
|
475
479
|
InFlightEntertainment.start()
|
|
476
480
|
didUpdateHandler((message) => {
|
|
477
481
|
InFlightEntertainment.writeStatus(message)
|
|
478
482
|
})
|
|
479
483
|
}
|
|
480
484
|
|
|
481
|
-
|
|
485
|
+
FeatureInstallerImpl.stopInFlightIntertainmentHandler = () => {
|
|
482
486
|
InFlightEntertainment.stop()
|
|
483
487
|
}
|
|
484
488
|
}
|
|
@@ -9,7 +9,7 @@ import ServiceFactory, {
|
|
|
9
9
|
} from '../services/ServiceFactory'
|
|
10
10
|
import StoreFactory, {
|
|
11
11
|
StoreCode,
|
|
12
|
-
|
|
12
|
+
CreateStoreOptions,
|
|
13
13
|
StoreMap,
|
|
14
14
|
} from '../stores/StoreFactory'
|
|
15
15
|
import {
|
|
@@ -79,9 +79,9 @@ export default abstract class AbstractAction<S extends Schema = Schema>
|
|
|
79
79
|
|
|
80
80
|
protected Store<C extends StoreCode>(
|
|
81
81
|
code: C,
|
|
82
|
-
options?:
|
|
82
|
+
options?: CreateStoreOptions<C>
|
|
83
83
|
): StoreMap[C] {
|
|
84
|
-
return this.storeFactory.Store(code, { cwd: this.cwd, ...options })
|
|
84
|
+
return this.storeFactory.Store(code, { cwd: this.cwd, ...(options as any) })
|
|
85
85
|
}
|
|
86
86
|
|
|
87
87
|
protected Writer<C extends WriterCode>(
|
|
@@ -10,7 +10,7 @@ import ServiceFactory, {
|
|
|
10
10
|
} from '../services/ServiceFactory'
|
|
11
11
|
import StoreFactory, {
|
|
12
12
|
StoreCode,
|
|
13
|
-
|
|
13
|
+
CreateStoreOptions,
|
|
14
14
|
StoreMap,
|
|
15
15
|
} from '../stores/StoreFactory'
|
|
16
16
|
import {
|
|
@@ -28,29 +28,6 @@ import featuresUtil from './feature.utilities'
|
|
|
28
28
|
import FeatureInstaller from './FeatureInstaller'
|
|
29
29
|
import { FeatureCode } from './features.types'
|
|
30
30
|
|
|
31
|
-
export interface InstallResults {
|
|
32
|
-
files?: GeneratedFile[]
|
|
33
|
-
cwd?: string
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
export interface FeatureDependency {
|
|
37
|
-
isRequired: boolean
|
|
38
|
-
code: FeatureCode
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
export interface FeatureOptions {
|
|
42
|
-
cwd: string
|
|
43
|
-
serviceFactory: ServiceFactory
|
|
44
|
-
templates: Templates
|
|
45
|
-
storeFactory: StoreFactory
|
|
46
|
-
actionFactory?: ActionFactory
|
|
47
|
-
featureInstaller: FeatureInstaller
|
|
48
|
-
ui: GraphicsInterface
|
|
49
|
-
emitter: GlobalEmitter
|
|
50
|
-
apiClientFactory: ApiClientFactory
|
|
51
|
-
actionExecuter: ActionExecuter
|
|
52
|
-
}
|
|
53
|
-
|
|
54
31
|
export default abstract class AbstractFeature<
|
|
55
32
|
S extends Schema | undefined = Schema | undefined
|
|
56
33
|
> implements ServiceProvider
|
|
@@ -162,9 +139,9 @@ export default abstract class AbstractFeature<
|
|
|
162
139
|
|
|
163
140
|
public Store<C extends StoreCode>(
|
|
164
141
|
code: C,
|
|
165
|
-
options?:
|
|
142
|
+
options?: CreateStoreOptions<C>
|
|
166
143
|
): StoreMap[C] {
|
|
167
|
-
return this.storeFactory.Store(code, { cwd: this.cwd, ...options })
|
|
144
|
+
return this.storeFactory.Store(code, { cwd: this.cwd, ...(options as any) })
|
|
168
145
|
}
|
|
169
146
|
|
|
170
147
|
protected async connectToApi(
|
|
@@ -173,3 +150,26 @@ export default abstract class AbstractFeature<
|
|
|
173
150
|
return this.apiClientFactory(options)
|
|
174
151
|
}
|
|
175
152
|
}
|
|
153
|
+
|
|
154
|
+
export interface InstallResults {
|
|
155
|
+
files?: GeneratedFile[]
|
|
156
|
+
cwd?: string
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
export interface FeatureDependency {
|
|
160
|
+
isRequired: boolean
|
|
161
|
+
code: FeatureCode
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
export interface FeatureOptions {
|
|
165
|
+
cwd: string
|
|
166
|
+
serviceFactory: ServiceFactory
|
|
167
|
+
templates: Templates
|
|
168
|
+
storeFactory: StoreFactory
|
|
169
|
+
actionFactory?: ActionFactory
|
|
170
|
+
featureInstaller: FeatureInstaller
|
|
171
|
+
ui: GraphicsInterface
|
|
172
|
+
emitter: GlobalEmitter
|
|
173
|
+
apiClientFactory: ApiClientFactory
|
|
174
|
+
actionExecuter: ActionExecuter
|
|
175
|
+
}
|
|
@@ -14,15 +14,6 @@ import {
|
|
|
14
14
|
FeatureActionResponse,
|
|
15
15
|
} from './features.types'
|
|
16
16
|
|
|
17
|
-
export interface ActionExecuterOptions {
|
|
18
|
-
ui: GraphicsInterface
|
|
19
|
-
emitter: GlobalEmitter
|
|
20
|
-
actionFactory: ActionFactory
|
|
21
|
-
featureInstallerFactory: () => FeatureInstaller
|
|
22
|
-
shouldAutoHandleDependencies?: boolean
|
|
23
|
-
shouldThrowOnListenerError?: boolean
|
|
24
|
-
}
|
|
25
|
-
|
|
26
17
|
export default class ActionExecuter {
|
|
27
18
|
private emitter: GlobalEmitter
|
|
28
19
|
private ui: GraphicsInterface
|
|
@@ -201,3 +192,12 @@ export default class ActionExecuter {
|
|
|
201
192
|
return action as any
|
|
202
193
|
}
|
|
203
194
|
}
|
|
195
|
+
|
|
196
|
+
export interface ActionExecuterOptions {
|
|
197
|
+
ui: GraphicsInterface
|
|
198
|
+
emitter: GlobalEmitter
|
|
199
|
+
actionFactory: ActionFactory
|
|
200
|
+
featureInstallerFactory: () => FeatureInstaller
|
|
201
|
+
shouldAutoHandleDependencies?: boolean
|
|
202
|
+
shouldThrowOnListenerError?: boolean
|
|
203
|
+
}
|
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
FeatureMap,
|
|
18
18
|
} from './features.types'
|
|
19
19
|
|
|
20
|
-
export
|
|
20
|
+
export class FeatureInstallerImpl implements ServiceProvider, FeatureInstaller {
|
|
21
21
|
public cwd: string
|
|
22
22
|
|
|
23
23
|
private featureMap: Partial<FeatureMap> = {}
|
|
@@ -97,12 +97,12 @@ export default class FeatureInstaller implements ServiceProvider {
|
|
|
97
97
|
}
|
|
98
98
|
|
|
99
99
|
public getFeatureDependencies<C extends FeatureCode>(
|
|
100
|
-
featureCode: C
|
|
101
|
-
trackedFeatures: FeatureDependency[] = []
|
|
100
|
+
featureCode: C
|
|
101
|
+
// trackedFeatures: FeatureDependency[] = []
|
|
102
102
|
): FeatureDependency[] {
|
|
103
103
|
let deps = this.getFeatureDependenciesIncludingSelf(
|
|
104
104
|
{ code: featureCode, isRequired: true },
|
|
105
|
-
trackedFeatures
|
|
105
|
+
[] // trackedFeatures
|
|
106
106
|
).filter((f) => f.code !== featureCode)
|
|
107
107
|
|
|
108
108
|
deps = this.sortFeatures(deps)
|
|
@@ -170,10 +170,10 @@ export default class FeatureInstaller implements ServiceProvider {
|
|
|
170
170
|
const shouldAllowEntertainment = !!features.find((f) => f.code === 'skill')
|
|
171
171
|
|
|
172
172
|
if (
|
|
173
|
-
|
|
173
|
+
FeatureInstallerImpl.startInFlightIntertainmentHandler &&
|
|
174
174
|
shouldAllowEntertainment
|
|
175
175
|
) {
|
|
176
|
-
|
|
176
|
+
FeatureInstallerImpl.startInFlightIntertainmentHandler(
|
|
177
177
|
(handler: InternalUpdateHandler) => {
|
|
178
178
|
didUpdateHandler = handler
|
|
179
179
|
}
|
|
@@ -193,6 +193,7 @@ export default class FeatureInstaller implements ServiceProvider {
|
|
|
193
193
|
didUpdateHandler?.(`Checking if ${code} is installed...`)
|
|
194
194
|
|
|
195
195
|
const isInstalled = await this.isInstalled(code)
|
|
196
|
+
|
|
196
197
|
if (!isInstalled && installFeatureDependencies) {
|
|
197
198
|
didUpdateHandler?.(`It is not, checking dependencies...`)
|
|
198
199
|
dependenciesToInstall = dependenciesToInstall.concat(
|
|
@@ -227,6 +228,7 @@ export default class FeatureInstaller implements ServiceProvider {
|
|
|
227
228
|
installFeature,
|
|
228
229
|
didUpdateHandler
|
|
229
230
|
)
|
|
231
|
+
|
|
230
232
|
results = merge(results, installResults)
|
|
231
233
|
}
|
|
232
234
|
}
|
|
@@ -235,10 +237,10 @@ export default class FeatureInstaller implements ServiceProvider {
|
|
|
235
237
|
results = merge(results, pendingResults)
|
|
236
238
|
|
|
237
239
|
if (
|
|
238
|
-
|
|
240
|
+
FeatureInstallerImpl.stopInFlightIntertainmentHandler &&
|
|
239
241
|
shouldAllowEntertainment
|
|
240
242
|
) {
|
|
241
|
-
|
|
243
|
+
FeatureInstallerImpl.stopInFlightIntertainmentHandler()
|
|
242
244
|
}
|
|
243
245
|
|
|
244
246
|
return results
|
|
@@ -308,8 +310,8 @@ export default class FeatureInstaller implements ServiceProvider {
|
|
|
308
310
|
features: AbstractFeature[],
|
|
309
311
|
didUpdateHandler?: InternalUpdateHandler
|
|
310
312
|
) {
|
|
311
|
-
if (
|
|
312
|
-
|
|
313
|
+
if (FeatureInstallerImpl.startInFlightIntertainmentHandler) {
|
|
314
|
+
FeatureInstallerImpl.startInFlightIntertainmentHandler(
|
|
313
315
|
(handler: InternalUpdateHandler) => {
|
|
314
316
|
didUpdateHandler = handler
|
|
315
317
|
}
|
|
@@ -325,8 +327,8 @@ export default class FeatureInstaller implements ServiceProvider {
|
|
|
325
327
|
|
|
326
328
|
await this.installAllPending(didUpdateHandler)
|
|
327
329
|
|
|
328
|
-
if (
|
|
329
|
-
|
|
330
|
+
if (FeatureInstallerImpl.stopInFlightIntertainmentHandler) {
|
|
331
|
+
FeatureInstallerImpl.stopInFlightIntertainmentHandler()
|
|
330
332
|
}
|
|
331
333
|
}
|
|
332
334
|
|
|
@@ -341,6 +343,7 @@ export default class FeatureInstaller implements ServiceProvider {
|
|
|
341
343
|
this.packagesToInstall.length === 1 ? '' : 's'
|
|
342
344
|
}. Please be patient.`
|
|
343
345
|
)
|
|
346
|
+
|
|
344
347
|
await pkgService.install(this.packagesToInstall, {})
|
|
345
348
|
}
|
|
346
349
|
|
|
@@ -350,6 +353,7 @@ export default class FeatureInstaller implements ServiceProvider {
|
|
|
350
353
|
this.devPackagesToInstall.length === 1 ? '' : 's'
|
|
351
354
|
}. Please be patient.`
|
|
352
355
|
)
|
|
356
|
+
|
|
353
357
|
await pkgService.install(this.devPackagesToInstall, {
|
|
354
358
|
isDev: true,
|
|
355
359
|
})
|
|
@@ -491,3 +495,19 @@ export default class FeatureInstaller implements ServiceProvider {
|
|
|
491
495
|
return installed.filter((f) => !!f) as FeatureMap[keyof FeatureMap][]
|
|
492
496
|
}
|
|
493
497
|
}
|
|
498
|
+
|
|
499
|
+
export default interface FeatureInstaller {
|
|
500
|
+
isInstalled(code: FeatureCode): Promise<boolean>
|
|
501
|
+
markAsSkippedThisRun(code: FeatureCode): void
|
|
502
|
+
markAsPermanentlySkipped(code: FeatureCode): void
|
|
503
|
+
isMarkedAsSkipped(code: FeatureCode): boolean
|
|
504
|
+
getFeature<C extends FeatureCode>(code: C): FeatureMap[C]
|
|
505
|
+
areInstalled(codes: FeatureCode[]): Promise<boolean>
|
|
506
|
+
install(options: InstallFeatureOptions): Promise<FeatureInstallResponse>
|
|
507
|
+
getInstalledFeatures(): Promise<FeatureMap[keyof FeatureMap][]>
|
|
508
|
+
getFeatureDependencies<C extends FeatureCode>(
|
|
509
|
+
featureCode: C
|
|
510
|
+
): FeatureDependency[]
|
|
511
|
+
getAllCodes(): FeatureCode[]
|
|
512
|
+
mapFeature<C extends FeatureCode>(code: C, feature: FeatureMap[C]): void
|
|
513
|
+
}
|
|
@@ -13,7 +13,7 @@ import DeployFeature from './deploy/DeployFeature'
|
|
|
13
13
|
import ErrorFeature from './error/ErrorFeature'
|
|
14
14
|
import EventFeature from './event/EventFeature'
|
|
15
15
|
import EventContractFeature from './eventContract/EventContractFeature'
|
|
16
|
-
import FeatureInstaller from './FeatureInstaller'
|
|
16
|
+
import FeatureInstaller, { FeatureInstallerImpl } from './FeatureInstaller'
|
|
17
17
|
import { FeatureCode } from './features.types'
|
|
18
18
|
import LogFeature from './log/LogFeature'
|
|
19
19
|
import NodeFeature from './node/NodeFeature'
|
|
@@ -30,6 +30,7 @@ import TestFeature from './test/TestFeature'
|
|
|
30
30
|
import ViewFeature from './view/ViewFeature'
|
|
31
31
|
import VsCodeFeature from './vscode/VsCodeFeature'
|
|
32
32
|
import WatchFeature from './watch/WatchFeature'
|
|
33
|
+
|
|
33
34
|
export default class FeatureInstallerFactory {
|
|
34
35
|
private static readonly features: any[] = [
|
|
35
36
|
ErrorFeature,
|
|
@@ -81,21 +82,14 @@ export default class FeatureInstallerFactory {
|
|
|
81
82
|
'permission',
|
|
82
83
|
]
|
|
83
84
|
|
|
84
|
-
public static WithAllFeatures(
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
storeFactory: StoreFactory
|
|
88
|
-
featureInstaller?: FeatureInstaller
|
|
89
|
-
ui: GraphicsInterface
|
|
90
|
-
emitter: GlobalEmitter
|
|
91
|
-
apiClientFactory: ApiClientFactory
|
|
92
|
-
actionExecuter: ActionExecuter
|
|
93
|
-
}): FeatureInstaller {
|
|
85
|
+
public static WithAllFeatures(
|
|
86
|
+
options: InstallerWithAllFeaturesOptions
|
|
87
|
+
): FeatureInstaller {
|
|
94
88
|
const { cwd, serviceFactory, storeFactory, ui, emitter, actionExecuter } =
|
|
95
89
|
options
|
|
96
90
|
|
|
97
91
|
const featureInstaller =
|
|
98
|
-
options.featureInstaller ?? new
|
|
92
|
+
options.featureInstaller ?? new FeatureInstallerImpl(cwd, serviceFactory)
|
|
99
93
|
|
|
100
94
|
const featureOptions: FeatureOptions = {
|
|
101
95
|
cwd,
|
|
@@ -111,10 +105,20 @@ export default class FeatureInstallerFactory {
|
|
|
111
105
|
|
|
112
106
|
this.features.forEach((Feature) => {
|
|
113
107
|
const feature = new Feature(featureOptions)
|
|
114
|
-
|
|
115
108
|
featureInstaller.mapFeature(feature.code, feature)
|
|
116
109
|
})
|
|
117
110
|
|
|
118
111
|
return featureInstaller
|
|
119
112
|
}
|
|
120
113
|
}
|
|
114
|
+
|
|
115
|
+
interface InstallerWithAllFeaturesOptions {
|
|
116
|
+
cwd: string
|
|
117
|
+
serviceFactory: ServiceFactory
|
|
118
|
+
storeFactory: StoreFactory
|
|
119
|
+
featureInstaller?: FeatureInstaller
|
|
120
|
+
ui: GraphicsInterface
|
|
121
|
+
emitter: GlobalEmitter
|
|
122
|
+
apiClientFactory: ApiClientFactory
|
|
123
|
+
actionExecuter: ActionExecuter
|
|
124
|
+
}
|
|
@@ -109,11 +109,8 @@ export default class OverrideActionDecorator implements FeatureAction {
|
|
|
109
109
|
public execute = async (optionsArg: any) => {
|
|
110
110
|
this.assertCommandIsNotBlocked()
|
|
111
111
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
options = this.mixinOptionOverrides(options)
|
|
115
|
-
|
|
116
|
-
let response = await this.childAction.execute(options)
|
|
112
|
+
const options = this.mixinOptionOverrides(optionsArg)
|
|
113
|
+
const response = await this.childAction.execute(options)
|
|
117
114
|
|
|
118
115
|
return response
|
|
119
116
|
}
|
|
@@ -157,6 +157,7 @@ export default class ListenAction extends AbstractAction<OptionsSchema> {
|
|
|
157
157
|
|
|
158
158
|
private async fetchEventContracts(namespace?: string) {
|
|
159
159
|
const eventStore = this.Store('event')
|
|
160
|
+
|
|
160
161
|
const skill = await this.Store('skill').loadCurrentSkill()
|
|
161
162
|
|
|
162
163
|
const namespacesForFetch =
|
|
@@ -8,7 +8,8 @@ const optionsSchema = buildSchema({
|
|
|
8
8
|
description: 'Point your skill to different Mercury environments.',
|
|
9
9
|
fields: {
|
|
10
10
|
remote: {
|
|
11
|
-
label: '
|
|
11
|
+
label: 'Set remote',
|
|
12
|
+
hint: 'Start with developer and read more here: https://developer.spruce.bot/#/skills/index',
|
|
12
13
|
type: 'select',
|
|
13
14
|
isRequired: true,
|
|
14
15
|
options: {
|
|
@@ -18,7 +18,6 @@ export default class SyncListenerAction extends AbstractAction<OptionsSchema> {
|
|
|
18
18
|
public async execute() {
|
|
19
19
|
const listeners = await this.Store('listener').loadListeners()
|
|
20
20
|
const builder = new ListenerTemplateItemBuilder()
|
|
21
|
-
|
|
22
21
|
const templateItems = builder.buildTemplateItems({
|
|
23
22
|
listeners,
|
|
24
23
|
cwd: this.cwd,
|
|
@@ -128,7 +128,9 @@ export default class NodeFeature<
|
|
|
128
128
|
pkg.unset('main')
|
|
129
129
|
pkg.unset('license')
|
|
130
130
|
|
|
131
|
-
await this.Store('skill', {
|
|
131
|
+
await this.Store('skill', {
|
|
132
|
+
cwd,
|
|
133
|
+
}).setCurrentSkillsNamespace(options.name)
|
|
132
134
|
|
|
133
135
|
return {}
|
|
134
136
|
}
|
|
@@ -134,9 +134,9 @@ export default class SkillFeature<
|
|
|
134
134
|
|
|
135
135
|
public async afterPackageInstall(options: SkillFeatureOptions) {
|
|
136
136
|
const destination = this.resolveDestination(options)
|
|
137
|
-
await this.Store('skill', {
|
|
138
|
-
|
|
139
|
-
)
|
|
137
|
+
await this.Store('skill', {
|
|
138
|
+
cwd: destination,
|
|
139
|
+
}).setCurrentSkillsNamespace(options.name)
|
|
140
140
|
return {}
|
|
141
141
|
}
|
|
142
142
|
|
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
import { eventResponseUtil } from '@sprucelabs/spruce-event-utils'
|
|
2
2
|
import { namesUtil } from '@sprucelabs/spruce-skill-utils'
|
|
3
3
|
import SpruceError from '../../../errors/SpruceError'
|
|
4
|
-
import AbstractStore from '../../../stores/AbstractStore'
|
|
4
|
+
import AbstractStore, { StoreOptions } from '../../../stores/AbstractStore'
|
|
5
5
|
import { CurrentSkill, RegisteredSkill } from '../../../types/cli.types'
|
|
6
6
|
|
|
7
7
|
export default class SkillStore extends AbstractStore {
|
|
8
8
|
public readonly name = 'skill'
|
|
9
9
|
private static currentSkill?: CurrentSkill
|
|
10
10
|
|
|
11
|
+
public constructor(options: StoreOptions<SkillStoreOptions>) {
|
|
12
|
+
super(options)
|
|
13
|
+
}
|
|
14
|
+
|
|
11
15
|
public static clearCurrentSkill() {
|
|
12
16
|
this.currentSkill = undefined
|
|
13
17
|
}
|
|
@@ -19,7 +23,7 @@ export default class SkillStore extends AbstractStore {
|
|
|
19
23
|
const isRegisteringCurrentSkill =
|
|
20
24
|
options?.isRegisteringCurrentSkill !== false
|
|
21
25
|
|
|
22
|
-
isRegisteringCurrentSkill && this.assertInSkill()
|
|
26
|
+
isRegisteringCurrentSkill && (await this.assertInSkill())
|
|
23
27
|
|
|
24
28
|
const { name, slug, description, isPublished } = values
|
|
25
29
|
const client = await this.connectToApi()
|
|
@@ -43,7 +47,7 @@ export default class SkillStore extends AbstractStore {
|
|
|
43
47
|
return skill
|
|
44
48
|
}
|
|
45
49
|
|
|
46
|
-
private assertInSkill() {
|
|
50
|
+
private async assertInSkill() {
|
|
47
51
|
const isInstalled = this.Service('settings').isMarkedAsInstalled('skill')
|
|
48
52
|
|
|
49
53
|
if (!isInstalled) {
|
|
@@ -56,7 +60,7 @@ export default class SkillStore extends AbstractStore {
|
|
|
56
60
|
return SkillStore.currentSkill
|
|
57
61
|
}
|
|
58
62
|
|
|
59
|
-
this.assertInSkill()
|
|
63
|
+
await this.assertInSkill()
|
|
60
64
|
|
|
61
65
|
const currentSkill = this.Service('auth').getCurrentSkill()
|
|
62
66
|
|
|
@@ -169,13 +173,14 @@ export default class SkillStore extends AbstractStore {
|
|
|
169
173
|
}) {
|
|
170
174
|
const client = await this.connectToApi()
|
|
171
175
|
|
|
172
|
-
const
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
176
|
+
const [{ skills }] = await client.emitAndFlattenResponses(
|
|
177
|
+
'list-skills::v2020_12_25',
|
|
178
|
+
{
|
|
179
|
+
payload: {
|
|
180
|
+
...query,
|
|
181
|
+
},
|
|
182
|
+
}
|
|
183
|
+
)
|
|
179
184
|
|
|
180
185
|
return skills
|
|
181
186
|
}
|
|
@@ -191,3 +196,5 @@ export interface CreateSkill {
|
|
|
191
196
|
export interface RegisterSkillOptions {
|
|
192
197
|
isRegisteringCurrentSkill?: boolean
|
|
193
198
|
}
|
|
199
|
+
|
|
200
|
+
export interface SkillStoreOptions {}
|
|
@@ -89,7 +89,7 @@ export default class WatchFeature extends AbstractFeature {
|
|
|
89
89
|
const changes = this.changesSinceLastChange
|
|
90
90
|
this.changesSinceLastChange = []
|
|
91
91
|
|
|
92
|
-
await this.emitter.
|
|
92
|
+
await this.emitter.emitAndFlattenResponses('watcher.did-detect-change', {
|
|
93
93
|
changes,
|
|
94
94
|
})
|
|
95
95
|
}
|
|
@@ -28,6 +28,7 @@ export default class SpyInterface implements GraphicsInterface {
|
|
|
28
28
|
private term?: TerminalInterface
|
|
29
29
|
private startTime: number
|
|
30
30
|
private promptTimeout?: any
|
|
31
|
+
private error?: Error
|
|
31
32
|
|
|
32
33
|
public constructor() {
|
|
33
34
|
this.startTime = new Date().getTime()
|
|
@@ -80,6 +81,10 @@ export default class SpyInterface implements GraphicsInterface {
|
|
|
80
81
|
clearTimeout(this.promptTimeout)
|
|
81
82
|
}
|
|
82
83
|
|
|
84
|
+
public setError(err: Error) {
|
|
85
|
+
this.error = err
|
|
86
|
+
}
|
|
87
|
+
|
|
83
88
|
public getLastInvocation() {
|
|
84
89
|
return this.invocations[this.invocations.length - 1]
|
|
85
90
|
}
|
|
@@ -298,6 +303,11 @@ export default class SpyInterface implements GraphicsInterface {
|
|
|
298
303
|
testUtil.log('waitForInput timeout reset because of new output.')
|
|
299
304
|
}
|
|
300
305
|
}
|
|
306
|
+
|
|
307
|
+
if (this.error) {
|
|
308
|
+
throw this.error
|
|
309
|
+
}
|
|
310
|
+
|
|
301
311
|
await new Promise((resolve) => setTimeout(resolve, checkInterval))
|
|
302
312
|
}
|
|
303
313
|
}
|