prisma-effect-kysely 1.1.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/CHANGELOG.md +46 -0
- package/LICENSE +21 -0
- package/README.md +219 -0
- package/dist/effect/enum.d.ts +10 -0
- package/dist/effect/enum.d.ts.map +1 -0
- package/dist/effect/enum.js +33 -0
- package/dist/effect/enum.js.map +1 -0
- package/dist/effect/generator.d.ts +33 -0
- package/dist/effect/generator.d.ts.map +1 -0
- package/dist/effect/generator.js +81 -0
- package/dist/effect/generator.js.map +1 -0
- package/dist/effect/type.d.ts +11 -0
- package/dist/effect/type.d.ts.map +1 -0
- package/dist/effect/type.js +64 -0
- package/dist/effect/type.js.map +1 -0
- package/dist/generator/index.d.ts +4 -0
- package/dist/generator/index.d.ts.map +1 -0
- package/dist/generator/index.js +34 -0
- package/dist/generator/index.js.map +1 -0
- package/dist/generator/orchestrator.d.ts +42 -0
- package/dist/generator/orchestrator.d.ts.map +1 -0
- package/dist/generator/orchestrator.js +111 -0
- package/dist/generator/orchestrator.js.map +1 -0
- package/dist/kysely/generator.d.ts +26 -0
- package/dist/kysely/generator.d.ts.map +1 -0
- package/dist/kysely/generator.js +44 -0
- package/dist/kysely/generator.js.map +1 -0
- package/dist/kysely/helpers.d.ts +50 -0
- package/dist/kysely/helpers.d.ts.map +1 -0
- package/dist/kysely/helpers.js +144 -0
- package/dist/kysely/helpers.js.map +1 -0
- package/dist/kysely/type.d.ts +33 -0
- package/dist/kysely/type.d.ts.map +1 -0
- package/dist/kysely/type.js +78 -0
- package/dist/kysely/type.js.map +1 -0
- package/dist/prisma/enum.d.ts +15 -0
- package/dist/prisma/enum.d.ts.map +1 -0
- package/dist/prisma/enum.js +25 -0
- package/dist/prisma/enum.js.map +1 -0
- package/dist/prisma/generator.d.ts +22 -0
- package/dist/prisma/generator.d.ts.map +1 -0
- package/dist/prisma/generator.js +69 -0
- package/dist/prisma/generator.js.map +1 -0
- package/dist/prisma/type.d.ts +47 -0
- package/dist/prisma/type.d.ts.map +1 -0
- package/dist/prisma/type.js +96 -0
- package/dist/prisma/type.js.map +1 -0
- package/dist/utils/annotations.d.ts +33 -0
- package/dist/utils/annotations.d.ts.map +1 -0
- package/dist/utils/annotations.js +86 -0
- package/dist/utils/annotations.js.map +1 -0
- package/dist/utils/file-manager.d.ts +20 -0
- package/dist/utils/file-manager.d.ts.map +1 -0
- package/dist/utils/file-manager.js +36 -0
- package/dist/utils/file-manager.js.map +1 -0
- package/dist/utils/templates.d.ts +2 -0
- package/dist/utils/templates.d.ts.map +1 -0
- package/dist/utils/templates.js +55 -0
- package/dist/utils/templates.js.map +1 -0
- package/package.json +82 -0
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.PrismaGenerator = void 0;
|
|
37
|
+
const PrismaEnum = __importStar(require("./enum"));
|
|
38
|
+
const PrismaType = __importStar(require("./type"));
|
|
39
|
+
/**
|
|
40
|
+
* Prisma domain generator - orchestrates DMMF parsing and extraction
|
|
41
|
+
* No schema generation here, just native Prisma data extraction
|
|
42
|
+
*/
|
|
43
|
+
class PrismaGenerator {
|
|
44
|
+
constructor(dmmf) {
|
|
45
|
+
this.dmmf = dmmf;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Get all enums from DMMF
|
|
49
|
+
*/
|
|
50
|
+
getEnums() {
|
|
51
|
+
return PrismaEnum.extractEnums(this.dmmf);
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Get all models from DMMF (filtered and sorted)
|
|
55
|
+
*/
|
|
56
|
+
getModels() {
|
|
57
|
+
const filtered = PrismaType.filterInternalModels(this.dmmf.datamodel.models);
|
|
58
|
+
return PrismaType.sortModels(filtered);
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Get schema fields for a model (filtered and sorted)
|
|
62
|
+
*/
|
|
63
|
+
getModelFields(model) {
|
|
64
|
+
const filtered = PrismaType.filterSchemaFields(model.fields);
|
|
65
|
+
return PrismaType.sortFields(filtered);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
exports.PrismaGenerator = PrismaGenerator;
|
|
69
|
+
//# sourceMappingURL=generator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generator.js","sourceRoot":"","sources":["../../src/prisma/generator.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACA,mDAAqC;AACrC,mDAAqC;AAErC;;;GAGG;AACH,MAAa,eAAe;IAC1B,YAA6B,IAAmB;QAAnB,SAAI,GAAJ,IAAI,CAAe;IAAG,CAAC;IAEpD;;OAEG;IACH,QAAQ;QACN,OAAO,UAAU,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC5C,CAAC;IAED;;OAEG;IACH,SAAS;QACP,MAAM,QAAQ,GAAG,UAAU,CAAC,oBAAoB,CAC9C,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAC3B,CAAC;QACF,OAAO,UAAU,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;IACzC,CAAC;IAED;;OAEG;IACH,cAAc,CAAC,KAAiB;QAC9B,MAAM,QAAQ,GAAG,UAAU,CAAC,kBAAkB,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QAC7D,OAAO,UAAU,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;IACzC,CAAC;CACF;AA3BD,0CA2BC"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { DMMF } from '@prisma/generator-helper';
|
|
2
|
+
/**
|
|
3
|
+
* Check if a field is a UUID using native DMMF type information
|
|
4
|
+
* 3-tier detection: native type � documentation � field name patterns
|
|
5
|
+
*/
|
|
6
|
+
export declare function isUuidField(field: DMMF.Field): boolean;
|
|
7
|
+
/**
|
|
8
|
+
* Get the database column name for a field (respects @map directive)
|
|
9
|
+
*/
|
|
10
|
+
export declare function getFieldDbName(field: DMMF.Field): string;
|
|
11
|
+
/**
|
|
12
|
+
* Check if field has a default value using native DMMF property
|
|
13
|
+
*/
|
|
14
|
+
export declare function hasDefaultValue(field: DMMF.Field): boolean;
|
|
15
|
+
/**
|
|
16
|
+
* Check if field is an ID field using native DMMF property
|
|
17
|
+
*/
|
|
18
|
+
export declare function isIdField(field: DMMF.Field): boolean;
|
|
19
|
+
/**
|
|
20
|
+
* Check if field is required using native DMMF property
|
|
21
|
+
*/
|
|
22
|
+
export declare function isRequiredField(field: DMMF.Field): boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Check if field is a list/array using native DMMF property
|
|
25
|
+
*/
|
|
26
|
+
export declare function isListField(field: DMMF.Field): boolean;
|
|
27
|
+
/**
|
|
28
|
+
* Filter models to exclude internal models (starting with _)
|
|
29
|
+
*/
|
|
30
|
+
export declare function filterInternalModels(models: readonly DMMF.Model[]): readonly DMMF.Model[];
|
|
31
|
+
/**
|
|
32
|
+
* Filter fields to only include scalar and enum fields (exclude relations)
|
|
33
|
+
*/
|
|
34
|
+
export declare function filterSchemaFields(fields: readonly DMMF.Field[]): readonly DMMF.Field[];
|
|
35
|
+
/**
|
|
36
|
+
* Get the database table name for a model (respects @@map directive)
|
|
37
|
+
*/
|
|
38
|
+
export declare function getModelDbName(model: DMMF.Model): string;
|
|
39
|
+
/**
|
|
40
|
+
* Sort models alphabetically for deterministic output
|
|
41
|
+
*/
|
|
42
|
+
export declare function sortModels(models: readonly DMMF.Model[]): readonly DMMF.Model[];
|
|
43
|
+
/**
|
|
44
|
+
* Sort fields alphabetically for deterministic output
|
|
45
|
+
*/
|
|
46
|
+
export declare function sortFields(fields: readonly DMMF.Field[]): readonly DMMF.Field[];
|
|
47
|
+
//# sourceMappingURL=type.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"type.d.ts","sourceRoot":"","sources":["../../src/prisma/type.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,0BAA0B,CAAC;AAErD;;;GAGG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,WAoB5C;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,UAE/C;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,WAEhD;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,WAE1C;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,WAEhD;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,WAE5C;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,SAAS,IAAI,CAAC,KAAK,EAAE,GAC5B,SAAS,IAAI,CAAC,KAAK,EAAE,CAEvB;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,SAAS,IAAI,CAAC,KAAK,EAAE,GAC5B,SAAS,IAAI,CAAC,KAAK,EAAE,CAIvB;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,UAE/C;AAED;;GAEG;AACH,wBAAgB,UAAU,CACxB,MAAM,EAAE,SAAS,IAAI,CAAC,KAAK,EAAE,GAC5B,SAAS,IAAI,CAAC,KAAK,EAAE,CAEvB;AAED;;GAEG;AACH,wBAAgB,UAAU,CACxB,MAAM,EAAE,SAAS,IAAI,CAAC,KAAK,EAAE,GAC5B,SAAS,IAAI,CAAC,KAAK,EAAE,CAEvB"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isUuidField = isUuidField;
|
|
4
|
+
exports.getFieldDbName = getFieldDbName;
|
|
5
|
+
exports.hasDefaultValue = hasDefaultValue;
|
|
6
|
+
exports.isIdField = isIdField;
|
|
7
|
+
exports.isRequiredField = isRequiredField;
|
|
8
|
+
exports.isListField = isListField;
|
|
9
|
+
exports.filterInternalModels = filterInternalModels;
|
|
10
|
+
exports.filterSchemaFields = filterSchemaFields;
|
|
11
|
+
exports.getModelDbName = getModelDbName;
|
|
12
|
+
exports.sortModels = sortModels;
|
|
13
|
+
exports.sortFields = sortFields;
|
|
14
|
+
/**
|
|
15
|
+
* Check if a field is a UUID using native DMMF type information
|
|
16
|
+
* 3-tier detection: native type � documentation � field name patterns
|
|
17
|
+
*/
|
|
18
|
+
function isUuidField(field) {
|
|
19
|
+
// 1. Check native type (most reliable)
|
|
20
|
+
if (field.nativeType?.[0] === 'Uuid') {
|
|
21
|
+
return true;
|
|
22
|
+
}
|
|
23
|
+
// 2. Check documentation for @db.Uuid
|
|
24
|
+
if (field.documentation?.includes('@db.Uuid')) {
|
|
25
|
+
return true;
|
|
26
|
+
}
|
|
27
|
+
// 3. Fallback: Field name patterns
|
|
28
|
+
const uuidFieldPatterns = [
|
|
29
|
+
/^id$/, // Primary ID fields
|
|
30
|
+
/_id$/, // Foreign key ID fields
|
|
31
|
+
/^.*_uuid$/, // uuid suffix
|
|
32
|
+
/^uuid$/, // Direct uuid fields
|
|
33
|
+
];
|
|
34
|
+
return uuidFieldPatterns.some((pattern) => pattern.test(field.name));
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Get the database column name for a field (respects @map directive)
|
|
38
|
+
*/
|
|
39
|
+
function getFieldDbName(field) {
|
|
40
|
+
return field.dbName ?? field.name;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Check if field has a default value using native DMMF property
|
|
44
|
+
*/
|
|
45
|
+
function hasDefaultValue(field) {
|
|
46
|
+
return field.hasDefaultValue === true;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Check if field is an ID field using native DMMF property
|
|
50
|
+
*/
|
|
51
|
+
function isIdField(field) {
|
|
52
|
+
return field.isId === true;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Check if field is required using native DMMF property
|
|
56
|
+
*/
|
|
57
|
+
function isRequiredField(field) {
|
|
58
|
+
return field.isRequired === true;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Check if field is a list/array using native DMMF property
|
|
62
|
+
*/
|
|
63
|
+
function isListField(field) {
|
|
64
|
+
return field.isList === true;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Filter models to exclude internal models (starting with _)
|
|
68
|
+
*/
|
|
69
|
+
function filterInternalModels(models) {
|
|
70
|
+
return models.filter((model) => !model.name.startsWith('_'));
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Filter fields to only include scalar and enum fields (exclude relations)
|
|
74
|
+
*/
|
|
75
|
+
function filterSchemaFields(fields) {
|
|
76
|
+
return fields.filter((field) => field.kind === 'scalar' || field.kind === 'enum');
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Get the database table name for a model (respects @@map directive)
|
|
80
|
+
*/
|
|
81
|
+
function getModelDbName(model) {
|
|
82
|
+
return model.dbName ?? model.name;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Sort models alphabetically for deterministic output
|
|
86
|
+
*/
|
|
87
|
+
function sortModels(models) {
|
|
88
|
+
return models.slice().sort((a, b) => a.name.localeCompare(b.name));
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Sort fields alphabetically for deterministic output
|
|
92
|
+
*/
|
|
93
|
+
function sortFields(fields) {
|
|
94
|
+
return fields.slice().sort((a, b) => a.name.localeCompare(b.name));
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=type.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"type.js","sourceRoot":"","sources":["../../src/prisma/type.ts"],"names":[],"mappings":";;AAMA,kCAoBC;AAKD,wCAEC;AAKD,0CAEC;AAKD,8BAEC;AAKD,0CAEC;AAKD,kCAEC;AAKD,oDAIC;AAKD,gDAMC;AAKD,wCAEC;AAKD,gCAIC;AAKD,gCAIC;AAxGD;;;GAGG;AACH,SAAgB,WAAW,CAAC,KAAiB;IAC3C,uCAAuC;IACvC,IAAI,KAAK,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,KAAK,MAAM,EAAE,CAAC;QACrC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,sCAAsC;IACtC,IAAI,KAAK,CAAC,aAAa,EAAE,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;QAC9C,OAAO,IAAI,CAAC;IACd,CAAC;IAED,mCAAmC;IACnC,MAAM,iBAAiB,GAAG;QACxB,MAAM,EAAE,oBAAoB;QAC5B,MAAM,EAAE,wBAAwB;QAChC,WAAW,EAAE,cAAc;QAC3B,QAAQ,EAAE,qBAAqB;KACvB,CAAC;IAEX,OAAO,iBAAiB,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;AACvE,CAAC;AAED;;GAEG;AACH,SAAgB,cAAc,CAAC,KAAiB;IAC9C,OAAO,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,IAAI,CAAC;AACpC,CAAC;AAED;;GAEG;AACH,SAAgB,eAAe,CAAC,KAAiB;IAC/C,OAAO,KAAK,CAAC,eAAe,KAAK,IAAI,CAAC;AACxC,CAAC;AAED;;GAEG;AACH,SAAgB,SAAS,CAAC,KAAiB;IACzC,OAAO,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC;AAC7B,CAAC;AAED;;GAEG;AACH,SAAgB,eAAe,CAAC,KAAiB;IAC/C,OAAO,KAAK,CAAC,UAAU,KAAK,IAAI,CAAC;AACnC,CAAC;AAED;;GAEG;AACH,SAAgB,WAAW,CAAC,KAAiB;IAC3C,OAAO,KAAK,CAAC,MAAM,KAAK,IAAI,CAAC;AAC/B,CAAC;AAED;;GAEG;AACH,SAAgB,oBAAoB,CAClC,MAA6B;IAE7B,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC;AAC/D,CAAC;AAED;;GAEG;AACH,SAAgB,kBAAkB,CAChC,MAA6B;IAE7B,OAAO,MAAM,CAAC,MAAM,CAClB,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,CAC5D,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAgB,cAAc,CAAC,KAAiB;IAC9C,OAAO,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,IAAI,CAAC;AACpC,CAAC;AAED;;GAEG;AACH,SAAgB,UAAU,CACxB,MAA6B;IAE7B,OAAO,MAAM,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;AACrE,CAAC;AAED;;GAEG;AACH,SAAgB,UAAU,CACxB,MAA6B;IAE7B,OAAO,MAAM,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;AACrE,CAAC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { DMMF } from '@prisma/generator-helper';
|
|
2
|
+
/**
|
|
3
|
+
* @customType Annotation Parser
|
|
4
|
+
*
|
|
5
|
+
* Allows overriding Effect Schema types for Prisma-supported fields.
|
|
6
|
+
*
|
|
7
|
+
* WORKS FOR: Prisma scalar types (String, Int, Boolean, DateTime, etc.)
|
|
8
|
+
*
|
|
9
|
+
* USE CASES:
|
|
10
|
+
* // Email validation for String field
|
|
11
|
+
* /// @customType(Schema.String.pipe(Schema.email()))
|
|
12
|
+
* email String
|
|
13
|
+
*
|
|
14
|
+
* // Positive number constraint for Int field
|
|
15
|
+
* /// @customType(Schema.Number.pipe(Schema.positive()))
|
|
16
|
+
* age Int
|
|
17
|
+
*
|
|
18
|
+
* // Custom branded type
|
|
19
|
+
* /// @customType(Schema.String.pipe(Schema.brand('UserId')))
|
|
20
|
+
* userId String
|
|
21
|
+
*
|
|
22
|
+
* @param field - Prisma DMMF field
|
|
23
|
+
* @returns Extracted type string or null if no annotation found
|
|
24
|
+
*/
|
|
25
|
+
export declare function extractEffectTypeOverride(field: DMMF.Field): string | null;
|
|
26
|
+
/**
|
|
27
|
+
* Check if field has any custom type annotations
|
|
28
|
+
*
|
|
29
|
+
* @param fields - Array of Prisma fields
|
|
30
|
+
* @returns true if any field uses custom types in @effectType
|
|
31
|
+
*/
|
|
32
|
+
export declare function hasCustomTypeAnnotations(fields: readonly DMMF.Field[]): boolean;
|
|
33
|
+
//# sourceMappingURL=annotations.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"annotations.d.ts","sourceRoot":"","sources":["../../src/utils/annotations.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,0BAA0B,CAAC;AAErD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,GAAG,MAAM,GAAG,IAAI,CAqC1E;AAgBD;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,SAAS,IAAI,CAAC,KAAK,EAAE,GAAG,OAAO,CAK/E"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.extractEffectTypeOverride = extractEffectTypeOverride;
|
|
4
|
+
exports.hasCustomTypeAnnotations = hasCustomTypeAnnotations;
|
|
5
|
+
/**
|
|
6
|
+
* @customType Annotation Parser
|
|
7
|
+
*
|
|
8
|
+
* Allows overriding Effect Schema types for Prisma-supported fields.
|
|
9
|
+
*
|
|
10
|
+
* WORKS FOR: Prisma scalar types (String, Int, Boolean, DateTime, etc.)
|
|
11
|
+
*
|
|
12
|
+
* USE CASES:
|
|
13
|
+
* // Email validation for String field
|
|
14
|
+
* /// @customType(Schema.String.pipe(Schema.email()))
|
|
15
|
+
* email String
|
|
16
|
+
*
|
|
17
|
+
* // Positive number constraint for Int field
|
|
18
|
+
* /// @customType(Schema.Number.pipe(Schema.positive()))
|
|
19
|
+
* age Int
|
|
20
|
+
*
|
|
21
|
+
* // Custom branded type
|
|
22
|
+
* /// @customType(Schema.String.pipe(Schema.brand('UserId')))
|
|
23
|
+
* userId String
|
|
24
|
+
*
|
|
25
|
+
* @param field - Prisma DMMF field
|
|
26
|
+
* @returns Extracted type string or null if no annotation found
|
|
27
|
+
*/
|
|
28
|
+
function extractEffectTypeOverride(field) {
|
|
29
|
+
if (!field.documentation)
|
|
30
|
+
return null;
|
|
31
|
+
// Match @customType annotation - handle balanced parentheses
|
|
32
|
+
const annotationMatch = field.documentation.match(/@customType\s*\(/);
|
|
33
|
+
if (!annotationMatch)
|
|
34
|
+
return null;
|
|
35
|
+
// Find the matching closing parenthesis
|
|
36
|
+
const startIdx = field.documentation.indexOf('@customType(') + '@customType('.length;
|
|
37
|
+
let parenCount = 1;
|
|
38
|
+
let endIdx = startIdx;
|
|
39
|
+
for (let i = startIdx; i < field.documentation.length && parenCount > 0; i++) {
|
|
40
|
+
if (field.documentation[i] === '(')
|
|
41
|
+
parenCount++;
|
|
42
|
+
if (field.documentation[i] === ')')
|
|
43
|
+
parenCount--;
|
|
44
|
+
if (parenCount === 0) {
|
|
45
|
+
endIdx = i;
|
|
46
|
+
break;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
if (parenCount !== 0) {
|
|
50
|
+
console.warn(`⚠️ Unbalanced parentheses in @customType for field: ${field.name}`);
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
const typeStr = field.documentation.substring(startIdx, endIdx).trim();
|
|
54
|
+
// Validate it's either a custom type or starts with Schema.
|
|
55
|
+
if (!typeStr.startsWith('Schema.') && !isCustomType(typeStr)) {
|
|
56
|
+
console.warn(`⚠️ Invalid @customType for ${field.name}: must start with "Schema." or be a custom type (e.g., Vector1536)`);
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
return typeStr;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Check if type string is a custom type reference
|
|
63
|
+
*
|
|
64
|
+
* Custom types are PascalCase identifiers without dots:
|
|
65
|
+
* - Valid: Vector1536, JSONBType, CustomEnum
|
|
66
|
+
* - Invalid: Schema.String, some.nested.type
|
|
67
|
+
*
|
|
68
|
+
* @param typeStr - Type string to check
|
|
69
|
+
* @returns true if it's a custom type reference
|
|
70
|
+
*/
|
|
71
|
+
function isCustomType(typeStr) {
|
|
72
|
+
return /^[A-Z][A-Za-z0-9]*$/.test(typeStr);
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Check if field has any custom type annotations
|
|
76
|
+
*
|
|
77
|
+
* @param fields - Array of Prisma fields
|
|
78
|
+
* @returns true if any field uses custom types in @effectType
|
|
79
|
+
*/
|
|
80
|
+
function hasCustomTypeAnnotations(fields) {
|
|
81
|
+
return fields.some((field) => {
|
|
82
|
+
const override = extractEffectTypeOverride(field);
|
|
83
|
+
return override && isCustomType(override);
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=annotations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"annotations.js","sourceRoot":"","sources":["../../src/utils/annotations.ts"],"names":[],"mappings":";;AAyBA,8DAqCC;AAsBD,4DAKC;AAvFD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,SAAgB,yBAAyB,CAAC,KAAiB;IACzD,IAAI,CAAC,KAAK,CAAC,aAAa;QAAE,OAAO,IAAI,CAAC;IAEtC,6DAA6D;IAC7D,MAAM,eAAe,GAAG,KAAK,CAAC,aAAa,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC;IACtE,IAAI,CAAC,eAAe;QAAE,OAAO,IAAI,CAAC;IAElC,wCAAwC;IACxC,MAAM,QAAQ,GAAG,KAAK,CAAC,aAAa,CAAC,OAAO,CAAC,cAAc,CAAC,GAAG,cAAc,CAAC,MAAM,CAAC;IACrF,IAAI,UAAU,GAAG,CAAC,CAAC;IACnB,IAAI,MAAM,GAAG,QAAQ,CAAC;IAEtB,KAAK,IAAI,CAAC,GAAG,QAAQ,EAAE,CAAC,GAAG,KAAK,CAAC,aAAa,CAAC,MAAM,IAAI,UAAU,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC7E,IAAI,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,KAAK,GAAG;YAAE,UAAU,EAAE,CAAC;QACjD,IAAI,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,KAAK,GAAG;YAAE,UAAU,EAAE,CAAC;QACjD,IAAI,UAAU,KAAK,CAAC,EAAE,CAAC;YACrB,MAAM,GAAG,CAAC,CAAC;YACX,MAAM;QACR,CAAC;IACH,CAAC;IAED,IAAI,UAAU,KAAK,CAAC,EAAE,CAAC;QACrB,OAAO,CAAC,IAAI,CAAC,wDAAwD,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;QACnF,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,OAAO,GAAG,KAAK,CAAC,aAAa,CAAC,SAAS,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;IAEvE,4DAA4D;IAC5D,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,EAAE,CAAC;QAC7D,OAAO,CAAC,IAAI,CACV,+BAA+B,KAAK,CAAC,IAAI,oEAAoE,CAC9G,CAAC;QACF,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;;;;;;;GASG;AACH,SAAS,YAAY,CAAC,OAAe;IACnC,OAAO,qBAAqB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;AAC7C,CAAC;AAED;;;;;GAKG;AACH,SAAgB,wBAAwB,CAAC,MAA6B;IACpE,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE;QAC3B,MAAM,QAAQ,GAAG,yBAAyB,CAAC,KAAK,CAAC,CAAC;QAClD,OAAO,QAAQ,IAAI,YAAY,CAAC,QAAQ,CAAC,CAAC;IAC5C,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Manages file system operations for the generator
|
|
3
|
+
*/
|
|
4
|
+
export declare class FileManager {
|
|
5
|
+
private readonly outputPath;
|
|
6
|
+
constructor(outputPath: string);
|
|
7
|
+
/**
|
|
8
|
+
* Ensure the output directory exists
|
|
9
|
+
*/
|
|
10
|
+
ensureDirectory(): Promise<void>;
|
|
11
|
+
/**
|
|
12
|
+
* Write a file with automatic code formatting
|
|
13
|
+
*/
|
|
14
|
+
writeFile(filename: string, content: string): Promise<void>;
|
|
15
|
+
/**
|
|
16
|
+
* Get the output path
|
|
17
|
+
*/
|
|
18
|
+
getOutputPath(): string;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=file-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-manager.d.ts","sourceRoot":"","sources":["../../src/utils/file-manager.ts"],"names":[],"mappings":"AAIA;;GAEG;AACH,qBAAa,WAAW;IACV,OAAO,CAAC,QAAQ,CAAC,UAAU;gBAAV,UAAU,EAAE,MAAM;IAE/C;;OAEG;IACG,eAAe;IAIrB;;OAEG;IACG,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;IAMjD;;OAEG;IACH,aAAa;CAGd"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.FileManager = void 0;
|
|
4
|
+
const promises_1 = require("fs/promises");
|
|
5
|
+
const path_1 = require("path");
|
|
6
|
+
const templates_1 = require("./templates");
|
|
7
|
+
/**
|
|
8
|
+
* Manages file system operations for the generator
|
|
9
|
+
*/
|
|
10
|
+
class FileManager {
|
|
11
|
+
constructor(outputPath) {
|
|
12
|
+
this.outputPath = outputPath;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Ensure the output directory exists
|
|
16
|
+
*/
|
|
17
|
+
async ensureDirectory() {
|
|
18
|
+
await (0, promises_1.mkdir)(this.outputPath, { recursive: true });
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Write a file with automatic code formatting
|
|
22
|
+
*/
|
|
23
|
+
async writeFile(filename, content) {
|
|
24
|
+
const formatted = await (0, templates_1.formatCode)(content);
|
|
25
|
+
const filePath = (0, path_1.join)(this.outputPath, filename);
|
|
26
|
+
await (0, promises_1.writeFile)(filePath, formatted);
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Get the output path
|
|
30
|
+
*/
|
|
31
|
+
getOutputPath() {
|
|
32
|
+
return this.outputPath;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
exports.FileManager = FileManager;
|
|
36
|
+
//# sourceMappingURL=file-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-manager.js","sourceRoot":"","sources":["../../src/utils/file-manager.ts"],"names":[],"mappings":";;;AAAA,0CAA+C;AAC/C,+BAA4B;AAC5B,2CAAyC;AAEzC;;GAEG;AACH,MAAa,WAAW;IACtB,YAA6B,UAAkB;QAAlB,eAAU,GAAV,UAAU,CAAQ;IAAG,CAAC;IAEnD;;OAEG;IACH,KAAK,CAAC,eAAe;QACnB,MAAM,IAAA,gBAAK,EAAC,IAAI,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACpD,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,SAAS,CAAC,QAAgB,EAAE,OAAe;QAC/C,MAAM,SAAS,GAAG,MAAM,IAAA,sBAAU,EAAC,OAAO,CAAC,CAAC;QAC5C,MAAM,QAAQ,GAAG,IAAA,WAAI,EAAC,IAAI,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;QACjD,MAAM,IAAA,oBAAS,EAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;IACvC,CAAC;IAED;;OAEG;IACH,aAAa;QACX,OAAO,IAAI,CAAC,UAAU,CAAC;IACzB,CAAC;CACF;AAzBD,kCAyBC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"templates.d.ts","sourceRoot":"","sources":["../../src/utils/templates.ts"],"names":[],"mappings":"AAEA,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,mBAkB5C"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.formatCode = formatCode;
|
|
37
|
+
const prettier = __importStar(require("prettier"));
|
|
38
|
+
async function formatCode(code) {
|
|
39
|
+
try {
|
|
40
|
+
return await prettier.format(code, {
|
|
41
|
+
parser: "typescript",
|
|
42
|
+
semi: true,
|
|
43
|
+
singleQuote: true,
|
|
44
|
+
trailingComma: "es5",
|
|
45
|
+
tabWidth: 2,
|
|
46
|
+
printWidth: 100,
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
catch (error) {
|
|
50
|
+
// If prettier fails, return the original code
|
|
51
|
+
console.warn("Prettier formatting failed, returning unformatted code:", error instanceof Error ? error.message : String(error));
|
|
52
|
+
return code;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=templates.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"templates.js","sourceRoot":"","sources":["../../src/utils/templates.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEA,gCAkBC;AApBD,mDAAqC;AAE9B,KAAK,UAAU,UAAU,CAAC,IAAY;IAC3C,IAAI,CAAC;QACH,OAAO,MAAM,QAAQ,CAAC,MAAM,CAAC,IAAI,EAAE;YACjC,MAAM,EAAE,YAAY;YACpB,IAAI,EAAE,IAAI;YACV,WAAW,EAAE,IAAI;YACjB,aAAa,EAAE,KAAK;YACpB,QAAQ,EAAE,CAAC;YACX,UAAU,EAAE,GAAG;SAChB,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,KAAc,EAAE,CAAC;QACxB,8CAA8C;QAC9C,OAAO,CAAC,IAAI,CACV,yDAAyD,EACzD,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CACvD,CAAC;QACF,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "prisma-effect-kysely",
|
|
3
|
+
"version": "1.1.0",
|
|
4
|
+
"description": "Prisma generator that creates Effect Schema types from Prisma schema compatible with Kysely",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"author": "Samuel Ho",
|
|
7
|
+
"main": "dist/generator/index.js",
|
|
8
|
+
"bin": {
|
|
9
|
+
"prisma-effect-kysely": "dist/generator/index.js"
|
|
10
|
+
},
|
|
11
|
+
"type": "commonjs",
|
|
12
|
+
"exports": {
|
|
13
|
+
".": {
|
|
14
|
+
"types": "./dist/generator/index.d.ts",
|
|
15
|
+
"require": "./dist/generator/index.js"
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
"files": [
|
|
19
|
+
"dist",
|
|
20
|
+
"README.md",
|
|
21
|
+
"LICENSE",
|
|
22
|
+
"CHANGELOG.md"
|
|
23
|
+
],
|
|
24
|
+
"sideEffects": false,
|
|
25
|
+
"keywords": [
|
|
26
|
+
"prisma",
|
|
27
|
+
"generator",
|
|
28
|
+
"effect",
|
|
29
|
+
"schema",
|
|
30
|
+
"typescript",
|
|
31
|
+
"type-safety",
|
|
32
|
+
"prisma-generator",
|
|
33
|
+
"effect-ts"
|
|
34
|
+
],
|
|
35
|
+
"repository": {
|
|
36
|
+
"type": "git",
|
|
37
|
+
"url": "git+https://github.com/samuelho-dev/prisma-effect-kysely.git"
|
|
38
|
+
},
|
|
39
|
+
"bugs": {
|
|
40
|
+
"url": "https://github.com/samuelho-dev/prisma-effect-kysely/issues"
|
|
41
|
+
},
|
|
42
|
+
"homepage": "https://github.com/samuelho-dev/prisma-effect-kysely#readme",
|
|
43
|
+
"engines": {
|
|
44
|
+
"node": ">=18.0.0",
|
|
45
|
+
"pnpm": ">=8.0.0"
|
|
46
|
+
},
|
|
47
|
+
"packageManager": "pnpm@10.0.0",
|
|
48
|
+
"scripts": {
|
|
49
|
+
"build": "tsc -p tsconfig.lib.json",
|
|
50
|
+
"prepare": "npm run build",
|
|
51
|
+
"test": "jest",
|
|
52
|
+
"test:watch": "jest --watch",
|
|
53
|
+
"test:coverage": "jest --coverage",
|
|
54
|
+
"typecheck": "tsc --noEmit -p tsconfig.lib.json",
|
|
55
|
+
"prepublishOnly": "npm run typecheck && npm run test && npm run build"
|
|
56
|
+
},
|
|
57
|
+
"dependencies": {
|
|
58
|
+
"@prisma/client": "6.16.3",
|
|
59
|
+
"@prisma/generator-helper": "^6.2.1",
|
|
60
|
+
"effect": "^3.11.7",
|
|
61
|
+
"prettier": "^3.4.2"
|
|
62
|
+
},
|
|
63
|
+
"peerDependencies": {
|
|
64
|
+
"kysely": "^0.27.2"
|
|
65
|
+
},
|
|
66
|
+
"peerDependenciesMeta": {
|
|
67
|
+
"kysely": {
|
|
68
|
+
"optional": true
|
|
69
|
+
}
|
|
70
|
+
},
|
|
71
|
+
"devDependencies": {
|
|
72
|
+
"@prisma/internals": "^6.16.3",
|
|
73
|
+
"@types/jest": "^29.5.14",
|
|
74
|
+
"@types/node": "^22.10.5",
|
|
75
|
+
"jest": "^29.7.0",
|
|
76
|
+
"kysely": "^0.27.2",
|
|
77
|
+
"prisma": "^6.16.3",
|
|
78
|
+
"ts-jest": "^29.2.5",
|
|
79
|
+
"ts-node": "^10.9.2",
|
|
80
|
+
"typescript": "^5.7.2"
|
|
81
|
+
}
|
|
82
|
+
}
|