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 +1 -1
- package/dist/bin/arktype.js +1 -1
- package/dist/bin/dbml.js +1 -1
- package/dist/bin/docs.js +1 -1
- package/dist/bin/drizzle.js +1 -1
- package/dist/bin/ecto.js +1 -1
- package/dist/bin/effect.js +1 -1
- package/dist/bin/gorm.js +1 -1
- package/dist/bin/mermaid-er.js +1 -1
- package/dist/bin/sea-orm.js +1 -1
- package/dist/bin/sqlalchemy.js +1 -1
- package/dist/bin/typebox.js +1 -1
- package/dist/bin/valibot.js +1 -1
- package/dist/bin/zod.js +1 -1
- package/dist/{bin-DLQOqGdU.js → bin-CR8sx_jS.js} +231 -52
- package/package.json +9 -11
package/dist/bin/ajv.js
CHANGED
package/dist/bin/arktype.js
CHANGED
package/dist/bin/dbml.js
CHANGED
package/dist/bin/docs.js
CHANGED
package/dist/bin/drizzle.js
CHANGED
package/dist/bin/ecto.js
CHANGED
package/dist/bin/effect.js
CHANGED
package/dist/bin/gorm.js
CHANGED
package/dist/bin/mermaid-er.js
CHANGED
package/dist/bin/sea-orm.js
CHANGED
package/dist/bin/sqlalchemy.js
CHANGED
package/dist/bin/typebox.js
CHANGED
package/dist/bin/valibot.js
CHANGED
package/dist/bin/zod.js
CHANGED
|
@@ -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(
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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)
|
|
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"
|
|
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
|
|
2624
|
+
const cols = fields.map((f) => {
|
|
2592
2625
|
return model.fields.find((mf) => mf.name === f)?.dbName ?? makeSnakeCase(f);
|
|
2593
|
-
})
|
|
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
|
|
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
|
-
|
|
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)}
|
|
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
|
-
|
|
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() +
|
|
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
|
|
3143
|
+
const emittedTargets = /* @__PURE__ */ new Set();
|
|
3029
3144
|
for (const assoc of associations.belongsTo) {
|
|
3030
|
-
if (
|
|
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 (
|
|
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 (
|
|
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
|
|
3093
|
-
const
|
|
3094
|
-
const
|
|
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 = [
|
|
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
|
-
|
|
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
|
|
3455
|
-
const
|
|
3456
|
-
const
|
|
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
|
|
3461
|
-
colArgs.push(`
|
|
3462
|
-
} else if (
|
|
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 ` ${
|
|
3481
|
-
return ` ${
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
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.
|
|
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
|
|
70
|
-
"@typescript/native-preview": "7.0.0-dev.
|
|
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.
|
|
73
|
-
"better-auth": "^1.6.
|
|
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.
|
|
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
|
-
"
|
|
87
|
+
"conformance": "pnpm build && bash conformance/check.sh"
|
|
90
88
|
}
|
|
91
89
|
}
|