@sprucelabs/spruce-cli 20.0.0 → 20.0.2
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 +16 -0
- package/build/__tests__/behavioral/EnablingAndDisablingCache.test.js +2 -1
- package/build/__tests__/behavioral/EnablingAndDisablingCache.test.js.map +1 -1
- package/build/__tests__/behavioral/upgrading/UpgradingASkill5.test.js +1 -1
- package/build/__tests__/behavioral/upgrading/UpgradingASkill5.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/plugins/CreatingAViewPlugin.test.d.ts +4 -0
- package/build/__tests__/behavioral/views/plugins/CreatingAViewPlugin.test.js +95 -17
- package/build/__tests__/behavioral/views/plugins/CreatingAViewPlugin.test.js.map +1 -1
- package/build/__tests__/implementation/EventCacheService.test.d.ts +4 -0
- package/build/__tests__/implementation/EventCacheService.test.js +84 -0
- package/build/__tests__/implementation/EventCacheService.test.js.map +1 -0
- package/build/errors/SpruceError.js +2 -2
- package/build/errors/SpruceError.js.map +1 -1
- package/build/features/cache/actions/EnableAction.js +3 -1
- package/build/features/cache/actions/EnableAction.js.map +1 -1
- package/build/features/event/EventFeature.js +2 -2
- package/build/features/event/EventFeature.js.map +1 -1
- package/build/features/event/actions/SyncAction.js +1 -1
- package/build/features/event/actions/SyncAction.js.map +1 -1
- package/build/features/event/services/{EventSettingsService.d.ts → EventCacheService.d.ts} +3 -3
- package/build/features/event/services/{EventSettingsService.js → EventCacheService.js} +8 -7
- package/build/features/event/services/EventCacheService.js.map +1 -0
- package/build/features/node/actions/UpgradeAction.d.ts +2 -2
- package/build/features/node/actions/UpgradeAction.js.map +1 -1
- package/build/features/universalFileDescriptions.js +1 -1
- package/build/features/universalFileDescriptions.js.map +1 -1
- package/build/features/view/actions/SyncAction.js +2 -0
- package/build/features/view/actions/SyncAction.js.map +1 -1
- package/build/services/ServiceFactory.d.ts +3 -2
- package/build/services/ServiceFactory.js +11 -7
- package/build/services/ServiceFactory.js.map +1 -1
- package/build/utilities/introspection.utility.d.ts +8 -4
- package/build/utilities/introspection.utility.js +189 -46
- package/build/utilities/introspection.utility.js.map +1 -1
- package/package.json +27 -27
- package/src/__tests__/behavioral/EnablingAndDisablingCache.test.ts +1 -0
- package/src/__tests__/behavioral/upgrading/UpgradingASkill5.test.ts +1 -1
- package/src/__tests__/behavioral/views/CreatingASkillView.test.ts +1 -1
- package/src/__tests__/behavioral/views/plugins/CreatingAViewPlugin.test.ts +53 -0
- package/src/__tests__/implementation/EventCacheService.test.ts +38 -0
- package/src/errors/SpruceError.ts +3 -1
- package/src/features/cache/actions/EnableAction.ts +6 -1
- package/src/features/event/EventFeature.ts +2 -2
- package/src/features/event/actions/SyncAction.ts +1 -1
- package/src/features/event/services/{EventSettingsService.ts → EventCacheService.ts} +5 -3
- package/src/features/node/actions/UpgradeAction.ts +4 -4
- package/src/features/universalFileDescriptions.ts +1 -1
- package/src/features/view/actions/SyncAction.ts +2 -0
- package/src/services/ServiceFactory.ts +11 -8
- package/src/utilities/introspection.utility.ts +233 -79
- package/build/features/event/services/EventSettingsService.js.map +0 -1
|
@@ -1,38 +1,9 @@
|
|
|
1
|
+
import { dirname } from 'path'
|
|
2
|
+
import { diskUtil } from '@sprucelabs/spruce-skill-utils'
|
|
1
3
|
import _ from 'lodash'
|
|
2
4
|
import * as tsutils from 'tsutils'
|
|
3
5
|
import * as ts from 'typescript'
|
|
4
6
|
|
|
5
|
-
export interface IntrospectionClass {
|
|
6
|
-
className: string
|
|
7
|
-
classPath: string
|
|
8
|
-
parentClassName: string | undefined
|
|
9
|
-
parentClassPath: string | undefined
|
|
10
|
-
optionsInterfaceName: string | undefined
|
|
11
|
-
isAbstract: boolean
|
|
12
|
-
staticProperties: StaticProperties
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
type StaticProperties = Record<string, any>
|
|
16
|
-
|
|
17
|
-
interface IntrospectionInterface {
|
|
18
|
-
interfaceName: string
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export interface Introspection {
|
|
22
|
-
classes: IntrospectionClass[]
|
|
23
|
-
interfaces: IntrospectionInterface[]
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
interface DocEntry {
|
|
27
|
-
name?: string
|
|
28
|
-
fileName?: string
|
|
29
|
-
documentation?: string
|
|
30
|
-
type?: string
|
|
31
|
-
constructors?: DocEntry[]
|
|
32
|
-
parameters?: DocEntry[]
|
|
33
|
-
returnType?: string
|
|
34
|
-
}
|
|
35
|
-
|
|
36
7
|
const serializeSymbol = (options: {
|
|
37
8
|
checker: ts.TypeChecker
|
|
38
9
|
symbol: ts.Symbol
|
|
@@ -84,59 +55,54 @@ const introspectionUtil = {
|
|
|
84
55
|
const sourceFile = program.getSourceFile(tsFile)
|
|
85
56
|
const results: Introspection = { classes: [], interfaces: [] }
|
|
86
57
|
if (sourceFile && _.includes(filePaths, sourceFile.fileName)) {
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
58
|
+
if (!this.hasClassDefinition(sourceFile)) {
|
|
59
|
+
const exports = this.getExports(sourceFile)
|
|
60
|
+
const firstExport = exports[0]
|
|
61
|
+
if (firstExport) {
|
|
62
|
+
const declaration = this.getClassDeclarationFromImportedFile(
|
|
63
|
+
firstExport,
|
|
64
|
+
dirname(tsFile),
|
|
65
|
+
program
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
if (declaration) {
|
|
69
|
+
const { classes, interfaces } = getDeclarationsFromNode(
|
|
70
|
+
declaration,
|
|
71
|
+
checker,
|
|
72
|
+
sourceFile
|
|
98
73
|
)
|
|
74
|
+
results.classes.push(...classes)
|
|
75
|
+
results.interfaces.push(...interfaces)
|
|
76
|
+
} else {
|
|
77
|
+
// must have imported from somewhere else (another node module)
|
|
78
|
+
const className = //@ts-ignore
|
|
79
|
+
firstExport.exportClause?.elements?.[0]?.propertyName?.text
|
|
99
80
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
81
|
+
if (className) {
|
|
82
|
+
results.classes.push({
|
|
83
|
+
className,
|
|
84
|
+
classPath: tsFile,
|
|
85
|
+
isAbstract: false,
|
|
86
|
+
optionsInterfaceName: undefined,
|
|
87
|
+
parentClassName: undefined,
|
|
88
|
+
parentClassPath: undefined,
|
|
89
|
+
staticProperties: {},
|
|
90
|
+
})
|
|
105
91
|
}
|
|
106
|
-
|
|
107
|
-
const parentClassName =
|
|
108
|
-
// @ts-ignore
|
|
109
|
-
parentClassSymbol?.valueDeclaration?.name?.text
|
|
110
|
-
// @ts-ignore
|
|
111
|
-
const parentClassPath = parentClassSymbol?.parent
|
|
112
|
-
?.getName()
|
|
113
|
-
.replace('"', '')
|
|
114
|
-
|
|
115
|
-
const isAbstractClass = tsutils.isModifierFlagSet(
|
|
116
|
-
node,
|
|
117
|
-
ts.ModifierFlags.Abstract
|
|
118
|
-
)
|
|
119
|
-
details.constructors = constructorType
|
|
120
|
-
.getConstructSignatures()
|
|
121
|
-
.map((s) => serializeSignature({ signature: s, checker }))
|
|
122
|
-
|
|
123
|
-
results.classes.push({
|
|
124
|
-
className: node.name.text,
|
|
125
|
-
classPath: sourceFile.fileName,
|
|
126
|
-
parentClassName,
|
|
127
|
-
parentClassPath,
|
|
128
|
-
staticProperties: pluckStaticProperties(node),
|
|
129
|
-
optionsInterfaceName:
|
|
130
|
-
details.constructors?.[0].parameters?.[0]?.type,
|
|
131
|
-
isAbstract: isAbstractClass,
|
|
132
|
-
})
|
|
133
92
|
}
|
|
134
|
-
} else if (ts.isInterfaceDeclaration(node)) {
|
|
135
|
-
results.interfaces.push({
|
|
136
|
-
interfaceName: node.name.text,
|
|
137
|
-
})
|
|
138
93
|
}
|
|
139
|
-
}
|
|
94
|
+
} else {
|
|
95
|
+
ts.forEachChild(sourceFile, (node) => {
|
|
96
|
+
const { classes, interfaces } = getDeclarationsFromNode(
|
|
97
|
+
node,
|
|
98
|
+
checker,
|
|
99
|
+
sourceFile
|
|
100
|
+
)
|
|
101
|
+
|
|
102
|
+
results.classes.push(...classes)
|
|
103
|
+
results.interfaces.push(...interfaces)
|
|
104
|
+
})
|
|
105
|
+
}
|
|
140
106
|
}
|
|
141
107
|
|
|
142
108
|
introspects.push(results)
|
|
@@ -144,10 +110,167 @@ const introspectionUtil = {
|
|
|
144
110
|
|
|
145
111
|
return introspects
|
|
146
112
|
},
|
|
113
|
+
|
|
114
|
+
getExports(sourceFile: ts.SourceFile): ts.Node[] {
|
|
115
|
+
const exports: ts.Node[] = []
|
|
116
|
+
|
|
117
|
+
const traverse = (node: ts.Node) => {
|
|
118
|
+
if (ts.isExportDeclaration(node)) {
|
|
119
|
+
exports.push(node)
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
ts.forEachChild(node, traverse)
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
traverse(sourceFile)
|
|
126
|
+
|
|
127
|
+
return exports
|
|
128
|
+
},
|
|
129
|
+
|
|
130
|
+
getClassDeclarationFromImportedFile(
|
|
131
|
+
exportDeclaration: ts.Node,
|
|
132
|
+
dirName: string,
|
|
133
|
+
program: ts.Program
|
|
134
|
+
): ts.ClassDeclaration | undefined {
|
|
135
|
+
if (!ts.isExportDeclaration(exportDeclaration)) {
|
|
136
|
+
return undefined
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
const exportClause = exportDeclaration.exportClause
|
|
140
|
+
if (!exportClause || !ts.isNamedExports(exportClause)) {
|
|
141
|
+
return undefined
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
for (const element of exportClause.elements) {
|
|
145
|
+
if (element.propertyName) {
|
|
146
|
+
const propertyName = element.propertyName.text
|
|
147
|
+
const moduleSpecifier = (
|
|
148
|
+
exportDeclaration.moduleSpecifier as ts.StringLiteral
|
|
149
|
+
).text
|
|
150
|
+
|
|
151
|
+
const sourceFile = diskUtil.resolveFile(
|
|
152
|
+
dirName,
|
|
153
|
+
moduleSpecifier.replace(/^\.\//, '')
|
|
154
|
+
)
|
|
155
|
+
|
|
156
|
+
if (!sourceFile) {
|
|
157
|
+
return undefined
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// Load the source file containing the class declaration
|
|
161
|
+
const declarationSourceFile = program.getSourceFile(sourceFile)
|
|
162
|
+
if (!declarationSourceFile) {
|
|
163
|
+
return undefined
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
const traverse = (node: ts.Node): ts.ClassDeclaration | undefined => {
|
|
167
|
+
if (
|
|
168
|
+
ts.isClassDeclaration(node) &&
|
|
169
|
+
node.name &&
|
|
170
|
+
node.name.text === propertyName
|
|
171
|
+
) {
|
|
172
|
+
return node
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
for (const child of node.getChildren(declarationSourceFile)) {
|
|
176
|
+
const result = traverse(child)
|
|
177
|
+
if (result) {
|
|
178
|
+
return result
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
return undefined
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
return traverse(declarationSourceFile)
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
return undefined
|
|
190
|
+
},
|
|
191
|
+
|
|
192
|
+
hasClassDefinition(sourceFile: ts.SourceFile): boolean {
|
|
193
|
+
let hasClass = false
|
|
194
|
+
|
|
195
|
+
const traverse = (node: ts.Node) => {
|
|
196
|
+
if (ts.isClassDeclaration(node)) {
|
|
197
|
+
hasClass = true
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
if (!hasClass) {
|
|
201
|
+
ts.forEachChild(node, traverse)
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
traverse(sourceFile)
|
|
206
|
+
|
|
207
|
+
return hasClass
|
|
208
|
+
},
|
|
147
209
|
}
|
|
148
210
|
|
|
149
211
|
export default introspectionUtil
|
|
150
212
|
|
|
213
|
+
function getDeclarationsFromNode(
|
|
214
|
+
node: ts.Node,
|
|
215
|
+
checker: ts.TypeChecker,
|
|
216
|
+
sourceFile: ts.SourceFile
|
|
217
|
+
) {
|
|
218
|
+
const classes: IntrospectionClass[] = []
|
|
219
|
+
const interfaces: IntrospectionInterface[] = []
|
|
220
|
+
|
|
221
|
+
// if this is a class declaration
|
|
222
|
+
if (ts.isClassDeclaration(node) && node.name) {
|
|
223
|
+
const symbol = checker.getSymbolAtLocation(node.name)
|
|
224
|
+
|
|
225
|
+
if (symbol?.valueDeclaration) {
|
|
226
|
+
const details = serializeSymbol({ checker, symbol })
|
|
227
|
+
// Get the construct signatures
|
|
228
|
+
const constructorType = checker.getTypeOfSymbolAtLocation(
|
|
229
|
+
symbol,
|
|
230
|
+
symbol.valueDeclaration
|
|
231
|
+
)
|
|
232
|
+
|
|
233
|
+
let parentClassSymbol: ts.Symbol | undefined
|
|
234
|
+
if (node.heritageClauses && node.heritageClauses[0]) {
|
|
235
|
+
parentClassSymbol = checker
|
|
236
|
+
.getTypeAtLocation(node.heritageClauses[0].types[0])
|
|
237
|
+
.getSymbol()
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
const parentClassName =
|
|
241
|
+
// @ts-ignore
|
|
242
|
+
parentClassSymbol?.valueDeclaration?.name?.text
|
|
243
|
+
// @ts-ignore
|
|
244
|
+
const parentClassPath = parentClassSymbol?.parent
|
|
245
|
+
?.getName()
|
|
246
|
+
.replace('"', '')
|
|
247
|
+
|
|
248
|
+
const isAbstractClass = tsutils.isModifierFlagSet(
|
|
249
|
+
node,
|
|
250
|
+
ts.ModifierFlags.Abstract
|
|
251
|
+
)
|
|
252
|
+
details.constructors = constructorType
|
|
253
|
+
.getConstructSignatures()
|
|
254
|
+
.map((s) => serializeSignature({ signature: s, checker }))
|
|
255
|
+
|
|
256
|
+
classes.push({
|
|
257
|
+
className: node.name.text,
|
|
258
|
+
classPath: sourceFile.fileName,
|
|
259
|
+
parentClassName,
|
|
260
|
+
parentClassPath,
|
|
261
|
+
staticProperties: pluckStaticProperties(node),
|
|
262
|
+
optionsInterfaceName: details.constructors?.[0].parameters?.[0]?.type,
|
|
263
|
+
isAbstract: isAbstractClass,
|
|
264
|
+
})
|
|
265
|
+
}
|
|
266
|
+
} else if (ts.isInterfaceDeclaration(node)) {
|
|
267
|
+
interfaces.push({
|
|
268
|
+
interfaceName: node.name.text,
|
|
269
|
+
})
|
|
270
|
+
}
|
|
271
|
+
return { classes, interfaces }
|
|
272
|
+
}
|
|
273
|
+
|
|
151
274
|
function pluckStaticProperties(node: ts.ClassDeclaration): StaticProperties {
|
|
152
275
|
const staticProps: StaticProperties = {}
|
|
153
276
|
|
|
@@ -164,3 +287,34 @@ function pluckStaticProperties(node: ts.ClassDeclaration): StaticProperties {
|
|
|
164
287
|
|
|
165
288
|
return staticProps
|
|
166
289
|
}
|
|
290
|
+
|
|
291
|
+
export interface IntrospectionClass {
|
|
292
|
+
className: string
|
|
293
|
+
classPath: string
|
|
294
|
+
parentClassName: string | undefined
|
|
295
|
+
parentClassPath: string | undefined
|
|
296
|
+
optionsInterfaceName: string | undefined
|
|
297
|
+
isAbstract: boolean
|
|
298
|
+
staticProperties: StaticProperties
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
type StaticProperties = Record<string, any>
|
|
302
|
+
|
|
303
|
+
interface IntrospectionInterface {
|
|
304
|
+
interfaceName: string
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
export interface Introspection {
|
|
308
|
+
classes: IntrospectionClass[]
|
|
309
|
+
interfaces: IntrospectionInterface[]
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
interface DocEntry {
|
|
313
|
+
name?: string
|
|
314
|
+
fileName?: string
|
|
315
|
+
documentation?: string
|
|
316
|
+
type?: string
|
|
317
|
+
constructors?: DocEntry[]
|
|
318
|
+
parameters?: DocEntry[]
|
|
319
|
+
returnType?: string
|
|
320
|
+
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"EventSettingsService.js","names":["EventSettingsService","exports","settings","_classCallCheck2","_defineProperty2","_createClass2","key","value","getLastSyncOptions","get","setLastSyncOptions","options","set","setListenerCache","clearListenerCache","unset","getListenerCache"],"sources":["../../../../src/features/event/services/EventSettingsService.ts"],"sourcesContent":["import { SettingsService } from '@sprucelabs/spruce-skill-utils'\n\nexport default class EventSettingsService {\n\tprivate settings: SettingsService<string>\n\tpublic constructor(settings: SettingsService) {\n\t\tthis.settings = settings\n\t}\n\n\tpublic getLastSyncOptions() {\n\t\treturn this.settings.get('events.lastSync')\n\t}\n\n\tpublic setLastSyncOptions(options: {\n\t\tshouldSyncOnlyCoreEvents?: boolean | null\n\t}) {\n\t\tthis.settings.set('events.lastSync', options)\n\t}\n\n\tpublic setListenerCache(value: Record<string, any>) {\n\t\tthis.settings.set('events.listenerCacheKeys', value)\n\t}\n\n\tpublic clearListenerCache() {\n\t\tthis.settings.unset('events.listenerCacheKeys')\n\t}\n\n\tpublic getListenerCache() {\n\t\treturn this.settings.get('events.listenerCacheKeys')\n\t}\n}\n"],"mappings":";;;;;;;;;;IAEqBA,oBAAoB,GAAAC,OAAA;EAExC,SAAAD,qBAAmBE,QAAyB,EAAE;IAAA,IAAAC,gBAAA,mBAAAH,oBAAA;IAAA,IAAAI,gBAAA;IAC7C,IAAI,CAACF,QAAQ,GAAGA,QAAQ;EACzB;EAAC,WAAAG,aAAA,aAAAL,oBAAA;IAAAM,GAAA;IAAAC,KAAA,EAED,SAAAC,mBAAA,EAA4B;MAC3B,OAAO,IAAI,CAACN,QAAQ,CAACO,GAAG,CAAC,iBAAiB,CAAC;IAC5C;EAAC;IAAAH,GAAA;IAAAC,KAAA,EAED,SAAAG,mBAA0BC,OAEzB,EAAE;MACF,IAAI,CAACT,QAAQ,CAACU,GAAG,CAAC,iBAAiB,EAAED,OAAO,CAAC;IAC9C;EAAC;IAAAL,GAAA;IAAAC,KAAA,EAED,SAAAM,iBAAwBN,KAA0B,EAAE;MACnD,IAAI,CAACL,QAAQ,CAACU,GAAG,CAAC,0BAA0B,EAAEL,KAAK,CAAC;IACrD;EAAC;IAAAD,GAAA;IAAAC,KAAA,EAED,SAAAO,mBAAA,EAA4B;MAC3B,IAAI,CAACZ,QAAQ,CAACa,KAAK,CAAC,0BAA0B,CAAC;IAChD;EAAC;IAAAT,GAAA;IAAAC,KAAA,EAED,SAAAS,iBAAA,EAA0B;MACzB,OAAO,IAAI,CAACd,QAAQ,CAACO,GAAG,CAAC,0BAA0B,CAAC;IACrD;EAAC;AAAA","ignoreList":[]}
|