@strav/cli 0.4.30 → 1.0.0-alpha.4
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 +17 -41
- package/src/binder.ts +88 -0
- package/src/command.ts +297 -0
- package/src/config_list.ts +42 -0
- package/src/config_show.ts +50 -0
- package/src/console_provider.ts +46 -0
- package/src/exit_codes.ts +26 -0
- package/src/index.ts +60 -2
- package/src/key_generate.ts +66 -0
- package/src/make/index.ts +17 -0
- package/src/make/make_command_file.ts +27 -0
- package/src/make/make_controller.ts +24 -0
- package/src/make/make_factory.ts +25 -0
- package/src/make/make_job.ts +25 -0
- package/src/make/make_mail.ts +27 -0
- package/src/make/make_middleware.ts +23 -0
- package/src/make/make_migration.ts +48 -0
- package/src/make/make_model.ts +91 -0
- package/src/make/make_notification.ts +23 -0
- package/src/make/make_policy.ts +24 -0
- package/src/make/make_provider.ts +29 -0
- package/src/make/make_repository.ts +30 -0
- package/src/make/make_request.ts +24 -0
- package/src/make/make_seeder.ts +23 -0
- package/src/make/make_test.ts +22 -0
- package/src/make_command.ts +69 -0
- package/src/run_cli.ts +121 -0
- package/src/scaffold_console_provider.ts +45 -0
- package/src/signature.ts +171 -0
- package/src/subset_boot.ts +51 -0
- package/src/util_console_provider.ts +18 -0
- package/src/cli/bootstrap.ts +0 -77
- package/src/cli/command_loader.ts +0 -180
- package/src/cli/index.ts +0 -3
- package/src/cli/strav.ts +0 -13
- package/src/commands/db_seed.ts +0 -77
- package/src/commands/db_setup_roles.ts +0 -101
- package/src/commands/generate_api.ts +0 -93
- package/src/commands/generate_key.ts +0 -47
- package/src/commands/generate_models.ts +0 -49
- package/src/commands/generate_seeder.ts +0 -68
- package/src/commands/migration_compare.ts +0 -167
- package/src/commands/migration_fresh.ts +0 -148
- package/src/commands/migration_generate.ts +0 -84
- package/src/commands/migration_rollback.ts +0 -54
- package/src/commands/migration_run.ts +0 -45
- package/src/commands/package_install.ts +0 -161
- package/src/commands/queue_flush.ts +0 -35
- package/src/commands/queue_retry.ts +0 -34
- package/src/commands/queue_work.ts +0 -101
- package/src/commands/scheduler_work.ts +0 -46
- package/src/commands/tenant_create.ts +0 -35
- package/src/commands/tenant_delete.ts +0 -64
- package/src/commands/tenant_list.ts +0 -39
- package/src/config/loader.ts +0 -50
- package/src/generators/api_generator.ts +0 -1035
- package/src/generators/config.ts +0 -113
- package/src/generators/doc_generator.ts +0 -996
- package/src/generators/index.ts +0 -11
- package/src/generators/model_generator.ts +0 -596
- package/src/generators/route_generator.ts +0 -187
- package/src/generators/test_generator.ts +0 -1667
- package/tsconfig.json +0 -5
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import type { Command } from 'commander'
|
|
2
|
-
import chalk from 'chalk'
|
|
3
|
-
import path from 'node:path'
|
|
4
|
-
import { bootstrap, shutdown } from '../cli/bootstrap.ts'
|
|
5
|
-
import Scheduler from '@strav/queue/scheduler/scheduler'
|
|
6
|
-
import SchedulerRunner from '@strav/queue/scheduler/runner'
|
|
7
|
-
|
|
8
|
-
export function register(program: Command): void {
|
|
9
|
-
program
|
|
10
|
-
.command('schedule')
|
|
11
|
-
.alias('scheduler:work')
|
|
12
|
-
.description('Start the task scheduler')
|
|
13
|
-
.action(async () => {
|
|
14
|
-
let db
|
|
15
|
-
try {
|
|
16
|
-
const { db: database } = await bootstrap()
|
|
17
|
-
db = database
|
|
18
|
-
|
|
19
|
-
// Load user's scheduled tasks
|
|
20
|
-
const schedulesPath = path.resolve('app/schedules.ts')
|
|
21
|
-
await import(schedulesPath)
|
|
22
|
-
|
|
23
|
-
const taskCount = Scheduler.tasks.length
|
|
24
|
-
if (taskCount === 0) {
|
|
25
|
-
console.log(chalk.yellow('No tasks registered. Add tasks in app/schedules.ts'))
|
|
26
|
-
return
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
console.log(chalk.cyan(`Scheduler starting with ${taskCount} task(s)...`))
|
|
30
|
-
for (const task of Scheduler.tasks) {
|
|
31
|
-
console.log(chalk.dim(` ${task.name}`))
|
|
32
|
-
}
|
|
33
|
-
console.log(chalk.dim(' Press Ctrl+C to stop.\n'))
|
|
34
|
-
|
|
35
|
-
const runner = new SchedulerRunner()
|
|
36
|
-
await runner.start()
|
|
37
|
-
|
|
38
|
-
console.log(chalk.dim('\nScheduler stopped.'))
|
|
39
|
-
} catch (err) {
|
|
40
|
-
console.error(chalk.red(`Error: ${err instanceof Error ? err.message : err}`))
|
|
41
|
-
process.exit(1)
|
|
42
|
-
} finally {
|
|
43
|
-
if (db) await shutdown(db)
|
|
44
|
-
}
|
|
45
|
-
})
|
|
46
|
-
}
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import type { Command } from 'commander'
|
|
2
|
-
import chalk from 'chalk'
|
|
3
|
-
import { bootstrap, shutdown } from '../cli/bootstrap.ts'
|
|
4
|
-
import TenantManager from '@strav/database/database/tenant/manager'
|
|
5
|
-
import { ensureTenantTable } from '@strav/database/database/tenant/seed'
|
|
6
|
-
|
|
7
|
-
export function register(program: Command): void {
|
|
8
|
-
program
|
|
9
|
-
.command('tenant:create')
|
|
10
|
-
.description('Create a new tenant')
|
|
11
|
-
.requiredOption('--slug <slug>', 'Unique tenant slug (used for subdomain/URLs)')
|
|
12
|
-
.requiredOption('--name <name>', 'Tenant display name')
|
|
13
|
-
.action(async (opts: { slug: string; name: string }) => {
|
|
14
|
-
let db
|
|
15
|
-
try {
|
|
16
|
-
const { db: database } = await bootstrap()
|
|
17
|
-
db = database
|
|
18
|
-
|
|
19
|
-
await ensureTenantTable(db.bypass, db.tenantIdType)
|
|
20
|
-
const manager = new TenantManager(db)
|
|
21
|
-
|
|
22
|
-
const tenant = await manager.create({ slug: opts.slug, name: opts.name })
|
|
23
|
-
|
|
24
|
-
console.log(chalk.green('\nTenant created:'))
|
|
25
|
-
console.log(chalk.dim(` id: ${tenant.id}`))
|
|
26
|
-
console.log(chalk.dim(` slug: ${tenant.slug}`))
|
|
27
|
-
console.log(chalk.dim(` name: ${tenant.name}`))
|
|
28
|
-
} catch (err) {
|
|
29
|
-
console.error(chalk.red(`Error: ${err instanceof Error ? err.message : err}`))
|
|
30
|
-
process.exit(1)
|
|
31
|
-
} finally {
|
|
32
|
-
if (db) await shutdown(db)
|
|
33
|
-
}
|
|
34
|
-
})
|
|
35
|
-
}
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
import type { Command } from 'commander'
|
|
2
|
-
import chalk from 'chalk'
|
|
3
|
-
import { createInterface } from 'node:readline'
|
|
4
|
-
import { bootstrap, shutdown } from '../cli/bootstrap.ts'
|
|
5
|
-
import TenantManager from '@strav/database/database/tenant/manager'
|
|
6
|
-
import { ensureTenantTable } from '@strav/database/database/tenant/seed'
|
|
7
|
-
|
|
8
|
-
export function register(program: Command): void {
|
|
9
|
-
program
|
|
10
|
-
.command('tenant:delete <id>')
|
|
11
|
-
.description('Delete a tenant and cascade-delete all their rows')
|
|
12
|
-
.option('-f, --force', 'Skip the confirmation prompt')
|
|
13
|
-
.action(async (id: string, opts: { force?: boolean }) => {
|
|
14
|
-
let db
|
|
15
|
-
try {
|
|
16
|
-
const { db: database } = await bootstrap()
|
|
17
|
-
db = database
|
|
18
|
-
|
|
19
|
-
await ensureTenantTable(db.bypass, db.tenantIdType)
|
|
20
|
-
const manager = new TenantManager(db)
|
|
21
|
-
|
|
22
|
-
const tenant = await manager.find(id)
|
|
23
|
-
if (!tenant) {
|
|
24
|
-
console.error(chalk.red(`Tenant not found: ${id}`))
|
|
25
|
-
process.exit(1)
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
if (!opts.force) {
|
|
29
|
-
console.log(
|
|
30
|
-
chalk.red('WARNING: ') +
|
|
31
|
-
`This will delete tenant "${tenant.slug}" and ` +
|
|
32
|
-
chalk.red('cascade-delete all their data') +
|
|
33
|
-
' across every tenant-scoped table.'
|
|
34
|
-
)
|
|
35
|
-
const challenge = tenant.slug
|
|
36
|
-
console.log(`\n Type ${chalk.yellow(challenge)} to confirm:\n`)
|
|
37
|
-
|
|
38
|
-
const answer = await prompt(' > ')
|
|
39
|
-
if (answer.trim() !== challenge) {
|
|
40
|
-
console.error(chalk.red('\nConfirmation does not match. Operation cancelled.'))
|
|
41
|
-
process.exit(1)
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
await manager.delete(id)
|
|
46
|
-
console.log(chalk.green(`\nTenant "${tenant.slug}" deleted.`))
|
|
47
|
-
} catch (err) {
|
|
48
|
-
console.error(chalk.red(`Error: ${err instanceof Error ? err.message : err}`))
|
|
49
|
-
process.exit(1)
|
|
50
|
-
} finally {
|
|
51
|
-
if (db) await shutdown(db)
|
|
52
|
-
}
|
|
53
|
-
})
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
function prompt(question: string): Promise<string> {
|
|
57
|
-
const rl = createInterface({ input: process.stdin, output: process.stdout })
|
|
58
|
-
return new Promise(resolve => {
|
|
59
|
-
rl.question(question, answer => {
|
|
60
|
-
rl.close()
|
|
61
|
-
resolve(answer)
|
|
62
|
-
})
|
|
63
|
-
})
|
|
64
|
-
}
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import type { Command } from 'commander'
|
|
2
|
-
import chalk from 'chalk'
|
|
3
|
-
import { bootstrap, shutdown } from '../cli/bootstrap.ts'
|
|
4
|
-
import TenantManager from '@strav/database/database/tenant/manager'
|
|
5
|
-
import { ensureTenantTable } from '@strav/database/database/tenant/seed'
|
|
6
|
-
|
|
7
|
-
export function register(program: Command): void {
|
|
8
|
-
program
|
|
9
|
-
.command('tenant:list')
|
|
10
|
-
.description('List all tenants')
|
|
11
|
-
.action(async () => {
|
|
12
|
-
let db
|
|
13
|
-
try {
|
|
14
|
-
const { db: database } = await bootstrap()
|
|
15
|
-
db = database
|
|
16
|
-
|
|
17
|
-
await ensureTenantTable(db.bypass, db.tenantIdType)
|
|
18
|
-
const manager = new TenantManager(db)
|
|
19
|
-
const tenants = await manager.list()
|
|
20
|
-
|
|
21
|
-
if (tenants.length === 0) {
|
|
22
|
-
console.log(chalk.yellow('No tenants found.'))
|
|
23
|
-
return
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
console.log(chalk.cyan(`\n${tenants.length} tenant(s):\n`))
|
|
27
|
-
for (const t of tenants) {
|
|
28
|
-
console.log(` ${chalk.green(t.slug)}`)
|
|
29
|
-
console.log(chalk.dim(` id: ${t.id}`))
|
|
30
|
-
console.log(chalk.dim(` name: ${t.name}`))
|
|
31
|
-
}
|
|
32
|
-
} catch (err) {
|
|
33
|
-
console.error(chalk.red(`Error: ${err instanceof Error ? err.message : err}`))
|
|
34
|
-
process.exit(1)
|
|
35
|
-
} finally {
|
|
36
|
-
if (db) await shutdown(db)
|
|
37
|
-
}
|
|
38
|
-
})
|
|
39
|
-
}
|
package/src/config/loader.ts
DELETED
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import { join } from 'node:path'
|
|
2
|
-
import type { GeneratorConfig, GeneratorPaths } from '../generators/config.ts'
|
|
3
|
-
import { resolvePaths } from '../generators/config.ts'
|
|
4
|
-
import {
|
|
5
|
-
type TenantIdType,
|
|
6
|
-
DEFAULT_TENANT_ID_TYPE,
|
|
7
|
-
} from '@strav/database/database/tenant/id_type'
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Load the generator configuration from the project's config/generators.ts file.
|
|
11
|
-
* Falls back to defaults if the file doesn't exist.
|
|
12
|
-
*/
|
|
13
|
-
export async function loadGeneratorConfig(): Promise<GeneratorConfig | undefined> {
|
|
14
|
-
try {
|
|
15
|
-
return (await import(join(process.cwd(), 'config/generators.ts'))).default
|
|
16
|
-
} catch {
|
|
17
|
-
return undefined
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* Get the fully resolved database paths from the configuration.
|
|
23
|
-
*/
|
|
24
|
-
export async function getDatabasePaths(): Promise<{ schemas: string; migrations: string }> {
|
|
25
|
-
const config = await loadGeneratorConfig()
|
|
26
|
-
const paths = resolvePaths(config)
|
|
27
|
-
return { schemas: paths.schemas, migrations: paths.migrations }
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Get all resolved paths from the configuration.
|
|
32
|
-
*/
|
|
33
|
-
export async function getAllPaths(): Promise<GeneratorPaths> {
|
|
34
|
-
const config = await loadGeneratorConfig()
|
|
35
|
-
return resolvePaths(config)
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* Read `database.tenant.idType` from `config/database.ts` for code-only
|
|
40
|
-
* generators (generate:models, generate:api) that don't connect to the DB.
|
|
41
|
-
* Falls back to the framework default if the config file or key is absent.
|
|
42
|
-
*/
|
|
43
|
-
export async function loadTenantIdType(): Promise<TenantIdType> {
|
|
44
|
-
try {
|
|
45
|
-
const dbConfig = (await import(join(process.cwd(), 'config/database.ts'))).default
|
|
46
|
-
return (dbConfig?.tenant?.idType as TenantIdType | undefined) ?? DEFAULT_TENANT_ID_TYPE
|
|
47
|
-
} catch {
|
|
48
|
-
return DEFAULT_TENANT_ID_TYPE
|
|
49
|
-
}
|
|
50
|
-
}
|