@sprucelabs/spruce-cli 14.29.30 → 14.29.31
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 +8 -0
- package/build/__tests__/behavioral/ListeningToCoreEvents.test.d.ts +6 -0
- package/build/__tests__/behavioral/ListeningToCoreEvents.test.js +128 -0
- package/build/__tests__/behavioral/ListeningToCoreEvents.test.js.map +1 -0
- package/build/__tests__/behavioral/schemas/CreatingANewSchemaBuilder.test.js +1 -1
- package/build/__tests__/behavioral/schemas/CreatingANewSchemaBuilder.test.js.map +1 -1
- package/build/features/event/actions/ListenAction.d.ts +4 -0
- package/build/features/event/actions/ListenAction.js +228 -127
- package/build/features/event/actions/ListenAction.js.map +1 -1
- package/build/features/event/writers/EventWriter.d.ts +1 -3
- package/build/features/event/writers/EventWriter.js +20 -14
- package/build/features/event/writers/EventWriter.js.map +1 -1
- package/build/interfaces/SpyInterface.js +1 -1
- package/build/interfaces/SpyInterface.js.map +1 -1
- package/build/templateItemBuilders/EventTemplateItemBuilder.js +2 -1
- package/build/templateItemBuilders/EventTemplateItemBuilder.js.map +1 -1
- package/package.json +17 -17
- package/src/__tests__/behavioral/ListeningToCoreEvents.test.ts +26 -0
- package/src/__tests__/behavioral/schemas/CreatingANewSchemaBuilder.test.ts +1 -1
- package/src/features/event/actions/ListenAction.ts +111 -58
- package/src/features/event/writers/EventWriter.ts +21 -35
- package/src/interfaces/SpyInterface.ts +3 -1
- package/src/templateItemBuilders/EventTemplateItemBuilder.ts +3 -0
|
@@ -23,6 +23,8 @@ import AbstractAction from '../../AbstractAction'
|
|
|
23
23
|
import { FeatureActionResponse } from '../../features.types'
|
|
24
24
|
|
|
25
25
|
const SKILL_EVENT_NAMESPACE = 'skill'
|
|
26
|
+
const CORE_EVENT_NAMESPACE = 'mercury'
|
|
27
|
+
|
|
26
28
|
type OptionsSchema =
|
|
27
29
|
SpruceSchemas.SpruceCli.v2020_07_22.ListenEventOptionsSchema
|
|
28
30
|
export default class ListenAction extends AbstractAction<OptionsSchema> {
|
|
@@ -44,28 +46,11 @@ export default class ListenAction extends AbstractAction<OptionsSchema> {
|
|
|
44
46
|
eventName,
|
|
45
47
|
namespace,
|
|
46
48
|
schemaTypesLookupDir,
|
|
47
|
-
contractDestinationDir,
|
|
48
49
|
} = normalizedOptions
|
|
49
50
|
|
|
50
51
|
this.ui.startLoading('Loading event contracts...')
|
|
51
52
|
|
|
52
|
-
const
|
|
53
|
-
|
|
54
|
-
const skill = await this.Store('skill').loadCurrentSkill()
|
|
55
|
-
|
|
56
|
-
const namespacesForFetch =
|
|
57
|
-
namespace && namespace !== 'skill' ? [namespace] : undefined
|
|
58
|
-
|
|
59
|
-
const { contracts } = skill.slug
|
|
60
|
-
? await eventStore.fetchEventContracts({
|
|
61
|
-
localNamespace: skill.slug,
|
|
62
|
-
namespaces: namespacesForFetch,
|
|
63
|
-
didUpdateHandler: (msg: string) => this.ui.startLoading(msg),
|
|
64
|
-
})
|
|
65
|
-
: await eventStore.fetchEventContracts({
|
|
66
|
-
namespaces: namespacesForFetch,
|
|
67
|
-
didUpdateHandler: (msg: string) => this.ui.startLoading(msg),
|
|
68
|
-
})
|
|
53
|
+
const contracts = await this.fetchEventContracts(namespace)
|
|
69
54
|
|
|
70
55
|
this.ui.stopLoading()
|
|
71
56
|
|
|
@@ -90,6 +75,11 @@ export default class ListenAction extends AbstractAction<OptionsSchema> {
|
|
|
90
75
|
eventName = await this.collectEvent(contracts, namespace)
|
|
91
76
|
}
|
|
92
77
|
|
|
78
|
+
const isCoreEvent = namespace === CORE_EVENT_NAMESPACE
|
|
79
|
+
if (isCoreEvent) {
|
|
80
|
+
namespace = undefined
|
|
81
|
+
}
|
|
82
|
+
|
|
93
83
|
const fqen = eventNameUtil.join({
|
|
94
84
|
eventName,
|
|
95
85
|
eventNamespace: namespace,
|
|
@@ -98,22 +88,13 @@ export default class ListenAction extends AbstractAction<OptionsSchema> {
|
|
|
98
88
|
|
|
99
89
|
let { version } = eventNameUtil.split(fqen)
|
|
100
90
|
|
|
101
|
-
|
|
102
|
-
|
|
91
|
+
this.assertIsValidChoice(
|
|
92
|
+
eventChoicesByNamespace,
|
|
93
|
+
namespace ?? 'mercury',
|
|
94
|
+
eventName,
|
|
95
|
+
fqen
|
|
103
96
|
)
|
|
104
97
|
|
|
105
|
-
if (!isValidEvent) {
|
|
106
|
-
throw new SchemaError({
|
|
107
|
-
code: 'INVALID_PARAMETERS',
|
|
108
|
-
friendlyMessage: `${eventName} is not a valid event . Try: \n\n${eventChoicesByNamespace[
|
|
109
|
-
namespace
|
|
110
|
-
]
|
|
111
|
-
.map((i) => i.value)
|
|
112
|
-
.join('\n')}`,
|
|
113
|
-
parameters: ['eventName'],
|
|
114
|
-
})
|
|
115
|
-
}
|
|
116
|
-
|
|
117
98
|
const resolvedDestination = diskUtil.resolvePath(
|
|
118
99
|
this.cwd,
|
|
119
100
|
listenerDestinationDir
|
|
@@ -124,11 +105,6 @@ export default class ListenAction extends AbstractAction<OptionsSchema> {
|
|
|
124
105
|
resolvedDestination
|
|
125
106
|
)
|
|
126
107
|
|
|
127
|
-
const resolvedSchemaTypesLookupDir = diskUtil.resolvePath(
|
|
128
|
-
this.cwd,
|
|
129
|
-
schemaTypesLookupDir
|
|
130
|
-
)
|
|
131
|
-
|
|
132
108
|
const isSkillEvent = namespace !== SKILL_EVENT_NAMESPACE
|
|
133
109
|
|
|
134
110
|
let emitPayloadSchemaTemplateItem: SchemaTemplateItem | undefined
|
|
@@ -139,7 +115,7 @@ export default class ListenAction extends AbstractAction<OptionsSchema> {
|
|
|
139
115
|
const templateItems = builder.buildEventTemplateItemForName(
|
|
140
116
|
contracts,
|
|
141
117
|
eventNameUtil.join({
|
|
142
|
-
eventNamespace: namespace,
|
|
118
|
+
eventNamespace: !isCoreEvent ? namespace : undefined,
|
|
143
119
|
eventName,
|
|
144
120
|
version: resolvedVersion,
|
|
145
121
|
})
|
|
@@ -151,21 +127,14 @@ export default class ListenAction extends AbstractAction<OptionsSchema> {
|
|
|
151
127
|
templateItems.responsePayloadSchemaTemplateItem
|
|
152
128
|
}
|
|
153
129
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
130
|
+
response.files = await this.writeListener({
|
|
131
|
+
schemaTypesLookupDir,
|
|
132
|
+
resolvedDestination,
|
|
157
133
|
version: resolvedVersion,
|
|
158
134
|
eventName,
|
|
159
|
-
|
|
160
|
-
fullyQualifiedEventName: eventNameUtil.join({
|
|
161
|
-
eventName,
|
|
162
|
-
eventNamespace: namespace,
|
|
163
|
-
version: resolvedVersion,
|
|
164
|
-
}),
|
|
135
|
+
namespace,
|
|
165
136
|
emitPayloadSchemaTemplateItem,
|
|
166
|
-
contractDestinationDir,
|
|
167
137
|
responsePayloadSchemaTemplateItem,
|
|
168
|
-
schemaTypesLookupDir: resolvedSchemaTypesLookupDir,
|
|
169
138
|
})
|
|
170
139
|
|
|
171
140
|
const syncResults = await this.syncListeners()
|
|
@@ -173,15 +142,7 @@ export default class ListenAction extends AbstractAction<OptionsSchema> {
|
|
|
173
142
|
response = actionUtil.mergeActionResults(syncResults, response)
|
|
174
143
|
|
|
175
144
|
if (isSkillEvent) {
|
|
176
|
-
const
|
|
177
|
-
syncEventActionSchema,
|
|
178
|
-
options
|
|
179
|
-
)
|
|
180
|
-
|
|
181
|
-
const syncResults = await this.Action('event', 'sync').execute(
|
|
182
|
-
syncOptions
|
|
183
|
-
)
|
|
184
|
-
|
|
145
|
+
const syncResults = await this.syncEvents(options)
|
|
185
146
|
response = actionUtil.mergeActionResults(syncResults, response)
|
|
186
147
|
}
|
|
187
148
|
|
|
@@ -193,6 +154,98 @@ export default class ListenAction extends AbstractAction<OptionsSchema> {
|
|
|
193
154
|
}
|
|
194
155
|
}
|
|
195
156
|
|
|
157
|
+
private async fetchEventContracts(namespace?: string) {
|
|
158
|
+
const eventStore = this.Store('event')
|
|
159
|
+
const skill = await this.Store('skill').loadCurrentSkill()
|
|
160
|
+
|
|
161
|
+
const namespacesForFetch =
|
|
162
|
+
namespace &&
|
|
163
|
+
namespace !== SKILL_EVENT_NAMESPACE &&
|
|
164
|
+
namespace !== CORE_EVENT_NAMESPACE
|
|
165
|
+
? [namespace]
|
|
166
|
+
: undefined
|
|
167
|
+
|
|
168
|
+
const { contracts } = skill.slug
|
|
169
|
+
? await eventStore.fetchEventContracts({
|
|
170
|
+
localNamespace: skill.slug,
|
|
171
|
+
namespaces: namespacesForFetch,
|
|
172
|
+
didUpdateHandler: (msg: string) => this.ui.startLoading(msg),
|
|
173
|
+
})
|
|
174
|
+
: await eventStore.fetchEventContracts({
|
|
175
|
+
namespaces: namespacesForFetch,
|
|
176
|
+
didUpdateHandler: (msg: string) => this.ui.startLoading(msg),
|
|
177
|
+
})
|
|
178
|
+
|
|
179
|
+
return contracts
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
private async syncEvents(
|
|
183
|
+
options: SpruceSchemas.SpruceCli.v2020_07_22.ListenEventOptions
|
|
184
|
+
) {
|
|
185
|
+
const syncOptions = normalizeSchemaValues(syncEventActionSchema, options)
|
|
186
|
+
|
|
187
|
+
const syncResults = await this.Action('event', 'sync').execute(syncOptions)
|
|
188
|
+
return syncResults
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
private async writeListener(options: {
|
|
192
|
+
resolvedDestination: string
|
|
193
|
+
schemaTypesLookupDir: string
|
|
194
|
+
namespace?: string | undefined
|
|
195
|
+
eventName: string
|
|
196
|
+
emitPayloadSchemaTemplateItem: SchemaTemplateItem | undefined
|
|
197
|
+
version: string
|
|
198
|
+
responsePayloadSchemaTemplateItem: SchemaTemplateItem | undefined
|
|
199
|
+
}) {
|
|
200
|
+
const {
|
|
201
|
+
resolvedDestination,
|
|
202
|
+
schemaTypesLookupDir,
|
|
203
|
+
namespace,
|
|
204
|
+
eventName,
|
|
205
|
+
version,
|
|
206
|
+
} = options
|
|
207
|
+
|
|
208
|
+
const resolvedSchemaTypesLookupDir = diskUtil.resolvePath(
|
|
209
|
+
this.cwd,
|
|
210
|
+
schemaTypesLookupDir
|
|
211
|
+
)
|
|
212
|
+
const writer = this.Writer('event')
|
|
213
|
+
const files = await writer.writeListener(resolvedDestination, {
|
|
214
|
+
...options,
|
|
215
|
+
fullyQualifiedEventName: eventNameUtil.join({
|
|
216
|
+
eventName,
|
|
217
|
+
eventNamespace: namespace,
|
|
218
|
+
version,
|
|
219
|
+
}),
|
|
220
|
+
schemaTypesLookupDir: resolvedSchemaTypesLookupDir,
|
|
221
|
+
})
|
|
222
|
+
|
|
223
|
+
return files
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
private assertIsValidChoice(
|
|
227
|
+
eventChoicesByNamespace: Record<string, SelectChoice[]>,
|
|
228
|
+
namespace: string,
|
|
229
|
+
eventName: string | undefined,
|
|
230
|
+
fqen: string
|
|
231
|
+
) {
|
|
232
|
+
const isValidEvent = !!eventChoicesByNamespace[namespace].find(
|
|
233
|
+
(e) => e.value === eventName || e.value === fqen
|
|
234
|
+
)
|
|
235
|
+
|
|
236
|
+
if (!isValidEvent) {
|
|
237
|
+
throw new SchemaError({
|
|
238
|
+
code: 'INVALID_PARAMETERS',
|
|
239
|
+
friendlyMessage: `${eventName} is not a valid event . Try: \n\n${eventChoicesByNamespace[
|
|
240
|
+
namespace
|
|
241
|
+
]
|
|
242
|
+
.map((i) => i.value)
|
|
243
|
+
.join('\n')}`,
|
|
244
|
+
parameters: ['eventName'],
|
|
245
|
+
})
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
|
|
196
249
|
private async syncListeners() {
|
|
197
250
|
return this.Action('event', 'sync.listeners').execute({})
|
|
198
251
|
}
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import pathUtil from 'path'
|
|
2
2
|
import { SchemaTemplateItem } from '@sprucelabs/schema'
|
|
3
|
-
import { eventDiskUtil } from '@sprucelabs/spruce-event-utils'
|
|
3
|
+
import { eventDiskUtil, eventNameUtil } from '@sprucelabs/spruce-event-utils'
|
|
4
4
|
import {
|
|
5
5
|
diskUtil,
|
|
6
|
-
namesUtil,
|
|
7
6
|
DEFAULT_SCHEMA_TYPES_FILENAME,
|
|
8
7
|
} from '@sprucelabs/spruce-skill-utils'
|
|
9
8
|
import {
|
|
@@ -129,53 +128,33 @@ export default class EventWriter extends AbstractWriter {
|
|
|
129
128
|
|
|
130
129
|
public async writeListener(
|
|
131
130
|
destinationDir: string,
|
|
132
|
-
options: Omit<
|
|
133
|
-
EventListenerOptions,
|
|
134
|
-
'nameConst' | 'schemaTypesFile' | 'contractsFile'
|
|
135
|
-
> & {
|
|
136
|
-
version: string
|
|
131
|
+
options: Omit<EventListenerOptions, 'schemaTypesFile'> & {
|
|
137
132
|
schemaTypesLookupDir: string
|
|
138
|
-
contractDestinationDir: string
|
|
139
133
|
}
|
|
140
134
|
) {
|
|
141
|
-
const {
|
|
142
|
-
eventName,
|
|
143
|
-
eventNamespace,
|
|
144
|
-
version,
|
|
145
|
-
schemaTypesLookupDir,
|
|
146
|
-
contractDestinationDir,
|
|
147
|
-
} = options
|
|
135
|
+
const { schemaTypesLookupDir, fullyQualifiedEventName } = options
|
|
148
136
|
|
|
137
|
+
const event = eventNameUtil.split(fullyQualifiedEventName)
|
|
149
138
|
const resolvedDestination = eventDiskUtil.resolveListenerPath(
|
|
150
139
|
destinationDir,
|
|
151
|
-
|
|
152
|
-
eventName,
|
|
153
|
-
eventNamespace,
|
|
154
|
-
version,
|
|
155
|
-
}
|
|
140
|
+
event as any
|
|
156
141
|
)
|
|
157
142
|
|
|
158
|
-
const relativeTypesFile = this.resolveSchemaTypesFile(
|
|
143
|
+
const relativeTypesFile = this.resolveSchemaTypesFile({
|
|
144
|
+
namespace: event.eventNamespace,
|
|
159
145
|
schemaTypesLookupDir,
|
|
160
|
-
resolvedDestination
|
|
161
|
-
)
|
|
162
|
-
|
|
163
|
-
const contractsFile = pathUtil.join(
|
|
164
|
-
contractDestinationDir,
|
|
165
|
-
CONTRACT_FILE_NAME.replace('.ts', '')
|
|
166
|
-
)
|
|
146
|
+
resolvedDestination,
|
|
147
|
+
})
|
|
167
148
|
|
|
168
149
|
const listenerContents = this.templates.listener({
|
|
169
150
|
...options,
|
|
170
|
-
nameConst: namesUtil.toConst(`${eventNamespace}_${eventName}`),
|
|
171
151
|
schemaTypesFile: relativeTypesFile,
|
|
172
|
-
contractsFile,
|
|
173
152
|
})
|
|
174
153
|
|
|
175
154
|
const results = await this.writeFileIfChangedMixinResults(
|
|
176
155
|
resolvedDestination,
|
|
177
156
|
listenerContents,
|
|
178
|
-
`Listener for ${
|
|
157
|
+
`Listener for ${fullyQualifiedEventName}.`
|
|
179
158
|
)
|
|
180
159
|
|
|
181
160
|
await this.lint(resolvedDestination)
|
|
@@ -195,7 +174,7 @@ export default class EventWriter extends AbstractWriter {
|
|
|
195
174
|
const results = await this.writeFileIfChangedMixinResults(
|
|
196
175
|
destination,
|
|
197
176
|
contents,
|
|
198
|
-
'
|
|
177
|
+
'All your listeners imported to one place for your skill to use when booting!'
|
|
199
178
|
)
|
|
200
179
|
|
|
201
180
|
return results
|
|
@@ -306,10 +285,17 @@ export default class EventWriter extends AbstractWriter {
|
|
|
306
285
|
return files
|
|
307
286
|
}
|
|
308
287
|
|
|
309
|
-
private resolveSchemaTypesFile(
|
|
310
|
-
|
|
288
|
+
private resolveSchemaTypesFile(options: {
|
|
289
|
+
namespace?: string
|
|
290
|
+
schemaTypesLookupDir: string
|
|
311
291
|
resolvedDestination: string
|
|
312
|
-
) {
|
|
292
|
+
}) {
|
|
293
|
+
const { schemaTypesLookupDir, resolvedDestination, namespace } = options
|
|
294
|
+
|
|
295
|
+
if (!namespace) {
|
|
296
|
+
return '@sprucelabs/mercury-types'
|
|
297
|
+
}
|
|
298
|
+
|
|
313
299
|
const schemaTypesFile = pathUtil.join(
|
|
314
300
|
schemaTypesLookupDir,
|
|
315
301
|
DEFAULT_SCHEMA_TYPES_FILENAME
|
|
@@ -245,7 +245,9 @@ export default class SpyInterface implements GraphicsInterface {
|
|
|
245
245
|
this.reset()
|
|
246
246
|
|
|
247
247
|
try {
|
|
248
|
-
assert.fail(
|
|
248
|
+
assert.fail(
|
|
249
|
+
`Timed out waiting for input with label: '${definition.label}'\n\nConsider passing what you need to Action().execute({ something })`
|
|
250
|
+
)
|
|
249
251
|
} catch (err: any) {
|
|
250
252
|
reject(err)
|
|
251
253
|
}
|
|
@@ -88,6 +88,9 @@ export default class EventTemplateItemBuilder {
|
|
|
88
88
|
throw new SchemaError({
|
|
89
89
|
code: 'INVALID_PARAMETERS',
|
|
90
90
|
parameters: ['fullyQualifiedEventName'],
|
|
91
|
+
friendlyMessages: [
|
|
92
|
+
`I could not find any events that match ${fullyQualifiedEventName}.`,
|
|
93
|
+
],
|
|
91
94
|
})
|
|
92
95
|
}
|
|
93
96
|
|