@strav/cli 0.4.0 → 0.4.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 +6 -6
- package/src/commands/generate_api.ts +31 -12
- package/src/commands/generate_models.ts +16 -8
- package/src/commands/migration_compare.ts +1 -1
- package/src/commands/migration_fresh.ts +2 -2
- package/src/commands/migration_generate.ts +2 -2
- package/src/commands/tenant_create.ts +1 -1
- package/src/commands/tenant_delete.ts +1 -1
- package/src/commands/tenant_list.ts +1 -1
- package/src/config/loader.ts +18 -0
- package/src/generators/api_generator.ts +3 -4
- package/src/generators/config.ts +26 -3
- package/src/generators/doc_generator.ts +13 -3
- package/src/generators/model_generator.ts +3 -4
- package/src/generators/route_generator.ts +3 -4
- package/src/generators/test_generator.ts +3 -4
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@strav/cli",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.4",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "CLI framework and code generators for the Strav framework",
|
|
6
6
|
"license": "MIT",
|
|
@@ -33,11 +33,11 @@
|
|
|
33
33
|
"strav": "./src/cli/strav.ts"
|
|
34
34
|
},
|
|
35
35
|
"peerDependencies": {
|
|
36
|
-
"@strav/kernel": "0.4.
|
|
37
|
-
"@strav/http": "0.4.
|
|
38
|
-
"@strav/database": "0.4.
|
|
39
|
-
"@strav/queue": "0.4.
|
|
40
|
-
"@strav/signal": "0.4.
|
|
36
|
+
"@strav/kernel": "0.4.4",
|
|
37
|
+
"@strav/http": "0.4.4",
|
|
38
|
+
"@strav/database": "0.4.4",
|
|
39
|
+
"@strav/queue": "0.4.4",
|
|
40
|
+
"@strav/signal": "0.4.4"
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
43
|
"chalk": "^5.6.2",
|
|
@@ -8,7 +8,7 @@ import TestGenerator from '../generators/test_generator.ts'
|
|
|
8
8
|
import DocGenerator from '../generators/doc_generator.ts'
|
|
9
9
|
import type { ApiRoutingConfig } from '../generators/route_generator.ts'
|
|
10
10
|
import type { GeneratorConfig } from '../generators/config.ts'
|
|
11
|
-
import { loadGeneratorConfig, getDatabasePaths } from '../config/loader.ts'
|
|
11
|
+
import { loadGeneratorConfig, getDatabasePaths, loadTenantIdType } from '../config/loader.ts'
|
|
12
12
|
|
|
13
13
|
export function register(program: Command): void {
|
|
14
14
|
program
|
|
@@ -17,7 +17,8 @@ export function register(program: Command): void {
|
|
|
17
17
|
.description(
|
|
18
18
|
'Generate services, controllers, policies, validators, events, and routes from schemas'
|
|
19
19
|
)
|
|
20
|
-
.
|
|
20
|
+
.option('-f, --force', 'Overwrite existing generated files')
|
|
21
|
+
.action(async ({ force }: { force?: boolean }) => {
|
|
21
22
|
try {
|
|
22
23
|
console.log(chalk.cyan('Generating API layer from schemas...'))
|
|
23
24
|
|
|
@@ -29,13 +30,14 @@ export function register(program: Command): void {
|
|
|
29
30
|
registry.validate()
|
|
30
31
|
|
|
31
32
|
const schemas = registry.resolve()
|
|
32
|
-
const
|
|
33
|
+
const tenantIdType = await loadTenantIdType()
|
|
34
|
+
const representation = registry.buildRepresentation(tenantIdType)
|
|
33
35
|
|
|
34
36
|
// Load generator config (if available)
|
|
35
37
|
const config = await loadGeneratorConfig()
|
|
36
38
|
|
|
37
39
|
const apiGen = new ApiGenerator(schemas, representation, config)
|
|
38
|
-
const
|
|
40
|
+
const apiResult = await apiGen.writeAll(force)
|
|
39
41
|
|
|
40
42
|
// Load API routing config from config/http.ts (if available)
|
|
41
43
|
let apiConfig: Partial<ApiRoutingConfig> | undefined
|
|
@@ -47,24 +49,41 @@ export function register(program: Command): void {
|
|
|
47
49
|
}
|
|
48
50
|
|
|
49
51
|
const routeGen = new RouteGenerator(schemas, config, apiConfig)
|
|
50
|
-
const
|
|
52
|
+
const routeResult = await routeGen.writeAll(force)
|
|
51
53
|
|
|
52
54
|
const testGen = new TestGenerator(schemas, representation, config, apiConfig)
|
|
53
|
-
const
|
|
55
|
+
const testResult = await testGen.writeAll(force)
|
|
54
56
|
|
|
55
57
|
const docGen = new DocGenerator(schemas, representation, config, apiConfig)
|
|
56
|
-
const
|
|
58
|
+
const docResult = await docGen.writeAll(force)
|
|
57
59
|
|
|
58
|
-
const
|
|
60
|
+
const written = [
|
|
61
|
+
...apiResult.written,
|
|
62
|
+
...routeResult.written,
|
|
63
|
+
...testResult.written,
|
|
64
|
+
...docResult.written,
|
|
65
|
+
]
|
|
66
|
+
const skipped = [
|
|
67
|
+
...apiResult.skipped,
|
|
68
|
+
...routeResult.skipped,
|
|
69
|
+
...testResult.skipped,
|
|
70
|
+
...docResult.skipped,
|
|
71
|
+
]
|
|
59
72
|
|
|
60
|
-
if (
|
|
73
|
+
if (written.length === 0 && skipped.length === 0) {
|
|
61
74
|
console.log(chalk.yellow('No API files to generate.'))
|
|
62
75
|
return
|
|
63
76
|
}
|
|
64
77
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
78
|
+
for (const file of written) {
|
|
79
|
+
console.log(chalk.green(` CREATE `) + chalk.dim(file.path))
|
|
80
|
+
}
|
|
81
|
+
for (const file of skipped) {
|
|
82
|
+
console.log(chalk.yellow(` SKIP `) + chalk.dim(file.path) + chalk.dim(' (already exists)'))
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if (skipped.length > 0) {
|
|
86
|
+
console.log(chalk.dim(`\nSkipped ${skipped.length} existing file(s). Use --force to overwrite.`))
|
|
68
87
|
}
|
|
69
88
|
} catch (err) {
|
|
70
89
|
console.error(chalk.red(`Error: ${err instanceof Error ? err.message : err}`))
|
|
@@ -2,14 +2,15 @@ import type { Command } from 'commander'
|
|
|
2
2
|
import chalk from 'chalk'
|
|
3
3
|
import SchemaRegistry from '@strav/database/schema/registry'
|
|
4
4
|
import ModelGenerator from '../generators/model_generator.ts'
|
|
5
|
-
import { loadGeneratorConfig, getDatabasePaths } from '../config/loader.ts'
|
|
5
|
+
import { loadGeneratorConfig, getDatabasePaths, loadTenantIdType } from '../config/loader.ts'
|
|
6
6
|
|
|
7
7
|
export function register(program: Command): void {
|
|
8
8
|
program
|
|
9
9
|
.command('generate:models')
|
|
10
10
|
.alias('g:models')
|
|
11
11
|
.description('Generate model classes and enums from schema definitions')
|
|
12
|
-
.
|
|
12
|
+
.option('-f, --force', 'Overwrite existing generated files')
|
|
13
|
+
.action(async ({ force }: { force?: boolean }) => {
|
|
13
14
|
try {
|
|
14
15
|
const dbPaths = await getDatabasePaths()
|
|
15
16
|
const config = await loadGeneratorConfig()
|
|
@@ -20,18 +21,25 @@ export function register(program: Command): void {
|
|
|
20
21
|
await registry.discover(dbPaths.schemas)
|
|
21
22
|
registry.validate()
|
|
22
23
|
|
|
23
|
-
const
|
|
24
|
+
const tenantIdType = await loadTenantIdType()
|
|
25
|
+
const representation = registry.buildRepresentation(tenantIdType)
|
|
24
26
|
const generator = new ModelGenerator(registry.all(), representation, config)
|
|
25
|
-
const
|
|
27
|
+
const { written, skipped } = await generator.writeAll(force)
|
|
26
28
|
|
|
27
|
-
if (
|
|
29
|
+
if (written.length === 0 && skipped.length === 0) {
|
|
28
30
|
console.log(chalk.yellow('No models to generate.'))
|
|
29
31
|
return
|
|
30
32
|
}
|
|
31
33
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
34
|
+
for (const file of written) {
|
|
35
|
+
console.log(chalk.green(` CREATE `) + chalk.dim(file.path))
|
|
36
|
+
}
|
|
37
|
+
for (const file of skipped) {
|
|
38
|
+
console.log(chalk.yellow(` SKIP `) + chalk.dim(file.path) + chalk.dim(' (already exists)'))
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (skipped.length > 0) {
|
|
42
|
+
console.log(chalk.dim(`\nSkipped ${skipped.length} existing file(s). Use --force to overwrite.`))
|
|
35
43
|
}
|
|
36
44
|
} catch (err) {
|
|
37
45
|
console.error(chalk.red(`Error: ${err instanceof Error ? err.message : err}`))
|
|
@@ -16,7 +16,7 @@ export function register(program: Command): void {
|
|
|
16
16
|
|
|
17
17
|
console.log(chalk.cyan('Comparing schema with database...\n'))
|
|
18
18
|
|
|
19
|
-
const desired = registry.buildRepresentation()
|
|
19
|
+
const desired = registry.buildRepresentation(database.tenantIdType)
|
|
20
20
|
const actual = await introspector.introspect()
|
|
21
21
|
const diff = new SchemaDiffer().diff(desired, actual)
|
|
22
22
|
|
|
@@ -53,11 +53,11 @@ export async function freshDatabase(
|
|
|
53
53
|
|
|
54
54
|
console.log(chalk.cyan('Generating fresh migration...'))
|
|
55
55
|
|
|
56
|
-
const desired = registry.buildRepresentation()
|
|
56
|
+
const desired = registry.buildRepresentation(db.tenantIdType)
|
|
57
57
|
const actual = await introspector.introspect()
|
|
58
58
|
const diff = new SchemaDiffer().diff(desired, actual)
|
|
59
59
|
|
|
60
|
-
const sql = new SqlGenerator().generate(diff)
|
|
60
|
+
const sql = new SqlGenerator(db.tenantIdType).generate(diff)
|
|
61
61
|
const version = Date.now().toString()
|
|
62
62
|
const tableOrder = desired.tables.map(t => t.name)
|
|
63
63
|
|
|
@@ -21,7 +21,7 @@ export function register(program: Command): void {
|
|
|
21
21
|
|
|
22
22
|
console.log(chalk.cyan('Comparing schema with database...'))
|
|
23
23
|
|
|
24
|
-
const desired = registry.buildRepresentation()
|
|
24
|
+
const desired = registry.buildRepresentation(database.tenantIdType)
|
|
25
25
|
const actual = await introspector.introspect()
|
|
26
26
|
const diff = new SchemaDiffer().diff(desired, actual)
|
|
27
27
|
|
|
@@ -36,7 +36,7 @@ export function register(program: Command): void {
|
|
|
36
36
|
return
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
-
const sql = new SqlGenerator().generate(diff)
|
|
39
|
+
const sql = new SqlGenerator(database.tenantIdType).generate(diff)
|
|
40
40
|
const version = Date.now().toString()
|
|
41
41
|
const tableOrder = desired.tables.map(t => t.name)
|
|
42
42
|
|
|
@@ -16,7 +16,7 @@ export function register(program: Command): void {
|
|
|
16
16
|
const { db: database } = await bootstrap()
|
|
17
17
|
db = database
|
|
18
18
|
|
|
19
|
-
await ensureTenantTable(db.bypass)
|
|
19
|
+
await ensureTenantTable(db.bypass, db.tenantIdType)
|
|
20
20
|
const manager = new TenantManager(db)
|
|
21
21
|
|
|
22
22
|
const tenant = await manager.create({ slug: opts.slug, name: opts.name })
|
|
@@ -16,7 +16,7 @@ export function register(program: Command): void {
|
|
|
16
16
|
const { db: database } = await bootstrap()
|
|
17
17
|
db = database
|
|
18
18
|
|
|
19
|
-
await ensureTenantTable(db.bypass)
|
|
19
|
+
await ensureTenantTable(db.bypass, db.tenantIdType)
|
|
20
20
|
const manager = new TenantManager(db)
|
|
21
21
|
|
|
22
22
|
const tenant = await manager.find(id)
|
|
@@ -14,7 +14,7 @@ export function register(program: Command): void {
|
|
|
14
14
|
const { db: database } = await bootstrap()
|
|
15
15
|
db = database
|
|
16
16
|
|
|
17
|
-
await ensureTenantTable(db.bypass)
|
|
17
|
+
await ensureTenantTable(db.bypass, db.tenantIdType)
|
|
18
18
|
const manager = new TenantManager(db)
|
|
19
19
|
const tenants = await manager.list()
|
|
20
20
|
|
package/src/config/loader.ts
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import { join } from 'node:path'
|
|
2
2
|
import type { GeneratorConfig, GeneratorPaths } from '../generators/config.ts'
|
|
3
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'
|
|
4
8
|
|
|
5
9
|
/**
|
|
6
10
|
* Load the generator configuration from the project's config/generators.ts file.
|
|
@@ -30,3 +34,17 @@ export async function getAllPaths(): Promise<GeneratorPaths> {
|
|
|
30
34
|
const config = await loadGeneratorConfig()
|
|
31
35
|
return resolvePaths(config)
|
|
32
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
|
+
}
|
|
@@ -10,7 +10,7 @@ import type { FieldDefinition, FieldValidator } from '@strav/database/schema/fie
|
|
|
10
10
|
import type { PostgreSQLCustomType } from '@strav/database/schema/postgres'
|
|
11
11
|
import { toSnakeCase, toCamelCase, toPascalCase } from '@strav/kernel/helpers/strings'
|
|
12
12
|
import type { GeneratedFile } from './model_generator.ts'
|
|
13
|
-
import type { GeneratorConfig, GeneratorPaths } from './config.ts'
|
|
13
|
+
import type { GeneratorConfig, GeneratorPaths, WriteResult } from './config.ts'
|
|
14
14
|
import { resolvePaths, relativeImport, formatAndWrite } from './config.ts'
|
|
15
15
|
|
|
16
16
|
// ---------------------------------------------------------------------------
|
|
@@ -208,10 +208,9 @@ export default class ApiGenerator {
|
|
|
208
208
|
}
|
|
209
209
|
|
|
210
210
|
/** Generate, format with Prettier, and write all files to disk. */
|
|
211
|
-
async writeAll(): Promise<
|
|
211
|
+
async writeAll(force?: boolean): Promise<WriteResult> {
|
|
212
212
|
const files = this.generate()
|
|
213
|
-
|
|
214
|
-
return files
|
|
213
|
+
return formatAndWrite(files, { force })
|
|
215
214
|
}
|
|
216
215
|
|
|
217
216
|
// ---------------------------------------------------------------------------
|
package/src/generators/config.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { existsSync } from 'node:fs'
|
|
1
2
|
import { resolve, relative } from 'node:path'
|
|
2
3
|
import type { GeneratedFile } from './model_generator.ts'
|
|
3
4
|
|
|
@@ -66,11 +67,22 @@ export function relativeImport(fromDir: string, toDir: string): string {
|
|
|
66
67
|
return rel.startsWith('.') ? rel : './' + rel
|
|
67
68
|
}
|
|
68
69
|
|
|
70
|
+
export interface WriteResult {
|
|
71
|
+
written: GeneratedFile[]
|
|
72
|
+
skipped: GeneratedFile[]
|
|
73
|
+
}
|
|
74
|
+
|
|
69
75
|
/**
|
|
70
76
|
* Format generated files with Prettier and write them to disk.
|
|
71
77
|
* Falls back to writing unformatted content if Prettier is not installed.
|
|
78
|
+
*
|
|
79
|
+
* Skips files that already exist unless `force` is true. Returns the
|
|
80
|
+
* partition of written and skipped files so callers can report them.
|
|
72
81
|
*/
|
|
73
|
-
export async function formatAndWrite(
|
|
82
|
+
export async function formatAndWrite(
|
|
83
|
+
files: GeneratedFile[],
|
|
84
|
+
options: { force?: boolean } = {}
|
|
85
|
+
): Promise<WriteResult> {
|
|
74
86
|
let prettier: typeof import('prettier') | null = null
|
|
75
87
|
try {
|
|
76
88
|
prettier = await import('prettier')
|
|
@@ -78,13 +90,24 @@ export async function formatAndWrite(files: GeneratedFile[]): Promise<void> {
|
|
|
78
90
|
// Prettier not installed — write unformatted
|
|
79
91
|
}
|
|
80
92
|
|
|
93
|
+
const written: GeneratedFile[] = []
|
|
94
|
+
const skipped: GeneratedFile[] = []
|
|
95
|
+
|
|
81
96
|
for (const file of files) {
|
|
97
|
+
if (existsSync(file.path) && !options.force) {
|
|
98
|
+
skipped.push(file)
|
|
99
|
+
continue
|
|
100
|
+
}
|
|
101
|
+
|
|
82
102
|
let content = file.content
|
|
83
103
|
if (prettier) {
|
|
84
104
|
const filePath = resolve(file.path)
|
|
85
|
-
const
|
|
86
|
-
content = await prettier.format(content, { ...
|
|
105
|
+
const prettierOpts = await prettier.resolveConfig(filePath)
|
|
106
|
+
content = await prettier.format(content, { ...prettierOpts, filepath: filePath })
|
|
87
107
|
}
|
|
88
108
|
await Bun.write(file.path, content)
|
|
109
|
+
written.push(file)
|
|
89
110
|
}
|
|
111
|
+
|
|
112
|
+
return { written, skipped }
|
|
90
113
|
}
|
|
@@ -14,8 +14,9 @@ import {
|
|
|
14
14
|
toPascalCase,
|
|
15
15
|
pluralize,
|
|
16
16
|
} from '@strav/kernel/helpers/strings'
|
|
17
|
+
import { existsSync } from 'node:fs'
|
|
17
18
|
import type { GeneratedFile } from './model_generator.ts'
|
|
18
|
-
import type { GeneratorConfig, GeneratorPaths } from './config.ts'
|
|
19
|
+
import type { GeneratorConfig, GeneratorPaths, WriteResult } from './config.ts'
|
|
19
20
|
import { resolvePaths } from './config.ts'
|
|
20
21
|
import { ApiRouting, toRouteSegment, toChildSegment } from './route_generator.ts'
|
|
21
22
|
import type { ApiRoutingConfig } from './route_generator.ts'
|
|
@@ -91,12 +92,21 @@ export default class DocGenerator {
|
|
|
91
92
|
return [this.generateIndexPage()]
|
|
92
93
|
}
|
|
93
94
|
|
|
94
|
-
async writeAll(): Promise<
|
|
95
|
+
async writeAll(force?: boolean): Promise<WriteResult> {
|
|
95
96
|
const files = this.generate()
|
|
97
|
+
const written: GeneratedFile[] = []
|
|
98
|
+
const skipped: GeneratedFile[] = []
|
|
99
|
+
|
|
96
100
|
for (const file of files) {
|
|
101
|
+
if (existsSync(file.path) && !force) {
|
|
102
|
+
skipped.push(file)
|
|
103
|
+
continue
|
|
104
|
+
}
|
|
97
105
|
await Bun.write(file.path, file.content)
|
|
106
|
+
written.push(file)
|
|
98
107
|
}
|
|
99
|
-
|
|
108
|
+
|
|
109
|
+
return { written, skipped }
|
|
100
110
|
}
|
|
101
111
|
|
|
102
112
|
// ---------------------------------------------------------------------------
|
|
@@ -9,7 +9,7 @@ import type {
|
|
|
9
9
|
} from '@strav/database/schema/database_representation'
|
|
10
10
|
import type { PostgreSQLCustomType } from '@strav/database/schema/postgres'
|
|
11
11
|
import { toSnakeCase, toCamelCase, toPascalCase } from '@strav/kernel/helpers/strings'
|
|
12
|
-
import type { GeneratorConfig, GeneratorPaths } from './config.ts'
|
|
12
|
+
import type { GeneratorConfig, GeneratorPaths, WriteResult } from './config.ts'
|
|
13
13
|
import { resolvePaths, relativeImport, formatAndWrite } from './config.ts'
|
|
14
14
|
|
|
15
15
|
export interface GeneratedFile {
|
|
@@ -54,10 +54,9 @@ export default class ModelGenerator {
|
|
|
54
54
|
}
|
|
55
55
|
|
|
56
56
|
/** Generate, format with Prettier, and write all files to disk. */
|
|
57
|
-
async writeAll(): Promise<
|
|
57
|
+
async writeAll(force?: boolean): Promise<WriteResult> {
|
|
58
58
|
const files = this.generate()
|
|
59
|
-
|
|
60
|
-
return files
|
|
59
|
+
return formatAndWrite(files, { force })
|
|
61
60
|
}
|
|
62
61
|
|
|
63
62
|
// ---------------------------------------------------------------------------
|
|
@@ -3,7 +3,7 @@ import { Archetype } from '@strav/database/schema/types'
|
|
|
3
3
|
import type { SchemaDefinition } from '@strav/database/schema/types'
|
|
4
4
|
import { toSnakeCase, toPascalCase, pluralize } from '@strav/kernel/helpers/strings'
|
|
5
5
|
import type { GeneratedFile } from './model_generator.ts'
|
|
6
|
-
import type { GeneratorConfig, GeneratorPaths } from './config.ts'
|
|
6
|
+
import type { GeneratorConfig, GeneratorPaths, WriteResult } from './config.ts'
|
|
7
7
|
import { resolvePaths, relativeImport, formatAndWrite } from './config.ts'
|
|
8
8
|
|
|
9
9
|
/** Archetypes that sit under a parent's /:parentId group. */
|
|
@@ -66,10 +66,9 @@ export default class RouteGenerator {
|
|
|
66
66
|
}
|
|
67
67
|
|
|
68
68
|
/** Generate, format with Prettier, and write the route file to disk. */
|
|
69
|
-
async writeAll(): Promise<
|
|
69
|
+
async writeAll(force?: boolean): Promise<WriteResult> {
|
|
70
70
|
const files = this.generate()
|
|
71
|
-
|
|
72
|
-
return files
|
|
71
|
+
return formatAndWrite(files, { force })
|
|
73
72
|
}
|
|
74
73
|
|
|
75
74
|
// ---------------------------------------------------------------------------
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
pluralize,
|
|
14
14
|
} from '@strav/kernel/helpers/strings'
|
|
15
15
|
import type { GeneratedFile } from './model_generator.ts'
|
|
16
|
-
import type { GeneratorConfig, GeneratorPaths } from './config.ts'
|
|
16
|
+
import type { GeneratorConfig, GeneratorPaths, WriteResult } from './config.ts'
|
|
17
17
|
import { resolvePaths, relativeImport, formatAndWrite } from './config.ts'
|
|
18
18
|
import { ApiRouting, toRouteSegment, toChildSegment } from './route_generator.ts'
|
|
19
19
|
import type { ApiRoutingConfig } from './route_generator.ts'
|
|
@@ -82,10 +82,9 @@ export default class TestGenerator {
|
|
|
82
82
|
return files
|
|
83
83
|
}
|
|
84
84
|
|
|
85
|
-
async writeAll(): Promise<
|
|
85
|
+
async writeAll(force?: boolean): Promise<WriteResult> {
|
|
86
86
|
const files = this.generate()
|
|
87
|
-
|
|
88
|
-
return files
|
|
87
|
+
return formatAndWrite(files, { force })
|
|
89
88
|
}
|
|
90
89
|
|
|
91
90
|
// ---------------------------------------------------------------------------
|