hekireki 0.8.6 → 0.9.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/dist/bin/ajv.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { t as registerGenerator } from "../bin-DLQOqGdU.js";
2
+ import { t as registerGenerator } from "../bin-CR8sx_jS.js";
3
3
  //#region src/bin/ajv.ts
4
4
  registerGenerator("ajv");
5
5
  //#endregion
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { t as registerGenerator } from "../bin-DLQOqGdU.js";
2
+ import { t as registerGenerator } from "../bin-CR8sx_jS.js";
3
3
  //#region src/bin/arktype.ts
4
4
  registerGenerator("arktype");
5
5
  //#endregion
package/dist/bin/dbml.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { t as registerGenerator } from "../bin-DLQOqGdU.js";
2
+ import { t as registerGenerator } from "../bin-CR8sx_jS.js";
3
3
  //#region src/bin/dbml.ts
4
4
  registerGenerator("dbml");
5
5
  //#endregion
package/dist/bin/docs.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { t as registerGenerator } from "../bin-DLQOqGdU.js";
2
+ import { t as registerGenerator } from "../bin-CR8sx_jS.js";
3
3
  //#region src/bin/docs.ts
4
4
  registerGenerator("docs");
5
5
  //#endregion
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { t as registerGenerator } from "../bin-DLQOqGdU.js";
2
+ import { t as registerGenerator } from "../bin-CR8sx_jS.js";
3
3
  //#region src/bin/drizzle.ts
4
4
  registerGenerator("drizzle");
5
5
  //#endregion
package/dist/bin/ecto.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { t as registerGenerator } from "../bin-DLQOqGdU.js";
2
+ import { t as registerGenerator } from "../bin-CR8sx_jS.js";
3
3
  //#region src/bin/ecto.ts
4
4
  registerGenerator("ecto");
5
5
  //#endregion
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { t as registerGenerator } from "../bin-DLQOqGdU.js";
2
+ import { t as registerGenerator } from "../bin-CR8sx_jS.js";
3
3
  //#region src/bin/effect.ts
4
4
  registerGenerator("effect");
5
5
  //#endregion
package/dist/bin/gorm.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { t as registerGenerator } from "../bin-DLQOqGdU.js";
2
+ import { t as registerGenerator } from "../bin-CR8sx_jS.js";
3
3
  //#region src/bin/gorm.ts
4
4
  registerGenerator("gorm");
5
5
  //#endregion
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { t as registerGenerator } from "../bin-DLQOqGdU.js";
2
+ import { t as registerGenerator } from "../bin-CR8sx_jS.js";
3
3
  //#region src/bin/mermaid-er.ts
4
4
  registerGenerator("mermaid-er");
5
5
  //#endregion
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { t as registerGenerator } from "../bin-DLQOqGdU.js";
2
+ import { t as registerGenerator } from "../bin-CR8sx_jS.js";
3
3
  //#region src/bin/sea-orm.ts
4
4
  registerGenerator("sea-orm");
5
5
  //#endregion
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { t as registerGenerator } from "../bin-DLQOqGdU.js";
2
+ import { t as registerGenerator } from "../bin-CR8sx_jS.js";
3
3
  //#region src/bin/sqlalchemy.ts
4
4
  registerGenerator("sqlalchemy");
5
5
  //#endregion
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { t as registerGenerator } from "../bin-DLQOqGdU.js";
2
+ import { t as registerGenerator } from "../bin-CR8sx_jS.js";
3
3
  //#region src/bin/typebox.ts
4
4
  registerGenerator("typebox");
5
5
  //#endregion
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { t as registerGenerator } from "../bin-DLQOqGdU.js";
2
+ import { t as registerGenerator } from "../bin-CR8sx_jS.js";
3
3
  //#region src/bin/valibot.ts
4
4
  registerGenerator("valibot");
5
5
  //#endregion
package/dist/bin/zod.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { t as registerGenerator } from "../bin-DLQOqGdU.js";
2
+ import { t as registerGenerator } from "../bin-CR8sx_jS.js";
3
3
  //#region src/bin/zod.ts
4
4
  registerGenerator("zod");
5
5
  //#endregion
@@ -1043,13 +1043,15 @@ const getOutputTypes = (dmmfOutputTypes) => dmmfOutputTypes.map((outputType) =>
1043
1043
  }))
1044
1044
  }));
1045
1045
  const getTypesData = (d) => {
1046
+ const prismaInputTypes = d.schema.inputObjectTypes.prisma ?? [];
1046
1047
  return {
1047
- inputTypes: getInputTypes(d.schema.inputObjectTypes.prisma ?? []),
1048
+ inputTypes: getInputTypes(prismaInputTypes),
1048
1049
  outputTypes: getOutputTypes([...d.schema.outputObjectTypes.model, ...d.schema.outputObjectTypes.prisma.filter((op) => op.name !== "Query" && op.name !== "Mutation")])
1049
1050
  };
1050
1051
  };
1051
1052
  const createTypes = (d) => {
1052
- return /* @__PURE__ */ jsx(TypesSection, { data: getTypesData(d) });
1053
+ const data = getTypesData(d);
1054
+ return /* @__PURE__ */ jsx(TypesSection, { data });
1053
1055
  };
1054
1056
  //#endregion
1055
1057
  //#region src/helper/docs/generator/model.tsx
@@ -1414,7 +1416,8 @@ const getModels$1 = (dmmf) => dmmf.datamodel.models.map((model) => ({
1414
1416
  }));
1415
1417
  const getModelData = (d) => ({ models: getModels$1(d) });
1416
1418
  const createModels = (d) => {
1417
- return /* @__PURE__ */ jsx(ModelsSection, { data: getModelData(d) });
1419
+ const data = getModelData(d);
1420
+ return /* @__PURE__ */ jsx(ModelsSection, { data });
1418
1421
  };
1419
1422
  //#endregion
1420
1423
  //#region src/helper/docs/generator/toc.tsx
@@ -1543,7 +1546,8 @@ const getTOCData = (d) => ({
1543
1546
  types: getTypes(d.schema)
1544
1547
  });
1545
1548
  const createTOC = (d) => {
1546
- return /* @__PURE__ */ jsx(TOCComponent, { data: getTOCData(d) });
1549
+ const data = getTOCData(d);
1550
+ return /* @__PURE__ */ jsx(TOCComponent, { data });
1547
1551
  };
1548
1552
  //#endregion
1549
1553
  //#region src/helper/docs/printer/index.tsx
@@ -1802,6 +1806,18 @@ function resolveVarNameByType(type, models) {
1802
1806
  function isFieldDefault(v) {
1803
1807
  return typeof v === "object" && v !== null && "name" in v;
1804
1808
  }
1809
+ function enumIdentifier(enumName) {
1810
+ return `${snakeToCamel(makeSnakeCase(enumName))}Enum`;
1811
+ }
1812
+ function makeEnumDeclarations(models, enums, provider, imports) {
1813
+ if (provider !== "postgresql") return [];
1814
+ const usedEnumNames = new Set(models.flatMap((m) => m.fields.filter((f) => f.kind === "enum").map((f) => f.type)));
1815
+ return enums.filter((e) => usedEnumNames.has(e.name)).map((e) => {
1816
+ imports.core.add("pgEnum");
1817
+ const values = e.values.map((v) => `'${v.name}'`).join(", ");
1818
+ return `export const ${enumIdentifier(e.name)} = pgEnum('${e.dbName ?? e.name}', [${values}])`;
1819
+ });
1820
+ }
1805
1821
  function resolveScalarType(field, provider) {
1806
1822
  if (field.nativeType && provider !== "sqlite") {
1807
1823
  const [nativeName, nativeArgs] = field.nativeType;
@@ -1816,10 +1832,7 @@ function makeColumnExpr(field, provider, imports, enums) {
1816
1832
  if (field.kind === "enum") {
1817
1833
  const enumDef = enums.find((e) => e.name === field.type);
1818
1834
  const enumValues = enumDef ? enumDef.values.map((v) => `'${v.name}'`).join(", ") : "";
1819
- if (provider === "postgresql") {
1820
- imports.core.add("pgEnum");
1821
- return `pgEnum('${enumDef?.dbName ?? field.type}', [${enumValues}])('${colName}')`;
1822
- }
1835
+ if (provider === "postgresql") return `${enumIdentifier(field.type)}('${colName}')`;
1823
1836
  if (provider === "mysql") {
1824
1837
  imports.core.add("mysqlEnum");
1825
1838
  return `mysqlEnum('${colName}', [${enumValues}])`;
@@ -1977,6 +1990,7 @@ function makeColumn(field, model, models, provider, imports, enums) {
1977
1990
  const hasCompositePK = model.primaryKey !== null;
1978
1991
  const colExpr = makeColumnExpr(field, provider, imports, enums);
1979
1992
  const chain = [
1993
+ field.isList && field.kind === "scalar" && provider === "postgresql" ? ".array()" : "",
1980
1994
  field.isId && !hasCompositePK ? isAutoincrement && provider === "sqlite" ? ".primaryKey({ autoIncrement: true })" : ".primaryKey()" : "",
1981
1995
  field.isRequired && !field.isId && !(isAutoincrement && provider === "postgresql") ? ".notNull()" : "",
1982
1996
  field.isUnique ? ".unique()" : "",
@@ -1986,8 +2000,7 @@ function makeColumn(field, model, models, provider, imports, enums) {
1986
2000
  if (r.needsSql) imports.orm.add("sql");
1987
2001
  return r.chain;
1988
2002
  })() : makeDefaultChain(field.default, field.type, provider, imports),
1989
- field.isUpdatedAt ? ".$onUpdate(() => new Date())" : "",
1990
- field.isList && field.kind === "scalar" && provider === "postgresql" ? ".array()" : ""
2003
+ field.isUpdatedAt ? ".$onUpdate(() => new Date())" : ""
1991
2004
  ].join("");
1992
2005
  return `${field.name}: ${colExpr}${chain}`;
1993
2006
  }
@@ -2055,6 +2068,7 @@ function makeRelations(models, imports) {
2055
2068
  function drizzleSchema(datamodel, provider, indexes) {
2056
2069
  const db = resolveDbProvider(provider);
2057
2070
  const imports = createImports();
2071
+ const enumLines = makeEnumDeclarations(datamodel.models, datamodel.enums, db, imports);
2058
2072
  const tableLines = datamodel.models.map((model) => makeTable(model, datamodel.models, db, imports, datamodel.enums, indexes));
2059
2073
  const relationsLines = makeRelations(datamodel.models, imports);
2060
2074
  const tableLinesWithGap = tableLines.flatMap((line, i) => i < tableLines.length - 1 ? [line, ""] : [line]);
@@ -2062,6 +2076,7 @@ function drizzleSchema(datamodel, provider, indexes) {
2062
2076
  return [
2063
2077
  generateImports(imports, db),
2064
2078
  "",
2079
+ ...enumLines.length > 0 ? [...enumLines, ""] : [],
2065
2080
  ...tableLinesWithGap,
2066
2081
  ...relationsLinesWithGap.length > 0 ? ["", ...relationsLinesWithGap] : []
2067
2082
  ].join("\n");
@@ -2198,6 +2213,7 @@ function getAssociations$3(model, allModels) {
2198
2213
  const belongsTo = [];
2199
2214
  const hasMany = [];
2200
2215
  const hasOne = [];
2216
+ const manyToMany = [];
2201
2217
  for (const field of model.fields) {
2202
2218
  if (field.kind !== "object") continue;
2203
2219
  if (field.relationFromFields && field.relationFromFields.length > 0) {
@@ -2213,7 +2229,15 @@ function getAssociations$3(model, allModels) {
2213
2229
  const targetModel = allModels.find((m) => m.name === field.type);
2214
2230
  if (!targetModel) continue;
2215
2231
  if (field.isList) {
2216
- if (targetModel.fields.find((f) => f.relationName === field.relationName && f.kind === "object")?.isList) continue;
2232
+ if (targetModel.fields.find((f) => f.relationName === field.relationName && f.kind === "object")?.isList) {
2233
+ const [left, right] = model.name < field.type ? [model.name, field.type] : [field.type, model.name];
2234
+ manyToMany.push({
2235
+ name: field.name,
2236
+ targetModel: field.type,
2237
+ joinThrough: `_${left}To${right}`
2238
+ });
2239
+ continue;
2240
+ }
2217
2241
  }
2218
2242
  const foreignKey = targetModel.fields.find((f) => f.relationName === field.relationName && f.relationFromFields && f.relationFromFields.length > 0)?.relationFromFields?.[0];
2219
2243
  if (!foreignKey) continue;
@@ -2231,7 +2255,8 @@ function getAssociations$3(model, allModels) {
2231
2255
  return {
2232
2256
  belongsTo,
2233
2257
  hasMany,
2234
- hasOne
2258
+ hasOne,
2259
+ manyToMany
2235
2260
  };
2236
2261
  }
2237
2262
  function ectoSchemas(models, app, allModels, enums) {
@@ -2271,7 +2296,8 @@ function ectoSchemas(models, app, allModels, enums) {
2271
2296
  }),
2272
2297
  ...associations.belongsTo.map((a) => `${makeSnakeCase(a.name)}: ${appName}.${a.targetModel}.t() | nil`),
2273
2298
  ...associations.hasOne.map((a) => `${makeSnakeCase(a.name)}: ${appName}.${a.targetModel}.t() | nil`),
2274
- ...associations.hasMany.map((a) => `${makeSnakeCase(a.name)}: [${appName}.${a.targetModel}.t()]`)
2299
+ ...associations.hasMany.map((a) => `${makeSnakeCase(a.name)}: [${appName}.${a.targetModel}.t()]`),
2300
+ ...associations.manyToMany.map((a) => `${makeSnakeCase(a.name)}: [${appName}.${a.targetModel}.t()]`)
2275
2301
  ];
2276
2302
  const typeSpecLines = [
2277
2303
  " @type t :: %__MODULE__{",
@@ -2294,7 +2320,8 @@ function ectoSchemas(models, app, allModels, enums) {
2294
2320
  const defaultOpt = ((def) => {
2295
2321
  if (def === void 0 || def === null) return null;
2296
2322
  if (typeof def === "string") return `default: "${def}"`;
2297
- if (typeof def === "number" || typeof def === "boolean") return `default: ${def}`;
2323
+ if (typeof def === "number") return type === "float" && Number.isInteger(def) ? `default: ${def}.0` : `default: ${def}`;
2324
+ if (typeof def === "boolean") return `default: ${def}`;
2298
2325
  return null;
2299
2326
  })(f.default);
2300
2327
  return ` field(:${snakeName}, ${ectoType}${primary}${defaultOpt ? `, ${defaultOpt}` : ""}${sourceOpt})`;
@@ -2331,6 +2358,9 @@ function ectoSchemas(models, app, allModels, enums) {
2331
2358
  const snakeFk = makeSnakeCase(a.foreignKey);
2332
2359
  return ` has_many(:${makeSnakeCase(a.name)}, ${appName}.${a.targetModel}, foreign_key: :${snakeFk})`;
2333
2360
  });
2361
+ const manyToManyLines = associations.manyToMany.map((a) => {
2362
+ return ` many_to_many(:${makeSnakeCase(a.name)}, ${appName}.${a.targetModel}, join_through: "${a.joinThrough}")`;
2363
+ });
2334
2364
  return [
2335
2365
  `defmodule ${appName}.${model.name} do`,
2336
2366
  " use Ecto.Schema",
@@ -2351,6 +2381,7 @@ function ectoSchemas(models, app, allModels, enums) {
2351
2381
  ...belongsToLines,
2352
2382
  ...hasOneLines,
2353
2383
  ...hasManyLines,
2384
+ ...manyToManyLines,
2354
2385
  ...timestampsLine ? [timestampsLine] : [],
2355
2386
  " end",
2356
2387
  "end"
@@ -2561,7 +2592,7 @@ function formatGoDefault(def) {
2561
2592
  if (def === void 0 || def === null) return null;
2562
2593
  if (typeof def === "boolean") return def ? "true" : "false";
2563
2594
  if (typeof def === "number") return String(def);
2564
- if (typeof def === "string") return def;
2595
+ if (typeof def === "string") return `'${def}'`;
2565
2596
  return null;
2566
2597
  }
2567
2598
  function buildGormTags(field, isPk, isCompositePk, compositeIndexTags) {
@@ -2580,6 +2611,7 @@ function buildGormTags(field, isPk, isCompositePk, compositeIndexTags) {
2580
2611
  field.isUnique ? "uniqueIndex" : null,
2581
2612
  ...compositeIndexTags,
2582
2613
  includeNativeType ? `type:${nativeType}` : null,
2614
+ field.isList && field.kind !== "object" ? "serializer:json" : null,
2583
2615
  includeAutoCreate ? "autoCreateTime" : null,
2584
2616
  defaultVal !== null ? `default:${defaultVal}` : null,
2585
2617
  field.isUpdatedAt ? "autoUpdateTime" : null,
@@ -2587,14 +2619,16 @@ function buildGormTags(field, isPk, isCompositePk, compositeIndexTags) {
2587
2619
  ].filter((p) => p !== null).join(";")}" json:"${columnName}"\``;
2588
2620
  }
2589
2621
  function collectCompositeIndexTags(model, indexes) {
2622
+ const tableName = model.dbName ?? makeSnakeCase(model.name);
2590
2623
  const uniqueTags = model.uniqueFields.filter((fields) => fields.length > 1).flatMap((fields) => {
2591
- const idxName = `idx_${fields.map((f) => {
2624
+ const cols = fields.map((f) => {
2592
2625
  return model.fields.find((mf) => mf.name === f)?.dbName ?? makeSnakeCase(f);
2593
- }).join("_")}_unique`;
2626
+ });
2627
+ const idxName = `idx_${tableName}_${cols.join("_")}_unique`;
2594
2628
  return fields.map((f) => [f, `uniqueIndex:${idxName}`]);
2595
2629
  });
2596
2630
  const indexTags = indexes.filter((idx) => idx.model === model.name && (idx.type === "normal" || idx.type === "fulltext")).flatMap((idx) => {
2597
- const idxName = idx.dbName ?? idx.name ?? `idx_${idx.fields.map((f) => makeSnakeCase(f.name)).join("_")}`;
2631
+ const idxName = idx.dbName ?? idx.name ?? `idx_${tableName}_${idx.fields.map((f) => makeSnakeCase(f.name)).join("_")}`;
2598
2632
  return idx.fields.map((f) => [f.name, `index:${idxName}`]);
2599
2633
  });
2600
2634
  return [...uniqueTags, ...indexTags].reduce((map, [fieldName, tag]) => {
@@ -2659,7 +2693,8 @@ function goFieldName(name) {
2659
2693
  }
2660
2694
  function generateStructField(field, isPk, isCompositePk, compositeIndexTags, _enumNames) {
2661
2695
  const fieldName = goFieldName(field.name);
2662
- const goType = field.kind === "enum" ? field.isRequired ? "string" : "*string" : prismaTypeToGoType(field.type, field.isRequired);
2696
+ const scalarType = field.kind === "enum" ? field.isRequired ? "string" : "*string" : prismaTypeToGoType(field.type, field.isRequired);
2697
+ const goType = field.isList ? `[]${field.kind === "enum" ? "string" : prismaTypeToGoType(field.type, true)}` : scalarType;
2663
2698
  const tag = buildGormTags(field, isPk, isCompositePk, compositeIndexTags);
2664
2699
  return `\t${fieldName} ${goType}${tag ? ` ${tag}` : ""}`;
2665
2700
  }
@@ -2675,7 +2710,8 @@ function generateRelationFields(model, associations) {
2675
2710
  const fkFieldName = goFieldName(assoc.foreignKey);
2676
2711
  const refsFieldName = goFieldName(assoc.references);
2677
2712
  const tagParts = [fieldName !== assoc.targetModel || associations.belongsTo.filter((a) => a.targetModel === assoc.targetModel).length > 1 ? `foreignKey:${fkFieldName}` : null, needsReferencesTag(assoc.references) ? `references:${refsFieldName}` : null].filter((p) => p !== null);
2678
- return tagParts.length > 0 ? `\t${fieldName} ${assoc.targetModel} ${buildRelationTag(tagParts)}` : `\t${fieldName} ${assoc.targetModel}`;
2713
+ const targetType = assoc.targetModel === model.name ? `*${assoc.targetModel}` : assoc.targetModel;
2714
+ return tagParts.length > 0 ? `\t${fieldName} ${targetType} ${buildRelationTag(tagParts)}` : `\t${fieldName} ${targetType}`;
2679
2715
  });
2680
2716
  const hasManyLines = associations.hasMany.map((assoc) => {
2681
2717
  const tagParts = [`foreignKey:${goFieldName(assoc.foreignKey)}`, ...needsReferencesTag(assoc.references) ? [`references:${goFieldName(assoc.references)}`] : []];
@@ -2683,7 +2719,7 @@ function generateRelationFields(model, associations) {
2683
2719
  });
2684
2720
  const hasOneLines = associations.hasOne.map((assoc) => {
2685
2721
  const tagParts = [`foreignKey:${goFieldName(assoc.foreignKey)}`, ...needsReferencesTag(assoc.references) ? [`references:${goFieldName(assoc.references)}`] : []];
2686
- return `\t${goFieldName(assoc.name)} ${assoc.targetModel} ${buildRelationTag(tagParts)}`;
2722
+ return `\t${goFieldName(assoc.name)} *${assoc.targetModel} ${buildRelationTag(tagParts)}`;
2687
2723
  });
2688
2724
  const manyToManyLines = associations.manyToMany.map((assoc) => {
2689
2725
  const [leftName, rightName] = model.name < assoc.targetModel ? [model.name, assoc.targetModel] : [assoc.targetModel, model.name];
@@ -2707,7 +2743,9 @@ function generateModelStruct(model, allModels, enums, indexes) {
2707
2743
  const compositeTagMap = collectCompositeIndexTags(model, indexes);
2708
2744
  const tableName = model.dbName ?? makeSnakeCase(model.name);
2709
2745
  const fieldLines = model.fields.filter((f) => f.kind !== "object").map((field) => {
2710
- return generateStructField(field, field.isId || compositePkFieldNames.has(field.name), isCompositePk, compositeTagMap.get(field.name) ?? [], enumNames);
2746
+ const isPk = field.isId || compositePkFieldNames.has(field.name);
2747
+ const fieldIndexTags = compositeTagMap.get(field.name) ?? [];
2748
+ return generateStructField(field, isPk, isCompositePk, fieldIndexTags, enumNames);
2711
2749
  });
2712
2750
  const relationLines = generateRelationFields(model, associations);
2713
2751
  const tableNameMethod = tableName !== makeSnakeCase(model.name) ? [
@@ -2774,6 +2812,9 @@ const RELATIONSHIPS = {
2774
2812
  "zero-many": "}o",
2775
2813
  many: "}|"
2776
2814
  };
2815
+ function escapeComment(comment) {
2816
+ return comment.replace(/\r?\n/g, " ").replace(/"/g, "#quot;");
2817
+ }
2777
2818
  function erRelationLine(relation, resolveName = (model) => model) {
2778
2819
  return ` ${resolveName(relation.from.model)} ${RELATIONSHIPS[relation.from.cardinality]}--${RELATIONSHIPS[relation.to.cardinality]} ${resolveName(relation.to.model)} : "(${relation.from.field}) - (${relation.to.field})"`;
2779
2820
  }
@@ -2784,7 +2825,7 @@ function modelFields(model) {
2784
2825
  const commentPart = stripAnnotations(field.documentation) ?? "";
2785
2826
  const keyMarker = field.isId ? "PK" : fkFields.has(field.name) ? "FK" : "";
2786
2827
  const keyPart = keyMarker ? ` ${keyMarker}` : "";
2787
- return ` ${field.type.toLowerCase()} ${field.name}${keyPart}${commentPart ? ` "${commentPart}"` : ""}`;
2828
+ return ` ${field.type.toLowerCase()} ${field.name}${keyPart}${commentPart ? ` "${escapeComment(commentPart)}"` : ""}`;
2788
2829
  }).filter((field) => field !== null);
2789
2830
  }
2790
2831
  function modelInfo(model) {
@@ -2845,6 +2886,80 @@ function prismaTypeToRustType(type, isRequired) {
2845
2886
  if (!isRequired) return `Option<${base}>`;
2846
2887
  return base;
2847
2888
  }
2889
+ const RUST_KEYWORDS = /* @__PURE__ */ new Set([
2890
+ "as",
2891
+ "break",
2892
+ "const",
2893
+ "continue",
2894
+ "crate",
2895
+ "dyn",
2896
+ "else",
2897
+ "enum",
2898
+ "extern",
2899
+ "false",
2900
+ "fn",
2901
+ "for",
2902
+ "if",
2903
+ "impl",
2904
+ "in",
2905
+ "let",
2906
+ "loop",
2907
+ "match",
2908
+ "mod",
2909
+ "move",
2910
+ "mut",
2911
+ "pub",
2912
+ "ref",
2913
+ "return",
2914
+ "self",
2915
+ "Self",
2916
+ "static",
2917
+ "struct",
2918
+ "super",
2919
+ "trait",
2920
+ "true",
2921
+ "type",
2922
+ "unsafe",
2923
+ "use",
2924
+ "where",
2925
+ "while",
2926
+ "async",
2927
+ "await",
2928
+ "abstract",
2929
+ "become",
2930
+ "box",
2931
+ "do",
2932
+ "final",
2933
+ "macro",
2934
+ "override",
2935
+ "priv",
2936
+ "typeof",
2937
+ "unsized",
2938
+ "virtual",
2939
+ "yield",
2940
+ "try",
2941
+ "gen"
2942
+ ]);
2943
+ const RUST_NON_RAW = /* @__PURE__ */ new Set([
2944
+ "self",
2945
+ "Self",
2946
+ "crate",
2947
+ "super"
2948
+ ]);
2949
+ function rustFieldIdent(snake) {
2950
+ if (!RUST_KEYWORDS.has(snake)) return {
2951
+ ident: snake,
2952
+ derivedColumn: snake
2953
+ };
2954
+ if (RUST_NON_RAW.has(snake)) return {
2955
+ ident: `${snake}_`,
2956
+ derivedColumn: `${snake}_`
2957
+ };
2958
+ return {
2959
+ ident: `r#${snake}`,
2960
+ derivedColumn: snake
2961
+ };
2962
+ }
2848
2963
  function resolveSeaOrmColumnType(field) {
2849
2964
  if (!field.nativeType) return null;
2850
2965
  const [nativeName, nativeArgs] = field.nativeType;
@@ -2887,7 +3002,7 @@ function formatRustDefault(def) {
2887
3002
  if (typeof def === "string") return `"${def}"`;
2888
3003
  return null;
2889
3004
  }
2890
- function buildSeaOrmAttributes(field, isPk, isCompositePk) {
3005
+ function buildSeaOrmAttributes(field, isPk, isCompositePk, derivedColumn) {
2891
3006
  const attrs = [];
2892
3007
  if (isPk) {
2893
3008
  const parts = ["primary_key"];
@@ -2897,7 +3012,7 @@ function buildSeaOrmAttributes(field, isPk, isCompositePk) {
2897
3012
  if (field.isUnique) attrs.push("#[sea_orm(unique)]");
2898
3013
  const columnParts = [];
2899
3014
  const columnName = field.dbName ?? makeSnakeCase(field.name);
2900
- if (columnName !== makeSnakeCase(field.name)) columnParts.push(`column_name = "${columnName}"`);
3015
+ if (columnName !== (derivedColumn ?? makeSnakeCase(field.name))) columnParts.push(`column_name = "${columnName}"`);
2901
3016
  const colType = resolveSeaOrmColumnType(field);
2902
3017
  if (colType) columnParts.push(`column_type = "${colType}"`);
2903
3018
  if (!isPk || isCompositePk) {
@@ -2984,7 +3099,7 @@ function buildSerdeAttributes(opts) {
2984
3099
  }
2985
3100
  function generateEnum(e, serde = {}) {
2986
3101
  const variants = e.values.map((v) => {
2987
- const pascalName = v.name.charAt(0).toUpperCase() + v.name.slice(1).toLowerCase();
3102
+ const pascalName = v.name.split("_").filter((part) => part !== "").map((part) => part.charAt(0).toUpperCase() + part.slice(1).toLowerCase()).join("");
2988
3103
  return ` #[sea_orm(string_value = "${v.name}")]\n ${pascalName},`;
2989
3104
  });
2990
3105
  return [
@@ -3025,9 +3140,10 @@ function generateRelationEnum(_model, associations) {
3025
3140
  }
3026
3141
  function generateRelatedImpls(model, associations) {
3027
3142
  const impls = [];
3028
- const m2mTargets = new Set(associations.manyToMany.map((a) => a.targetModel));
3143
+ const emittedTargets = /* @__PURE__ */ new Set();
3029
3144
  for (const assoc of associations.belongsTo) {
3030
- if (m2mTargets.has(assoc.targetModel)) continue;
3145
+ if (emittedTargets.has(assoc.targetModel)) continue;
3146
+ emittedTargets.add(assoc.targetModel);
3031
3147
  const targetModule = toModuleName(assoc.targetModel);
3032
3148
  impls.push([
3033
3149
  `impl Related<super::${targetModule}::Entity> for Entity {`,
@@ -3038,7 +3154,8 @@ function generateRelatedImpls(model, associations) {
3038
3154
  ].join("\n"));
3039
3155
  }
3040
3156
  for (const assoc of associations.hasMany) {
3041
- if (m2mTargets.has(assoc.targetModel)) continue;
3157
+ if (emittedTargets.has(assoc.targetModel)) continue;
3158
+ emittedTargets.add(assoc.targetModel);
3042
3159
  const targetModule = toModuleName(assoc.targetModel);
3043
3160
  impls.push([
3044
3161
  `impl Related<super::${targetModule}::Entity> for Entity {`,
@@ -3049,7 +3166,8 @@ function generateRelatedImpls(model, associations) {
3049
3166
  ].join("\n"));
3050
3167
  }
3051
3168
  for (const assoc of associations.hasOne) {
3052
- if (m2mTargets.has(assoc.targetModel)) continue;
3169
+ if (emittedTargets.has(assoc.targetModel)) continue;
3170
+ emittedTargets.add(assoc.targetModel);
3053
3171
  const targetModule = toModuleName(assoc.targetModel);
3054
3172
  impls.push([
3055
3173
  `impl Related<super::${targetModule}::Entity> for Entity {`,
@@ -3060,6 +3178,8 @@ function generateRelatedImpls(model, associations) {
3060
3178
  ].join("\n"));
3061
3179
  }
3062
3180
  for (const assoc of associations.manyToMany) {
3181
+ if (emittedTargets.has(assoc.targetModel)) continue;
3182
+ emittedTargets.add(assoc.targetModel);
3063
3183
  const targetModule = toModuleName(assoc.targetModel);
3064
3184
  const [leftName, rightName] = model.name < assoc.targetModel ? [model.name, assoc.targetModel] : [assoc.targetModel, model.name];
3065
3185
  const junctionModule = toSnakeCase(`${leftName}To${rightName}`);
@@ -3089,15 +3209,21 @@ function generateEntityFile(model, allModels, enums, serde = {}) {
3089
3209
  const scalarFields = model.fields.filter((f) => f.kind !== "object");
3090
3210
  const fieldLines = [];
3091
3211
  for (const field of scalarFields) {
3092
- const attrs = buildSeaOrmAttributes(field, field.isId || compositePkFieldNames.has(field.name), isCompositePk);
3093
- const rustType = enumNames.has(field.type) ? field.isRequired ? field.type : `Option<${field.type}>` : prismaTypeToRustType(field.type, field.isRequired);
3094
- const fieldName = toSnakeCase(field.name);
3212
+ const isPk = field.isId || compositePkFieldNames.has(field.name);
3213
+ const { ident: fieldName, derivedColumn } = rustFieldIdent(toSnakeCase(field.name));
3214
+ const attrs = buildSeaOrmAttributes(field, isPk, isCompositePk, derivedColumn);
3215
+ const elemType = enumNames.has(field.type) ? field.type : prismaTypeToRustType(field.type, true);
3216
+ const rustType = field.isList ? `Vec<${elemType}>` : enumNames.has(field.type) ? field.isRequired ? field.type : `Option<${field.type}>` : prismaTypeToRustType(field.type, field.isRequired);
3095
3217
  for (const attr of attrs) fieldLines.push(` ${attr}`);
3096
3218
  fieldLines.push(` pub ${fieldName}: ${rustType},`);
3097
3219
  }
3098
3220
  const relationEnum = generateRelationEnum(model, associations);
3099
3221
  const relatedImpls = generateRelatedImpls(model, associations);
3100
- const useLines = ["use sea_orm::entity::prelude::*;", "use serde::{Deserialize, Serialize};"];
3222
+ const useLines = [
3223
+ "use sea_orm::entity::prelude::*;",
3224
+ "use serde::{Deserialize, Serialize};",
3225
+ ...[...new Set(scalarFields.filter((f) => enumNames.has(f.type)).map((f) => f.type))].sort().map((name) => `use super::${toSnakeCase(name)}::${name};`)
3226
+ ];
3101
3227
  const deriveModel = canDeriveEq(scalarFields) ? "#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel, Serialize, Deserialize)]" : "#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Serialize, Deserialize)]";
3102
3228
  const serdeAttrs = buildSerdeAttributes(serde);
3103
3229
  return [
@@ -3253,7 +3379,7 @@ const PRISMA_TO_PYTHON = {
3253
3379
  Decimal: "Decimal",
3254
3380
  Boolean: "bool",
3255
3381
  DateTime: "datetime",
3256
- Json: "dict",
3382
+ Json: "dict[str, Any]",
3257
3383
  Bytes: "bytes"
3258
3384
  };
3259
3385
  const PRISMA_TO_SQLALCHEMY = {
@@ -3273,6 +3399,46 @@ function prismaTypeToSQLAlchemyType(type) {
3273
3399
  function prismaTypeToPythonType(type) {
3274
3400
  return PRISMA_TO_PYTHON[type] ?? "str";
3275
3401
  }
3402
+ const PYTHON_KEYWORDS = /* @__PURE__ */ new Set([
3403
+ "False",
3404
+ "None",
3405
+ "True",
3406
+ "and",
3407
+ "as",
3408
+ "assert",
3409
+ "async",
3410
+ "await",
3411
+ "break",
3412
+ "class",
3413
+ "continue",
3414
+ "def",
3415
+ "del",
3416
+ "elif",
3417
+ "else",
3418
+ "except",
3419
+ "finally",
3420
+ "for",
3421
+ "from",
3422
+ "global",
3423
+ "if",
3424
+ "import",
3425
+ "in",
3426
+ "is",
3427
+ "lambda",
3428
+ "nonlocal",
3429
+ "not",
3430
+ "or",
3431
+ "pass",
3432
+ "raise",
3433
+ "return",
3434
+ "try",
3435
+ "while",
3436
+ "with",
3437
+ "yield"
3438
+ ]);
3439
+ function pythonAttrName(columnName) {
3440
+ return PYTHON_KEYWORDS.has(columnName) ? `${columnName}_` : columnName;
3441
+ }
3276
3442
  function resolveNativeType(field) {
3277
3443
  const baseType = prismaTypeToSQLAlchemyType(field.type);
3278
3444
  if (!field.nativeType) return baseType;
@@ -3431,16 +3597,18 @@ function isAutoincrement(field) {
3431
3597
  function needsForeignKeysParam(targetModel, assocs) {
3432
3598
  return assocs.filter((a) => a.targetModel === targetModel).length > 1;
3433
3599
  }
3434
- function findBackPopulates(targetModelName, sourceModelName, foreignKey, allModels) {
3600
+ function findBackPopulates(targetModelName, sourceModelName, foreignKey, allModels, sourceFieldName) {
3435
3601
  const targetModel = allModels.find((m) => m.name === targetModelName);
3602
+ const sourceModel = allModels.find((m) => m.name === sourceModelName);
3436
3603
  if (!targetModel) return makeSnakeCase(sourceModelName);
3604
+ const relationName = (sourceModel?.fields.find((f) => f.kind === "object" && f.name === sourceFieldName))?.relationName;
3437
3605
  const backField = targetModel.fields.find((f) => {
3438
3606
  if (f.kind !== "object") return false;
3439
3607
  if (f.type !== sourceModelName) return false;
3608
+ if (targetModelName === sourceModelName && f.name === sourceFieldName) return false;
3609
+ if (relationName !== void 0) return f.relationName === relationName;
3440
3610
  if (f.relationFromFields?.includes(foreignKey)) return true;
3441
- const sourceModel = allModels.find((m) => m.name === sourceModelName);
3442
- if (!sourceModel) return false;
3443
- return sourceModel.fields.some((sf) => sf.relationName === f.relationName && sf.relationFromFields && sf.relationFromFields.includes(foreignKey));
3611
+ return sourceModel ? sourceModel.fields.some((sf) => sf.relationName === f.relationName && sf.relationFromFields?.includes(foreignKey)) : false;
3444
3612
  });
3445
3613
  return backField ? makeSnakeCase(backField.name) : makeSnakeCase(sourceModelName);
3446
3614
  }
@@ -3451,15 +3619,19 @@ function findM2MBackPopulates(targetModelName, sourceModelName, relationName, al
3451
3619
  return backField ? makeSnakeCase(backField.name) : makeSnakeCase(sourceModelName);
3452
3620
  }
3453
3621
  function generateColumn(field, isPk, isFk, associations, allModels, enumMap) {
3454
- const snakeName = field.dbName ?? makeSnakeCase(field.name);
3455
- const pythonType = field.kind === "enum" ? "str" : pythonTypeForNative(field);
3456
- const typeHint = field.isRequired ? pythonType : `Optional[${pythonType}]`;
3622
+ const columnName = field.dbName ?? makeSnakeCase(field.name);
3623
+ const attrName = pythonAttrName(columnName);
3624
+ const elemPythonType = field.kind === "enum" ? "str" : pythonTypeForNative(field);
3625
+ const pythonType = field.isList ? `list[${elemPythonType}]` : elemPythonType;
3626
+ const typeHint = field.isList || field.isRequired ? pythonType : `Optional[${pythonType}]`;
3457
3627
  const colArgs = [];
3628
+ if (attrName !== columnName) colArgs.push(`"${columnName}"`);
3458
3629
  if (field.kind === "enum") {
3459
3630
  const values = enumMap.get(field.type);
3460
- const valuesStr = values ? values.map((v) => `"${v}"`).join(", ") : "";
3461
- colArgs.push(`Enum(${valuesStr}, name="${makeSnakeCase(field.type)}")`);
3462
- } else if (needsExplicitSaType(field)) colArgs.push(resolveNativeType(field));
3631
+ const enumType = `Enum(${values ? values.map((v) => `"${v}"`).join(", ") : ""}, name="${makeSnakeCase(field.type)}")`;
3632
+ colArgs.push(field.isList ? `ARRAY(${enumType})` : enumType);
3633
+ } else if (field.isList) colArgs.push(`ARRAY(${prismaTypeToSQLAlchemyType(field.type)})`);
3634
+ else if (needsExplicitSaType(field)) colArgs.push(resolveNativeType(field));
3463
3635
  if (isFk) {
3464
3636
  const assoc = associations.belongsTo.find((a) => a.foreignKey === field.name);
3465
3637
  if (assoc) {
@@ -3477,8 +3649,8 @@ function generateColumn(field, isPk, isFk, associations, allModels, enumMap) {
3477
3649
  if (defaultVal !== null && !isPk) colArgs.push(`default=${defaultVal}`);
3478
3650
  }
3479
3651
  if (field.isUpdatedAt) colArgs.push("onupdate=func.now()");
3480
- if (colArgs.length === 0) return ` ${snakeName}: Mapped[${typeHint}]`;
3481
- return ` ${snakeName}: Mapped[${typeHint}] = mapped_column(${colArgs.join(", ")})`;
3652
+ if (colArgs.length === 0) return ` ${attrName}: Mapped[${typeHint}]`;
3653
+ return ` ${attrName}: Mapped[${typeHint}] = mapped_column(${colArgs.join(", ")})`;
3482
3654
  }
3483
3655
  function generateTableArgs(model, indexes) {
3484
3656
  const uniqueConstraints = model.uniqueFields.map((fields) => {
@@ -3504,15 +3676,17 @@ function generateBelongsToRelationships(associations, model, allModels) {
3504
3676
  return associations.belongsTo.map((assoc) => {
3505
3677
  const snakeName = makeSnakeCase(assoc.name);
3506
3678
  const snakeFk = model.fields.find((f) => f.name === assoc.foreignKey)?.dbName ?? makeSnakeCase(assoc.foreignKey);
3507
- const backPop = findBackPopulates(assoc.targetModel, model.name, assoc.foreignKey, allModels);
3679
+ const backPop = findBackPopulates(assoc.targetModel, model.name, assoc.foreignKey, allModels, assoc.name);
3508
3680
  const fkClause = needsForeignKeysParam(assoc.targetModel, associations.belongsTo) ? `foreign_keys=[${snakeFk}], ` : "";
3509
- return ` ${snakeName}: Mapped["${assoc.targetModel}"] = relationship(${fkClause}back_populates="${backPop}")`;
3681
+ const pkField = model.fields.find((f) => f.isId);
3682
+ const remoteClause = assoc.targetModel === model.name && pkField ? `remote_side=[${pkField.dbName ?? makeSnakeCase(pkField.name)}], ` : "";
3683
+ return ` ${snakeName}: Mapped["${assoc.targetModel}"] = relationship(${remoteClause}${fkClause}back_populates="${backPop}")`;
3510
3684
  });
3511
3685
  }
3512
3686
  function generateHasManyRelationships(associations, model, allModels) {
3513
3687
  return associations.hasMany.map((assoc) => {
3514
3688
  const snakeName = makeSnakeCase(assoc.name);
3515
- const backPop = findBackPopulates(assoc.targetModel, model.name, assoc.foreignKey, allModels);
3689
+ const backPop = findBackPopulates(assoc.targetModel, model.name, assoc.foreignKey, allModels, assoc.name);
3516
3690
  const targetModel = allModels.find((m) => m.name === assoc.targetModel);
3517
3691
  const needsFkParam = targetModel ? needsForeignKeysParam(model.name, getAssociations(targetModel, allModels).belongsTo) : false;
3518
3692
  const targetFkSnake = makeSnakeCase(assoc.foreignKey);
@@ -3523,7 +3697,7 @@ function generateHasManyRelationships(associations, model, allModels) {
3523
3697
  function generateHasOneRelationships(associations, model, allModels) {
3524
3698
  return associations.hasOne.map((assoc) => {
3525
3699
  const snakeName = makeSnakeCase(assoc.name);
3526
- const backPop = findBackPopulates(assoc.targetModel, model.name, assoc.foreignKey, allModels);
3700
+ const backPop = findBackPopulates(assoc.targetModel, model.name, assoc.foreignKey, allModels, assoc.name);
3527
3701
  const targetModel = allModels.find((m) => m.name === assoc.targetModel);
3528
3702
  const needsFkParam = targetModel ? needsForeignKeysParam(model.name, getAssociations(targetModel, allModels).belongsTo) : false;
3529
3703
  const targetFkSnake = makeSnakeCase(assoc.foreignKey);
@@ -3575,6 +3749,8 @@ function collectGlobalImports(models, _enums, indexes, m2mTables) {
3575
3749
  const needsOptional = models.some((m) => m.fields.some((f) => f.kind !== "object" && !f.isRequired));
3576
3750
  const hasRelationship = models.some((m) => m.fields.some((f) => f.kind === "object"));
3577
3751
  const needsFunc = models.some((m) => m.fields.some((f) => f.type === "DateTime" && isFunctionDefault(f.default) && f.default.name === "now" || f.isUpdatedAt));
3752
+ const needsAny = models.some((m) => m.fields.some((f) => f.type === "Json"));
3753
+ const needsArray = models.some((m) => m.fields.some((f) => f.kind !== "object" && f.isList));
3578
3754
  const needsDecimal = models.some((m) => m.fields.some((f) => f.type === "Decimal"));
3579
3755
  const needsDatetime = models.some((m) => m.fields.some((f) => f.type === "DateTime"));
3580
3756
  const needsUuid = models.some((m) => m.fields.some((f) => {
@@ -3599,6 +3775,7 @@ function collectGlobalImports(models, _enums, indexes, m2mTables) {
3599
3775
  saImports.add("Enum");
3600
3776
  continue;
3601
3777
  }
3778
+ if (field.isList) saImports.add(prismaTypeToSQLAlchemyType(field.type));
3602
3779
  if (needsExplicitSaType(field)) {
3603
3780
  const resolved = resolveNativeType(field);
3604
3781
  saImports.add(resolved.replace(/\(.*\)$/, ""));
@@ -3624,6 +3801,7 @@ function collectGlobalImports(models, _enums, indexes, m2mTables) {
3624
3801
  }
3625
3802
  }
3626
3803
  if (needsFunc) saImports.add("func");
3804
+ if (needsArray) saImports.add("ARRAY");
3627
3805
  const lines = [];
3628
3806
  const sortedSa = [...saImports].sort();
3629
3807
  if (sortedSa.length > 0) lines.push(`from sqlalchemy import ${sortedSa.join(", ")}`);
@@ -3634,7 +3812,8 @@ function collectGlobalImports(models, _enums, indexes, m2mTables) {
3634
3812
  ];
3635
3813
  if (hasRelationship) ormImports.push("relationship");
3636
3814
  lines.push(`from sqlalchemy.orm import ${ormImports.sort().join(", ")}`);
3637
- if (needsOptional) lines.push("from typing import Optional");
3815
+ const typingImports = [needsAny ? "Any" : null, needsOptional ? "Optional" : null].filter((i) => i !== null);
3816
+ if (typingImports.length > 0) lines.push(`from typing import ${typingImports.join(", ")}`);
3638
3817
  if (needsDecimal) lines.push("from decimal import Decimal as DecimalType");
3639
3818
  const dtParts = [];
3640
3819
  if (needsDatetime) dtParts.push("datetime");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hekireki",
3
- "version": "0.8.6",
3
+ "version": "0.9.1",
4
4
  "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.",
5
5
  "keywords": [
6
6
  "ajv",
@@ -51,26 +51,24 @@
51
51
  "dist"
52
52
  ],
53
53
  "type": "module",
54
- "publishConfig": {
55
- "access": "public"
56
- },
57
54
  "dependencies": {
58
55
  "@hono/node-server": "^2.0.6",
59
56
  "@prisma/generator-helper": "^7.8.0",
60
57
  "@resvg/resvg-js": "^2.6.2",
61
58
  "@softwaretechnik/dbml-renderer": "^1.0.31",
62
59
  "hono": "^4.12.27",
63
- "oxfmt": "^0.56.0"
60
+ "oxfmt": "^0.57.0"
64
61
  },
65
62
  "devDependencies": {
66
63
  "@paralleldrive/cuid2": "^3.3.0",
67
64
  "@prisma/client": "^7.8.0",
68
65
  "@sinclair/typebox": "^0.34.49",
69
- "@types/node": "^26.0.1",
70
- "@typescript/native-preview": "7.0.0-dev.20260624.1",
66
+ "@types/node": "^26.1.0",
67
+ "@typescript/native-preview": "7.0.0-dev.20260701.1",
71
68
  "ajv": "^8.20.0",
72
- "arktype": "^2.2.1",
73
- "better-auth": "^1.6.20",
69
+ "arktype": "^2.2.2",
70
+ "better-auth": "^1.6.23",
71
+ "cuid": "^3.0.0",
74
72
  "drizzle-kit": "^0.31.10",
75
73
  "drizzle-orm": "^0.45.2",
76
74
  "effect": "^3.21.4",
@@ -79,13 +77,13 @@
79
77
  "tsdown": "^0.22.3",
80
78
  "tsx": "^4.22.4",
81
79
  "typescript": "^6.0.3",
82
- "valibot": "1.4.1",
80
+ "valibot": "1.4.2",
83
81
  "zod": "^4.4.3"
84
82
  },
85
83
  "scripts": {
86
84
  "generate": "prisma generate",
87
85
  "deps": "rm -rf node_modules && pnpm install",
88
86
  "build": "tsdown",
89
- "release": "npm pkg fix && pnpm build && npm publish"
87
+ "conformance": "pnpm build && bash conformance/check.sh"
90
88
  }
91
89
  }