@antislop/zero-lucid-generator 1.0.0 → 1.1.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/README.md +42 -50
- package/dist/index.d.ts +3 -4
- package/dist/index.js +41 -78
- package/package.json +13 -7
package/README.md
CHANGED
|
@@ -26,13 +26,13 @@ npm add -D @antislop/zero-lucid-generator
|
|
|
26
26
|
|
|
27
27
|
### 1. Create a config file
|
|
28
28
|
|
|
29
|
-
Create `
|
|
29
|
+
Create `config/lucid_zero.ts`:
|
|
30
30
|
|
|
31
31
|
```ts
|
|
32
32
|
import type { Config } from '@antislop/zero-lucid-generator'
|
|
33
33
|
|
|
34
34
|
const config: Config = {
|
|
35
|
-
|
|
35
|
+
modelsDirectory: './app/models', // Optional; this is the default
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
export default config
|
|
@@ -44,7 +44,7 @@ export default config
|
|
|
44
44
|
npx lucid-zero generate
|
|
45
45
|
```
|
|
46
46
|
|
|
47
|
-
This writes `zero-schema.gen.ts`
|
|
47
|
+
Run this from your project root. This writes `zero-schema.gen.ts` in the current working directory.
|
|
48
48
|
|
|
49
49
|
### 3. Import the schema
|
|
50
50
|
|
|
@@ -56,13 +56,12 @@ import { schema, zql } from './zero-schema.gen.js'
|
|
|
56
56
|
|
|
57
57
|
## Config options
|
|
58
58
|
|
|
59
|
-
| Option
|
|
60
|
-
|
|
61
|
-
| `
|
|
62
|
-
| `
|
|
63
|
-
| `
|
|
64
|
-
| `
|
|
65
|
-
| `columnTypes` | `Record<string, Record<string, string>>` | `{}` | Override the inferred Zero type for specific columns |
|
|
59
|
+
| Option | Type | Default | Description |
|
|
60
|
+
| --------------------- | ---------------------------------------- | -------------------- | ------------------------------------------------------------------------ |
|
|
61
|
+
| `modelsDirectory` | `string` | `./app/models` | Path to your models directory, relative to the current working directory |
|
|
62
|
+
| `outputPath` | `string` | `zero-schema.gen.ts` | Output file path, relative to the current working directory |
|
|
63
|
+
| `excludeModels` | `LucidModel[]` | `[]` | Models to exclude from the generated schema |
|
|
64
|
+
| `columnTypeOverrides` | `Record<string, Record<string, string>>` | `{}` | Override the inferred Zero type for specific columns |
|
|
66
65
|
|
|
67
66
|
---
|
|
68
67
|
|
|
@@ -72,8 +71,8 @@ import { schema, zql } from './zero-schema.gen.js'
|
|
|
72
71
|
lucid-zero generate [options]
|
|
73
72
|
|
|
74
73
|
Options:
|
|
75
|
-
-c, --config <path> Path to config file (default:
|
|
76
|
-
-t, --tsconfig <path> Path to tsconfig.json (default: tsconfig.json
|
|
74
|
+
-c, --config <path> Path to config file (default: config/lucid_zero.ts)
|
|
75
|
+
-t, --tsconfig <path> Path to tsconfig.json (default: tsconfig.json in cwd)
|
|
77
76
|
```
|
|
78
77
|
|
|
79
78
|
---
|
|
@@ -82,24 +81,24 @@ Options:
|
|
|
82
81
|
|
|
83
82
|
`@antislop/zero-lucid-generator` maps TypeScript types to Zero types automatically:
|
|
84
83
|
|
|
85
|
-
| TypeScript type
|
|
86
|
-
|
|
87
|
-
| `string`
|
|
88
|
-
| `number`
|
|
89
|
-
| `boolean`
|
|
90
|
-
| `DateTime` / `Date`
|
|
91
|
-
| `object` / `unknown` / `any`
|
|
92
|
-
| `T \| null` or `T \| undefined` | `.optional()`
|
|
84
|
+
| TypeScript type | Zero type |
|
|
85
|
+
| ------------------------------- | -------------------- |
|
|
86
|
+
| `string` | `string()` |
|
|
87
|
+
| `number` | `number()` |
|
|
88
|
+
| `boolean` | `boolean()` |
|
|
89
|
+
| `DateTime` / `Date` | `number()` (Unix ms) |
|
|
90
|
+
| `object` / `unknown` / `any` | `json()` |
|
|
91
|
+
| `T \| null` or `T \| undefined` | `.optional()` |
|
|
93
92
|
|
|
94
|
-
When inference isn't accurate — for example a JSON column with a known shape — use `
|
|
93
|
+
When inference isn't accurate — for example a JSON column with a known shape — use `columnTypeOverrides`:
|
|
95
94
|
|
|
96
95
|
```ts
|
|
97
96
|
import type { Config } from '@antislop/zero-lucid-generator'
|
|
98
|
-
import Session from
|
|
97
|
+
import Session from '#models/session'
|
|
99
98
|
|
|
100
99
|
const config: Config = {
|
|
101
|
-
|
|
102
|
-
|
|
100
|
+
modelsDirectory: './app/models',
|
|
101
|
+
columnTypeOverrides: {
|
|
103
102
|
Issue: {
|
|
104
103
|
// metadata is typed as `unknown` but has a known shape
|
|
105
104
|
metadata: 'json<{ priority: number; labels: string[] }>()',
|
|
@@ -124,61 +123,54 @@ Valid Zero base types: `string`, `number`, `boolean`, `json`, `enumeration`.
|
|
|
124
123
|
```ts
|
|
125
124
|
// zero-schema.gen.ts (auto-generated — do not edit)
|
|
126
125
|
|
|
127
|
-
import {
|
|
128
|
-
createBuilder,
|
|
129
|
-
createSchema,
|
|
130
|
-
number,
|
|
131
|
-
relationships,
|
|
132
|
-
string,
|
|
133
|
-
table,
|
|
134
|
-
} from "@rocicorp/zero";
|
|
126
|
+
import { createBuilder, createSchema, number, relationships, string, table } from '@rocicorp/zero'
|
|
135
127
|
|
|
136
|
-
export const users = table(
|
|
128
|
+
export const users = table('users')
|
|
137
129
|
.columns({
|
|
138
130
|
id: number(),
|
|
139
131
|
name: string(),
|
|
140
132
|
email: string(),
|
|
141
133
|
})
|
|
142
|
-
.primaryKey(
|
|
134
|
+
.primaryKey('id')
|
|
143
135
|
|
|
144
|
-
export const posts = table(
|
|
136
|
+
export const posts = table('posts')
|
|
145
137
|
.columns({
|
|
146
138
|
id: number(),
|
|
147
139
|
userId: number().from('user_id'),
|
|
148
140
|
title: string(),
|
|
149
141
|
body: string().optional(),
|
|
150
142
|
})
|
|
151
|
-
.primaryKey(
|
|
143
|
+
.primaryKey('id')
|
|
152
144
|
|
|
153
145
|
export const usersRelationships = relationships(users, ({ many }) => ({
|
|
154
146
|
posts: many({
|
|
155
|
-
sourceField: [
|
|
156
|
-
destField: [
|
|
147
|
+
sourceField: ['id'],
|
|
148
|
+
destField: ['userId'],
|
|
157
149
|
destSchema: posts,
|
|
158
150
|
}),
|
|
159
|
-
}))
|
|
151
|
+
}))
|
|
160
152
|
|
|
161
153
|
export const schema = createSchema({
|
|
162
154
|
tables: [users, posts],
|
|
163
155
|
relationships: [usersRelationships],
|
|
164
|
-
})
|
|
156
|
+
})
|
|
165
157
|
|
|
166
|
-
export type Schema = typeof schema
|
|
158
|
+
export type Schema = typeof schema
|
|
167
159
|
|
|
168
|
-
export const zql = createBuilder(schema)
|
|
160
|
+
export const zql = createBuilder(schema)
|
|
169
161
|
```
|
|
170
162
|
|
|
171
163
|
## Supported relation types
|
|
172
164
|
|
|
173
|
-
| Lucid relation
|
|
174
|
-
|
|
175
|
-
| `hasOne`
|
|
176
|
-
| `hasMany`
|
|
177
|
-
| `belongsTo`
|
|
178
|
-
| `manyToMany`
|
|
179
|
-
| `hasManyThrough` | `many([...chain])`
|
|
165
|
+
| Lucid relation | Zero mapping |
|
|
166
|
+
| ---------------- | ---------------------------------- |
|
|
167
|
+
| `hasOne` | `one(...)` |
|
|
168
|
+
| `hasMany` | `many(...)` |
|
|
169
|
+
| `belongsTo` | `one(...)` |
|
|
170
|
+
| `manyToMany` | `many([...chain])` via pivot table |
|
|
171
|
+
| `hasManyThrough` | `many([...chain])` |
|
|
180
172
|
|
|
181
|
-
Relations pointing to a model not found in `
|
|
173
|
+
Relations pointing to a model not found in `modelsDirectory` are skipped with a warning.
|
|
182
174
|
|
|
183
175
|
---
|
|
184
176
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
type ConfigInput = {
|
|
3
|
-
|
|
3
|
+
modelsDirectory?: string;
|
|
4
4
|
/**
|
|
5
5
|
* Models to exclude from the generated schema.
|
|
6
6
|
* Typed as a constructor array rather than `LucidModel[]` so that model
|
|
@@ -8,9 +8,8 @@ type ConfigInput = {
|
|
|
8
8
|
* without a structural mismatch from duplicate copies of the package.
|
|
9
9
|
*/
|
|
10
10
|
excludeModels?: (abstract new (...args: any[]) => any)[];
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
columnTypes?: Record<string, Record<string, string>>;
|
|
11
|
+
outputPath?: string;
|
|
12
|
+
columnTypeOverrides?: Record<string, Record<string, string>>;
|
|
14
13
|
};
|
|
15
14
|
|
|
16
15
|
export type { ConfigInput as Config };
|
package/dist/index.js
CHANGED
|
@@ -17,61 +17,60 @@ async function getDefaultExportFromModulePath(modulePath) {
|
|
|
17
17
|
try {
|
|
18
18
|
await fs.access(modulePath);
|
|
19
19
|
} catch {
|
|
20
|
-
throw new Error(`
|
|
20
|
+
throw new Error(`Module not found at ${modulePath}`);
|
|
21
21
|
}
|
|
22
22
|
const { tsImport } = await import("tsx/esm/api");
|
|
23
23
|
const moduleUrl = url.pathToFileURL(modulePath).href;
|
|
24
24
|
const module = await tsImport(moduleUrl, { parentURL: import.meta.url });
|
|
25
25
|
const defaultExport = module.default;
|
|
26
26
|
if (!defaultExport) {
|
|
27
|
-
throw new Error(`
|
|
27
|
+
throw new Error(`Module at ${modulePath} does not have a default export`);
|
|
28
28
|
}
|
|
29
29
|
return defaultExport;
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
// src/config.ts
|
|
33
|
-
var DEFAULT_CONFIG_FILE_PATH = "
|
|
33
|
+
var DEFAULT_CONFIG_FILE_PATH = "config/lucid_zero.ts";
|
|
34
34
|
var DEFAULT_OUTPUT_FILE_PATH = "zero-schema.gen.ts";
|
|
35
|
+
var DEFAULT_MODELS_DIRECTORY = "./app/models";
|
|
35
36
|
var Config = class {
|
|
36
|
-
|
|
37
|
+
modelsDirectory;
|
|
37
38
|
excludeModels;
|
|
38
39
|
outputFilePath;
|
|
39
|
-
|
|
40
|
-
columnTypes;
|
|
40
|
+
columnTypeOverrides;
|
|
41
41
|
tsconfigPath;
|
|
42
|
-
/**
|
|
43
|
-
|
|
42
|
+
/** Working directory used to resolve relative paths */
|
|
43
|
+
cwd;
|
|
44
44
|
/** Populated by this.loadModels() */
|
|
45
45
|
models = [];
|
|
46
|
-
constructor(configInput,
|
|
47
|
-
this.
|
|
48
|
-
this.
|
|
46
|
+
constructor(configInput, tsconfigPath) {
|
|
47
|
+
this.cwd = process.cwd();
|
|
48
|
+
this.modelsDirectory = configInput.modelsDirectory ?? DEFAULT_MODELS_DIRECTORY;
|
|
49
49
|
this.excludeModels = configInput.excludeModels ?? [];
|
|
50
|
-
this.outputFilePath = path.resolve(
|
|
51
|
-
this.tsconfigPath =
|
|
52
|
-
this.
|
|
53
|
-
this.columnTypes = configInput.columnTypes ?? {};
|
|
50
|
+
this.outputFilePath = path.resolve(this.cwd, configInput.outputPath ?? DEFAULT_OUTPUT_FILE_PATH);
|
|
51
|
+
this.tsconfigPath = path.resolve(this.cwd, tsconfigPath ?? "tsconfig.json");
|
|
52
|
+
this.columnTypeOverrides = configInput.columnTypeOverrides ?? {};
|
|
54
53
|
}
|
|
55
54
|
async verify() {
|
|
56
|
-
if (!this.
|
|
57
|
-
throw new Error("
|
|
55
|
+
if (!this.modelsDirectory) {
|
|
56
|
+
throw new Error("modelsDirectory must not be empty");
|
|
58
57
|
}
|
|
59
58
|
await this.loadModels();
|
|
60
59
|
if (this.models.length === 0) {
|
|
61
60
|
throw new Error(
|
|
62
|
-
`
|
|
61
|
+
`No Lucid models found in modelsDirectory. Each model file must have a default export that extends BaseModel.`
|
|
63
62
|
);
|
|
64
63
|
}
|
|
65
|
-
this.
|
|
64
|
+
this.verifyColumnTypeOverrides();
|
|
66
65
|
}
|
|
67
66
|
async loadModels() {
|
|
68
|
-
const
|
|
67
|
+
const modelsDirectoryAbsPath = path.resolve(this.cwd, this.modelsDirectory);
|
|
69
68
|
let fileNames;
|
|
70
69
|
try {
|
|
71
|
-
fileNames = await fs2.readdir(
|
|
70
|
+
fileNames = await fs2.readdir(modelsDirectoryAbsPath);
|
|
72
71
|
} catch (e) {
|
|
73
72
|
throw new Error(
|
|
74
|
-
`
|
|
73
|
+
`Could not read modelsDirectory at ${modelsDirectoryAbsPath}. Does the directory exist?Error: ${e}`
|
|
75
74
|
);
|
|
76
75
|
}
|
|
77
76
|
const tsFileNames = fileNames.filter((f) => f.endsWith(".ts") && !f.endsWith(".d.ts"));
|
|
@@ -81,10 +80,10 @@ var Config = class {
|
|
|
81
80
|
let defaultExport;
|
|
82
81
|
try {
|
|
83
82
|
defaultExport = await getDefaultExportFromModulePath(
|
|
84
|
-
path.join(
|
|
83
|
+
path.join(modelsDirectoryAbsPath, fileName)
|
|
85
84
|
);
|
|
86
85
|
} catch (err) {
|
|
87
|
-
console.warn(`
|
|
86
|
+
console.warn(`Failed to import ${fileName}, skipping: ${String(err)}`);
|
|
88
87
|
return null;
|
|
89
88
|
}
|
|
90
89
|
if (!this.isLucidModel(defaultExport)) {
|
|
@@ -100,20 +99,20 @@ var Config = class {
|
|
|
100
99
|
);
|
|
101
100
|
this.models = results.filter((m) => m !== null);
|
|
102
101
|
}
|
|
103
|
-
|
|
102
|
+
verifyColumnTypeOverrides() {
|
|
104
103
|
const validZeroTypes = ["string", "number", "boolean", "json", "enumeration"];
|
|
105
104
|
const modelNames = new Set(this.models.map((m) => m.name));
|
|
106
|
-
for (const [modelName, columnOverrides] of Object.entries(this.
|
|
105
|
+
for (const [modelName, columnOverrides] of Object.entries(this.columnTypeOverrides ?? {})) {
|
|
107
106
|
if (!modelNames.has(modelName)) {
|
|
108
107
|
throw new Error(
|
|
109
|
-
`
|
|
108
|
+
`columnTypeOverrides has unknown model "${modelName}". Known models: ${[...modelNames].join(", ")}`
|
|
110
109
|
);
|
|
111
110
|
}
|
|
112
111
|
for (const [attributeName, typeString] of Object.entries(columnOverrides)) {
|
|
113
112
|
const baseTypeName = typeString.match(/^([a-z]+)/)?.[1];
|
|
114
113
|
if (!baseTypeName || !validZeroTypes.includes(baseTypeName)) {
|
|
115
114
|
throw new Error(
|
|
116
|
-
`
|
|
115
|
+
`columnTypeOverrides override for ${modelName}.${attributeName} has unrecognised type "${typeString}". Expected one of: ${validZeroTypes.join(", ")}`
|
|
117
116
|
);
|
|
118
117
|
}
|
|
119
118
|
}
|
|
@@ -137,11 +136,11 @@ var ConfigLoader = class {
|
|
|
137
136
|
defaultExport = await getDefaultExportFromModulePath(absoluteConfigPath);
|
|
138
137
|
} catch (err) {
|
|
139
138
|
throw new Error(
|
|
140
|
-
`
|
|
141
|
-
Error: ${String(err)}`
|
|
139
|
+
`Failed to import config at ${absoluteConfigPath}
|
|
140
|
+
Error: ${err instanceof Error ? err.message : String(err)}`
|
|
142
141
|
);
|
|
143
142
|
}
|
|
144
|
-
const config = new Config(defaultExport,
|
|
143
|
+
const config = new Config(defaultExport, opts.tsconfigPath);
|
|
145
144
|
return config;
|
|
146
145
|
}
|
|
147
146
|
};
|
|
@@ -166,13 +165,13 @@ var SchemaTransformer = class {
|
|
|
166
165
|
project;
|
|
167
166
|
constructor(config, tsconfigPath) {
|
|
168
167
|
this.config = config;
|
|
169
|
-
this.project = new Project({ tsConfigFilePath: tsconfigPath ??
|
|
168
|
+
this.project = new Project({ tsConfigFilePath: tsconfigPath ?? config.tsconfigPath });
|
|
170
169
|
}
|
|
171
170
|
transform() {
|
|
172
171
|
return {
|
|
173
172
|
models: this.config.models.map((model) => {
|
|
174
173
|
const columnNameAndTypePairs = this.extractColumnNameAndType(model);
|
|
175
|
-
const columnOverrides = this.config.
|
|
174
|
+
const columnOverrides = this.config.columnTypeOverrides?.[model.name];
|
|
176
175
|
return {
|
|
177
176
|
tableName: model.table,
|
|
178
177
|
columns: this.mapColumns(columnNameAndTypePairs, columnOverrides, model),
|
|
@@ -190,12 +189,12 @@ var SchemaTransformer = class {
|
|
|
190
189
|
});
|
|
191
190
|
if (!modelSourceFile) {
|
|
192
191
|
throw new Error(
|
|
193
|
-
`
|
|
192
|
+
`Could not find source file for model ${model.name} in ${this.project.getSourceFiles().map((sourceFile) => sourceFile.getFilePath()).join(", ")}`
|
|
194
193
|
);
|
|
195
194
|
}
|
|
196
195
|
const classDeclaration = modelSourceFile.getClass(model.name);
|
|
197
196
|
if (!classDeclaration) {
|
|
198
|
-
throw new Error(`
|
|
197
|
+
throw new Error(`Could not find class declaration for model ${model.name}`);
|
|
199
198
|
}
|
|
200
199
|
let currentClass = classDeclaration;
|
|
201
200
|
while (currentClass) {
|
|
@@ -226,7 +225,7 @@ var SchemaTransformer = class {
|
|
|
226
225
|
zeroType = tsTypeToZeroType(tsType);
|
|
227
226
|
} else {
|
|
228
227
|
console.warn(
|
|
229
|
-
`
|
|
228
|
+
`Could not infer Zero type for ${model.name}.${attributeName}. Falling back to json(). Add a columnTypeOverrides entry if this is wrong.`
|
|
230
229
|
);
|
|
231
230
|
zeroType = "json()";
|
|
232
231
|
}
|
|
@@ -247,13 +246,13 @@ var SchemaTransformer = class {
|
|
|
247
246
|
relation.boot();
|
|
248
247
|
} catch (err) {
|
|
249
248
|
throw new Error(
|
|
250
|
-
`
|
|
249
|
+
`Failed to boot relation "${relationName}" on ${model.name}: ${String(err)}`
|
|
251
250
|
);
|
|
252
251
|
}
|
|
253
252
|
const relatedModel = relation.relatedModel();
|
|
254
253
|
if (!allModels.some((m) => m.name === relatedModel.name)) {
|
|
255
254
|
console.info(
|
|
256
|
-
`
|
|
255
|
+
`Skipping relation "${relationName}" on ${model.name} \u2014 ${relatedModel.name} is not included.`
|
|
257
256
|
);
|
|
258
257
|
continue;
|
|
259
258
|
}
|
|
@@ -285,7 +284,7 @@ var SchemaTransformer = class {
|
|
|
285
284
|
case "manyToMany": {
|
|
286
285
|
if (!relation.pivotTable || !relation.pivotForeignKey || !relation.pivotRelatedForeignKey) {
|
|
287
286
|
throw new Error(
|
|
288
|
-
`
|
|
287
|
+
`manyToMany relation "${relationName}" on ${model.name} \u2014 pivot table fields could not be resolved after boot().`
|
|
289
288
|
);
|
|
290
289
|
}
|
|
291
290
|
relationships[relationName] = {
|
|
@@ -310,7 +309,7 @@ var SchemaTransformer = class {
|
|
|
310
309
|
const throughRel = relation;
|
|
311
310
|
if (!throughRel.throughModel) {
|
|
312
311
|
throw new Error(
|
|
313
|
-
`
|
|
312
|
+
`hasManyThrough relation "${relationName}" on ${model.name} \u2014 throughModel could not be resolved after boot().`
|
|
314
313
|
);
|
|
315
314
|
}
|
|
316
315
|
const throughModel = throughRel.throughModel();
|
|
@@ -350,39 +349,6 @@ function tsTypeToZeroType(type) {
|
|
|
350
349
|
|
|
351
350
|
// src/code-generator.ts
|
|
352
351
|
import fs3 from "fs";
|
|
353
|
-
|
|
354
|
-
// src/formatter.ts
|
|
355
|
-
var Formatter = class _Formatter {
|
|
356
|
-
static async loadPrettier() {
|
|
357
|
-
let prettier;
|
|
358
|
-
try {
|
|
359
|
-
const { createRequire } = await import("module");
|
|
360
|
-
const req = createRequire(process.cwd() + "/package.json");
|
|
361
|
-
const prettierPath = req.resolve("prettier");
|
|
362
|
-
const { pathToFileURL } = await import("url");
|
|
363
|
-
prettier = await import(pathToFileURL(prettierPath).href);
|
|
364
|
-
return prettier;
|
|
365
|
-
} catch {
|
|
366
|
-
return null;
|
|
367
|
-
}
|
|
368
|
-
}
|
|
369
|
-
static async format(code) {
|
|
370
|
-
const prettier = await _Formatter.loadPrettier();
|
|
371
|
-
if (!prettier) {
|
|
372
|
-
console.warn("lucid-zero: prettier not found \u2014 skipping formatting");
|
|
373
|
-
return code;
|
|
374
|
-
}
|
|
375
|
-
try {
|
|
376
|
-
const options = await prettier.resolveConfig(process.cwd());
|
|
377
|
-
return await prettier.format(code, { ...options, parser: "typescript" });
|
|
378
|
-
} catch {
|
|
379
|
-
console.warn("lucid-zero: prettier formatting failed \u2014 skipping");
|
|
380
|
-
return code;
|
|
381
|
-
}
|
|
382
|
-
}
|
|
383
|
-
};
|
|
384
|
-
|
|
385
|
-
// src/code-generator.ts
|
|
386
352
|
var HEADER = `// This file was automatically generated by lucid-zero.
|
|
387
353
|
// Do NOT edit this file manually \u2014 it will be overwritten on the next run.`;
|
|
388
354
|
var CodeGenerator = class {
|
|
@@ -393,10 +359,7 @@ var CodeGenerator = class {
|
|
|
393
359
|
this.schema = schema;
|
|
394
360
|
}
|
|
395
361
|
async generateToOutputFile() {
|
|
396
|
-
|
|
397
|
-
if (this.config.formatOutputFile) {
|
|
398
|
-
code = await Formatter.format(code);
|
|
399
|
-
}
|
|
362
|
+
const code = this.generate();
|
|
400
363
|
fs3.writeFileSync(this.config.outputFilePath, code);
|
|
401
364
|
}
|
|
402
365
|
generate() {
|
|
@@ -548,7 +511,7 @@ async function run(options) {
|
|
|
548
511
|
try {
|
|
549
512
|
const config = await ConfigLoader.load(options);
|
|
550
513
|
await config.verify();
|
|
551
|
-
const schemaTransformer = new SchemaTransformer(config
|
|
514
|
+
const schemaTransformer = new SchemaTransformer(config);
|
|
552
515
|
const transformedSchema = schemaTransformer.transform();
|
|
553
516
|
const codeGenerator = new CodeGenerator(config, transformedSchema);
|
|
554
517
|
await codeGenerator.generateToOutputFile();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@antislop/zero-lucid-generator",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.1",
|
|
4
4
|
"description": "Generate Zero schemas from Lucid ORM models",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -19,13 +19,20 @@
|
|
|
19
19
|
"check-types": "tsc --noEmit",
|
|
20
20
|
"lint": "eslint src tests",
|
|
21
21
|
"lint:fix": "eslint src tests --fix",
|
|
22
|
-
"format": "
|
|
23
|
-
"format:check": "
|
|
22
|
+
"format": "oxfmt \"src/**/*.ts\" \"tests/**/*.ts\"",
|
|
23
|
+
"format:check": "oxfmt --check \"src/**/*.ts\" \"tests/**/*.ts\""
|
|
24
24
|
},
|
|
25
25
|
"bin": {
|
|
26
|
-
"lucid-zero": "
|
|
26
|
+
"lucid-zero": "dist/index.js"
|
|
27
27
|
},
|
|
28
|
-
"keywords": [
|
|
28
|
+
"keywords": [
|
|
29
|
+
"zero",
|
|
30
|
+
"lucid",
|
|
31
|
+
"adonisjs",
|
|
32
|
+
"schema",
|
|
33
|
+
"generator",
|
|
34
|
+
"rocicorp"
|
|
35
|
+
],
|
|
29
36
|
"author": "antislop",
|
|
30
37
|
"license": "ISC",
|
|
31
38
|
"publishConfig": {
|
|
@@ -43,8 +50,7 @@
|
|
|
43
50
|
"@typescript-eslint/parser": "^8.61.0",
|
|
44
51
|
"@vitest/coverage-v8": "^4.1.8",
|
|
45
52
|
"eslint": "^10.4.1",
|
|
46
|
-
"
|
|
47
|
-
"prettier": "^3.8.4",
|
|
53
|
+
"oxfmt": "^0.54.0",
|
|
48
54
|
"tsup": "^8.5.1",
|
|
49
55
|
"tsx": "^4.22.4",
|
|
50
56
|
"typescript": "^6.0.3",
|