@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.
@@ -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 eventStore = this.Store('event')
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
- const isValidEvent = !!eventChoicesByNamespace[namespace].find(
102
- (e) => e.value === eventName || e.value === fqen
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
- const writer = this.Writer('event')
155
- response.files = await writer.writeListener(resolvedDestination, {
156
- ...normalizedOptions,
130
+ response.files = await this.writeListener({
131
+ schemaTypesLookupDir,
132
+ resolvedDestination,
157
133
  version: resolvedVersion,
158
134
  eventName,
159
- eventNamespace: namespace,
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 syncOptions = normalizeSchemaValues(
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 ${eventNamespace}.${eventName}.`
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
- 'An object holding all your data stores for easy import!'
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
- schemaTypesLookupDir: string,
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(`Timed out waiting for input: ${definition.label}`)
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