hekireki 0.6.0 โ 0.6.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 +68 -28
- package/dist/cli/index.js +1 -1
- package/dist/generator/dbml/index.js +32 -16
- package/dist/generator/docs/index.js +11 -37
- package/dist/generator/mermaid-er/index.js +1 -1
- package/package.json +16 -15
package/README.md
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+

|
|
2
|
+
|
|
1
3
|
# Hekireki
|
|
2
4
|
|
|
3
5
|
**[Hekireki](https://www.npmjs.com/package/hekireki)** is a tool that generates validation schemas for Zod, Valibot, ArkType, and Effect Schema, as well as ER diagrams, from [Prisma](https://www.prisma.io/) schemas annotated with comments.
|
|
@@ -9,8 +11,7 @@
|
|
|
9
11
|
- ๐น Automatically generates [ArkType](https://arktype.io/) schemas from your Prisma schema
|
|
10
12
|
- โก Automatically generates [Effect Schema](https://effect.website/docs/schema/introduction/) from your Prisma schema
|
|
11
13
|
- ๐ Creates [Mermaid](https://mermaid.js.org/) ER diagrams with PK/FK markers
|
|
12
|
-
- ๐ Generates [DBML](https://dbml.dbdiagram.io/) (Database Markup Language) files
|
|
13
|
-
- ๐ผ๏ธ Outputs ER diagrams as **PNG/SVG** images using [dbml-renderer](https://github.com/softwaretechnik-berlin/dbml-renderer)
|
|
14
|
+
- ๐ Generates [DBML](https://dbml.dbdiagram.io/) (Database Markup Language) files and **PNG** ER diagrams via [dbml-renderer](https://github.com/softwaretechnik-berlin/dbml-renderer) โ output format is determined by the file extension (`.dbml` or `.png`)
|
|
14
15
|
- ๐งช Generates [Ecto](https://hexdocs.pm/ecto/Ecto.Schema.html) schemas for Elixir projects
|
|
15
16
|
โ ๏ธ Foreign key constraints are **not** included โ manage relationships in your application logic
|
|
16
17
|
|
|
@@ -51,28 +52,30 @@ generator Hekireki-ArkType {
|
|
|
51
52
|
provider = "hekireki-arktype"
|
|
52
53
|
type = true
|
|
53
54
|
comment = true
|
|
55
|
+
relation = true
|
|
54
56
|
}
|
|
55
57
|
|
|
56
58
|
generator Hekireki-Effect {
|
|
57
59
|
provider = "hekireki-effect"
|
|
58
60
|
type = true
|
|
59
61
|
comment = true
|
|
62
|
+
relation = true
|
|
60
63
|
}
|
|
61
64
|
|
|
62
65
|
generator Hekireki-Ecto {
|
|
63
66
|
provider = "hekireki-ecto"
|
|
64
|
-
output = "
|
|
67
|
+
output = "./ecto"
|
|
65
68
|
app = "DBSchema"
|
|
66
69
|
}
|
|
67
70
|
|
|
68
71
|
generator Hekireki-DBML {
|
|
69
72
|
provider = "hekireki-dbml"
|
|
73
|
+
output = "docs/schema.dbml"
|
|
70
74
|
}
|
|
71
75
|
|
|
72
|
-
generator Hekireki-
|
|
73
|
-
provider = "hekireki-
|
|
74
|
-
output = "docs"
|
|
75
|
-
format = "png"
|
|
76
|
+
generator Hekireki-Docs {
|
|
77
|
+
provider = "hekireki-docs"
|
|
78
|
+
output = "./docs"
|
|
76
79
|
}
|
|
77
80
|
|
|
78
81
|
model User {
|
|
@@ -122,9 +125,9 @@ model Post {
|
|
|
122
125
|
}
|
|
123
126
|
```
|
|
124
127
|
|
|
125
|
-
##
|
|
128
|
+
## Generated Output
|
|
126
129
|
|
|
127
|
-
|
|
130
|
+
### Zod
|
|
128
131
|
|
|
129
132
|
```ts
|
|
130
133
|
import * as z from 'zod'
|
|
@@ -178,7 +181,7 @@ export const PostRelationsSchema = z.object({
|
|
|
178
181
|
export type PostRelations = z.infer<typeof PostRelationsSchema>
|
|
179
182
|
```
|
|
180
183
|
|
|
181
|
-
|
|
184
|
+
### Valibot
|
|
182
185
|
|
|
183
186
|
```ts
|
|
184
187
|
import * as v from 'valibot'
|
|
@@ -232,7 +235,7 @@ export const PostRelationsSchema = v.object({
|
|
|
232
235
|
export type PostRelations = v.InferInput<typeof PostRelationsSchema>
|
|
233
236
|
```
|
|
234
237
|
|
|
235
|
-
|
|
238
|
+
### ArkType
|
|
236
239
|
|
|
237
240
|
```ts
|
|
238
241
|
import { type } from 'arktype'
|
|
@@ -260,7 +263,7 @@ export const PostSchema = type({
|
|
|
260
263
|
export type Post = typeof PostSchema.infer
|
|
261
264
|
```
|
|
262
265
|
|
|
263
|
-
|
|
266
|
+
### Effect Schema
|
|
264
267
|
|
|
265
268
|
```ts
|
|
266
269
|
import { Schema } from 'effect'
|
|
@@ -288,7 +291,7 @@ export const PostSchema = Schema.Struct({
|
|
|
288
291
|
export type Post = Schema.Schema.Type<typeof PostSchema>
|
|
289
292
|
```
|
|
290
293
|
|
|
291
|
-
|
|
294
|
+
### Mermaid
|
|
292
295
|
|
|
293
296
|
```mermaid
|
|
294
297
|
erDiagram
|
|
@@ -305,7 +308,7 @@ erDiagram
|
|
|
305
308
|
}
|
|
306
309
|
```
|
|
307
310
|
|
|
308
|
-
|
|
311
|
+
### Ecto
|
|
309
312
|
|
|
310
313
|
```elixir
|
|
311
314
|
defmodule DBSchema.User do
|
|
@@ -345,7 +348,7 @@ defmodule DBSchema.Post do
|
|
|
345
348
|
end
|
|
346
349
|
```
|
|
347
350
|
|
|
348
|
-
|
|
351
|
+
### DBML
|
|
349
352
|
|
|
350
353
|
```dbml
|
|
351
354
|
Table User {
|
|
@@ -365,11 +368,27 @@ Table Post {
|
|
|
365
368
|
Ref Post_userId_fk: Post.userId > User.id
|
|
366
369
|
```
|
|
367
370
|
|
|
368
|
-
|
|
371
|
+
### PNG
|
|
369
372
|
|
|
370
|
-
The `hekireki-
|
|
373
|
+
The `hekireki-dbml` generator also outputs ER diagrams as PNG images when the `output` path ends with `.png`:
|
|
371
374
|
|
|
372
|
-
|
|
375
|
+
```prisma
|
|
376
|
+
generator Hekireki-PNG {
|
|
377
|
+
provider = "hekireki-dbml"
|
|
378
|
+
output = "docs/er-diagram.png"
|
|
379
|
+
}
|
|
380
|
+
```
|
|
381
|
+
|
|
382
|
+
### Docs
|
|
383
|
+
|
|
384
|
+
The `hekireki-docs` generator creates an HTML documentation page from your Prisma schema. Serve it locally with `hekireki docs serve`:
|
|
385
|
+
|
|
386
|
+
```prisma
|
|
387
|
+
generator Hekireki-Docs {
|
|
388
|
+
provider = "hekireki-docs"
|
|
389
|
+
output = "./docs"
|
|
390
|
+
}
|
|
391
|
+
```
|
|
373
392
|
|
|
374
393
|
## Configuration
|
|
375
394
|
|
|
@@ -404,6 +423,7 @@ generator Hekireki-ArkType {
|
|
|
404
423
|
file = "index.ts" // File name (default: index.ts)
|
|
405
424
|
type = true // Generate TypeScript types (default: false)
|
|
406
425
|
comment = true // Include schema documentation (default: false)
|
|
426
|
+
relation = true // Generate relation schemas (default: false)
|
|
407
427
|
}
|
|
408
428
|
|
|
409
429
|
// Effect Schema Generator
|
|
@@ -413,6 +433,7 @@ generator Hekireki-Effect {
|
|
|
413
433
|
file = "index.ts" // File name (default: index.ts)
|
|
414
434
|
type = true // Generate TypeScript types (default: false)
|
|
415
435
|
comment = true // Include schema documentation (default: false)
|
|
436
|
+
relation = true // Generate relation schemas (default: false)
|
|
416
437
|
}
|
|
417
438
|
|
|
418
439
|
// Mermaid ER Generator
|
|
@@ -425,26 +446,45 @@ generator Hekireki-ER {
|
|
|
425
446
|
// Ecto Generator
|
|
426
447
|
generator Hekireki-Ecto {
|
|
427
448
|
provider = "hekireki-ecto"
|
|
428
|
-
output = "./ecto" // Output directory (default: ./ecto)
|
|
449
|
+
output = "./ecto" // Output directory (default: ./ecto/)
|
|
429
450
|
app = "MyApp" // App name (default: MyApp)
|
|
430
451
|
}
|
|
431
452
|
|
|
432
|
-
// DBML Generator
|
|
453
|
+
// DBML Generator (output extension determines format: .dbml or .png)
|
|
433
454
|
generator Hekireki-DBML {
|
|
434
455
|
provider = "hekireki-dbml"
|
|
435
|
-
output = "
|
|
436
|
-
|
|
456
|
+
output = "docs/schema.dbml" // File path ending in .dbml or .png
|
|
457
|
+
mapToDbSchema = true // Map to DB schema names (default: true)
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
// PNG output (same provider, different extension)
|
|
461
|
+
generator Hekireki-PNG {
|
|
462
|
+
provider = "hekireki-dbml"
|
|
463
|
+
output = "docs/er-diagram.png" // .png extension โ PNG output
|
|
464
|
+
mapToDbSchema = true // Map to DB schema names (default: true)
|
|
437
465
|
}
|
|
438
466
|
|
|
439
|
-
//
|
|
440
|
-
generator Hekireki-
|
|
441
|
-
provider = "hekireki-
|
|
442
|
-
output = "./docs"
|
|
443
|
-
file = "er-diagram" // File name without extension (default: er-diagram)
|
|
444
|
-
format = "png" // Output format: "png", "svg", or "dot" (default: png)
|
|
467
|
+
// Docs Generator
|
|
468
|
+
generator Hekireki-Docs {
|
|
469
|
+
provider = "hekireki-docs"
|
|
470
|
+
output = "./docs" // Output directory (default: ./docs)
|
|
445
471
|
}
|
|
446
472
|
```
|
|
447
473
|
|
|
474
|
+
## Docs Server
|
|
475
|
+
|
|
476
|
+
Hekireki includes a built-in documentation server powered by [Hono](https://hono.dev/). After generating docs with `prisma generate`, you can preview them locally:
|
|
477
|
+
|
|
478
|
+
```bash
|
|
479
|
+
# Start the docs server (default: http://localhost:5858)
|
|
480
|
+
hekireki docs serve
|
|
481
|
+
|
|
482
|
+
# Specify a custom port
|
|
483
|
+
hekireki docs serve -p 3000
|
|
484
|
+
```
|
|
485
|
+
|
|
486
|
+
> **Note:** Run `prisma generate` first to generate the `docs/` directory with `index.html`.
|
|
487
|
+
|
|
448
488
|
## License
|
|
449
489
|
|
|
450
490
|
Distributed under the MIT License. See [LICENSE](https://github.com/nakita628/hekireki?tab=MIT-1-ov-file) for more information.
|
package/dist/cli/index.js
CHANGED
|
@@ -58,7 +58,7 @@ const parsePort = (args) => {
|
|
|
58
58
|
error: "โ Error: --port requires a number"
|
|
59
59
|
};
|
|
60
60
|
const port = parseInt(portStr, 10);
|
|
61
|
-
if (isNaN(port)) return {
|
|
61
|
+
if (Number.isNaN(port)) return {
|
|
62
62
|
ok: false,
|
|
63
63
|
error: `โ Error: Invalid port number: ${portStr}`
|
|
64
64
|
};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { A as writeFileBinary, D as stripAnnotations, O as mkdir, T as quote, a as generateEnum, c as generateRef, k as writeFile, o as generateIndex, r as escapeNote, s as generatePrismaColumn, t as combineKeys, u as getString } from "../../utils-0nIzqFtt.js";
|
|
3
|
+
import { dirname } from "node:path";
|
|
3
4
|
import pkg from "@prisma/generator-helper";
|
|
4
5
|
import { Resvg } from "@resvg/resvg-js";
|
|
5
6
|
import { run } from "@softwaretechnik/dbml-renderer";
|
|
@@ -37,10 +38,10 @@ function generateTableIndexes(model) {
|
|
|
37
38
|
isUnique: true
|
|
38
39
|
}))];
|
|
39
40
|
}
|
|
40
|
-
function generateTables(models, mapToDbSchema = false
|
|
41
|
+
function generateTables(models, mapToDbSchema = false) {
|
|
41
42
|
return models.map((model) => {
|
|
42
43
|
const modelName = mapToDbSchema && model.dbName ? model.dbName : model.name;
|
|
43
|
-
const columnLines =
|
|
44
|
+
const columnLines = model.fields.map((field) => toDBMLColumn(field, models, mapToDbSchema)).map(generatePrismaColumn).join("\n");
|
|
44
45
|
const indexes = generateTableIndexes(model);
|
|
45
46
|
const indexBlock = indexes.length > 0 ? `\n\n indexes {\n${indexes.map(generateIndex).join("\n")}\n }` : "";
|
|
46
47
|
const strippedNote = stripAnnotations(model.documentation);
|
|
@@ -79,8 +80,8 @@ function generateRelations(models, mapToDbSchema = false) {
|
|
|
79
80
|
});
|
|
80
81
|
}));
|
|
81
82
|
}
|
|
82
|
-
function dbmlContent(datamodel, mapToDbSchema = false
|
|
83
|
-
const tables = generateTables(datamodel.models, mapToDbSchema
|
|
83
|
+
function dbmlContent(datamodel, mapToDbSchema = false) {
|
|
84
|
+
const tables = generateTables(datamodel.models, mapToDbSchema);
|
|
84
85
|
const enums = generateEnums(datamodel.enums);
|
|
85
86
|
const refs = generateRelations(datamodel.models, mapToDbSchema);
|
|
86
87
|
return [
|
|
@@ -98,8 +99,10 @@ const generateDbmlFile = async (outputDir, content, fileName) => {
|
|
|
98
99
|
return { ok: true };
|
|
99
100
|
};
|
|
100
101
|
const generatePng = async (outputDir, dbml, fileName) => {
|
|
101
|
-
|
|
102
|
-
|
|
102
|
+
return generatePngFile(`${outputDir}/${fileName}`, dbml);
|
|
103
|
+
};
|
|
104
|
+
const generatePngFile = async (outputPath, dbml) => {
|
|
105
|
+
const writeResult = await writeFileBinary(outputPath, new Resvg(run(dbml, "svg"), { font: { loadSystemFonts: true } }).render().asPng());
|
|
103
106
|
if (!writeResult.ok) return {
|
|
104
107
|
ok: false,
|
|
105
108
|
error: `Failed to write PNG: ${writeResult.error}`
|
|
@@ -113,17 +116,30 @@ const { generatorHandler } = pkg;
|
|
|
113
116
|
async function main(options) {
|
|
114
117
|
const { config } = options.generator;
|
|
115
118
|
const mapToDbSchema = getString(config?.mapToDbSchema) !== "false";
|
|
116
|
-
const
|
|
117
|
-
const content = dbmlContent(options.dmmf.datamodel, mapToDbSchema, includeRelationFields);
|
|
119
|
+
const content = dbmlContent(options.dmmf.datamodel, mapToDbSchema);
|
|
118
120
|
const output = options.generator.output?.value ?? "./dbml";
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
121
|
+
if (output.endsWith(".png") || output.endsWith(".dbml")) {
|
|
122
|
+
const mkdirResult = await mkdir(dirname(output));
|
|
123
|
+
if (!mkdirResult.ok) throw new Error(`Failed to create directory: ${mkdirResult.error}`);
|
|
124
|
+
if (output.endsWith(".png")) {
|
|
125
|
+
const pngResult = await generatePngFile(output, content);
|
|
126
|
+
if (!pngResult.ok) throw new Error(pngResult.error);
|
|
127
|
+
} else {
|
|
128
|
+
const dbmlResult = await writeFile(output, content);
|
|
129
|
+
if (!dbmlResult.ok) throw new Error(`Failed to write DBML: ${dbmlResult.error}`);
|
|
130
|
+
}
|
|
131
|
+
} else {
|
|
132
|
+
const file = getString(config?.file, "schema.dbml") ?? "schema.dbml";
|
|
133
|
+
const mkdirResult = await mkdir(output);
|
|
134
|
+
if (!mkdirResult.ok) throw new Error(`Failed to create directory: ${mkdirResult.error}`);
|
|
135
|
+
if (file.endsWith(".png")) {
|
|
136
|
+
const pngResult = await generatePng(output, content, file);
|
|
137
|
+
if (!pngResult.ok) throw new Error(pngResult.error);
|
|
138
|
+
} else {
|
|
139
|
+
const dbmlResult = await generateDbmlFile(output, content, file);
|
|
140
|
+
if (!dbmlResult.ok) throw new Error(dbmlResult.error);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
127
143
|
}
|
|
128
144
|
generatorHandler({
|
|
129
145
|
onManifest() {
|
|
@@ -25,19 +25,11 @@ const getMappings = (mappings, datamodel) => {
|
|
|
25
25
|
upsert: mapping.upsertOne || mapping.upsertSingle || mapping.upsert
|
|
26
26
|
}));
|
|
27
27
|
};
|
|
28
|
-
const transformDMMF = (dmmf
|
|
29
|
-
let datamodel = dmmf.datamodel;
|
|
30
|
-
if (!includeRelationFields) datamodel = {
|
|
31
|
-
...dmmf.datamodel,
|
|
32
|
-
models: dmmf.datamodel.models.map((model) => ({
|
|
33
|
-
...model,
|
|
34
|
-
fields: model.fields.filter((field) => !field.relationName)
|
|
35
|
-
}))
|
|
36
|
-
};
|
|
28
|
+
const transformDMMF = (dmmf) => {
|
|
37
29
|
return {
|
|
38
30
|
...dmmf,
|
|
39
|
-
datamodel,
|
|
40
|
-
mappings: getMappings(dmmf.mappings, datamodel)
|
|
31
|
+
datamodel: dmmf.datamodel,
|
|
32
|
+
mappings: getMappings(dmmf.mappings, dmmf.datamodel)
|
|
41
33
|
};
|
|
42
34
|
};
|
|
43
35
|
|
|
@@ -138,7 +130,6 @@ const darkModeToggleLabelClass = css`
|
|
|
138
130
|
`;
|
|
139
131
|
const iconClass = css`
|
|
140
132
|
color: var(--icon-color);
|
|
141
|
-
cursor: pointer;
|
|
142
133
|
`;
|
|
143
134
|
const h1Class = css`
|
|
144
135
|
font-size: 1.875rem;
|
|
@@ -167,9 +158,6 @@ const h4Class = css`
|
|
|
167
158
|
const textClass = css`
|
|
168
159
|
color: var(--text-primary);
|
|
169
160
|
`;
|
|
170
|
-
const textMutedClass = css`
|
|
171
|
-
color: var(--text-muted);
|
|
172
|
-
`;
|
|
173
161
|
const tableClass = css`
|
|
174
162
|
border-collapse: collapse;
|
|
175
163
|
table-layout: auto;
|
|
@@ -263,26 +251,12 @@ const hrSmallClass = css`
|
|
|
263
251
|
border: none;
|
|
264
252
|
border-top: 1px solid var(--border-color);
|
|
265
253
|
`;
|
|
266
|
-
const listClass = css`
|
|
267
|
-
margin: 0;
|
|
268
|
-
padding: 0;
|
|
269
|
-
list-style: none;
|
|
270
|
-
`;
|
|
271
254
|
const listItemClass = css`
|
|
272
255
|
margin-bottom: 1rem;
|
|
273
256
|
`;
|
|
274
257
|
const mb2Class = css`
|
|
275
258
|
margin-bottom: 0.5rem;
|
|
276
259
|
`;
|
|
277
|
-
const mb4Class = css`
|
|
278
|
-
margin-bottom: 1rem;
|
|
279
|
-
`;
|
|
280
|
-
const mt2Class = css`
|
|
281
|
-
margin-top: 0.5rem;
|
|
282
|
-
`;
|
|
283
|
-
const mt4Class = css`
|
|
284
|
-
margin-top: 1rem;
|
|
285
|
-
`;
|
|
286
260
|
const ml4Class = css`
|
|
287
261
|
margin-left: 1rem;
|
|
288
262
|
`;
|
|
@@ -373,8 +347,7 @@ const getOutputTypes = (dmmfOutputTypes) => dmmfOutputTypes.map((outputType) =>
|
|
|
373
347
|
nullable: !op.isNullable,
|
|
374
348
|
type: [{
|
|
375
349
|
isList: op.outputType.isList,
|
|
376
|
-
type: op.outputType.type
|
|
377
|
-
location: op.outputType.location
|
|
350
|
+
type: op.outputType.type
|
|
378
351
|
}]
|
|
379
352
|
}))
|
|
380
353
|
}));
|
|
@@ -401,6 +374,9 @@ const ModelAction = {
|
|
|
401
374
|
updateMany: "updateMany",
|
|
402
375
|
upsert: "upsert"
|
|
403
376
|
};
|
|
377
|
+
function isFieldDefault(v) {
|
|
378
|
+
return typeof v === "object" && v !== null && "name" in v && "args" in v;
|
|
379
|
+
}
|
|
404
380
|
const fieldDirectiveMap = new Map([
|
|
405
381
|
["isUnique", "@unique"],
|
|
406
382
|
["isId", "@id"],
|
|
@@ -593,7 +569,7 @@ const getFieldDirectives = (field) => {
|
|
|
593
569
|
if (mappedDirectiveValue) if (k === "hasDefaultValue" && field.default !== void 0) {
|
|
594
570
|
if (typeof field.default === "string" || typeof field.default === "number" || typeof field.default === "boolean") directives.push(`${mappedDirectiveValue}(${field.default})`);
|
|
595
571
|
else if (Array.isArray(field.default)) directives.push(`${mappedDirectiveValue}([${field.default.toString()}])`);
|
|
596
|
-
else if (
|
|
572
|
+
else if (isFieldDefault(field.default)) directives.push(`${mappedDirectiveValue}(${field.default.name}(${field.default.args.join(",")}))`);
|
|
597
573
|
} else directives.push(mappedDirectiveValue);
|
|
598
574
|
});
|
|
599
575
|
return directives;
|
|
@@ -883,7 +859,7 @@ const createTOC = (d) => {
|
|
|
883
859
|
|
|
884
860
|
//#endregion
|
|
885
861
|
//#region src/generator/docs/printer/index.tsx
|
|
886
|
-
const
|
|
862
|
+
const HekirekiLogo = () => /* @__PURE__ */ jsxs("svg", {
|
|
887
863
|
width: "40",
|
|
888
864
|
height: "40",
|
|
889
865
|
viewBox: "0 0 40 40",
|
|
@@ -953,7 +929,7 @@ const Sidebar = ({ toc }) => /* @__PURE__ */ jsxs("div", {
|
|
|
953
929
|
class: headerClass,
|
|
954
930
|
children: [/* @__PURE__ */ jsxs("div", {
|
|
955
931
|
class: logoContainerClass,
|
|
956
|
-
children: [/* @__PURE__ */ jsx(
|
|
932
|
+
children: [/* @__PURE__ */ jsx(HekirekiLogo, {}), /* @__PURE__ */ jsx("span", {
|
|
957
933
|
class: logoTextClass,
|
|
958
934
|
children: "Hekireki Docs"
|
|
959
935
|
})]
|
|
@@ -985,9 +961,7 @@ generatorHandler({
|
|
|
985
961
|
};
|
|
986
962
|
},
|
|
987
963
|
async onGenerate(options) {
|
|
988
|
-
const
|
|
989
|
-
const includeRelationFields = config.includeRelationFields !== "false";
|
|
990
|
-
const html = await generateHTML(transformDMMF(options.dmmf, { includeRelationFields }));
|
|
964
|
+
const html = await generateHTML(transformDMMF(options.dmmf));
|
|
991
965
|
const output = options.generator.output?.value;
|
|
992
966
|
if (!output) throw new Error("No output was specified for Hekireki Docs Generator");
|
|
993
967
|
await fs.mkdir(output, { recursive: true });
|
|
@@ -36,7 +36,7 @@ function extractRelationsFromDmmf(models) {
|
|
|
36
36
|
return models.flatMap((model) => model.fields.filter((field) => field.kind === "object" && field.relationFromFields && field.relationFromFields.length > 0).map((field) => {
|
|
37
37
|
const toModel = model.name;
|
|
38
38
|
const fromModel = field.type;
|
|
39
|
-
const toField = field.relationFromFields[0];
|
|
39
|
+
const toField = field.relationFromFields?.[0];
|
|
40
40
|
const fromField = field.relationToFields?.[0] ?? "id";
|
|
41
41
|
const fromCardinality = "one";
|
|
42
42
|
const toCardinality = (models.find((m) => m.name === fromModel)?.fields.find((f) => f.relationName === field.relationName && f.name !== field.name))?.isList ? field.isRequired ? "many" : "zero-many" : field.isRequired ? "one" : "zero-one";
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hekireki",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.6.
|
|
4
|
+
"version": "0.6.1",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"description": "Hekireki is a tool that generates validation schemas for Zod, Valibot, ArkType, and Effect Schema, as well as ER diagrams and DBML, from Prisma schemas annotated with comments.",
|
|
7
7
|
"keywords": [
|
|
@@ -51,25 +51,26 @@
|
|
|
51
51
|
"release": "npm pkg fix && pnpm build && npm publish"
|
|
52
52
|
},
|
|
53
53
|
"dependencies": {
|
|
54
|
-
"@hono/node-server": "^1.
|
|
55
|
-
"@prisma/generator-helper": "^7.0
|
|
54
|
+
"@hono/node-server": "^1.19.9",
|
|
55
|
+
"@prisma/generator-helper": "^7.4.0",
|
|
56
56
|
"@resvg/resvg-js": "^2.6.2",
|
|
57
57
|
"@softwaretechnik/dbml-renderer": "^1.0.31",
|
|
58
|
-
"hono": "^4.
|
|
59
|
-
"oxfmt": "^0.
|
|
58
|
+
"hono": "^4.11.9",
|
|
59
|
+
"oxfmt": "^0.32.0"
|
|
60
60
|
},
|
|
61
61
|
"devDependencies": {
|
|
62
|
-
"@prisma/client": "^7.0
|
|
63
|
-
"@types/node": "^
|
|
64
|
-
"@typescript/native-preview": "7.0.0-dev.
|
|
65
|
-
"@vitest/coverage-v8": "^4.0.
|
|
62
|
+
"@prisma/client": "^7.4.0",
|
|
63
|
+
"@types/node": "^25.2.3",
|
|
64
|
+
"@typescript/native-preview": "7.0.0-dev.20260214.1",
|
|
65
|
+
"@vitest/coverage-v8": "^4.0.18",
|
|
66
66
|
"arktype": "^2.1.29",
|
|
67
|
-
"effect": "^3.19.
|
|
68
|
-
"prisma": "^7.0
|
|
69
|
-
"tsdown": "^0.20.
|
|
70
|
-
"tsx": "^4.
|
|
67
|
+
"effect": "^3.19.17",
|
|
68
|
+
"prisma": "^7.4.0",
|
|
69
|
+
"tsdown": "^0.20.3",
|
|
70
|
+
"tsx": "^4.21.0",
|
|
71
|
+
"typescript": "^5.9.3",
|
|
71
72
|
"valibot": "1.2.0",
|
|
72
|
-
"vitest": "^4.0.
|
|
73
|
-
"zod": "^4.
|
|
73
|
+
"vitest": "^4.0.18",
|
|
74
|
+
"zod": "^4.3.6"
|
|
74
75
|
}
|
|
75
76
|
}
|