@sprucelabs/spruce-cli 22.3.0 → 23.0.0

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 (93) hide show
  1. package/.env +1 -1
  2. package/.eslintcache +1 -1
  3. package/build/.spruce/errors/errors.types.d.ts +4 -4
  4. package/build/.spruce/errors/options.types.d.ts +3 -3
  5. package/build/.spruce/errors/spruceCli/appControllerAlreadyExists.schema.d.ts +3 -0
  6. package/build/.spruce/errors/spruceCli/appControllerAlreadyExists.schema.js +12 -0
  7. package/build/.spruce/errors/spruceCli/appControllerAlreadyExists.schema.js.map +1 -0
  8. package/build/.spruce/schemas/schemas.types.d.ts +2 -4
  9. package/build/__tests__/behavioral/onboard/StartingOnboarding.test.js +17 -7
  10. package/build/__tests__/behavioral/onboard/StartingOnboarding.test.js.map +1 -1
  11. package/build/__tests__/behavioral/schemas/HandlesRelatedSchemas.test.js +1 -1
  12. package/build/__tests__/behavioral/schemas/HandlesRelatedSchemas.test.js.map +1 -1
  13. package/build/__tests__/behavioral/schemas/UsingSchemasInCli.test.js +17 -7
  14. package/build/__tests__/behavioral/schemas/UsingSchemasInCli.test.js.map +1 -1
  15. package/build/__tests__/behavioral/views/{CreatingAnAppViewController.test.d.ts → CreatingAnAppController.test.d.ts} +9 -5
  16. package/build/__tests__/behavioral/views/{CreatingAnAppViewController.test.js → CreatingAnAppController.test.js} +63 -34
  17. package/build/__tests__/behavioral/views/CreatingAnAppController.test.js.map +1 -0
  18. package/build/__tests__/behavioral/views/CreatingViewControllers.test.d.ts +5 -0
  19. package/build/__tests__/behavioral/views/CreatingViewControllers.test.js +37 -0
  20. package/build/__tests__/behavioral/views/CreatingViewControllers.test.js.map +1 -0
  21. package/build/__tests__/behavioral/views/KeepingViewsInSync.test.d.ts +1 -0
  22. package/build/__tests__/behavioral/views/KeepingViewsInSync.test.js +14 -0
  23. package/build/__tests__/behavioral/views/KeepingViewsInSync.test.js.map +1 -1
  24. package/build/__tests__/behavioral/watchers/WatchingForChanges.test.js +5 -10
  25. package/build/__tests__/behavioral/watchers/WatchingForChanges.test.js.map +1 -1
  26. package/build/__tests__/implementation/ArgParser.test.js +17 -7
  27. package/build/__tests__/implementation/ArgParser.test.js.map +1 -1
  28. package/build/__tests__/implementation/BulkImporting.test.js +17 -7
  29. package/build/__tests__/implementation/BulkImporting.test.js.map +1 -1
  30. package/build/__tests__/implementation/CommanderCommandResultMapper.test.js +17 -7
  31. package/build/__tests__/implementation/CommanderCommandResultMapper.test.js.map +1 -1
  32. package/build/__tests__/implementation/EventContractCleanerUtil.test.js +17 -7
  33. package/build/__tests__/implementation/EventContractCleanerUtil.test.js.map +1 -1
  34. package/build/__tests__/implementation/FeaturesUtil.test.js +17 -7
  35. package/build/__tests__/implementation/FeaturesUtil.test.js.map +1 -1
  36. package/build/__tests__/implementation/JestJsonParser.test.js +17 -7
  37. package/build/__tests__/implementation/JestJsonParser.test.js.map +1 -1
  38. package/build/__tests__/implementation/SchemaValueTypeWriter.test.js +1 -1
  39. package/build/__tests__/implementation/SchemaValueTypeWriter.test.js.map +1 -1
  40. package/build/__tests__/implementation/TerminalInterface.test.js +17 -7
  41. package/build/__tests__/implementation/TerminalInterface.test.js.map +1 -1
  42. package/build/errors/SpruceError.js +2 -2
  43. package/build/errors/SpruceError.js.map +1 -1
  44. package/build/errors/{appViewControllerAlreadyExists.builder.js → appControllerAlreadyExists.builder.js} +2 -2
  45. package/build/errors/appControllerAlreadyExists.builder.js.map +1 -0
  46. package/build/features/skill/actions/InstallFeatureAction.js +1 -0
  47. package/build/features/skill/actions/InstallFeatureAction.js.map +1 -1
  48. package/build/features/validateAndNormalize.utility.js.map +1 -1
  49. package/build/features/view/actions/CreateAppAction.js +4 -3
  50. package/build/features/view/actions/CreateAppAction.js.map +1 -1
  51. package/build/features/view/actions/SyncAction.js +6 -6
  52. package/build/features/view/actions/SyncAction.js.map +1 -1
  53. package/build/features/view/writers/ViewWriter.d.ts +2 -1
  54. package/build/features/view/writers/ViewWriter.js +15 -8
  55. package/build/features/view/writers/ViewWriter.js.map +1 -1
  56. package/build/features/watch/WatchFeature.js +1 -2
  57. package/build/features/watch/WatchFeature.js.map +1 -1
  58. package/build/tests/AbstractCliTest.js +17 -7
  59. package/build/tests/AbstractCliTest.js.map +1 -1
  60. package/build/tests/cleanTestData.js +17 -7
  61. package/build/tests/cleanTestData.js.map +1 -1
  62. package/build/utilities/introspection.utility.js +17 -7
  63. package/build/utilities/introspection.utility.js.map +1 -1
  64. package/junit.xml +8 -1773
  65. package/package.json +30 -30
  66. package/src/.spruce/errors/errors.types.ts +4 -4
  67. package/src/.spruce/errors/options.types.ts +3 -3
  68. package/src/.spruce/errors/spruceCli/appControllerAlreadyExists.schema.ts +16 -0
  69. package/src/.spruce/schemas/schemas.types.ts +1 -1
  70. package/src/__tests__/behavioral/schemas/HandlesRelatedSchemas.test.ts +1 -1
  71. package/src/__tests__/behavioral/views/{CreatingAnAppViewController.test.ts → CreatingAnAppController.test.ts} +57 -25
  72. package/src/__tests__/behavioral/views/CreatingViewControllers.test.ts +28 -0
  73. package/src/__tests__/behavioral/views/KeepingViewsInSync.test.ts +16 -0
  74. package/src/__tests__/behavioral/watchers/WatchingForChanges.test.ts +6 -11
  75. package/src/__tests__/implementation/SchemaValueTypeWriter.test.ts +1 -1
  76. package/src/errors/SpruceError.ts +2 -2
  77. package/src/errors/{appViewControllerAlreadyExists.builder.ts → appControllerAlreadyExists.builder.ts} +1 -1
  78. package/src/features/skill/actions/InstallFeatureAction.ts +3 -0
  79. package/src/features/validateAndNormalize.utility.ts +2 -1
  80. package/src/features/view/actions/CreateAppAction.ts +8 -3
  81. package/src/features/view/actions/SyncAction.ts +12 -8
  82. package/src/features/view/writers/ViewWriter.ts +34 -9
  83. package/src/features/watch/WatchFeature.ts +2 -3
  84. package/build/.spruce/errors/spruceCli/appViewControllerAlreadyExists.schema.d.ts +0 -3
  85. package/build/.spruce/errors/spruceCli/appViewControllerAlreadyExists.schema.js +0 -12
  86. package/build/.spruce/errors/spruceCli/appViewControllerAlreadyExists.schema.js.map +0 -1
  87. package/build/__tests__/behavioral/views/CreatingAnAppViewController.test.js.map +0 -1
  88. package/build/errors/appViewControllerAlreadyExists.builder.js.map +0 -1
  89. package/build/features/skill/actions/InstallFeature.d.ts +0 -0
  90. package/build/features/skill/actions/InstallFeature.js +0 -2
  91. package/build/features/skill/actions/InstallFeature.js.map +0 -1
  92. package/src/.spruce/errors/spruceCli/appViewControllerAlreadyExists.schema.ts +0 -16
  93. /package/build/errors/{appViewControllerAlreadyExists.builder.d.ts → appControllerAlreadyExists.builder.d.ts} +0 -0
package/package.json CHANGED
@@ -17,7 +17,7 @@
17
17
  ]
18
18
  },
19
19
  "license": "MIT",
20
- "version": "22.3.0",
20
+ "version": "23.0.0",
21
21
  "bin": {
22
22
  "spruce": "./build/index.js"
23
23
  },
@@ -73,23 +73,23 @@
73
73
  },
74
74
  "dependencies": {
75
75
  "@jest/reporters": "^29.7.0",
76
- "@sprucelabs/error": "^6.0.537",
77
- "@sprucelabs/globby": "^2.0.498",
78
- "@sprucelabs/heartwood-view-controllers": "^111.1.0",
79
- "@sprucelabs/jest-json-reporter": "^8.0.538",
80
- "@sprucelabs/mercury-client": "^42.0.590",
81
- "@sprucelabs/mercury-event-emitter": "^42.0.590",
82
- "@sprucelabs/mercury-types": "^47.0.594",
83
- "@sprucelabs/schema": "^30.0.553",
84
- "@sprucelabs/spruce-core-schemas": "^40.1.540",
85
- "@sprucelabs/spruce-event-utils": "^40.1.314",
86
- "@sprucelabs/spruce-skill-utils": "^31.0.614",
87
- "@sprucelabs/spruce-templates": "^22.3.0",
76
+ "@sprucelabs/error": "^6.0.556",
77
+ "@sprucelabs/globby": "^2.0.501",
78
+ "@sprucelabs/heartwood-view-controllers": "^113.0.1",
79
+ "@sprucelabs/jest-json-reporter": "^8.0.558",
80
+ "@sprucelabs/mercury-client": "^42.0.658",
81
+ "@sprucelabs/mercury-event-emitter": "^42.0.658",
82
+ "@sprucelabs/mercury-types": "^47.0.640",
83
+ "@sprucelabs/schema": "^31.0.3",
84
+ "@sprucelabs/spruce-core-schemas": "^40.1.585",
85
+ "@sprucelabs/spruce-event-utils": "^40.1.369",
86
+ "@sprucelabs/spruce-skill-utils": "^31.1.8",
87
+ "@sprucelabs/spruce-templates": "^23.0.0",
88
88
  "@typescript-eslint/eslint-plugin": "^7.7.1",
89
89
  "@typescript-eslint/parser": "^7.7.1",
90
90
  "cfonts": "^3.3.0",
91
91
  "chalk": "4.1.2",
92
- "chokidar": "^4.0.1",
92
+ "chokidar": "^4.0.3",
93
93
  "cli-table3": "^0.6.5",
94
94
  "commander": "7.2.0",
95
95
  "emphasize": "4.2.0",
@@ -106,27 +106,27 @@
106
106
  "terminal-kit": "sprucelabsai/terminal-kit",
107
107
  "tree-kill": "^1.2.2",
108
108
  "tsutils": "^3.21.0",
109
- "typescript": "^5.6.3",
110
- "uuid": "^11.0.2"
109
+ "typescript": "^5.7.2",
110
+ "uuid": "^11.0.3"
111
111
  },
112
112
  "devDependencies": {
113
- "@sprucelabs/data-stores": "^28.3.207",
114
- "@sprucelabs/jest-sheets-reporter": "^3.0.182",
115
- "@sprucelabs/mercury-core-events": "^25.0.35",
116
- "@sprucelabs/resolve-path-aliases": "^2.0.513",
117
- "@sprucelabs/spruce-conversation-plugin": "^62.4.2",
118
- "@sprucelabs/spruce-deploy-plugin": "^62.4.2",
119
- "@sprucelabs/spruce-store-plugin": "^62.4.2",
120
- "@sprucelabs/spruce-test-fixtures": "^62.4.2",
121
- "@sprucelabs/test": "^9.0.57",
122
- "@sprucelabs/test-utils": "^5.1.496",
113
+ "@sprucelabs/data-stores": "^28.3.281",
114
+ "@sprucelabs/jest-sheets-reporter": "^3.0.197",
115
+ "@sprucelabs/mercury-core-events": "^25.0.104",
116
+ "@sprucelabs/resolve-path-aliases": "^2.0.523",
117
+ "@sprucelabs/spruce-conversation-plugin": "^62.6.12",
118
+ "@sprucelabs/spruce-deploy-plugin": "^62.6.12",
119
+ "@sprucelabs/spruce-store-plugin": "^62.6.12",
120
+ "@sprucelabs/spruce-test-fixtures": "^62.6.12",
121
+ "@sprucelabs/test": "^9.0.64",
122
+ "@sprucelabs/test-utils": "^5.1.529",
123
123
  "@types/blessed": "^0.1.25",
124
124
  "@types/eslint": "^9.6.1",
125
125
  "@types/fs-extra": "^11.0.4",
126
126
  "@types/inquirer": "^9.0.7",
127
127
  "@types/lodash": "^4.17.13",
128
128
  "@types/md5": "^2.3.5",
129
- "@types/node": "^22.8.7",
129
+ "@types/node": "^22.10.2",
130
130
  "@types/promise.allsettled": "^1.0.6",
131
131
  "@types/ps-node": "^0.1.3",
132
132
  "@types/semver": "^7.5.8",
@@ -138,8 +138,8 @@
138
138
  "chokidar-cli": "^3.0.0",
139
139
  "concurrently": "^9.1.0",
140
140
  "conventional-changelog-sprucelabs": "2.0.1",
141
- "dotenv": "^16.4.5",
142
- "eslint": "^9.14.0",
141
+ "dotenv": "^16.4.7",
142
+ "eslint": "^9.17.0",
143
143
  "eslint-config-spruce": "^11.2.26",
144
144
  "find-process": "^1.4.7",
145
145
  "jest": "^29.7.0",
@@ -150,7 +150,7 @@
150
150
  "ps-node": "^0.1.6",
151
151
  "ts-jest": "^29.2.5",
152
152
  "ts-node": "^10.9.2",
153
- "tsc-watch": "^6.2.0",
153
+ "tsc-watch": "^6.2.1",
154
154
  "tsconfig-paths": "^4.2.0"
155
155
  },
156
156
  "testSkillCache": {
@@ -1293,19 +1293,19 @@ export declare namespace SpruceErrors.SpruceCli {
1293
1293
  export declare namespace SpruceErrors.SpruceCli {
1294
1294
 
1295
1295
 
1296
- export interface AppViewControllerAlreadyExists {
1296
+ export interface AppControllerAlreadyExists {
1297
1297
 
1298
1298
  }
1299
1299
 
1300
- export interface AppViewControllerAlreadyExistsSchema extends SpruceSchema.Schema {
1301
- id: 'appViewControllerAlreadyExists',
1300
+ export interface AppControllerAlreadyExistsSchema extends SpruceSchema.Schema {
1301
+ id: 'appControllerAlreadyExists',
1302
1302
  namespace: 'SpruceCli',
1303
1303
  name: 'App view controller already exists',
1304
1304
  fields: {
1305
1305
  }
1306
1306
  }
1307
1307
 
1308
- export type AppViewControllerAlreadyExistsEntity = SchemaEntity<SpruceErrors.SpruceCli.AppViewControllerAlreadyExistsSchema>
1308
+ export type AppControllerAlreadyExistsEntity = SchemaEntity<SpruceErrors.SpruceCli.AppControllerAlreadyExistsSchema>
1309
1309
 
1310
1310
  }
1311
1311
 
@@ -124,13 +124,13 @@ export interface BuildFailedErrorOptions extends SpruceErrors.SpruceCli.BuildFai
124
124
  export interface BootErrorErrorOptions extends SpruceErrors.SpruceCli.BootError, ISpruceErrorOptions {
125
125
  code: 'BOOT_ERROR'
126
126
  }
127
- export interface AppViewControllerAlreadyExistsErrorOptions extends SpruceErrors.SpruceCli.AppViewControllerAlreadyExists, ISpruceErrorOptions {
128
- code: 'APP_VIEW_CONTROLLER_ALREADY_EXISTS'
127
+ export interface AppControllerAlreadyExistsErrorOptions extends SpruceErrors.SpruceCli.AppControllerAlreadyExists, ISpruceErrorOptions {
128
+ code: 'APP_CONTROLLER_ALREADY_EXISTS'
129
129
  }
130
130
  export interface ActionCancelledErrorOptions extends SpruceErrors.SpruceCli.ActionCancelled, ISpruceErrorOptions {
131
131
  code: 'ACTION_CANCELLED'
132
132
  }
133
133
 
134
- type ErrorOptions = | VscodeNotInstalledErrorOptions | ViewPluginAlreadyExistsErrorOptions | TransportAlreadyExistsErrorOptions | ThemeExistsErrorOptions | TestFailedErrorOptions | StoreExistsErrorOptions | SkillViewExistsErrorOptions | SkillNotRegisteredErrorOptions | SkillNotFoundErrorOptions | SchemaTemplateItemBuildingFailedErrorOptions | SchemaFailedToImportErrorOptions | SchemaExistsErrorOptions | NotLoggedInErrorOptions | NotImplementedErrorOptions | NoSkillsRegisteredErrorOptions | NoOrganizationsFoundErrorOptions | MissingDependenciesErrorOptions | MercuryResponseErrorErrorOptions | LintFailedErrorOptions | InvalidTestDirectoryErrorOptions | InvalidFeatureCodeErrorOptions | InvalidEventContractErrorOptions | InvalidCommandErrorOptions | GenericErrorOptions | FileExistsErrorOptions | FeatureNotInstalledErrorOptions | FailedToImportErrorOptions | ExecutingCommandFailedErrorOptions | DockerNotStartedErrorOptions | DirectoryNotSkillErrorOptions | DirectoryEmptyErrorOptions | DeployFailedErrorOptions | DependencyExistsErrorOptions | CreateAutoloaderFailedErrorOptions | CommandNotImplementedErrorOptions | CommandBlockedErrorOptions | CommandAbortedErrorOptions | CannotPromptInCiErrorOptions | CacheNotEnabledErrorOptions | BuildFailedErrorOptions | BootErrorErrorOptions | AppViewControllerAlreadyExistsErrorOptions | ActionCancelledErrorOptions
134
+ type ErrorOptions = | VscodeNotInstalledErrorOptions | ViewPluginAlreadyExistsErrorOptions | TransportAlreadyExistsErrorOptions | ThemeExistsErrorOptions | TestFailedErrorOptions | StoreExistsErrorOptions | SkillViewExistsErrorOptions | SkillNotRegisteredErrorOptions | SkillNotFoundErrorOptions | SchemaTemplateItemBuildingFailedErrorOptions | SchemaFailedToImportErrorOptions | SchemaExistsErrorOptions | NotLoggedInErrorOptions | NotImplementedErrorOptions | NoSkillsRegisteredErrorOptions | NoOrganizationsFoundErrorOptions | MissingDependenciesErrorOptions | MercuryResponseErrorErrorOptions | LintFailedErrorOptions | InvalidTestDirectoryErrorOptions | InvalidFeatureCodeErrorOptions | InvalidEventContractErrorOptions | InvalidCommandErrorOptions | GenericErrorOptions | FileExistsErrorOptions | FeatureNotInstalledErrorOptions | FailedToImportErrorOptions | ExecutingCommandFailedErrorOptions | DockerNotStartedErrorOptions | DirectoryNotSkillErrorOptions | DirectoryEmptyErrorOptions | DeployFailedErrorOptions | DependencyExistsErrorOptions | CreateAutoloaderFailedErrorOptions | CommandNotImplementedErrorOptions | CommandBlockedErrorOptions | CommandAbortedErrorOptions | CannotPromptInCiErrorOptions | CacheNotEnabledErrorOptions | BuildFailedErrorOptions | BootErrorErrorOptions | AppControllerAlreadyExistsErrorOptions | ActionCancelledErrorOptions
135
135
 
136
136
  export default ErrorOptions
@@ -0,0 +1,16 @@
1
+ import { SchemaRegistry } from '@sprucelabs/schema'
2
+ import { SpruceErrors } from '../errors.types'
3
+
4
+
5
+
6
+ const appControllerAlreadyExistsSchema: SpruceErrors.SpruceCli.AppControllerAlreadyExistsSchema = {
7
+ id: 'appControllerAlreadyExists',
8
+ namespace: 'SpruceCli',
9
+ name: 'App view controller already exists',
10
+ fields: {
11
+ }
12
+ }
13
+
14
+ SchemaRegistry.getInstance().trackSchema(appControllerAlreadyExistsSchema)
15
+
16
+ export default appControllerAlreadyExistsSchema
@@ -75,7 +75,7 @@ declare module '@sprucelabs/spruce-core-schemas/build/.spruce/schemas/core.schem
75
75
  interface WatcherDidDetectChangesEmitPayload {
76
76
 
77
77
 
78
- 'changes': ({ schemaId: 'generatedFile', version: 'v2020_07_22', values: SpruceSchemas.SpruceCli.v2020_07_22.GeneratedFile } | { schemaId: 'generatedDir', version: 'v2020_07_22', values: SpruceSchemas.SpruceCli.v2020_07_22.GeneratedDir })[]
78
+ 'changes': ({ id: 'generatedFile', values: SpruceSchemas.SpruceCli.v2020_07_22.GeneratedFile } | { id: 'generatedDir', values: SpruceSchemas.SpruceCli.v2020_07_22.GeneratedDir })[]
79
79
  }
80
80
 
81
81
  interface WatcherDidDetectChangesEmitPayloadSchema extends SpruceSchema.Schema {
@@ -48,7 +48,7 @@ export default class HandlesRelatedSchemasTest extends AbstractSchemaTest {
48
48
 
49
49
  assert.doesInclude(
50
50
  typesContent,
51
- "[fullyQualifiedEventName:string]: { schemaId: 'eventSignature', version: 'v2020_07_22', values: SpruceSchemas.TestingSchemas.v2020_07_22.EventSignature } | { schemaId: 'eventSignature2', version: 'v2020_07_22', values: SpruceSchemas.TestingSchemas.v2020_07_22.EventSignature2 }"
51
+ "[fullyQualifiedEventName:string]: { id: 'eventSignature', values: SpruceSchemas.TestingSchemas.v2020_07_22.EventSignature } | { id: 'eventSignature2', values: SpruceSchemas.TestingSchemas.v2020_07_22.EventSignature2 }"
52
52
  )
53
53
 
54
54
  await this.Service('typeChecker').check(typesPath)
@@ -1,12 +1,13 @@
1
- import { diskUtil } from '@sprucelabs/spruce-skill-utils'
1
+ import { diskUtil, namesUtil } from '@sprucelabs/spruce-skill-utils'
2
2
  import { test, assert, errorAssert, generateId } from '@sprucelabs/test-utils'
3
3
  import CreateAppAction from '../../../features/view/actions/CreateAppAction'
4
4
  import AbstractSkillTest from '../../../tests/AbstractSkillTest'
5
5
  import testUtil from '../../../tests/utilities/test.utility'
6
6
 
7
- export default class CreatingAnAppViewControllerTest extends AbstractSkillTest {
7
+ export default class CreatingAnAppControllerTest extends AbstractSkillTest {
8
8
  protected static skillCacheKey = 'views'
9
- private static avcPath: string
9
+ private static acPath: string
10
+ private static skillNamespace = generateId().replace(/\d/g, '')
10
11
 
11
12
  private static action: CreateAppAction
12
13
  private static lastExecution: {
@@ -16,7 +17,9 @@ export default class CreatingAnAppViewControllerTest extends AbstractSkillTest {
16
17
 
17
18
  protected static async beforeAll(): Promise<void> {
18
19
  await super.beforeAll()
19
- this.avcPath = this.resolvePath('src/App.avc.ts')
20
+ this.acPath = this.resolvePath('src/App.ac.ts')
21
+ const pgk = this.Service('pkg')
22
+ pgk.set({ path: 'skill.namespace', value: this.skillNamespace })
20
23
  }
21
24
 
22
25
  protected static async beforeEach(): Promise<void> {
@@ -33,12 +36,12 @@ export default class CreatingAnAppViewControllerTest extends AbstractSkillTest {
33
36
  const results = await this.execute()
34
37
  assert.isFalsy(results.errors)
35
38
 
36
- testUtil.assertFileByPathInGeneratedFiles(this.avcPath, results.files)
39
+ testUtil.assertFileByPathInGeneratedFiles(this.acPath, results.files)
37
40
 
38
41
  assert.doesInclude(results.files, {
39
42
  action: 'generated',
40
- name: 'App.avc.ts',
41
- path: this.avcPath,
43
+ name: 'App.ac.ts',
44
+ path: this.acPath,
42
45
  })
43
46
 
44
47
  assert.doesInclude(results.files, {
@@ -50,7 +53,6 @@ export default class CreatingAnAppViewControllerTest extends AbstractSkillTest {
50
53
 
51
54
  @test()
52
55
  protected static async syncsViewsOnCreation() {
53
- debugger
54
56
  assert.doesInclude(this.lastExecution, {
55
57
  actionCode: 'sync',
56
58
  featureCode: 'view',
@@ -68,22 +70,22 @@ export default class CreatingAnAppViewControllerTest extends AbstractSkillTest {
68
70
  }
69
71
 
70
72
  @test()
71
- protected static async avcIncludesExpectedContents() {
72
- const contents = diskUtil.readFile(this.avcPath)
73
+ protected static async acIncludesExpectedContents() {
74
+ const contents = diskUtil.readFile(this.acPath)
73
75
  assert.doesInclude(
74
76
  contents,
75
- 'export default class AppViewControllerImpl extends AbstractAppViewController'
77
+ `export default class ${this.className} extends AbstractAppController`
76
78
  )
77
79
 
78
80
  assert.doesInclude(
79
81
  contents,
80
- 'public async (_options: AppViewControllerLoadOptions)'
82
+ 'public async load(_options: AppControllerLoadOptions)'
81
83
  )
82
84
  }
83
85
 
84
86
  @test()
85
87
  protected static async generatedFilesAreValid() {
86
- await this.Service('typeChecker').check(this.avcPath)
88
+ await this.Service('typeChecker').check(this.acPath)
87
89
  await this.assertCombinedViewsFileIsValid()
88
90
  }
89
91
 
@@ -96,36 +98,62 @@ export default class CreatingAnAppViewControllerTest extends AbstractSkillTest {
96
98
  @test()
97
99
  protected static async callsHeartwoodImportFunctionAsExpected() {
98
100
  this.assertCombinedViewsContains(
99
- 'heartwood({ vcs, pluginsByName, App: AppViewControllerImpl })'
101
+ `heartwood({ vcs, pluginsByName, App: ${this.className} })`
100
102
  )
101
103
  }
102
104
 
103
105
  @test()
104
- protected static async throwsEvenIfAppAvcMoves() {
105
- const destination = this.resolvePath(`src/${generateId()}/App.avc.ts`)
106
- diskUtil.moveFile(this.avcPath, destination)
106
+ protected static async combineViewsTypesAsExpected() {
107
+ const expected = `interface AppControllerMap {
108
+ '${this.skillNamespace}' : ${this.className}
109
+ }`
110
+
111
+ this.assertCombinedViewsContains(expected)
112
+ }
113
+
114
+ @test()
115
+ protected static async throwsEvenIfAppMoves() {
116
+ const destination = this.resolvePath(`src/${generateId()}/App.ac.ts`)
117
+ diskUtil.moveFile(this.acPath, destination)
107
118
 
108
119
  await this.executeAndAssertThrowsAvcExists()
109
- this.avcPath = destination
120
+ this.acPath = destination
110
121
  }
111
122
 
112
123
  @test()
113
- protected static async canRenameAppAvcAndItUpdatesCombinedViews() {
114
- const contents = diskUtil.readFile(this.avcPath)
124
+ protected static async canRenameAppAndItUpdatesCombinedViews() {
125
+ const contents = diskUtil.readFile(this.acPath)
115
126
  const updatedContents = contents.replace(
116
- 'AppViewControllerImpl',
117
- 'NewAppViewControllerImpl'
127
+ this.className,
128
+ 'NewAppControllerImpl'
118
129
  )
119
- diskUtil.writeFile(this.avcPath, updatedContents)
130
+ diskUtil.writeFile(this.acPath, updatedContents)
120
131
  await this.Action('view', 'sync').execute({})
121
132
 
122
133
  this.assertCombinedViewsContains(
123
- 'heartwood({ vcs, pluginsByName, App: NewAppViewControllerImpl })'
134
+ 'heartwood({ vcs, pluginsByName, App: NewAppControllerImpl })'
124
135
  )
125
136
 
126
137
  await this.assertCombinedViewsFileIsValid()
127
138
  }
128
139
 
140
+ @test()
141
+ protected static async importsAppFromCombinedViews() {
142
+ const testScript =
143
+ `import { App } from '#` +
144
+ `spruce/views/views'
145
+ const app = new App({} as any)
146
+ console.log(app)
147
+ if (App.id !== '${this.skillNamespace}') {
148
+ throw new Error('App.id is not correct')
149
+ }`
150
+
151
+ const testScriptPath = this.resolvePath('src/test.ts')
152
+ diskUtil.writeFile(testScriptPath, testScript)
153
+
154
+ await this.Service('typeChecker').check(testScriptPath)
155
+ }
156
+
129
157
  private static async assertCombinedViewsFileIsValid() {
130
158
  await this.Service('typeChecker').check(this.combinedViewsPath)
131
159
  }
@@ -143,12 +171,16 @@ export default class CreatingAnAppViewControllerTest extends AbstractSkillTest {
143
171
  return this.resolveHashSprucePath('views', 'views.ts')
144
172
  }
145
173
 
174
+ private static get className() {
175
+ return `${namesUtil.toPascal(this.skillNamespace)}AppController`
176
+ }
177
+
146
178
  private static async executeAndAssertThrowsAvcExists() {
147
179
  const results = await this.execute()
148
180
  assert.isTruthy(results.errors)
149
181
  errorAssert.assertError(
150
182
  results.errors[0],
151
- 'APP_VIEW_CONTROLLER_ALREADY_EXISTS'
183
+ 'APP_CONTROLLER_ALREADY_EXISTS'
152
184
  )
153
185
  }
154
186
 
@@ -0,0 +1,28 @@
1
+ import { diskUtil } from '@sprucelabs/spruce-skill-utils'
2
+ import { test, assert } from '@sprucelabs/test-utils'
3
+ import CreateAction from '../../../features/view/actions/CreateAction'
4
+ import AbstractSkillTest from '../../../tests/AbstractSkillTest'
5
+
6
+ export default class CreatingViewControllersTest extends AbstractSkillTest {
7
+ protected static skillCacheKey = 'views'
8
+
9
+ @test()
10
+ protected static async canCreateListViewController() {
11
+ const action = this.Action('view', 'create') as CreateAction
12
+ const results = await action.execute({
13
+ viewType: 'view',
14
+ isRoot: false,
15
+ viewModel: 'List',
16
+ nameReadable: 'My List',
17
+ namePascal: 'MyList',
18
+ })
19
+
20
+ assert.isFalsy(results.errors)
21
+
22
+ const file = results.files?.[0]
23
+ assert.isTruthy(file?.path)
24
+ const contents = diskUtil.readFile(file.path)
25
+
26
+ assert.doesInclude(contents, 'extends AbstractViewController<List>')
27
+ }
28
+ }
@@ -1,3 +1,4 @@
1
+ import { diskUtil } from '@sprucelabs/spruce-skill-utils'
1
2
  import { test, assert } from '@sprucelabs/test-utils'
2
3
  import { FeatureActionResponse } from '../../../features/features.types'
3
4
  import SyncAction from '../../../features/view/actions/SyncAction'
@@ -46,6 +47,21 @@ export default class KeepingViewsInSyncTest extends AbstractSkillTest {
46
47
  await this.assertValuedViewsFile(results)
47
48
  }
48
49
 
50
+ @test()
51
+ protected static async exportUndefinedApp() {
52
+ const testScript =
53
+ `import { App } from '#` +
54
+ `spruce/views/views'
55
+ if (App !== undefined) {
56
+ throw new Error('App should be undefined')
57
+ }`
58
+
59
+ const testScriptPath = this.resolvePath('src/test.ts')
60
+ diskUtil.writeFile(testScriptPath, testScript)
61
+
62
+ await this.Service('typeChecker').check(testScriptPath)
63
+ }
64
+
49
65
  private static async assertValuedViewsFile(results: FeatureActionResponse) {
50
66
  const match = testUtil.assertFileByPathInGeneratedFiles(
51
67
  `views/views.ts`,
@@ -1,4 +1,4 @@
1
- import { CORE_SCHEMA_VERSION, diskUtil } from '@sprucelabs/spruce-skill-utils'
1
+ import { diskUtil } from '@sprucelabs/spruce-skill-utils'
2
2
  import { test, assert } from '@sprucelabs/test-utils'
3
3
  import WatchFeature from '../../../features/watch/WatchFeature'
4
4
  import AbstractCliTest from '../../../tests/AbstractCliTest'
@@ -98,8 +98,7 @@ export default class WatchingForChangesTest extends AbstractCliTest {
98
98
  'console.log("hello world")'
99
99
  )
100
100
  expectedChanges.push({
101
- schemaId: 'generatedFile',
102
- version: CORE_SCHEMA_VERSION.constValue,
101
+ id: 'generatedFile',
103
102
  values: {
104
103
  action: 'generated',
105
104
  path: this.resolvePath('build', filename),
@@ -126,8 +125,7 @@ export default class WatchingForChangesTest extends AbstractCliTest {
126
125
 
127
126
  const expected: GeneratedFileOrDir[] = [
128
127
  {
129
- schemaId: 'generatedDir',
130
- version: 'v2020_07_22',
128
+ id: 'generatedDir',
131
129
  values: {
132
130
  action: 'generated',
133
131
  name: 'new_dir',
@@ -149,8 +147,7 @@ export default class WatchingForChangesTest extends AbstractCliTest {
149
147
 
150
148
  const expected: GeneratedFileOrDir[] = [
151
149
  {
152
- schemaId: 'generatedDir',
153
- version: 'v2020_07_22',
150
+ id: 'generatedDir',
154
151
  values: {
155
152
  action: 'deleted',
156
153
  name: 'new_dir',
@@ -173,8 +170,7 @@ export default class WatchingForChangesTest extends AbstractCliTest {
173
170
 
174
171
  const expected: GeneratedFileOrDir[] = [
175
172
  {
176
- schemaId: 'generatedFile',
177
- version: 'v2020_07_22',
173
+ id: 'generatedFile',
178
174
  values: {
179
175
  action: 'deleted',
180
176
  name: 'test.js',
@@ -199,8 +195,7 @@ export default class WatchingForChangesTest extends AbstractCliTest {
199
195
 
200
196
  const expected: GeneratedFileOrDir[] = [
201
197
  {
202
- schemaId: 'generatedFile',
203
- version: 'v2020_07_22',
198
+ id: 'generatedFile',
204
199
  values: {
205
200
  action: 'deleted',
206
201
  name: 'test.js',
@@ -95,7 +95,7 @@ export default class SchemaValueTypeGenerationTest extends AbstractSchemaTest {
95
95
  'generates dynamic field with nested schemas',
96
96
  `${LOCAL_NAMESPACE}.mercuryContract.${CORE_SCHEMA_VERSION.constValue}.__dynamicFieldSignature.valueTypes`,
97
97
  {
98
- type: `{ schemaId: 'eventSignature', version: 'v2020_07_22', values: SpruceSchemas.${LOCAL_NAMESPACE}.v2020_07_22.EventSignature } | { schemaId: 'eventSignature2', version: 'v2020_07_22', values: SpruceSchemas.${LOCAL_NAMESPACE}.v2020_07_22.EventSignature2 }`,
98
+ type: `{ id: 'eventSignature', values: SpruceSchemas.${LOCAL_NAMESPACE}.v2020_07_22.EventSignature } | { id: 'eventSignature2', values: SpruceSchemas.${LOCAL_NAMESPACE}.v2020_07_22.EventSignature2 }`,
99
99
  value: '[eventSignatureSchema_v2020_07_22, eventSignature2Schema_v2020_07_22]',
100
100
  schemaType: `(SpruceSchemas.${LOCAL_NAMESPACE}.v2020_07_22.EventSignatureSchema | SpruceSchemas.${LOCAL_NAMESPACE}.v2020_07_22.EventSignature2Schema)[]`,
101
101
  }
@@ -273,8 +273,8 @@ export default class SpruceError extends AbstractSpruceError<ErrorOptions> {
273
273
  message = 'A cannot prompt in ci just happened!'
274
274
  break
275
275
 
276
- case 'APP_VIEW_CONTROLLER_ALREADY_EXISTS':
277
- message = `You already have an AppViewController! Run \`spruce sync.views\` if you are having issues.`
276
+ case 'APP_CONTROLLER_ALREADY_EXISTS':
277
+ message = `You already have an AppController! Run \`spruce sync.views\` if you are having issues.`
278
278
  break
279
279
 
280
280
  default:
@@ -1,7 +1,7 @@
1
1
  import { buildErrorSchema } from '@sprucelabs/schema'
2
2
 
3
3
  export default buildErrorSchema({
4
- id: 'appViewControllerAlreadyExists',
4
+ id: 'appControllerAlreadyExists',
5
5
  name: 'App view controller already exists',
6
6
  fields: {},
7
7
  })
@@ -26,6 +26,9 @@ export default class InstallFeatureAction extends AbstractAction<OptionsSchema>
26
26
 
27
27
  code = await this.promptForFeature(choices)
28
28
  }
29
+
30
+ this.ui.startLoading('Installing feature...')
31
+
29
32
  const results = await this.features.install({
30
33
  features: [{ code: code as any }],
31
34
  })
@@ -3,6 +3,7 @@ import {
3
3
  normalizeSchemaValues,
4
4
  Schema,
5
5
  SchemaPartialValues,
6
+ SchemaValues,
6
7
  SchemaValuesWithDefaults,
7
8
  validateSchemaValues,
8
9
  } from '@sprucelabs/schema'
@@ -19,7 +20,7 @@ const validateAndNormalizer = {
19
20
  const values = {
20
21
  ...defaultSchemaValues(schema),
21
22
  ...this.stripUndefined(options),
22
- } as SchemaPartialValues<S, false>
23
+ } as SchemaValues<S>
23
24
 
24
25
  validateSchemaValues(schema, values, {})
25
26
 
@@ -6,11 +6,16 @@ import { FeatureActionResponse } from '../../features.types'
6
6
  export default class CreateAppAction extends AbstractAction<OptionsSchema> {
7
7
  public optionsSchema = optionsSchema
8
8
  public invocationMessage = 'Creating new app view controller... '
9
- public readonly commandAliases = ['create.avc']
9
+ public readonly commandAliases = ['create.avc', 'create.app']
10
10
 
11
11
  public async execute(): Promise<FeatureActionResponse> {
12
12
  const writer = this.Writer('view', {})
13
- const files = await writer.writeAppViewController(this.cwd)
13
+ const id = await this.Store('skill').loadCurrentSkillsNamespace()
14
+ const files = await writer.writeAppController(
15
+ this.cwd,
16
+ id.toLocaleLowerCase(),
17
+ id
18
+ )
14
19
 
15
20
  const results = await this.Action('view', 'sync').execute({})
16
21
  const merged = actionUtil.mergeActionResults(
@@ -25,7 +30,7 @@ export default class CreateAppAction extends AbstractAction<OptionsSchema> {
25
30
  }
26
31
 
27
32
  const optionsSchema = buildSchema({
28
- id: 'createAppViewControllerOptions',
33
+ id: 'createAppControllerOptions',
29
34
  fields: {},
30
35
  })
31
36
 
@@ -19,7 +19,7 @@ export default class SyncAction extends AbstractAction<OptionsSchema> {
19
19
  public async execute(): Promise<FeatureActionResponse> {
20
20
  const targetDir = diskUtil.resolvePath(this.cwd, 'src')
21
21
  const matches = await globby(
22
- ['**/*.svc.ts', '**/*.vc.ts', '**/*.view.plugin.ts', '**/*.avc.ts'],
22
+ ['**/*.svc.ts', '**/*.vc.ts', '**/*.view.plugin.ts', '**/*.ac.ts'],
23
23
  {
24
24
  cwd: targetDir,
25
25
  }
@@ -39,8 +39,12 @@ export default class SyncAction extends AbstractAction<OptionsSchema> {
39
39
 
40
40
  introspect.forEach(({ classes }) => {
41
41
  for (const thisClass of classes) {
42
- const { vc, svc, plugin, avc } =
43
- this.mapIntrospectedClassToTemplateItem(thisClass)
42
+ const {
43
+ vc,
44
+ svc,
45
+ plugin,
46
+ ac: avc,
47
+ } = this.mapIntrospectedClassToTemplateItem(thisClass)
44
48
 
45
49
  if (vc) {
46
50
  vcTemplateItems.push(vc)
@@ -77,7 +81,7 @@ export default class SyncAction extends AbstractAction<OptionsSchema> {
77
81
  vc?: VcTemplateItem
78
82
  svc?: VcTemplateItem
79
83
  plugin?: ViewControllerPluginItem
80
- avc?: VcTemplateItem
84
+ ac?: VcTemplateItem
81
85
  } {
82
86
  const item = {
83
87
  id: c.staticProperties.id,
@@ -87,13 +91,13 @@ export default class SyncAction extends AbstractAction<OptionsSchema> {
87
91
 
88
92
  let vc: VcTemplateItem | undefined
89
93
  let svc: VcTemplateItem | undefined
90
- let avc: VcTemplateItem | undefined
94
+ let ac: VcTemplateItem | undefined
91
95
  let plugin: ViewControllerPluginItem | undefined
92
96
 
93
97
  if (c.classPath.endsWith('.svc.ts')) {
94
98
  svc = item
95
- } else if (c.classPath.endsWith('avc.ts')) {
96
- avc = item
99
+ } else if (c.classPath.endsWith('ac.ts')) {
100
+ ac = item
97
101
  } else if (c.classPath.endsWith('view.plugin.ts')) {
98
102
  const nameCamel = c.classPath.match(/([^/]+).view.plugin.ts$/)![1]
99
103
  plugin = { ...item, nameCamel }
@@ -101,7 +105,7 @@ export default class SyncAction extends AbstractAction<OptionsSchema> {
101
105
  vc = item
102
106
  }
103
107
 
104
- return { svc, vc, plugin, avc }
108
+ return { svc, vc, plugin, ac }
105
109
  }
106
110
  }
107
111