@strav/cli 1.0.0-alpha.9 → 1.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@strav/cli",
3
- "version": "1.0.0-alpha.9",
3
+ "version": "1.0.1",
4
4
  "description": "Strav CLI layer — Command base, signature parser, ConsoleProvider, interactive prompts on top of @strav/kernel's ConsoleKernel",
5
5
  "type": "module",
6
6
  "main": "./src/index.ts",
@@ -19,7 +19,7 @@
19
19
  "access": "public"
20
20
  },
21
21
  "dependencies": {
22
- "@strav/kernel": "1.0.0-alpha.9"
22
+ "@strav/kernel": "1.0.1"
23
23
  },
24
24
  "peerDependencies": {
25
25
  "@types/bun": ">=1.3.14"
@@ -11,7 +11,7 @@ export class MakeMail extends MakeCommand {
11
11
 
12
12
  protected stub(name: string): string {
13
13
  const cls = pascal(name)
14
- return `import { Mailable, type Message } from '@strav/signal'
14
+ return `import { Mailable, type Message } from '@strav/mail'
15
15
 
16
16
  export class ${cls} extends Mailable<unknown> {
17
17
  build(payload: unknown): Message {
@@ -11,12 +11,21 @@ export class MakeNotification extends MakeCommand {
11
11
 
12
12
  protected stub(name: string): string {
13
13
  const cls = pascal(name)
14
- return `// ${cls} notification
15
- // Implement channels (mail, database, broadcast) once @strav/signal notifications land.
16
- export class ${cls} {
17
- via(): string[] {
14
+ return `import { BaseNotification, type Notifiable } from '@strav/notification'
15
+ import { type Message } from '@strav/mail'
16
+
17
+ export class ${cls} extends BaseNotification {
18
+ override via(_notifiable: Notifiable): readonly string[] {
18
19
  return ['mail']
19
20
  }
21
+
22
+ override toMail(_notifiable: Notifiable): Message {
23
+ return {
24
+ to: [],
25
+ subject: '${cls}',
26
+ text: 'Edit packages/.../notifications/${snake(name)}.ts',
27
+ }
28
+ }
20
29
  }
21
30
  `
22
31
  }
@@ -14,17 +14,21 @@ export class MakeRepository extends MakeCommand {
14
14
  const base = pascal(name).replace(/Repository$/, '')
15
15
  const cls = `${base}Repository`
16
16
  const model = base
17
- return `import { inject } from '@strav/kernel'
18
- import { type Database, PostgresDatabase, Repository } from '@strav/database'
17
+ return `import { Repository } from '@strav/database'
19
18
  import { ${model} } from '../models/${snake(model)}.ts'
20
19
  import { ${snake(model)}Schema } from '../../database/schemas/${snake(model)}_schema.ts'
21
20
 
22
- @inject()
23
21
  export class ${cls} extends Repository<${model}> {
24
- constructor(db: PostgresDatabase) {
25
- super(db, ${snake(model)}Schema)
26
- }
22
+ static override readonly schema = ${snake(model)}Schema
23
+ static override readonly model = ${model}
27
24
  }
25
+
26
+ // Bind in your ServiceProvider:
27
+ //
28
+ // app.singleton(${cls}, (c) => new ${cls}({
29
+ // db: c.resolve(PostgresDatabase),
30
+ // events: c.resolve(EventBus),
31
+ // }))
28
32
  `
29
33
  }
30
34
  }
package/src/run_cli.ts CHANGED
@@ -29,7 +29,9 @@ import {
29
29
  ConsoleKernel,
30
30
  type ConsoleOutputOptions,
31
31
  parseArgv,
32
+ resolveProviders,
32
33
  type ServiceProvider,
34
+ type ServiceProviderEntry,
33
35
  } from '@strav/kernel'
34
36
  import type { CliCommandClass } from './command.ts'
35
37
  import { collectCommands } from './console_provider.ts'
@@ -37,8 +39,13 @@ import { selectProviders } from './subset_boot.ts'
37
39
 
38
40
  export interface RunCliOptions {
39
41
  argv: readonly string[]
40
- /** Full default provider list — typically from `bootstrap/providers.ts`. */
41
- defaultProviders: readonly ServiceProvider[]
42
+ /**
43
+ * Full default provider list — typically from `bootstrap/providers.ts`.
44
+ * Accepts the same entry forms as `Application.useProviders`: instances,
45
+ * zero-arg constructors, and closures. Entries are resolved once, up front,
46
+ * so command collection and subset-boot can read provider metadata.
47
+ */
48
+ defaultProviders: readonly ServiceProviderEntry[]
42
49
  /**
43
50
  * Explicit command list. Optional — when omitted, commands are collected
44
51
  * from every `ConsoleProvider` subclass in `defaultProviders`.
@@ -52,7 +59,11 @@ export interface RunCliOptions {
52
59
  }
53
60
 
54
61
  export async function runCli(options: RunCliOptions): Promise<number> {
55
- const commands = options.commands ?? collectCommands(options.defaultProviders)
62
+ // Resolve provider entries (constructors / closures) to instances once, up
63
+ // front — `collectCommands` and `selectProviders` read instance metadata
64
+ // (`commands`, `name`, `dependencies`) that bare entries don't expose.
65
+ const defaultProviders = await resolveProviders(options.defaultProviders)
66
+ const commands = options.commands ?? collectCommands(defaultProviders)
56
67
  assertUniqueCommands(commands)
57
68
  const byName = indexByName(commands)
58
69
  const { command: commandName } = parseArgv(options.argv)
@@ -71,7 +82,7 @@ export async function runCli(options: RunCliOptions): Promise<number> {
71
82
  } else {
72
83
  const Class = byName.get(commandName)
73
84
  const requested = (Class as { providers?: readonly string[] } | undefined)?.providers
74
- providers = selectProviders(options.defaultProviders, requested, commandName)
85
+ providers = selectProviders(defaultProviders, requested, commandName)
75
86
  }
76
87
 
77
88
  // ─── delegate to kernel's ConsoleKernel.run ────────────────────────────────