hekireki 0.8.6 → 0.9.0
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-Dh-MFTeu.js} +227 -51
- 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) ? [
|
|
@@ -2845,6 +2883,80 @@ function prismaTypeToRustType(type, isRequired) {
|
|
|
2845
2883
|
if (!isRequired) return `Option<${base}>`;
|
|
2846
2884
|
return base;
|
|
2847
2885
|
}
|
|
2886
|
+
const RUST_KEYWORDS = /* @__PURE__ */ new Set([
|
|
2887
|
+
"as",
|
|
2888
|
+
"break",
|
|
2889
|
+
"const",
|
|
2890
|
+
"continue",
|
|
2891
|
+
"crate",
|
|
2892
|
+
"dyn",
|
|
2893
|
+
"else",
|
|
2894
|
+
"enum",
|
|
2895
|
+
"extern",
|
|
2896
|
+
"false",
|
|
2897
|
+
"fn",
|
|
2898
|
+
"for",
|
|
2899
|
+
"if",
|
|
2900
|
+
"impl",
|
|
2901
|
+
"in",
|
|
2902
|
+
"let",
|
|
2903
|
+
"loop",
|
|
2904
|
+
"match",
|
|
2905
|
+
"mod",
|
|
2906
|
+
"move",
|
|
2907
|
+
"mut",
|
|
2908
|
+
"pub",
|
|
2909
|
+
"ref",
|
|
2910
|
+
"return",
|
|
2911
|
+
"self",
|
|
2912
|
+
"Self",
|
|
2913
|
+
"static",
|
|
2914
|
+
"struct",
|
|
2915
|
+
"super",
|
|
2916
|
+
"trait",
|
|
2917
|
+
"true",
|
|
2918
|
+
"type",
|
|
2919
|
+
"unsafe",
|
|
2920
|
+
"use",
|
|
2921
|
+
"where",
|
|
2922
|
+
"while",
|
|
2923
|
+
"async",
|
|
2924
|
+
"await",
|
|
2925
|
+
"abstract",
|
|
2926
|
+
"become",
|
|
2927
|
+
"box",
|
|
2928
|
+
"do",
|
|
2929
|
+
"final",
|
|
2930
|
+
"macro",
|
|
2931
|
+
"override",
|
|
2932
|
+
"priv",
|
|
2933
|
+
"typeof",
|
|
2934
|
+
"unsized",
|
|
2935
|
+
"virtual",
|
|
2936
|
+
"yield",
|
|
2937
|
+
"try",
|
|
2938
|
+
"gen"
|
|
2939
|
+
]);
|
|
2940
|
+
const RUST_NON_RAW = /* @__PURE__ */ new Set([
|
|
2941
|
+
"self",
|
|
2942
|
+
"Self",
|
|
2943
|
+
"crate",
|
|
2944
|
+
"super"
|
|
2945
|
+
]);
|
|
2946
|
+
function rustFieldIdent(snake) {
|
|
2947
|
+
if (!RUST_KEYWORDS.has(snake)) return {
|
|
2948
|
+
ident: snake,
|
|
2949
|
+
derivedColumn: snake
|
|
2950
|
+
};
|
|
2951
|
+
if (RUST_NON_RAW.has(snake)) return {
|
|
2952
|
+
ident: `${snake}_`,
|
|
2953
|
+
derivedColumn: `${snake}_`
|
|
2954
|
+
};
|
|
2955
|
+
return {
|
|
2956
|
+
ident: `r#${snake}`,
|
|
2957
|
+
derivedColumn: snake
|
|
2958
|
+
};
|
|
2959
|
+
}
|
|
2848
2960
|
function resolveSeaOrmColumnType(field) {
|
|
2849
2961
|
if (!field.nativeType) return null;
|
|
2850
2962
|
const [nativeName, nativeArgs] = field.nativeType;
|
|
@@ -2887,7 +2999,7 @@ function formatRustDefault(def) {
|
|
|
2887
2999
|
if (typeof def === "string") return `"${def}"`;
|
|
2888
3000
|
return null;
|
|
2889
3001
|
}
|
|
2890
|
-
function buildSeaOrmAttributes(field, isPk, isCompositePk) {
|
|
3002
|
+
function buildSeaOrmAttributes(field, isPk, isCompositePk, derivedColumn) {
|
|
2891
3003
|
const attrs = [];
|
|
2892
3004
|
if (isPk) {
|
|
2893
3005
|
const parts = ["primary_key"];
|
|
@@ -2897,7 +3009,7 @@ function buildSeaOrmAttributes(field, isPk, isCompositePk) {
|
|
|
2897
3009
|
if (field.isUnique) attrs.push("#[sea_orm(unique)]");
|
|
2898
3010
|
const columnParts = [];
|
|
2899
3011
|
const columnName = field.dbName ?? makeSnakeCase(field.name);
|
|
2900
|
-
if (columnName !== makeSnakeCase(field.name)) columnParts.push(`column_name = "${columnName}"`);
|
|
3012
|
+
if (columnName !== (derivedColumn ?? makeSnakeCase(field.name))) columnParts.push(`column_name = "${columnName}"`);
|
|
2901
3013
|
const colType = resolveSeaOrmColumnType(field);
|
|
2902
3014
|
if (colType) columnParts.push(`column_type = "${colType}"`);
|
|
2903
3015
|
if (!isPk || isCompositePk) {
|
|
@@ -2984,7 +3096,7 @@ function buildSerdeAttributes(opts) {
|
|
|
2984
3096
|
}
|
|
2985
3097
|
function generateEnum(e, serde = {}) {
|
|
2986
3098
|
const variants = e.values.map((v) => {
|
|
2987
|
-
const pascalName = v.name.charAt(0).toUpperCase() +
|
|
3099
|
+
const pascalName = v.name.split("_").filter((part) => part !== "").map((part) => part.charAt(0).toUpperCase() + part.slice(1).toLowerCase()).join("");
|
|
2988
3100
|
return ` #[sea_orm(string_value = "${v.name}")]\n ${pascalName},`;
|
|
2989
3101
|
});
|
|
2990
3102
|
return [
|
|
@@ -3025,9 +3137,10 @@ function generateRelationEnum(_model, associations) {
|
|
|
3025
3137
|
}
|
|
3026
3138
|
function generateRelatedImpls(model, associations) {
|
|
3027
3139
|
const impls = [];
|
|
3028
|
-
const
|
|
3140
|
+
const emittedTargets = /* @__PURE__ */ new Set();
|
|
3029
3141
|
for (const assoc of associations.belongsTo) {
|
|
3030
|
-
if (
|
|
3142
|
+
if (emittedTargets.has(assoc.targetModel)) continue;
|
|
3143
|
+
emittedTargets.add(assoc.targetModel);
|
|
3031
3144
|
const targetModule = toModuleName(assoc.targetModel);
|
|
3032
3145
|
impls.push([
|
|
3033
3146
|
`impl Related<super::${targetModule}::Entity> for Entity {`,
|
|
@@ -3038,7 +3151,8 @@ function generateRelatedImpls(model, associations) {
|
|
|
3038
3151
|
].join("\n"));
|
|
3039
3152
|
}
|
|
3040
3153
|
for (const assoc of associations.hasMany) {
|
|
3041
|
-
if (
|
|
3154
|
+
if (emittedTargets.has(assoc.targetModel)) continue;
|
|
3155
|
+
emittedTargets.add(assoc.targetModel);
|
|
3042
3156
|
const targetModule = toModuleName(assoc.targetModel);
|
|
3043
3157
|
impls.push([
|
|
3044
3158
|
`impl Related<super::${targetModule}::Entity> for Entity {`,
|
|
@@ -3049,7 +3163,8 @@ function generateRelatedImpls(model, associations) {
|
|
|
3049
3163
|
].join("\n"));
|
|
3050
3164
|
}
|
|
3051
3165
|
for (const assoc of associations.hasOne) {
|
|
3052
|
-
if (
|
|
3166
|
+
if (emittedTargets.has(assoc.targetModel)) continue;
|
|
3167
|
+
emittedTargets.add(assoc.targetModel);
|
|
3053
3168
|
const targetModule = toModuleName(assoc.targetModel);
|
|
3054
3169
|
impls.push([
|
|
3055
3170
|
`impl Related<super::${targetModule}::Entity> for Entity {`,
|
|
@@ -3060,6 +3175,8 @@ function generateRelatedImpls(model, associations) {
|
|
|
3060
3175
|
].join("\n"));
|
|
3061
3176
|
}
|
|
3062
3177
|
for (const assoc of associations.manyToMany) {
|
|
3178
|
+
if (emittedTargets.has(assoc.targetModel)) continue;
|
|
3179
|
+
emittedTargets.add(assoc.targetModel);
|
|
3063
3180
|
const targetModule = toModuleName(assoc.targetModel);
|
|
3064
3181
|
const [leftName, rightName] = model.name < assoc.targetModel ? [model.name, assoc.targetModel] : [assoc.targetModel, model.name];
|
|
3065
3182
|
const junctionModule = toSnakeCase(`${leftName}To${rightName}`);
|
|
@@ -3089,15 +3206,21 @@ function generateEntityFile(model, allModels, enums, serde = {}) {
|
|
|
3089
3206
|
const scalarFields = model.fields.filter((f) => f.kind !== "object");
|
|
3090
3207
|
const fieldLines = [];
|
|
3091
3208
|
for (const field of scalarFields) {
|
|
3092
|
-
const
|
|
3093
|
-
const
|
|
3094
|
-
const
|
|
3209
|
+
const isPk = field.isId || compositePkFieldNames.has(field.name);
|
|
3210
|
+
const { ident: fieldName, derivedColumn } = rustFieldIdent(toSnakeCase(field.name));
|
|
3211
|
+
const attrs = buildSeaOrmAttributes(field, isPk, isCompositePk, derivedColumn);
|
|
3212
|
+
const elemType = enumNames.has(field.type) ? field.type : prismaTypeToRustType(field.type, true);
|
|
3213
|
+
const rustType = field.isList ? `Vec<${elemType}>` : enumNames.has(field.type) ? field.isRequired ? field.type : `Option<${field.type}>` : prismaTypeToRustType(field.type, field.isRequired);
|
|
3095
3214
|
for (const attr of attrs) fieldLines.push(` ${attr}`);
|
|
3096
3215
|
fieldLines.push(` pub ${fieldName}: ${rustType},`);
|
|
3097
3216
|
}
|
|
3098
3217
|
const relationEnum = generateRelationEnum(model, associations);
|
|
3099
3218
|
const relatedImpls = generateRelatedImpls(model, associations);
|
|
3100
|
-
const useLines = [
|
|
3219
|
+
const useLines = [
|
|
3220
|
+
"use sea_orm::entity::prelude::*;",
|
|
3221
|
+
"use serde::{Deserialize, Serialize};",
|
|
3222
|
+
...[...new Set(scalarFields.filter((f) => enumNames.has(f.type)).map((f) => f.type))].sort().map((name) => `use super::${toSnakeCase(name)}::${name};`)
|
|
3223
|
+
];
|
|
3101
3224
|
const deriveModel = canDeriveEq(scalarFields) ? "#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel, Serialize, Deserialize)]" : "#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Serialize, Deserialize)]";
|
|
3102
3225
|
const serdeAttrs = buildSerdeAttributes(serde);
|
|
3103
3226
|
return [
|
|
@@ -3253,7 +3376,7 @@ const PRISMA_TO_PYTHON = {
|
|
|
3253
3376
|
Decimal: "Decimal",
|
|
3254
3377
|
Boolean: "bool",
|
|
3255
3378
|
DateTime: "datetime",
|
|
3256
|
-
Json: "dict",
|
|
3379
|
+
Json: "dict[str, Any]",
|
|
3257
3380
|
Bytes: "bytes"
|
|
3258
3381
|
};
|
|
3259
3382
|
const PRISMA_TO_SQLALCHEMY = {
|
|
@@ -3273,6 +3396,46 @@ function prismaTypeToSQLAlchemyType(type) {
|
|
|
3273
3396
|
function prismaTypeToPythonType(type) {
|
|
3274
3397
|
return PRISMA_TO_PYTHON[type] ?? "str";
|
|
3275
3398
|
}
|
|
3399
|
+
const PYTHON_KEYWORDS = /* @__PURE__ */ new Set([
|
|
3400
|
+
"False",
|
|
3401
|
+
"None",
|
|
3402
|
+
"True",
|
|
3403
|
+
"and",
|
|
3404
|
+
"as",
|
|
3405
|
+
"assert",
|
|
3406
|
+
"async",
|
|
3407
|
+
"await",
|
|
3408
|
+
"break",
|
|
3409
|
+
"class",
|
|
3410
|
+
"continue",
|
|
3411
|
+
"def",
|
|
3412
|
+
"del",
|
|
3413
|
+
"elif",
|
|
3414
|
+
"else",
|
|
3415
|
+
"except",
|
|
3416
|
+
"finally",
|
|
3417
|
+
"for",
|
|
3418
|
+
"from",
|
|
3419
|
+
"global",
|
|
3420
|
+
"if",
|
|
3421
|
+
"import",
|
|
3422
|
+
"in",
|
|
3423
|
+
"is",
|
|
3424
|
+
"lambda",
|
|
3425
|
+
"nonlocal",
|
|
3426
|
+
"not",
|
|
3427
|
+
"or",
|
|
3428
|
+
"pass",
|
|
3429
|
+
"raise",
|
|
3430
|
+
"return",
|
|
3431
|
+
"try",
|
|
3432
|
+
"while",
|
|
3433
|
+
"with",
|
|
3434
|
+
"yield"
|
|
3435
|
+
]);
|
|
3436
|
+
function pythonAttrName(columnName) {
|
|
3437
|
+
return PYTHON_KEYWORDS.has(columnName) ? `${columnName}_` : columnName;
|
|
3438
|
+
}
|
|
3276
3439
|
function resolveNativeType(field) {
|
|
3277
3440
|
const baseType = prismaTypeToSQLAlchemyType(field.type);
|
|
3278
3441
|
if (!field.nativeType) return baseType;
|
|
@@ -3431,16 +3594,18 @@ function isAutoincrement(field) {
|
|
|
3431
3594
|
function needsForeignKeysParam(targetModel, assocs) {
|
|
3432
3595
|
return assocs.filter((a) => a.targetModel === targetModel).length > 1;
|
|
3433
3596
|
}
|
|
3434
|
-
function findBackPopulates(targetModelName, sourceModelName, foreignKey, allModels) {
|
|
3597
|
+
function findBackPopulates(targetModelName, sourceModelName, foreignKey, allModels, sourceFieldName) {
|
|
3435
3598
|
const targetModel = allModels.find((m) => m.name === targetModelName);
|
|
3599
|
+
const sourceModel = allModels.find((m) => m.name === sourceModelName);
|
|
3436
3600
|
if (!targetModel) return makeSnakeCase(sourceModelName);
|
|
3601
|
+
const relationName = (sourceModel?.fields.find((f) => f.kind === "object" && f.name === sourceFieldName))?.relationName;
|
|
3437
3602
|
const backField = targetModel.fields.find((f) => {
|
|
3438
3603
|
if (f.kind !== "object") return false;
|
|
3439
3604
|
if (f.type !== sourceModelName) return false;
|
|
3605
|
+
if (targetModelName === sourceModelName && f.name === sourceFieldName) return false;
|
|
3606
|
+
if (relationName !== void 0) return f.relationName === relationName;
|
|
3440
3607
|
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));
|
|
3608
|
+
return sourceModel ? sourceModel.fields.some((sf) => sf.relationName === f.relationName && sf.relationFromFields?.includes(foreignKey)) : false;
|
|
3444
3609
|
});
|
|
3445
3610
|
return backField ? makeSnakeCase(backField.name) : makeSnakeCase(sourceModelName);
|
|
3446
3611
|
}
|
|
@@ -3451,15 +3616,19 @@ function findM2MBackPopulates(targetModelName, sourceModelName, relationName, al
|
|
|
3451
3616
|
return backField ? makeSnakeCase(backField.name) : makeSnakeCase(sourceModelName);
|
|
3452
3617
|
}
|
|
3453
3618
|
function generateColumn(field, isPk, isFk, associations, allModels, enumMap) {
|
|
3454
|
-
const
|
|
3455
|
-
const
|
|
3456
|
-
const
|
|
3619
|
+
const columnName = field.dbName ?? makeSnakeCase(field.name);
|
|
3620
|
+
const attrName = pythonAttrName(columnName);
|
|
3621
|
+
const elemPythonType = field.kind === "enum" ? "str" : pythonTypeForNative(field);
|
|
3622
|
+
const pythonType = field.isList ? `list[${elemPythonType}]` : elemPythonType;
|
|
3623
|
+
const typeHint = field.isList || field.isRequired ? pythonType : `Optional[${pythonType}]`;
|
|
3457
3624
|
const colArgs = [];
|
|
3625
|
+
if (attrName !== columnName) colArgs.push(`"${columnName}"`);
|
|
3458
3626
|
if (field.kind === "enum") {
|
|
3459
3627
|
const values = enumMap.get(field.type);
|
|
3460
|
-
const
|
|
3461
|
-
colArgs.push(`
|
|
3462
|
-
} else if (
|
|
3628
|
+
const enumType = `Enum(${values ? values.map((v) => `"${v}"`).join(", ") : ""}, name="${makeSnakeCase(field.type)}")`;
|
|
3629
|
+
colArgs.push(field.isList ? `ARRAY(${enumType})` : enumType);
|
|
3630
|
+
} else if (field.isList) colArgs.push(`ARRAY(${prismaTypeToSQLAlchemyType(field.type)})`);
|
|
3631
|
+
else if (needsExplicitSaType(field)) colArgs.push(resolveNativeType(field));
|
|
3463
3632
|
if (isFk) {
|
|
3464
3633
|
const assoc = associations.belongsTo.find((a) => a.foreignKey === field.name);
|
|
3465
3634
|
if (assoc) {
|
|
@@ -3477,8 +3646,8 @@ function generateColumn(field, isPk, isFk, associations, allModels, enumMap) {
|
|
|
3477
3646
|
if (defaultVal !== null && !isPk) colArgs.push(`default=${defaultVal}`);
|
|
3478
3647
|
}
|
|
3479
3648
|
if (field.isUpdatedAt) colArgs.push("onupdate=func.now()");
|
|
3480
|
-
if (colArgs.length === 0) return ` ${
|
|
3481
|
-
return ` ${
|
|
3649
|
+
if (colArgs.length === 0) return ` ${attrName}: Mapped[${typeHint}]`;
|
|
3650
|
+
return ` ${attrName}: Mapped[${typeHint}] = mapped_column(${colArgs.join(", ")})`;
|
|
3482
3651
|
}
|
|
3483
3652
|
function generateTableArgs(model, indexes) {
|
|
3484
3653
|
const uniqueConstraints = model.uniqueFields.map((fields) => {
|
|
@@ -3504,15 +3673,17 @@ function generateBelongsToRelationships(associations, model, allModels) {
|
|
|
3504
3673
|
return associations.belongsTo.map((assoc) => {
|
|
3505
3674
|
const snakeName = makeSnakeCase(assoc.name);
|
|
3506
3675
|
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);
|
|
3676
|
+
const backPop = findBackPopulates(assoc.targetModel, model.name, assoc.foreignKey, allModels, assoc.name);
|
|
3508
3677
|
const fkClause = needsForeignKeysParam(assoc.targetModel, associations.belongsTo) ? `foreign_keys=[${snakeFk}], ` : "";
|
|
3509
|
-
|
|
3678
|
+
const pkField = model.fields.find((f) => f.isId);
|
|
3679
|
+
const remoteClause = assoc.targetModel === model.name && pkField ? `remote_side=[${pkField.dbName ?? makeSnakeCase(pkField.name)}], ` : "";
|
|
3680
|
+
return ` ${snakeName}: Mapped["${assoc.targetModel}"] = relationship(${remoteClause}${fkClause}back_populates="${backPop}")`;
|
|
3510
3681
|
});
|
|
3511
3682
|
}
|
|
3512
3683
|
function generateHasManyRelationships(associations, model, allModels) {
|
|
3513
3684
|
return associations.hasMany.map((assoc) => {
|
|
3514
3685
|
const snakeName = makeSnakeCase(assoc.name);
|
|
3515
|
-
const backPop = findBackPopulates(assoc.targetModel, model.name, assoc.foreignKey, allModels);
|
|
3686
|
+
const backPop = findBackPopulates(assoc.targetModel, model.name, assoc.foreignKey, allModels, assoc.name);
|
|
3516
3687
|
const targetModel = allModels.find((m) => m.name === assoc.targetModel);
|
|
3517
3688
|
const needsFkParam = targetModel ? needsForeignKeysParam(model.name, getAssociations(targetModel, allModels).belongsTo) : false;
|
|
3518
3689
|
const targetFkSnake = makeSnakeCase(assoc.foreignKey);
|
|
@@ -3523,7 +3694,7 @@ function generateHasManyRelationships(associations, model, allModels) {
|
|
|
3523
3694
|
function generateHasOneRelationships(associations, model, allModels) {
|
|
3524
3695
|
return associations.hasOne.map((assoc) => {
|
|
3525
3696
|
const snakeName = makeSnakeCase(assoc.name);
|
|
3526
|
-
const backPop = findBackPopulates(assoc.targetModel, model.name, assoc.foreignKey, allModels);
|
|
3697
|
+
const backPop = findBackPopulates(assoc.targetModel, model.name, assoc.foreignKey, allModels, assoc.name);
|
|
3527
3698
|
const targetModel = allModels.find((m) => m.name === assoc.targetModel);
|
|
3528
3699
|
const needsFkParam = targetModel ? needsForeignKeysParam(model.name, getAssociations(targetModel, allModels).belongsTo) : false;
|
|
3529
3700
|
const targetFkSnake = makeSnakeCase(assoc.foreignKey);
|
|
@@ -3575,6 +3746,8 @@ function collectGlobalImports(models, _enums, indexes, m2mTables) {
|
|
|
3575
3746
|
const needsOptional = models.some((m) => m.fields.some((f) => f.kind !== "object" && !f.isRequired));
|
|
3576
3747
|
const hasRelationship = models.some((m) => m.fields.some((f) => f.kind === "object"));
|
|
3577
3748
|
const needsFunc = models.some((m) => m.fields.some((f) => f.type === "DateTime" && isFunctionDefault(f.default) && f.default.name === "now" || f.isUpdatedAt));
|
|
3749
|
+
const needsAny = models.some((m) => m.fields.some((f) => f.type === "Json"));
|
|
3750
|
+
const needsArray = models.some((m) => m.fields.some((f) => f.kind !== "object" && f.isList));
|
|
3578
3751
|
const needsDecimal = models.some((m) => m.fields.some((f) => f.type === "Decimal"));
|
|
3579
3752
|
const needsDatetime = models.some((m) => m.fields.some((f) => f.type === "DateTime"));
|
|
3580
3753
|
const needsUuid = models.some((m) => m.fields.some((f) => {
|
|
@@ -3599,6 +3772,7 @@ function collectGlobalImports(models, _enums, indexes, m2mTables) {
|
|
|
3599
3772
|
saImports.add("Enum");
|
|
3600
3773
|
continue;
|
|
3601
3774
|
}
|
|
3775
|
+
if (field.isList) saImports.add(prismaTypeToSQLAlchemyType(field.type));
|
|
3602
3776
|
if (needsExplicitSaType(field)) {
|
|
3603
3777
|
const resolved = resolveNativeType(field);
|
|
3604
3778
|
saImports.add(resolved.replace(/\(.*\)$/, ""));
|
|
@@ -3624,6 +3798,7 @@ function collectGlobalImports(models, _enums, indexes, m2mTables) {
|
|
|
3624
3798
|
}
|
|
3625
3799
|
}
|
|
3626
3800
|
if (needsFunc) saImports.add("func");
|
|
3801
|
+
if (needsArray) saImports.add("ARRAY");
|
|
3627
3802
|
const lines = [];
|
|
3628
3803
|
const sortedSa = [...saImports].sort();
|
|
3629
3804
|
if (sortedSa.length > 0) lines.push(`from sqlalchemy import ${sortedSa.join(", ")}`);
|
|
@@ -3634,7 +3809,8 @@ function collectGlobalImports(models, _enums, indexes, m2mTables) {
|
|
|
3634
3809
|
];
|
|
3635
3810
|
if (hasRelationship) ormImports.push("relationship");
|
|
3636
3811
|
lines.push(`from sqlalchemy.orm import ${ormImports.sort().join(", ")}`);
|
|
3637
|
-
|
|
3812
|
+
const typingImports = [needsAny ? "Any" : null, needsOptional ? "Optional" : null].filter((i) => i !== null);
|
|
3813
|
+
if (typingImports.length > 0) lines.push(`from typing import ${typingImports.join(", ")}`);
|
|
3638
3814
|
if (needsDecimal) lines.push("from decimal import Decimal as DecimalType");
|
|
3639
3815
|
const dtParts = [];
|
|
3640
3816
|
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.0",
|
|
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
|
}
|