@sprucelabs/spruce-cli 28.2.3 → 29.0.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.
Files changed (232) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/build/.spruce/errors/errors.types.d.ts +23 -2
  3. package/build/.spruce/errors/options.types.d.ts +4 -1
  4. package/build/.spruce/errors/spruceCli/directoryNotGoModule.schema.d.ts +3 -0
  5. package/build/.spruce/errors/spruceCli/directoryNotGoModule.schema.js +20 -0
  6. package/build/.spruce/errors/spruceCli/directoryNotGoModule.schema.js.map +1 -0
  7. package/build/__tests__/behavioral/OverridingCommandsInPackageJson.test.d.ts +7 -2
  8. package/build/__tests__/behavioral/OverridingCommandsInPackageJson.test.js +36 -13
  9. package/build/__tests__/behavioral/OverridingCommandsInPackageJson.test.js.map +1 -1
  10. package/build/__tests__/behavioral/events/DifferentEventOptions.test.d.ts +16 -0
  11. package/build/__tests__/behavioral/events/DifferentEventOptions.test.js +105 -0
  12. package/build/__tests__/behavioral/events/DifferentEventOptions.test.js.map +1 -0
  13. package/build/__tests__/behavioral/events/KeepingEventsInSync.test.js.map +1 -1
  14. package/build/__tests__/behavioral/features/InstallFeaturesInGo.test.d.ts +5 -0
  15. package/build/__tests__/behavioral/features/InstallFeaturesInGo.test.js +32 -0
  16. package/build/__tests__/behavioral/features/InstallFeaturesInGo.test.js.map +1 -0
  17. package/build/__tests__/behavioral/organization/CreatingAnOrg.test.d.ts +5 -0
  18. package/build/__tests__/behavioral/organization/CreatingAnOrg.test.js +21 -13
  19. package/build/__tests__/behavioral/organization/CreatingAnOrg.test.js.map +1 -1
  20. package/build/__tests__/behavioral/schemas/KeepingSchemasInSync.test.d.ts +1 -1
  21. package/build/__tests__/behavioral/schemas/KeepingSchemasInSync.test.js +7 -7
  22. package/build/__tests__/behavioral/schemas/KeepingSchemasInSync.test.js.map +1 -1
  23. package/build/__tests__/behavioral/schemas/SyncingCoreSchemasInGo.test.d.ts +39 -0
  24. package/build/__tests__/behavioral/schemas/SyncingCoreSchemasInGo.test.js +289 -0
  25. package/build/__tests__/behavioral/schemas/SyncingCoreSchemasInGo.test.js.map +1 -0
  26. package/build/__tests__/behavioral/schemas/SyncingSchemasInChildDirInGo.test.d.ts +7 -0
  27. package/build/__tests__/behavioral/schemas/SyncingSchemasInChildDirInGo.test.js +46 -0
  28. package/build/__tests__/behavioral/schemas/SyncingSchemasInChildDirInGo.test.js.map +1 -0
  29. package/build/__tests__/behavioral/schemas/SyncingSchemasInGo.test.d.ts +5 -0
  30. package/build/__tests__/behavioral/schemas/SyncingSchemasInGo.test.js +31 -0
  31. package/build/__tests__/behavioral/schemas/SyncingSchemasInGo.test.js.map +1 -0
  32. package/build/__tests__/behavioral/tests/SelectingAnAbstractTestClass.test.js +1 -1
  33. package/build/__tests__/behavioral/tests/SelectingAnAbstractTestClass.test.js.map +1 -1
  34. package/build/__tests__/behavioral/upgrading/UpdatingDependencies2.test.js +10 -1
  35. package/build/__tests__/behavioral/upgrading/UpdatingDependencies2.test.js.map +1 -1
  36. package/build/__tests__/implementation/SkillStore.test.d.ts +5 -0
  37. package/build/__tests__/implementation/SkillStore.test.js +37 -0
  38. package/build/__tests__/implementation/SkillStore.test.js.map +1 -1
  39. package/build/__tests__/support/EventFaker.d.ts +7 -0
  40. package/build/__tests__/support/EventFaker.js +43 -0
  41. package/build/__tests__/support/EventFaker.js.map +1 -1
  42. package/build/cli/Cli.js +12 -9
  43. package/build/cli/Cli.js.map +1 -1
  44. package/build/errors/SpruceError.js +3 -0
  45. package/build/errors/SpruceError.js.map +1 -1
  46. package/build/errors/directoryNotGoModule.builder.d.ts +12 -0
  47. package/build/errors/directoryNotGoModule.builder.js +15 -0
  48. package/build/errors/directoryNotGoModule.builder.js.map +1 -0
  49. package/build/features/AbstractAction.d.ts +1 -0
  50. package/build/features/AbstractAction.js +5 -1
  51. package/build/features/AbstractAction.js.map +1 -1
  52. package/build/features/AbstractFeature.d.ts +8 -1
  53. package/build/features/AbstractFeature.js +12 -1
  54. package/build/features/AbstractFeature.js.map +1 -1
  55. package/build/features/ActionFactory.js +1 -2
  56. package/build/features/ActionFactory.js.map +1 -1
  57. package/build/features/ActionQuestionAsker.js +0 -1
  58. package/build/features/ActionQuestionAsker.js.map +1 -1
  59. package/build/features/FeatureInstaller.d.ts +1 -0
  60. package/build/features/FeatureInstaller.js +21 -7
  61. package/build/features/FeatureInstaller.js.map +1 -1
  62. package/build/features/FeatureInstallerFactory.d.ts +1 -0
  63. package/build/features/FeatureInstallerFactory.js +7 -0
  64. package/build/features/FeatureInstallerFactory.js.map +1 -1
  65. package/build/features/OverrideActionDecorator.js +1 -1
  66. package/build/features/OverrideActionDecorator.js.map +1 -1
  67. package/build/features/VersionResolver.js +1 -1
  68. package/build/features/VersionResolver.js.map +1 -1
  69. package/build/features/agent/AgentFeature.d.ts +1 -1
  70. package/build/features/agent/AgentFeature.js +1 -1
  71. package/build/features/agent/AgentFeature.js.map +1 -1
  72. package/build/features/conversation/ConversationFeature.d.ts +1 -1
  73. package/build/features/conversation/ConversationFeature.js +1 -1
  74. package/build/features/conversation/ConversationFeature.js.map +1 -1
  75. package/build/features/dependencies/DependencyFeature.d.ts +0 -1
  76. package/build/features/dependencies/DependencyFeature.js +0 -1
  77. package/build/features/dependencies/DependencyFeature.js.map +1 -1
  78. package/build/features/deploy/DeployFeature.d.ts +1 -1
  79. package/build/features/deploy/DeployFeature.js +1 -1
  80. package/build/features/deploy/DeployFeature.js.map +1 -1
  81. package/build/features/error/ErrorFeature.d.ts +1 -1
  82. package/build/features/error/ErrorFeature.js +1 -1
  83. package/build/features/error/ErrorFeature.js.map +1 -1
  84. package/build/features/event/EventFeature.d.ts +1 -1
  85. package/build/features/event/EventFeature.js +1 -1
  86. package/build/features/event/EventFeature.js.map +1 -1
  87. package/build/features/eventContract/EventContractFeature.d.ts +1 -3
  88. package/build/features/eventContract/EventContractFeature.js +0 -2
  89. package/build/features/eventContract/EventContractFeature.js.map +1 -1
  90. package/build/features/node/NodeFeature.d.ts +1 -1
  91. package/build/features/node/NodeFeature.js +1 -1
  92. package/build/features/node/NodeFeature.js.map +1 -1
  93. package/build/features/onboard/OnboardFeature.d.ts +1 -3
  94. package/build/features/onboard/OnboardFeature.js +0 -2
  95. package/build/features/onboard/OnboardFeature.js.map +1 -1
  96. package/build/features/organization/OrganizationFeature.d.ts +0 -1
  97. package/build/features/organization/OrganizationFeature.js +0 -1
  98. package/build/features/organization/OrganizationFeature.js.map +1 -1
  99. package/build/features/permission/PermissionFeature.d.ts +2 -3
  100. package/build/features/permission/PermissionFeature.js +1 -2
  101. package/build/features/permission/PermissionFeature.js.map +1 -1
  102. package/build/features/person/PersonFeature.d.ts +1 -3
  103. package/build/features/person/PersonFeature.js +0 -2
  104. package/build/features/person/PersonFeature.js.map +1 -1
  105. package/build/features/polish/PolishFeature.d.ts +1 -1
  106. package/build/features/polish/PolishFeature.js +1 -1
  107. package/build/features/polish/PolishFeature.js.map +1 -1
  108. package/build/features/sandbox/SandboxFeature.d.ts +0 -1
  109. package/build/features/sandbox/SandboxFeature.js +0 -1
  110. package/build/features/sandbox/SandboxFeature.js.map +1 -1
  111. package/build/features/schema/SchemaFeature.d.ts +2 -3
  112. package/build/features/schema/SchemaFeature.js +6 -1
  113. package/build/features/schema/SchemaFeature.js.map +1 -1
  114. package/build/features/schema/actions/SyncAction.d.ts +5 -2
  115. package/build/features/schema/actions/SyncAction.js +50 -16
  116. package/build/features/schema/actions/SyncAction.js.map +1 -1
  117. package/build/features/schema/utilities/schemaDisk.utility.d.ts +7 -0
  118. package/build/features/schema/utilities/schemaDisk.utility.js +22 -4
  119. package/build/features/schema/utilities/schemaDisk.utility.js.map +1 -1
  120. package/build/features/schema/utilities/schemaGenerator.utility.d.ts +1 -0
  121. package/build/features/schema/utilities/schemaGenerator.utility.js +18 -10
  122. package/build/features/schema/utilities/schemaGenerator.utility.js.map +1 -1
  123. package/build/features/schema/writers/SchemaWriter.d.ts +9 -9
  124. package/build/features/schema/writers/SchemaWriter.js +38 -17
  125. package/build/features/schema/writers/SchemaWriter.js.map +1 -1
  126. package/build/features/skill/SkillFeature.d.ts +1 -1
  127. package/build/features/skill/SkillFeature.js +1 -1
  128. package/build/features/skill/SkillFeature.js.map +1 -1
  129. package/build/features/skill/stores/SkillStore.d.ts +5 -0
  130. package/build/features/skill/stores/SkillStore.js +40 -3
  131. package/build/features/skill/stores/SkillStore.js.map +1 -1
  132. package/build/features/store/StoreFeature.d.ts +1 -1
  133. package/build/features/store/StoreFeature.js +1 -1
  134. package/build/features/store/StoreFeature.js.map +1 -1
  135. package/build/features/test/TestFeature.d.ts +1 -1
  136. package/build/features/test/TestFeature.js +1 -1
  137. package/build/features/test/TestFeature.js.map +1 -1
  138. package/build/features/test/TestReporter.js +1 -1
  139. package/build/features/test/TestReporter.js.map +1 -1
  140. package/build/features/view/ViewFeature.d.ts +1 -1
  141. package/build/features/view/ViewFeature.js +1 -1
  142. package/build/features/view/ViewFeature.js.map +1 -1
  143. package/build/migration/EsLint9Migrator.d.ts +1 -0
  144. package/build/packageManager/NodePackageManager.d.ts +14 -0
  145. package/build/packageManager/NodePackageManager.js +88 -0
  146. package/build/packageManager/NodePackageManager.js.map +1 -0
  147. package/build/packageManager/packageManager.types.d.ts +16 -0
  148. package/build/packageManager/packageManager.types.js +3 -0
  149. package/build/packageManager/packageManager.types.js.map +1 -0
  150. package/build/services/GoPackageManager.d.ts +10 -0
  151. package/build/services/GoPackageManager.js +39 -0
  152. package/build/services/GoPackageManager.js.map +1 -0
  153. package/build/services/PkgService.d.ts +3 -7
  154. package/build/services/PkgService.js +13 -68
  155. package/build/services/PkgService.js.map +1 -1
  156. package/build/templateItemBuilders/SchemaTemplateItemBuilder.js.map +1 -1
  157. package/build/tests/AbstractCliTest.d.ts +5 -1
  158. package/build/tests/AbstractCliTest.js +15 -3
  159. package/build/tests/AbstractCliTest.js.map +1 -1
  160. package/build/tests/fixtures/FeatureFixture.js +4 -1
  161. package/build/tests/fixtures/FeatureFixture.js.map +1 -1
  162. package/build/tests/fixtures/GoFixture.d.ts +12 -0
  163. package/build/tests/fixtures/GoFixture.js +39 -0
  164. package/build/tests/fixtures/GoFixture.js.map +1 -0
  165. package/build/tests/staticToInstanceMigration/StaticToInstanceMigrator.d.ts +1 -0
  166. package/build/widgets/terminalKit/TkTextWidget.js +3 -2
  167. package/build/widgets/terminalKit/TkTextWidget.js.map +1 -1
  168. package/build/writers/AbstractWriter.js +7 -6
  169. package/build/writers/AbstractWriter.js.map +1 -1
  170. package/package.json +30 -30
  171. package/src/.spruce/errors/errors.types.ts +32 -2
  172. package/src/.spruce/errors/options.types.ts +4 -1
  173. package/src/.spruce/errors/spruceCli/directoryNotGoModule.schema.ts +23 -0
  174. package/src/__tests__/behavioral/OverridingCommandsInPackageJson.test.ts +60 -13
  175. package/src/__tests__/behavioral/events/DifferentEventOptions.test.ts +134 -0
  176. package/src/__tests__/behavioral/events/KeepingEventsInSync.test.ts +0 -1
  177. package/src/__tests__/behavioral/features/InstallFeaturesInGo.test.ts +17 -0
  178. package/src/__tests__/behavioral/organization/CreatingAnOrg.test.ts +29 -22
  179. package/src/__tests__/behavioral/schemas/KeepingSchemasInSync.test.ts +6 -9
  180. package/src/__tests__/behavioral/schemas/SyncingCoreSchemasInGo.test.ts +376 -0
  181. package/src/__tests__/behavioral/schemas/SyncingSchemasInChildDirInGo.test.ts +46 -0
  182. package/src/__tests__/behavioral/schemas/SyncingSchemasInGo.test.ts +23 -0
  183. package/src/__tests__/behavioral/tests/SelectingAnAbstractTestClass.test.ts +1 -1
  184. package/src/__tests__/behavioral/upgrading/UpdatingDependencies2.test.ts +15 -2
  185. package/src/__tests__/implementation/SkillStore.test.ts +44 -1
  186. package/src/__tests__/support/EventFaker.ts +56 -0
  187. package/src/cli/Cli.ts +20 -12
  188. package/src/errors/SpruceError.ts +4 -0
  189. package/src/errors/directoryNotGoModule.builder.ts +13 -0
  190. package/src/features/AbstractAction.ts +6 -4
  191. package/src/features/AbstractFeature.ts +20 -1
  192. package/src/features/ActionFactory.ts +2 -2
  193. package/src/features/ActionQuestionAsker.ts +0 -1
  194. package/src/features/FeatureInstaller.ts +30 -6
  195. package/src/features/FeatureInstallerFactory.ts +9 -0
  196. package/src/features/OverrideActionDecorator.ts +1 -1
  197. package/src/features/VersionResolver.ts +2 -1
  198. package/src/features/agent/AgentFeature.ts +1 -1
  199. package/src/features/conversation/ConversationFeature.ts +1 -1
  200. package/src/features/dependencies/DependencyFeature.ts +0 -1
  201. package/src/features/deploy/DeployFeature.ts +1 -1
  202. package/src/features/error/ErrorFeature.ts +1 -1
  203. package/src/features/event/EventFeature.ts +1 -1
  204. package/src/features/eventContract/EventContractFeature.ts +1 -3
  205. package/src/features/node/NodeFeature.ts +1 -1
  206. package/src/features/onboard/OnboardFeature.ts +1 -7
  207. package/src/features/organization/OrganizationFeature.ts +0 -1
  208. package/src/features/permission/PermissionFeature.ts +1 -3
  209. package/src/features/person/PersonFeature.ts +1 -4
  210. package/src/features/polish/PolishFeature.ts +1 -1
  211. package/src/features/sandbox/SandboxFeature.ts +0 -1
  212. package/src/features/schema/SchemaFeature.ts +8 -2
  213. package/src/features/schema/actions/SyncAction.ts +68 -26
  214. package/src/features/schema/utilities/schemaDisk.utility.ts +43 -11
  215. package/src/features/schema/utilities/schemaGenerator.utility.ts +33 -13
  216. package/src/features/schema/writers/SchemaWriter.ts +71 -25
  217. package/src/features/skill/SkillFeature.ts +1 -1
  218. package/src/features/skill/stores/SkillStore.ts +51 -5
  219. package/src/features/store/StoreFeature.ts +1 -1
  220. package/src/features/test/TestFeature.ts +1 -1
  221. package/src/features/test/TestReporter.ts +1 -1
  222. package/src/features/view/ViewFeature.ts +1 -1
  223. package/src/packageManager/NodePackageManager.ts +115 -0
  224. package/src/packageManager/packageManager.types.ts +21 -0
  225. package/src/services/GoPackageManager.ts +45 -0
  226. package/src/services/PkgService.ts +17 -92
  227. package/src/templateItemBuilders/SchemaTemplateItemBuilder.ts +6 -6
  228. package/src/tests/AbstractCliTest.ts +19 -5
  229. package/src/tests/fixtures/FeatureFixture.ts +3 -1
  230. package/src/tests/fixtures/GoFixture.ts +39 -0
  231. package/src/widgets/terminalKit/TkTextWidget.ts +3 -2
  232. package/src/writers/AbstractWriter.ts +15 -6
@@ -0,0 +1,376 @@
1
+ import globby from '@sprucelabs/globby'
2
+ import { buildSchema, Schema, SchemaTypesRenderer } from '@sprucelabs/schema'
3
+ import {
4
+ CORE_NAMESPACE,
5
+ diskUtil,
6
+ namesUtil,
7
+ randomUtil,
8
+ versionUtil,
9
+ } from '@sprucelabs/spruce-skill-utils'
10
+ import { test, assert, generateId } from '@sprucelabs/test-utils'
11
+ import CommandServiceImpl from '../../../services/CommandService'
12
+ import LintService from '../../../services/LintService'
13
+ import SchemaTemplateItemBuilder from '../../../templateItemBuilders/SchemaTemplateItemBuilder'
14
+ import AbstractSkillTest from '../../../tests/AbstractSkillTest'
15
+ import testUtil from '../../../tests/utilities/test.utility'
16
+ import { GeneratedFile } from '../../../types/cli.types'
17
+
18
+ export default class SyncingSchemasInGoTest extends AbstractSkillTest {
19
+ protected static skillCacheKey = 'schemas'
20
+ private static goDir: string
21
+ private static builder1Name = 'aSchemaIBuilt'
22
+ private static builder2Name = 'anotherSchemaIBuilt'
23
+ private static renderer: SchemaTypesRenderer
24
+ private static goModuleName = randomUtil.rand([
25
+ 'my-skill',
26
+ 'awesome-skill',
27
+ 'super-skill',
28
+ ])
29
+
30
+ private static version = versionUtil.generateVersion().constValue
31
+ private static skillNamespace: string = CORE_NAMESPACE
32
+ private static schemaTemplateItemBuilder: SchemaTemplateItemBuilder
33
+ private static goFullModuleName: string
34
+
35
+ protected static async beforeEach(): Promise<void> {
36
+ await super.beforeEach()
37
+
38
+ if (!this.goDir) {
39
+ this.goDir = this.resolvePath(this.skillDir, 'go-schemas')
40
+ diskUtil.createDir(this.goDir)
41
+ }
42
+
43
+ CommandServiceImpl.fakeCommand(/yarn.*?/, {
44
+ code: 1,
45
+ })
46
+
47
+ this.renderer = SchemaTypesRenderer.Renderer()
48
+ this.schemaTemplateItemBuilder = new SchemaTemplateItemBuilder(
49
+ CORE_NAMESPACE
50
+ )
51
+ }
52
+
53
+ @test()
54
+ protected static async canSyncCoreSchemasWithoutError() {
55
+ this.moveToGoDir()
56
+
57
+ this.goFullModuleName = await this.go.initGoProject(this.goModuleName)
58
+ await this.sync()
59
+
60
+ const tsFiles = await globby('**/*.ts', {
61
+ cwd: this.cwd,
62
+ ignore: ['go/pkg/**'],
63
+ })
64
+ assert.isLength(tsFiles, 0, 'Expected no .ts files to be generated.')
65
+ }
66
+
67
+ @test()
68
+ protected static async syncingGeneratesCoreGoFileIfSchemaDoesExist() {
69
+ await this.createSchema(this.builder1Name)
70
+
71
+ this.moveToGoDir()
72
+
73
+ const syncResults = await this.sync()
74
+ testUtil.assertFileByPathInGeneratedFiles(
75
+ this.coreSchemaGoFilepath,
76
+ syncResults.files
77
+ )
78
+
79
+ assert.isTrue(
80
+ diskUtil.doesFileExist(this.coreSchemaGoFilepath),
81
+ 'Expected core_schemas.go file to exist.'
82
+ )
83
+ }
84
+
85
+ @test()
86
+ protected static async coreSchemasFileHasStructBasedOnSchema() {
87
+ await this.assertCoreFileIncludesSchema(this.builder1Name)
88
+ }
89
+
90
+ @test()
91
+ protected static async coreShowsDifferentSchema() {
92
+ await this.createSchema(this.builder2Name)
93
+ this.moveToGoDir()
94
+ await this.sync()
95
+ await this.assertCoreFileIncludesSchema(this.builder2Name)
96
+ }
97
+
98
+ @test()
99
+ protected static async doesNotIncludeSchemaIfDeleted() {
100
+ diskUtil.deleteFile(this.getBuilderFilepath(this.builder1Name))
101
+
102
+ this.moveToGoDir()
103
+ await this.sync()
104
+
105
+ const contents = this.loadCoreSchemasFile()
106
+ assert.doesNotInclude(
107
+ contents,
108
+ namesUtil.toPascal(this.builder1Name),
109
+ 'Expected core_schemas.go to not include deleted schema.'
110
+ )
111
+ }
112
+
113
+ @test()
114
+ protected static async coreSchemasFileIncludesPackageDeclaration() {
115
+ this.assertCoreSchemaFileIncludes('package schemas')
116
+ }
117
+
118
+ @test()
119
+ protected static async goFileIsValid() {
120
+ this.moveToGoDir()
121
+ await this.go.exec('build', './...')
122
+ }
123
+
124
+ @test()
125
+ protected static async canRenderNestedSchemas() {
126
+ const schema2 = await this.importBuilder(this.builder2Name)
127
+ schema2.fields = {
128
+ ...schema2.fields,
129
+ hasNestedSchema: {
130
+ type: 'schema',
131
+ options: {
132
+ schema: nestedSchema,
133
+ },
134
+ },
135
+ dateOfBirth: {
136
+ type: 'date',
137
+ },
138
+ }
139
+
140
+ diskUtil.writeFile(
141
+ this.getBuilderFilepath(this.builder2Name),
142
+ `import { buildSchema } from '@sprucelabs/schema'
143
+
144
+ export default buildSchema(${JSON.stringify(schema2, null, 4)})`
145
+ )
146
+
147
+ await this.lintBuilders()
148
+
149
+ schema2.namespace = this.skillNamespace
150
+ const expected = this.renderSchemaAsStruct(schema2)
151
+
152
+ this.moveToGoDir()
153
+ await this.sync()
154
+
155
+ this.assertCoreSchemaFileIncludes(expected)
156
+ }
157
+
158
+ @test()
159
+ protected static async generatedFileShouldPassVet() {
160
+ this.moveToGoDir()
161
+ await this.go.vet()
162
+ }
163
+
164
+ @test()
165
+ protected static async writesSchemaFileForEachSchemaFound() {
166
+ this.moveToGoDir()
167
+ const results = await this.sync()
168
+ const generated = ['nestedSchema', 'anotherSchemaIBuilt']
169
+ for (const schema of generated) {
170
+ this.assertSchemaFileWrittenWithExpectedPackage(
171
+ schema,
172
+ results.files
173
+ )
174
+ }
175
+ }
176
+
177
+ @test()
178
+ protected static async canActuallyUseGeneratedSchemasInGoTest() {
179
+ this.moveToGoDir()
180
+ const testSrc = buildGoTest({
181
+ pwd: this.goFullModuleName,
182
+ name: generateId(),
183
+ age: Date.now() % 100,
184
+ version: this.version,
185
+ })
186
+
187
+ diskUtil.writeFile(
188
+ this.resolvePath(this.cwd, 'test_schema.go'),
189
+ testSrc
190
+ )
191
+
192
+ await this.go.exec('test', './...')
193
+ }
194
+
195
+ @test()
196
+ protected static async creatingSchemaWithDifferentVersionAlsoWorks() {
197
+ this.version = versionUtil.generateVersion('2020_01_01').constValue
198
+ await this.createSchema('versionedSchema')
199
+ this.moveToGoDir()
200
+ const results = await this.sync()
201
+ this.assertSchemaFileWrittenWithExpectedPackage(
202
+ 'versionedSchema',
203
+ results.files
204
+ )
205
+ }
206
+
207
+ private static assertSchemaFileWrittenWithExpectedPackage(
208
+ schema: string,
209
+ files: GeneratedFile[] = []
210
+ ) {
211
+ assert.isAbove(files.length, 0, 'Expected at least one generated file.')
212
+
213
+ const path = testUtil.assertFileByPathInGeneratedFiles(
214
+ `schemas/${this.skillNamespace.toLowerCase()}/${this.version}/${namesUtil.toSnake(schema)}.go`,
215
+ files
216
+ )
217
+ const contents = diskUtil.readFile(path)
218
+ assert.doesInclude(
219
+ contents,
220
+ `package ${this.version}`,
221
+ 'Did not include expected package declaration.'
222
+ )
223
+ }
224
+
225
+ private static async lintBuilders() {
226
+ LintService.enableLinting()
227
+ await this.Service('lint').fix(`**/*.builder.ts`)
228
+ }
229
+
230
+ private static async assertCoreFileIncludesSchema(name: string) {
231
+ const struct = await this.importStructForSchema(name)
232
+ this.assertCoreSchemaFileIncludes(struct)
233
+ }
234
+
235
+ private static assertCoreSchemaFileIncludes(needle: string) {
236
+ const contents = this.loadCoreSchemasFile()
237
+
238
+ assert.doesInclude(
239
+ contents,
240
+ needle,
241
+ 'core_schemas.go missing expected content'
242
+ )
243
+ }
244
+
245
+ private static async importStructForSchema(name: string) {
246
+ const imported = await this.importBuilder(name)
247
+ imported.namespace = this.skillNamespace
248
+ const struct = this.renderSchemaAsStruct(imported)
249
+
250
+ return struct
251
+ }
252
+
253
+ private static loadCoreSchemasFile() {
254
+ return diskUtil.readFile(this.coreSchemaGoFilepath)
255
+ }
256
+
257
+ private static renderSchemaAsStruct(imported: Schema) {
258
+ const templateItems = this.schemaTemplateItemBuilder.buildTemplateItems(
259
+ {
260
+ [CORE_NAMESPACE]: [imported],
261
+ }
262
+ )
263
+
264
+ return this.renderer.render(imported, {
265
+ language: 'go',
266
+ schemaTemplateItems: templateItems,
267
+ })
268
+ }
269
+
270
+ private static async importBuilder(name: string) {
271
+ return (await this.Service('import').importDefault(
272
+ this.getBuilderFilepath(name)
273
+ )) as Schema
274
+ }
275
+
276
+ private static async createSchema(name: string) {
277
+ const results = await this.Action('schema', 'create').execute({
278
+ nameReadable: 'A schema i built!',
279
+ nameCamel: name,
280
+ version: this.version,
281
+ })
282
+
283
+ assert.isFalsy(
284
+ results.errors,
285
+ 'Expected no errors when creating schema.'
286
+ )
287
+ }
288
+
289
+ private static getBuilderFilepath(name: string) {
290
+ return this.resolvePath(
291
+ this.skillDir,
292
+ 'src',
293
+ 'schemas',
294
+ versionUtil.generateVersion().dirValue,
295
+ `${name}.builder.ts`
296
+ )
297
+ }
298
+
299
+ private static get coreSchemaGoFilepath() {
300
+ return diskUtil.resolvePath(this.goDir, 'schemas/core_schemas.go')
301
+ }
302
+
303
+ private static async sync() {
304
+ const results = await this.Action('schema', 'sync', {
305
+ shouldAutoHandleDependencies: true,
306
+ }).execute({
307
+ shouldGenerateCoreSchemaTypes: true,
308
+ schemaLookupDir: this.resolvePath(this.skillDir, 'src'),
309
+ })
310
+
311
+ assert.isFalsy(
312
+ results.errors,
313
+ 'Expected no errors when syncing core schemas in a go project.'
314
+ )
315
+
316
+ assert.isTruthy(
317
+ results.files,
318
+ 'Expected some generated files when syncing core schemas in a go project.'
319
+ )
320
+
321
+ return results
322
+ }
323
+
324
+ private static moveToGoDir() {
325
+ this.cwd = this.goDir
326
+ this.setCwd(this.cwd)
327
+ }
328
+ }
329
+
330
+ const nestedSchema = buildSchema({
331
+ id: 'nestedSchema',
332
+ fields: {
333
+ name: {
334
+ type: 'text',
335
+ },
336
+ age: {
337
+ type: 'number',
338
+ },
339
+ },
340
+ })
341
+
342
+ const buildGoTest = (options: {
343
+ pwd: string
344
+ name: string
345
+ age: number
346
+ version: string
347
+ }) => `
348
+ package goschemas
349
+
350
+ import (
351
+ "testing"
352
+ spruce "${options.pwd}/schemas/spruce/${options.version}"
353
+ )
354
+
355
+ func TestMakeASchemaIBuilt(t *testing.T) {
356
+ data := map[string]interface{}{
357
+ "name": "${options.name}",
358
+ "age": ${options.age},
359
+ }
360
+
361
+ result, err := spruce.MakeNestedSchema(data)
362
+ if err != nil {
363
+ t.Fatalf("MakeNestedSchema failed: %v", err)
364
+ }
365
+
366
+ if result.Name != "${options.name}" {
367
+ t.Errorf("Expected Name to be '${options.name}', got '%s'",
368
+ result.Name)
369
+ }
370
+
371
+ if result.Age != ${options.age} {
372
+ t.Errorf("Expected Age to be ${options.age}, got %f",
373
+ result.Age)
374
+ }
375
+ }
376
+ `
@@ -0,0 +1,46 @@
1
+ import { diskUtil } from '@sprucelabs/spruce-skill-utils'
2
+ import { test, assert } from '@sprucelabs/test-utils'
3
+ import AbstractSkillTest from '../../../tests/AbstractSkillTest'
4
+ import generateShortAlphaId from '../permissions/support/generateShortAlphaId'
5
+
6
+ export default class SyncingSchemasInChildDirInGoTest extends AbstractSkillTest {
7
+ protected static skillCacheKey = 'schemas'
8
+ private static schemaNameCamel = generateShortAlphaId()
9
+
10
+ @test()
11
+ protected static async importsTheCorrectPath() {
12
+ await this.go.initGoProject()
13
+ await this.createSchema()
14
+
15
+ const dir = 'pgk'
16
+ diskUtil.createDir(this.resolvePath(dir))
17
+
18
+ this.cwd = this.resolvePath(dir)
19
+ this.setCwd(this.cwd)
20
+
21
+ const results = await this.Action('schema', 'sync', {
22
+ shouldAutoHandleDependencies: true,
23
+ }).execute({
24
+ schemaLookupDir: '../src/',
25
+ })
26
+
27
+ assert.isFalsy(
28
+ results.errors,
29
+ 'Expected no errors when syncing schema.'
30
+ )
31
+
32
+ await this.go.vet()
33
+ }
34
+
35
+ private static async createSchema() {
36
+ const results = await this.Action('schema', 'create').execute({
37
+ nameReadable: 'A schema i built!',
38
+ nameCamel: this.schemaNameCamel,
39
+ })
40
+
41
+ assert.isFalsy(
42
+ results.errors,
43
+ 'Expected no errors when creating schema.'
44
+ )
45
+ }
46
+ }
@@ -0,0 +1,23 @@
1
+ import { assert, test } from '@sprucelabs/test-utils'
2
+ import AbstractCliTest from '../../../tests/AbstractCliTest'
3
+
4
+ export default class SyncingSchemasInGoTest extends AbstractCliTest {
5
+ @test()
6
+ protected static async canSyncWithoutError() {
7
+ await this.go.initGoProject()
8
+ await this.sync()
9
+ }
10
+
11
+ private static async sync() {
12
+ const results = await this.Action('schema', 'sync', {
13
+ shouldAutoHandleDependencies: true,
14
+ }).execute({})
15
+
16
+ assert.isFalsy(
17
+ results.errors,
18
+ 'Expected no errors when syncing core schemas in a go project.'
19
+ )
20
+
21
+ return results
22
+ }
23
+ }
@@ -204,7 +204,7 @@ export default class SelectingAnAbstractTestClassTest extends AbstractTestTest {
204
204
 
205
205
  await assert.doesThrowAsync(
206
206
  () => this.Service('command').execute('yarn test'),
207
- /Expected: false/gis
207
+ /Expected: true/gis
208
208
  )
209
209
  }
210
210
 
@@ -1,6 +1,8 @@
1
1
  import { test, assert } from '@sprucelabs/test-utils'
2
2
  import { random, uniq } from 'lodash'
3
+ import FeatureInstallerFactory from '../../../features/FeatureInstallerFactory'
3
4
  import UpdateDependenciesAction from '../../../features/node/actions/UpdateDependenciesAction'
5
+ import SkillFeature from '../../../features/skill/SkillFeature'
4
6
  import CommandServiceImpl from '../../../services/CommandService'
5
7
  import AbstractCliTest from '../../../tests/AbstractCliTest'
6
8
  import { NpmPackage } from '../../../types/cli.types'
@@ -10,6 +12,7 @@ export default class UpdateDependencies2Test extends AbstractCliTest {
10
12
 
11
13
  protected static async beforeEach() {
12
14
  await super.beforeEach()
15
+ FeatureInstallerFactory.setFeature('skill', SpySkillFeature)
13
16
  this.action = this.Action('node', 'updateDependencies')
14
17
  }
15
18
 
@@ -19,8 +22,12 @@ export default class UpdateDependencies2Test extends AbstractCliTest {
19
22
 
20
23
  this.Service('pkg').set({ path: 'dependencies.axios', value: '0.0.1' })
21
24
 
22
- const skill = this.featureInstaller.getFeature('skill')
23
- skill.packageDependencies.push({
25
+ debugger
26
+ const skill = this.featureInstaller.getFeature(
27
+ 'skill'
28
+ ) as SpySkillFeature
29
+
30
+ skill.addPackageDependency({
24
31
  name: 'axios',
25
32
  version: '0.21.3',
26
33
  })
@@ -141,3 +148,9 @@ export default class UpdateDependencies2Test extends AbstractCliTest {
141
148
  return name
142
149
  }
143
150
  }
151
+
152
+ class SpySkillFeature extends SkillFeature {
153
+ public addPackageDependency(dependency: NpmPackage) {
154
+ this._packageDependencies.push(dependency)
155
+ }
156
+ }
@@ -1,4 +1,5 @@
1
- import { test, assert } from '@sprucelabs/test-utils'
1
+ import { diskUtil, namesUtil, randomUtil } from '@sprucelabs/spruce-skill-utils'
2
+ import { test, assert, generateId } from '@sprucelabs/test-utils'
2
3
  import { errorAssert } from '@sprucelabs/test-utils'
3
4
  import SkillStoreImpl from '../../features/skill/stores/SkillStore'
4
5
  import AbstractCliTest from '../../tests/AbstractCliTest'
@@ -115,6 +116,48 @@ export default class SkillStoreTest extends AbstractCliTest {
115
116
  assert.isEqual(namespace, slug)
116
117
  }
117
118
 
119
+ @test()
120
+ protected static async returnsExpectedModuleInGoProject() {
121
+ const name = await this.initRandomGoProject()
122
+ await this.assertCurrentNamespaceEquals(name)
123
+ }
124
+
125
+ @test()
126
+ protected static async canFindGoModuleInSubdirectory() {
127
+ const name = await this.initRandomGoProject()
128
+ const newCwd = this.resolvePath(this.cwd, generateId())
129
+ diskUtil.createDir(newCwd)
130
+ this.setCwd(newCwd)
131
+ this.store = this.SkillStore()
132
+ await this.assertCurrentNamespaceEquals(name)
133
+ }
134
+
135
+ @test()
136
+ protected static async throwsNotInGoModuleErrorIfNotInGoProject() {
137
+ const err = await assert.doesThrowAsync(() =>
138
+ this.store.getGoModuleName()
139
+ )
140
+ errorAssert.assertError(err, 'DIRECTORY_NOT_GO_MODULE', {
141
+ cwd: this.cwd,
142
+ })
143
+ }
144
+
145
+ private static async assertCurrentNamespaceEquals(name: string) {
146
+ const actual = await this.store.loadCurrentSkillsNamespace()
147
+
148
+ assert.isEqual(
149
+ actual,
150
+ namesUtil.toPascal(name),
151
+ 'Expected namespace to match go module name'
152
+ )
153
+ }
154
+
155
+ private static async initRandomGoProject() {
156
+ const name = randomUtil.rand(['my-skill', 'superSkill', 'AwesomeSkill'])
157
+ await this.go.initGoProject(name)
158
+ return name
159
+ }
160
+
118
161
  private static SkillStore(): SkillStoreImpl {
119
162
  return this.Store('skill', {})
120
163
  }
@@ -1,9 +1,63 @@
1
1
  import { SpruceSchemas } from '@sprucelabs/mercury-types'
2
+ import { Organization } from '@sprucelabs/spruce-core-schemas'
2
3
  import { eventFaker } from '@sprucelabs/spruce-test-fixtures'
3
4
  import { generateId } from '@sprucelabs/test-utils'
4
5
  import { ListPermContractsTargetAndPayload } from '../../features/permission/stores/PermissionStore'
5
6
 
6
7
  export default class EventFaker {
8
+ public async fakeSyncPermissionContracts() {
9
+ await eventFaker.on('sync-permission-contracts::v2020_12_25', () => {
10
+ return {
11
+ contractRecords: [],
12
+ }
13
+ })
14
+ }
15
+ public async fakeRegisterEvents(cb?: () => void) {
16
+ await eventFaker.on('register-events::v2020_12_25', () => {
17
+ cb?.()
18
+ return {
19
+ fqens: [],
20
+ }
21
+ })
22
+ }
23
+ public async fakeGetEventContracts() {
24
+ await eventFaker.on('get-event-contracts::v2020_12_25', () => {
25
+ return {
26
+ contracts: [
27
+ {
28
+ id: generateId(),
29
+ eventSignatures: {},
30
+ },
31
+ ],
32
+ }
33
+ })
34
+ }
35
+ public async fakeCreateOrganization(
36
+ cb?: (
37
+ targetAndPayload: CreateOrganizationTargetAndPayload
38
+ ) => void | Organization
39
+ ) {
40
+ await eventFaker.on(
41
+ 'create-organization::v2020_12_25',
42
+ (targetAndPayload) => {
43
+ return {
44
+ organization:
45
+ cb?.(targetAndPayload) ??
46
+ this.generateOrganizationValues(),
47
+ }
48
+ }
49
+ )
50
+ }
51
+
52
+ public generateOrganizationValues(): Organization {
53
+ return {
54
+ id: generateId(),
55
+ name: generateId(),
56
+ slug: generateId(),
57
+ dateCreated: Date.now(),
58
+ }
59
+ }
60
+
7
61
  public async fakeListSkills(cb?: () => void | ListSkill[]) {
8
62
  await eventFaker.on('list-skills::v2020_12_25', () => {
9
63
  return {
@@ -52,3 +106,5 @@ export default class EventFaker {
52
106
  }
53
107
 
54
108
  export type ListSkill = SpruceSchemas.Mercury.v2020_12_25.ListSkillsSkill
109
+ export type CreateOrganizationTargetAndPayload =
110
+ SpruceSchemas.Mercury.v2020_12_25.CreateOrganizationEmitTargetAndPayload
package/src/cli/Cli.ts CHANGED
@@ -7,6 +7,7 @@ import { SpruceSchemas } from '@sprucelabs/mercury-types'
7
7
  import {
8
8
  HealthCheckResults,
9
9
  HEALTH_DIVIDER,
10
+ SettingsService,
10
11
  } from '@sprucelabs/spruce-skill-utils'
11
12
  import { templates } from '@sprucelabs/spruce-templates'
12
13
  import { DEFAULT_HOST } from '../constants'
@@ -183,19 +184,19 @@ export default class Cli implements CliInterface {
183
184
  new TerminalInterface(cwd)) as GraphicsInterface
184
185
  let featureInstaller: FeatureInstaller | undefined
185
186
 
187
+ const settings = services.Service(cwd, 'settings')
188
+
186
189
  const writerFactory = new WriterFactory({
187
190
  templates,
188
191
  ui,
189
- settings: services.Service(cwd, 'settings'),
192
+ settings,
190
193
  linter: services.Service(cwd, 'lint'),
191
194
  })
192
195
 
193
196
  const pkg = services.Service(cwd, 'pkg')
194
197
 
195
- const optionOverrides = this.loadOptionOverrides(pkg)
196
- const blockedCommands = this.loadCommandBlocks(
197
- services.Service(cwd, 'pkg')
198
- )
198
+ const optionOverrides = this.loadOptionOverrides(pkg, settings)
199
+ const blockedCommands = this.loadCommandBlocks(pkg)
199
200
 
200
201
  try {
201
202
  const s = pkg.getSkillNamespace()
@@ -287,17 +288,24 @@ export default class Cli implements CliInterface {
287
288
  return blocks
288
289
  }
289
290
 
290
- private static loadOptionOverrides(pkg: PkgService): OptionOverrides {
291
+ private static loadOptionOverrides(
292
+ pkg: PkgService,
293
+ settings: SettingsService
294
+ ): OptionOverrides {
291
295
  const mapped: OptionOverrides = {}
296
+ let overrides: Record<string, string> = {}
292
297
 
293
298
  if (pkg.doesExist()) {
294
- const overrides = pkg.get('skill.commandOverrides')
295
-
296
- Object.keys(overrides ?? {}).forEach((command) => {
297
- const options = argParserUtil.parse(overrides[command])
298
- mapped[command] = options
299
- })
299
+ overrides = pkg.get('skill.commandOverrides')
300
300
  }
301
+
302
+ overrides = { ...settings.get('commandOverrides'), ...overrides }
303
+
304
+ Object.keys(overrides ?? {}).forEach((command) => {
305
+ const options = argParserUtil.parse(overrides[command])
306
+ mapped[command] = options
307
+ })
308
+
301
309
  return mapped
302
310
  }
303
311
 
@@ -281,6 +281,10 @@ export default class SpruceError extends AbstractSpruceError<ErrorOptions> {
281
281
  message = `You already registerd an AI Agent at ${options.promptPath}. If you want to register a new one, delete that file first.`
282
282
  break
283
283
 
284
+ case 'DIRECTORY_NOT_GO_MODULE':
285
+ message = 'A Directory not go module just happened!'
286
+ break
287
+
284
288
  default:
285
289
  message = super.friendlyMessage()
286
290
  }