prisma-ts-select 0.0.33 → 0.1.2
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/LICENSE +21 -0
- package/README.md +1455 -263
- package/dist/bin.cjs +1 -1
- package/dist/bin.js +1 -1
- package/dist/chunk-47KZVQLD.js +283 -0
- package/dist/chunk-54D2J5AR.cjs +291 -0
- package/dist/extend/dialects/index.d.ts +13 -0
- package/dist/extend/dialects/index.js +186 -0
- package/dist/extend/dialects/mysql-v6.d.ts +100 -0
- package/dist/extend/dialects/mysql-v6.js +152 -0
- package/dist/extend/dialects/mysql-v7.d.ts +6 -0
- package/dist/extend/dialects/mysql-v7.js +138 -0
- package/dist/extend/dialects/mysql.d.ts +90 -0
- package/dist/extend/dialects/mysql.js +156 -0
- package/dist/extend/dialects/postgresql-v6.d.ts +97 -0
- package/dist/extend/dialects/postgresql-v6.js +136 -0
- package/dist/extend/dialects/postgresql-v7.d.ts +97 -0
- package/dist/extend/dialects/postgresql-v7.js +136 -0
- package/dist/extend/dialects/postgresql.d.ts +89 -0
- package/dist/extend/dialects/postgresql.js +147 -0
- package/dist/extend/dialects/shared.d.ts +6 -0
- package/dist/extend/dialects/shared.js +5 -0
- package/dist/extend/dialects/sqlite.d.ts +63 -0
- package/dist/extend/dialects/sqlite.js +138 -0
- package/dist/extend/dialects/types.d.ts +12 -0
- package/dist/extend/dialects/types.js +4 -0
- package/dist/extend/extend.d.ts +342 -57
- package/dist/extend/extend.js +813 -161
- package/dist/extend/sql-expr-BaKWzJ-r.d.ts +10 -0
- package/dist/extend/types-D84lxYVc.d.ts +5 -0
- package/dist/generator.cjs +1 -1
- package/dist/generator.js +1 -1
- package/package.json +52 -41
- package/built/extend.cjs +0 -565
- package/built/extend.d.cts +0 -451
- package/built/extend.d.ts +0 -451
- package/built/extend.js +0 -563
- package/dist/chunk-G66FOFCO.cjs +0 -195
- package/dist/chunk-GBXPF5FT.js +0 -187
- package/dist/extend/extend.cjs +0 -277
- package/dist/extend/extend.d.cts +0 -222
package/dist/bin.cjs
CHANGED
package/dist/bin.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import './chunk-
|
|
2
|
+
import './chunk-47KZVQLD.js';
|
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
import { generatorHandler } from '@prisma/generator-helper';
|
|
2
|
+
import { logger } from '@prisma/internals';
|
|
3
|
+
import path2 from 'node:path';
|
|
4
|
+
import fs2 from 'node:fs';
|
|
5
|
+
import { createRequire } from 'node:module';
|
|
6
|
+
|
|
7
|
+
// src/generator.ts
|
|
8
|
+
|
|
9
|
+
// src/constants.ts
|
|
10
|
+
var GENERATOR_NAME = "prisma-ts-select";
|
|
11
|
+
function writeFileSafely(writeLocation, content) {
|
|
12
|
+
fs2.mkdirSync(path2.dirname(writeLocation), {
|
|
13
|
+
recursive: true
|
|
14
|
+
});
|
|
15
|
+
fs2.writeFileSync(writeLocation, content);
|
|
16
|
+
}
|
|
17
|
+
var _require = createRequire(import.meta.url);
|
|
18
|
+
var SupportedProviders = {
|
|
19
|
+
sqlite: true,
|
|
20
|
+
mysql: true,
|
|
21
|
+
postgresql: true,
|
|
22
|
+
"prisma+postgres": false,
|
|
23
|
+
cockroachdb: false,
|
|
24
|
+
mongodb: false,
|
|
25
|
+
postgres: false,
|
|
26
|
+
sqlserver: false
|
|
27
|
+
};
|
|
28
|
+
generatorHandler({
|
|
29
|
+
onManifest() {
|
|
30
|
+
logger.info(`${GENERATOR_NAME}:Registered`);
|
|
31
|
+
return {
|
|
32
|
+
defaultOutput: "",
|
|
33
|
+
prettyName: GENERATOR_NAME
|
|
34
|
+
};
|
|
35
|
+
},
|
|
36
|
+
onGenerate: async (options) => {
|
|
37
|
+
const provider = options.datasources[0]?.provider;
|
|
38
|
+
const output = options.generator.output?.value;
|
|
39
|
+
if (!output) throw new Error(`${GENERATOR_NAME}: No output directory found. Please add an output directory to your schema.prisma file.`);
|
|
40
|
+
const outputPath = path2.resolve(output);
|
|
41
|
+
fs2.mkdirSync(outputPath, { recursive: true });
|
|
42
|
+
console.log(`${GENERATOR_NAME}: Generating to ${outputPath}`);
|
|
43
|
+
const validDS = options.datasources.map((ds) => ds.provider).filter((type) => SupportedProviders[type]);
|
|
44
|
+
if (validDS.length === 0) {
|
|
45
|
+
throw new Error(`${GENERATOR_NAME}: Supported DataSource Providers are: ${Object.entries(SupportedProviders).reduce((acc, [name, supported]) => {
|
|
46
|
+
if (!supported) return acc;
|
|
47
|
+
acc.push(name);
|
|
48
|
+
return acc;
|
|
49
|
+
}, []).join(", ")}`);
|
|
50
|
+
}
|
|
51
|
+
const modelToId = {};
|
|
52
|
+
const models = options.dmmf.datamodel.models.reduce((acc, model) => {
|
|
53
|
+
const modelObj = acc[model.name] = acc[model.name] ?? {
|
|
54
|
+
fields: {},
|
|
55
|
+
relations: {}
|
|
56
|
+
};
|
|
57
|
+
for (const field of model.fields) {
|
|
58
|
+
if (field.kind !== "object") {
|
|
59
|
+
if (field.isId) modelToId[model.name] = [field.name, field.type];
|
|
60
|
+
modelObj.fields = modelObj.fields ?? {};
|
|
61
|
+
modelObj.fields[field.name] = (!field.isRequired ? "?" : "") + field.type;
|
|
62
|
+
} else {
|
|
63
|
+
if (field.relationFromFields && field.relationFromFields.length > 0 && (field.relationToFields && field.relationToFields.length > 0)) {
|
|
64
|
+
const fieldObj = modelObj.relations[field.type] = modelObj.relations[field.type] ?? {};
|
|
65
|
+
field.relationFromFields.forEach((relationFromField, i) => {
|
|
66
|
+
if (!field.relationToFields) return;
|
|
67
|
+
const relationToField = field.relationToFields[i];
|
|
68
|
+
if (!relationToField) return;
|
|
69
|
+
fieldObj[relationFromField] = fieldObj[relationFromField] || [];
|
|
70
|
+
fieldObj[relationFromField].push(relationToField);
|
|
71
|
+
const accModel = acc[field.type] = acc[field.type] ?? {};
|
|
72
|
+
const accModelRelations = accModel.relations = accModel.relations ?? {};
|
|
73
|
+
const accModelRelationToModel = accModelRelations[model.name] = accModelRelations[model.name] ?? {};
|
|
74
|
+
const relationFromFieldList = accModelRelationToModel[relationToField] = accModelRelationToModel[relationToField] ?? [];
|
|
75
|
+
relationFromFieldList.push(relationFromField);
|
|
76
|
+
});
|
|
77
|
+
} else {
|
|
78
|
+
if (!isManyToManyRelationShip(field)) continue;
|
|
79
|
+
const joinTableName = "_" + field.relationName;
|
|
80
|
+
const joinTableModel = acc[joinTableName] = acc[joinTableName] ?? {
|
|
81
|
+
fields: {
|
|
82
|
+
"A": "",
|
|
83
|
+
"B": ""
|
|
84
|
+
},
|
|
85
|
+
relations: {}
|
|
86
|
+
};
|
|
87
|
+
const abJoin = [field.type, model.name].toSorted().indexOf(model.name) === 0 ? "A" : "B";
|
|
88
|
+
const [idName, idType] = getModelId(model.name);
|
|
89
|
+
joinTableModel.fields[abJoin] = idType;
|
|
90
|
+
{
|
|
91
|
+
const mr = joinTableModel.relations[model.name] = joinTableModel.relations[model.name] ?? {};
|
|
92
|
+
const mrt = mr[abJoin] = mr[abJoin] ?? [];
|
|
93
|
+
mrt.push(idName);
|
|
94
|
+
}
|
|
95
|
+
const m = modelObj.relations[joinTableName] = modelObj.relations[joinTableName] ?? {};
|
|
96
|
+
const mf = m[idName] = m[idName] ?? [];
|
|
97
|
+
mf.push(abJoin);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return acc;
|
|
102
|
+
}, {});
|
|
103
|
+
const pTSSelPath = path2.dirname(_require.resolve("prisma-ts-select"));
|
|
104
|
+
logger.info("pTSSelPath", pTSSelPath);
|
|
105
|
+
const srcDir = path2.join(pTSSelPath, "extend");
|
|
106
|
+
const hasVersions = provider !== "sqlite";
|
|
107
|
+
const dialectFiles = [
|
|
108
|
+
"types",
|
|
109
|
+
"shared",
|
|
110
|
+
provider,
|
|
111
|
+
...hasVersions ? [`${provider}-v6`, `${provider}-v7`] : []
|
|
112
|
+
];
|
|
113
|
+
const dialectOutDir = path2.join(outputPath, "dialects");
|
|
114
|
+
fs2.mkdirSync(dialectOutDir, { recursive: true });
|
|
115
|
+
for (const baseName of dialectFiles) {
|
|
116
|
+
for (const ext of [".js", ".d.ts"]) {
|
|
117
|
+
const src = path2.join(pTSSelPath, "extend", "dialects", `${baseName}${ext}`);
|
|
118
|
+
const dest = path2.join(dialectOutDir, `${baseName}${ext}`);
|
|
119
|
+
if (fs2.existsSync(src)) {
|
|
120
|
+
fs2.copyFileSync(src, dest);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
const defaultCtxFns = hasVersions ? `${provider}V7ContextFns` : `${provider}ContextFns`;
|
|
125
|
+
const defaultSrc = hasVersions ? `${provider}-v7` : provider;
|
|
126
|
+
const dialectIndexJs = `export { ${provider}Dialect as dialect, ${defaultCtxFns} as dialectContextFns } from './${defaultSrc}.js';
|
|
127
|
+
`;
|
|
128
|
+
fs2.writeFileSync(path2.join(dialectOutDir, "index.js"), dialectIndexJs);
|
|
129
|
+
const dialectIndexDts = `export { type Dialect, type FunctionRegistry, SUPPORTED_PROVIDERS, type SupportedProvider } from './types.js';
|
|
130
|
+
export { sharedFunctions } from './shared.js';
|
|
131
|
+
export { ${provider}Dialect as dialect, ${provider}Dialect, ${defaultCtxFns} as dialectContextFns } from './${defaultSrc}.js';
|
|
132
|
+
`;
|
|
133
|
+
fs2.writeFileSync(path2.join(dialectOutDir, "index.d.ts"), dialectIndexDts);
|
|
134
|
+
for (const ver of ["v6", "v7"]) {
|
|
135
|
+
const ctxName = hasVersions ? `${provider}${ver === "v6" ? "V6" : "V7"}ContextFns` : `${provider}ContextFns`;
|
|
136
|
+
const srcFile = hasVersions ? `${provider}-${ver}` : provider;
|
|
137
|
+
const js = `export { ${provider}Dialect as dialect, ${ctxName} as dialectContextFns } from './${srcFile}.js';
|
|
138
|
+
`;
|
|
139
|
+
const dts = `export { type Dialect, type FunctionRegistry, SUPPORTED_PROVIDERS, type SupportedProvider } from './types.js';
|
|
140
|
+
export { sharedFunctions } from './shared.js';
|
|
141
|
+
export { ${provider}Dialect as dialect, ${provider}Dialect, ${ctxName} as dialectContextFns } from './${srcFile}.js';
|
|
142
|
+
`;
|
|
143
|
+
fs2.writeFileSync(path2.join(dialectOutDir, `${ver}.js`), js);
|
|
144
|
+
fs2.writeFileSync(path2.join(dialectOutDir, `${ver}.d.ts`), dts);
|
|
145
|
+
}
|
|
146
|
+
const extendContents = fs2.readFileSync(path2.join(srcDir, "extend.js"), { encoding: "utf-8" });
|
|
147
|
+
writeFileSafely(
|
|
148
|
+
path2.join(outputPath, "extend.js"),
|
|
149
|
+
extendContents.replace("var DB = {};", `var DB = ${JSON.stringify(models, null, 2)};`)
|
|
150
|
+
);
|
|
151
|
+
const declaration = generateReadonlyDeclaration(models);
|
|
152
|
+
const ALL_JOIN_METHODS = [
|
|
153
|
+
"join",
|
|
154
|
+
"joinUnsafeTypeEnforced",
|
|
155
|
+
"joinUnsafeIgnoreType",
|
|
156
|
+
"innerJoin",
|
|
157
|
+
"innerJoinUnsafeTypeEnforced",
|
|
158
|
+
"innerJoinUnsafeIgnoreType",
|
|
159
|
+
"leftJoin",
|
|
160
|
+
"leftJoinUnsafeTypeEnforced",
|
|
161
|
+
"leftJoinUnsafeIgnoreType",
|
|
162
|
+
"rightJoin",
|
|
163
|
+
"rightJoinUnsafeTypeEnforced",
|
|
164
|
+
"rightJoinUnsafeIgnoreType",
|
|
165
|
+
"fullJoin",
|
|
166
|
+
"fullJoinUnsafeTypeEnforced",
|
|
167
|
+
"fullJoinUnsafeIgnoreType",
|
|
168
|
+
"crossJoin",
|
|
169
|
+
"crossJoinUnsafeTypeEnforced",
|
|
170
|
+
"crossJoinUnsafeIgnoreType",
|
|
171
|
+
"manyToManyJoin"
|
|
172
|
+
];
|
|
173
|
+
const SUPPORTED_JOIN_METHODS = {
|
|
174
|
+
sqlite: [
|
|
175
|
+
"join",
|
|
176
|
+
"joinUnsafeTypeEnforced",
|
|
177
|
+
"joinUnsafeIgnoreType",
|
|
178
|
+
"innerJoin",
|
|
179
|
+
"innerJoinUnsafeTypeEnforced",
|
|
180
|
+
"innerJoinUnsafeIgnoreType",
|
|
181
|
+
"leftJoin",
|
|
182
|
+
"leftJoinUnsafeTypeEnforced",
|
|
183
|
+
"leftJoinUnsafeIgnoreType",
|
|
184
|
+
"crossJoin",
|
|
185
|
+
"crossJoinUnsafeTypeEnforced",
|
|
186
|
+
"crossJoinUnsafeIgnoreType",
|
|
187
|
+
"manyToManyJoin"
|
|
188
|
+
],
|
|
189
|
+
mysql: [
|
|
190
|
+
"join",
|
|
191
|
+
"joinUnsafeTypeEnforced",
|
|
192
|
+
"joinUnsafeIgnoreType",
|
|
193
|
+
"innerJoin",
|
|
194
|
+
"innerJoinUnsafeTypeEnforced",
|
|
195
|
+
"innerJoinUnsafeIgnoreType",
|
|
196
|
+
"leftJoin",
|
|
197
|
+
"leftJoinUnsafeTypeEnforced",
|
|
198
|
+
"leftJoinUnsafeIgnoreType",
|
|
199
|
+
"rightJoin",
|
|
200
|
+
"rightJoinUnsafeTypeEnforced",
|
|
201
|
+
"rightJoinUnsafeIgnoreType",
|
|
202
|
+
"crossJoin",
|
|
203
|
+
"crossJoinUnsafeTypeEnforced",
|
|
204
|
+
"crossJoinUnsafeIgnoreType",
|
|
205
|
+
"manyToManyJoin"
|
|
206
|
+
],
|
|
207
|
+
postgresql: ALL_JOIN_METHODS
|
|
208
|
+
};
|
|
209
|
+
const supportedMethods = (provider ? SUPPORTED_JOIN_METHODS[provider] : void 0) ?? ALL_JOIN_METHODS;
|
|
210
|
+
const omittedMethods = ALL_JOIN_METHODS.filter((m) => !supportedMethods.includes(m));
|
|
211
|
+
const extendDts = fs2.readFileSync(path2.join(srcDir, "extend.d.ts"), { encoding: "utf-8" });
|
|
212
|
+
const PLACEHOLDER = "type SelectFnContext<_TSources extends TArrSources, _TFields extends TFieldsType> = BaseSelectFnContext<_TSources, _TFields>;";
|
|
213
|
+
const JOIN_RETURN_RE = /type _fJoinReturn<[^>]+>[^;]+;/;
|
|
214
|
+
const joinReturnReplacement = omittedMethods.length > 0 ? `type _fJoinReturn<TSources extends TArrSources, TFields extends TFieldsType, TCTEs extends Record<string, Record<string, any>> = {}> = Omit<_fJoin<TSources, TFields, TCTEs>, ${omittedMethods.map((m) => `"${m}"`).join(" | ")}>;` : `type _fJoinReturn<TSources extends TArrSources, TFields extends TFieldsType, TCTEs extends Record<string, Record<string, any>> = {}> = _fJoin<TSources, TFields, TCTEs>;`;
|
|
215
|
+
const replacedExtendDts = extendDts.replace("declare const DB: DBType;", declaration).replace(
|
|
216
|
+
PLACEHOLDER,
|
|
217
|
+
`type SelectFnContext<_TSources extends TArrSources, _TFields extends TFieldsType> = Omit<BaseSelectFnContext<_TSources, _TFields>, keyof DialectFns<ColEntries<_TSources, _TFields>, WhereCriteria<_TSources, _TFields>>> & DialectFns<ColEntries<_TSources, _TFields>, WhereCriteria<_TSources, _TFields>>;`
|
|
218
|
+
).replace(JOIN_RETURN_RE, joinReturnReplacement);
|
|
219
|
+
const dtsWithDialect = `import type { DialectFns } from './dialects/${provider}.js';
|
|
220
|
+
` + replacedExtendDts;
|
|
221
|
+
writeFileSafely(path2.join(outputPath, "extend.d.ts"), dtsWithDialect);
|
|
222
|
+
for (const ver of ["v6", "v7"]) {
|
|
223
|
+
const srcFile = hasVersions ? `${provider}-${ver}` : provider;
|
|
224
|
+
writeFileSafely(path2.join(outputPath, `extend-${ver}.js`), `export * from './extend.js';
|
|
225
|
+
export { default } from './extend.js';
|
|
226
|
+
`);
|
|
227
|
+
const vDts = `import type { DialectFns } from './dialects/${srcFile}.js';
|
|
228
|
+
` + replacedExtendDts;
|
|
229
|
+
writeFileSafely(path2.join(outputPath, `extend-${ver}.d.ts`), vDts);
|
|
230
|
+
}
|
|
231
|
+
for (const file of fs2.readdirSync(srcDir)) {
|
|
232
|
+
if (file !== "extend.d.ts" && file !== "extend.js" && file.endsWith(".d.ts")) {
|
|
233
|
+
fs2.copyFileSync(path2.join(srcDir, file), path2.join(outputPath, file));
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
function isManyToManyRelationShip(field) {
|
|
237
|
+
if (!(field.kind === "object" && field.isList)) return false;
|
|
238
|
+
const { type, relationName } = field;
|
|
239
|
+
const typeModel = options.dmmf.datamodel.models.find((m) => m.name === type);
|
|
240
|
+
if (!typeModel) return false;
|
|
241
|
+
if (!typeModel.fields.find((f) => f.kind === "object" && f.isList && f.relationName === relationName)) return false;
|
|
242
|
+
return true;
|
|
243
|
+
}
|
|
244
|
+
function getModelId(name) {
|
|
245
|
+
if (!modelToId[name]) {
|
|
246
|
+
for (const m of options.dmmf.datamodel.models) {
|
|
247
|
+
if (m.name !== name) continue;
|
|
248
|
+
for (const f of m.fields) {
|
|
249
|
+
if (f.isId) {
|
|
250
|
+
modelToId[m.name] = [f.name, f.type];
|
|
251
|
+
break;
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
const remoteId = modelToId[name];
|
|
257
|
+
if (!remoteId) throw new Error(`Remote: Unable to find @id field for model, ${name}`);
|
|
258
|
+
return remoteId;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
});
|
|
262
|
+
function generateReadonlyDeclaration(db) {
|
|
263
|
+
const traverse = (obj, level = 0) => {
|
|
264
|
+
const indent = " ".repeat(level);
|
|
265
|
+
const lines = [];
|
|
266
|
+
if (obj === null) return lines.join("\n");
|
|
267
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
268
|
+
if (typeof value === "object" && !Array.isArray(value)) {
|
|
269
|
+
lines.push(`${indent}readonly ${key}: {`);
|
|
270
|
+
lines.push(traverse(value, level + 1));
|
|
271
|
+
lines.push(`${indent}};`);
|
|
272
|
+
} else if (Array.isArray(value)) {
|
|
273
|
+
lines.push(`${indent}readonly ${key}: [${value.map((v) => `"${v}"`).join(", ")}];`);
|
|
274
|
+
} else {
|
|
275
|
+
lines.push(`${indent}readonly ${key}: "${value}";`);
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
return lines.join("\n");
|
|
279
|
+
};
|
|
280
|
+
return `declare const DB: {
|
|
281
|
+
${traverse(db, 1)}
|
|
282
|
+
};`;
|
|
283
|
+
}
|
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var generatorHelper = require('@prisma/generator-helper');
|
|
4
|
+
var internals = require('@prisma/internals');
|
|
5
|
+
var path2 = require('path');
|
|
6
|
+
var fs2 = require('fs');
|
|
7
|
+
var module$1 = require('module');
|
|
8
|
+
|
|
9
|
+
var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
|
|
10
|
+
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
11
|
+
|
|
12
|
+
var path2__default = /*#__PURE__*/_interopDefault(path2);
|
|
13
|
+
var fs2__default = /*#__PURE__*/_interopDefault(fs2);
|
|
14
|
+
|
|
15
|
+
// src/generator.ts
|
|
16
|
+
|
|
17
|
+
// src/constants.ts
|
|
18
|
+
var GENERATOR_NAME = "prisma-ts-select";
|
|
19
|
+
function writeFileSafely(writeLocation, content) {
|
|
20
|
+
fs2__default.default.mkdirSync(path2__default.default.dirname(writeLocation), {
|
|
21
|
+
recursive: true
|
|
22
|
+
});
|
|
23
|
+
fs2__default.default.writeFileSync(writeLocation, content);
|
|
24
|
+
}
|
|
25
|
+
var _require = module$1.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.src || new URL('out.js', document.baseURI).href)));
|
|
26
|
+
var SupportedProviders = {
|
|
27
|
+
sqlite: true,
|
|
28
|
+
mysql: true,
|
|
29
|
+
postgresql: true,
|
|
30
|
+
"prisma+postgres": false,
|
|
31
|
+
cockroachdb: false,
|
|
32
|
+
mongodb: false,
|
|
33
|
+
postgres: false,
|
|
34
|
+
sqlserver: false
|
|
35
|
+
};
|
|
36
|
+
generatorHelper.generatorHandler({
|
|
37
|
+
onManifest() {
|
|
38
|
+
internals.logger.info(`${GENERATOR_NAME}:Registered`);
|
|
39
|
+
return {
|
|
40
|
+
defaultOutput: "",
|
|
41
|
+
prettyName: GENERATOR_NAME
|
|
42
|
+
};
|
|
43
|
+
},
|
|
44
|
+
onGenerate: async (options) => {
|
|
45
|
+
const provider = options.datasources[0]?.provider;
|
|
46
|
+
const output = options.generator.output?.value;
|
|
47
|
+
if (!output) throw new Error(`${GENERATOR_NAME}: No output directory found. Please add an output directory to your schema.prisma file.`);
|
|
48
|
+
const outputPath = path2__default.default.resolve(output);
|
|
49
|
+
fs2__default.default.mkdirSync(outputPath, { recursive: true });
|
|
50
|
+
console.log(`${GENERATOR_NAME}: Generating to ${outputPath}`);
|
|
51
|
+
const validDS = options.datasources.map((ds) => ds.provider).filter((type) => SupportedProviders[type]);
|
|
52
|
+
if (validDS.length === 0) {
|
|
53
|
+
throw new Error(`${GENERATOR_NAME}: Supported DataSource Providers are: ${Object.entries(SupportedProviders).reduce((acc, [name, supported]) => {
|
|
54
|
+
if (!supported) return acc;
|
|
55
|
+
acc.push(name);
|
|
56
|
+
return acc;
|
|
57
|
+
}, []).join(", ")}`);
|
|
58
|
+
}
|
|
59
|
+
const modelToId = {};
|
|
60
|
+
const models = options.dmmf.datamodel.models.reduce((acc, model) => {
|
|
61
|
+
const modelObj = acc[model.name] = acc[model.name] ?? {
|
|
62
|
+
fields: {},
|
|
63
|
+
relations: {}
|
|
64
|
+
};
|
|
65
|
+
for (const field of model.fields) {
|
|
66
|
+
if (field.kind !== "object") {
|
|
67
|
+
if (field.isId) modelToId[model.name] = [field.name, field.type];
|
|
68
|
+
modelObj.fields = modelObj.fields ?? {};
|
|
69
|
+
modelObj.fields[field.name] = (!field.isRequired ? "?" : "") + field.type;
|
|
70
|
+
} else {
|
|
71
|
+
if (field.relationFromFields && field.relationFromFields.length > 0 && (field.relationToFields && field.relationToFields.length > 0)) {
|
|
72
|
+
const fieldObj = modelObj.relations[field.type] = modelObj.relations[field.type] ?? {};
|
|
73
|
+
field.relationFromFields.forEach((relationFromField, i) => {
|
|
74
|
+
if (!field.relationToFields) return;
|
|
75
|
+
const relationToField = field.relationToFields[i];
|
|
76
|
+
if (!relationToField) return;
|
|
77
|
+
fieldObj[relationFromField] = fieldObj[relationFromField] || [];
|
|
78
|
+
fieldObj[relationFromField].push(relationToField);
|
|
79
|
+
const accModel = acc[field.type] = acc[field.type] ?? {};
|
|
80
|
+
const accModelRelations = accModel.relations = accModel.relations ?? {};
|
|
81
|
+
const accModelRelationToModel = accModelRelations[model.name] = accModelRelations[model.name] ?? {};
|
|
82
|
+
const relationFromFieldList = accModelRelationToModel[relationToField] = accModelRelationToModel[relationToField] ?? [];
|
|
83
|
+
relationFromFieldList.push(relationFromField);
|
|
84
|
+
});
|
|
85
|
+
} else {
|
|
86
|
+
if (!isManyToManyRelationShip(field)) continue;
|
|
87
|
+
const joinTableName = "_" + field.relationName;
|
|
88
|
+
const joinTableModel = acc[joinTableName] = acc[joinTableName] ?? {
|
|
89
|
+
fields: {
|
|
90
|
+
"A": "",
|
|
91
|
+
"B": ""
|
|
92
|
+
},
|
|
93
|
+
relations: {}
|
|
94
|
+
};
|
|
95
|
+
const abJoin = [field.type, model.name].toSorted().indexOf(model.name) === 0 ? "A" : "B";
|
|
96
|
+
const [idName, idType] = getModelId(model.name);
|
|
97
|
+
joinTableModel.fields[abJoin] = idType;
|
|
98
|
+
{
|
|
99
|
+
const mr = joinTableModel.relations[model.name] = joinTableModel.relations[model.name] ?? {};
|
|
100
|
+
const mrt = mr[abJoin] = mr[abJoin] ?? [];
|
|
101
|
+
mrt.push(idName);
|
|
102
|
+
}
|
|
103
|
+
const m = modelObj.relations[joinTableName] = modelObj.relations[joinTableName] ?? {};
|
|
104
|
+
const mf = m[idName] = m[idName] ?? [];
|
|
105
|
+
mf.push(abJoin);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
return acc;
|
|
110
|
+
}, {});
|
|
111
|
+
const pTSSelPath = path2__default.default.dirname(_require.resolve("prisma-ts-select"));
|
|
112
|
+
internals.logger.info("pTSSelPath", pTSSelPath);
|
|
113
|
+
const srcDir = path2__default.default.join(pTSSelPath, "extend");
|
|
114
|
+
const hasVersions = provider !== "sqlite";
|
|
115
|
+
const dialectFiles = [
|
|
116
|
+
"types",
|
|
117
|
+
"shared",
|
|
118
|
+
provider,
|
|
119
|
+
...hasVersions ? [`${provider}-v6`, `${provider}-v7`] : []
|
|
120
|
+
];
|
|
121
|
+
const dialectOutDir = path2__default.default.join(outputPath, "dialects");
|
|
122
|
+
fs2__default.default.mkdirSync(dialectOutDir, { recursive: true });
|
|
123
|
+
for (const baseName of dialectFiles) {
|
|
124
|
+
for (const ext of [".js", ".d.ts"]) {
|
|
125
|
+
const src = path2__default.default.join(pTSSelPath, "extend", "dialects", `${baseName}${ext}`);
|
|
126
|
+
const dest = path2__default.default.join(dialectOutDir, `${baseName}${ext}`);
|
|
127
|
+
if (fs2__default.default.existsSync(src)) {
|
|
128
|
+
fs2__default.default.copyFileSync(src, dest);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
const defaultCtxFns = hasVersions ? `${provider}V7ContextFns` : `${provider}ContextFns`;
|
|
133
|
+
const defaultSrc = hasVersions ? `${provider}-v7` : provider;
|
|
134
|
+
const dialectIndexJs = `export { ${provider}Dialect as dialect, ${defaultCtxFns} as dialectContextFns } from './${defaultSrc}.js';
|
|
135
|
+
`;
|
|
136
|
+
fs2__default.default.writeFileSync(path2__default.default.join(dialectOutDir, "index.js"), dialectIndexJs);
|
|
137
|
+
const dialectIndexDts = `export { type Dialect, type FunctionRegistry, SUPPORTED_PROVIDERS, type SupportedProvider } from './types.js';
|
|
138
|
+
export { sharedFunctions } from './shared.js';
|
|
139
|
+
export { ${provider}Dialect as dialect, ${provider}Dialect, ${defaultCtxFns} as dialectContextFns } from './${defaultSrc}.js';
|
|
140
|
+
`;
|
|
141
|
+
fs2__default.default.writeFileSync(path2__default.default.join(dialectOutDir, "index.d.ts"), dialectIndexDts);
|
|
142
|
+
for (const ver of ["v6", "v7"]) {
|
|
143
|
+
const ctxName = hasVersions ? `${provider}${ver === "v6" ? "V6" : "V7"}ContextFns` : `${provider}ContextFns`;
|
|
144
|
+
const srcFile = hasVersions ? `${provider}-${ver}` : provider;
|
|
145
|
+
const js = `export { ${provider}Dialect as dialect, ${ctxName} as dialectContextFns } from './${srcFile}.js';
|
|
146
|
+
`;
|
|
147
|
+
const dts = `export { type Dialect, type FunctionRegistry, SUPPORTED_PROVIDERS, type SupportedProvider } from './types.js';
|
|
148
|
+
export { sharedFunctions } from './shared.js';
|
|
149
|
+
export { ${provider}Dialect as dialect, ${provider}Dialect, ${ctxName} as dialectContextFns } from './${srcFile}.js';
|
|
150
|
+
`;
|
|
151
|
+
fs2__default.default.writeFileSync(path2__default.default.join(dialectOutDir, `${ver}.js`), js);
|
|
152
|
+
fs2__default.default.writeFileSync(path2__default.default.join(dialectOutDir, `${ver}.d.ts`), dts);
|
|
153
|
+
}
|
|
154
|
+
const extendContents = fs2__default.default.readFileSync(path2__default.default.join(srcDir, "extend.js"), { encoding: "utf-8" });
|
|
155
|
+
writeFileSafely(
|
|
156
|
+
path2__default.default.join(outputPath, "extend.js"),
|
|
157
|
+
extendContents.replace("var DB = {};", `var DB = ${JSON.stringify(models, null, 2)};`)
|
|
158
|
+
);
|
|
159
|
+
const declaration = generateReadonlyDeclaration(models);
|
|
160
|
+
const ALL_JOIN_METHODS = [
|
|
161
|
+
"join",
|
|
162
|
+
"joinUnsafeTypeEnforced",
|
|
163
|
+
"joinUnsafeIgnoreType",
|
|
164
|
+
"innerJoin",
|
|
165
|
+
"innerJoinUnsafeTypeEnforced",
|
|
166
|
+
"innerJoinUnsafeIgnoreType",
|
|
167
|
+
"leftJoin",
|
|
168
|
+
"leftJoinUnsafeTypeEnforced",
|
|
169
|
+
"leftJoinUnsafeIgnoreType",
|
|
170
|
+
"rightJoin",
|
|
171
|
+
"rightJoinUnsafeTypeEnforced",
|
|
172
|
+
"rightJoinUnsafeIgnoreType",
|
|
173
|
+
"fullJoin",
|
|
174
|
+
"fullJoinUnsafeTypeEnforced",
|
|
175
|
+
"fullJoinUnsafeIgnoreType",
|
|
176
|
+
"crossJoin",
|
|
177
|
+
"crossJoinUnsafeTypeEnforced",
|
|
178
|
+
"crossJoinUnsafeIgnoreType",
|
|
179
|
+
"manyToManyJoin"
|
|
180
|
+
];
|
|
181
|
+
const SUPPORTED_JOIN_METHODS = {
|
|
182
|
+
sqlite: [
|
|
183
|
+
"join",
|
|
184
|
+
"joinUnsafeTypeEnforced",
|
|
185
|
+
"joinUnsafeIgnoreType",
|
|
186
|
+
"innerJoin",
|
|
187
|
+
"innerJoinUnsafeTypeEnforced",
|
|
188
|
+
"innerJoinUnsafeIgnoreType",
|
|
189
|
+
"leftJoin",
|
|
190
|
+
"leftJoinUnsafeTypeEnforced",
|
|
191
|
+
"leftJoinUnsafeIgnoreType",
|
|
192
|
+
"crossJoin",
|
|
193
|
+
"crossJoinUnsafeTypeEnforced",
|
|
194
|
+
"crossJoinUnsafeIgnoreType",
|
|
195
|
+
"manyToManyJoin"
|
|
196
|
+
],
|
|
197
|
+
mysql: [
|
|
198
|
+
"join",
|
|
199
|
+
"joinUnsafeTypeEnforced",
|
|
200
|
+
"joinUnsafeIgnoreType",
|
|
201
|
+
"innerJoin",
|
|
202
|
+
"innerJoinUnsafeTypeEnforced",
|
|
203
|
+
"innerJoinUnsafeIgnoreType",
|
|
204
|
+
"leftJoin",
|
|
205
|
+
"leftJoinUnsafeTypeEnforced",
|
|
206
|
+
"leftJoinUnsafeIgnoreType",
|
|
207
|
+
"rightJoin",
|
|
208
|
+
"rightJoinUnsafeTypeEnforced",
|
|
209
|
+
"rightJoinUnsafeIgnoreType",
|
|
210
|
+
"crossJoin",
|
|
211
|
+
"crossJoinUnsafeTypeEnforced",
|
|
212
|
+
"crossJoinUnsafeIgnoreType",
|
|
213
|
+
"manyToManyJoin"
|
|
214
|
+
],
|
|
215
|
+
postgresql: ALL_JOIN_METHODS
|
|
216
|
+
};
|
|
217
|
+
const supportedMethods = (provider ? SUPPORTED_JOIN_METHODS[provider] : void 0) ?? ALL_JOIN_METHODS;
|
|
218
|
+
const omittedMethods = ALL_JOIN_METHODS.filter((m) => !supportedMethods.includes(m));
|
|
219
|
+
const extendDts = fs2__default.default.readFileSync(path2__default.default.join(srcDir, "extend.d.ts"), { encoding: "utf-8" });
|
|
220
|
+
const PLACEHOLDER = "type SelectFnContext<_TSources extends TArrSources, _TFields extends TFieldsType> = BaseSelectFnContext<_TSources, _TFields>;";
|
|
221
|
+
const JOIN_RETURN_RE = /type _fJoinReturn<[^>]+>[^;]+;/;
|
|
222
|
+
const joinReturnReplacement = omittedMethods.length > 0 ? `type _fJoinReturn<TSources extends TArrSources, TFields extends TFieldsType, TCTEs extends Record<string, Record<string, any>> = {}> = Omit<_fJoin<TSources, TFields, TCTEs>, ${omittedMethods.map((m) => `"${m}"`).join(" | ")}>;` : `type _fJoinReturn<TSources extends TArrSources, TFields extends TFieldsType, TCTEs extends Record<string, Record<string, any>> = {}> = _fJoin<TSources, TFields, TCTEs>;`;
|
|
223
|
+
const replacedExtendDts = extendDts.replace("declare const DB: DBType;", declaration).replace(
|
|
224
|
+
PLACEHOLDER,
|
|
225
|
+
`type SelectFnContext<_TSources extends TArrSources, _TFields extends TFieldsType> = Omit<BaseSelectFnContext<_TSources, _TFields>, keyof DialectFns<ColEntries<_TSources, _TFields>, WhereCriteria<_TSources, _TFields>>> & DialectFns<ColEntries<_TSources, _TFields>, WhereCriteria<_TSources, _TFields>>;`
|
|
226
|
+
).replace(JOIN_RETURN_RE, joinReturnReplacement);
|
|
227
|
+
const dtsWithDialect = `import type { DialectFns } from './dialects/${provider}.js';
|
|
228
|
+
` + replacedExtendDts;
|
|
229
|
+
writeFileSafely(path2__default.default.join(outputPath, "extend.d.ts"), dtsWithDialect);
|
|
230
|
+
for (const ver of ["v6", "v7"]) {
|
|
231
|
+
const srcFile = hasVersions ? `${provider}-${ver}` : provider;
|
|
232
|
+
writeFileSafely(path2__default.default.join(outputPath, `extend-${ver}.js`), `export * from './extend.js';
|
|
233
|
+
export { default } from './extend.js';
|
|
234
|
+
`);
|
|
235
|
+
const vDts = `import type { DialectFns } from './dialects/${srcFile}.js';
|
|
236
|
+
` + replacedExtendDts;
|
|
237
|
+
writeFileSafely(path2__default.default.join(outputPath, `extend-${ver}.d.ts`), vDts);
|
|
238
|
+
}
|
|
239
|
+
for (const file of fs2__default.default.readdirSync(srcDir)) {
|
|
240
|
+
if (file !== "extend.d.ts" && file !== "extend.js" && file.endsWith(".d.ts")) {
|
|
241
|
+
fs2__default.default.copyFileSync(path2__default.default.join(srcDir, file), path2__default.default.join(outputPath, file));
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
function isManyToManyRelationShip(field) {
|
|
245
|
+
if (!(field.kind === "object" && field.isList)) return false;
|
|
246
|
+
const { type, relationName } = field;
|
|
247
|
+
const typeModel = options.dmmf.datamodel.models.find((m) => m.name === type);
|
|
248
|
+
if (!typeModel) return false;
|
|
249
|
+
if (!typeModel.fields.find((f) => f.kind === "object" && f.isList && f.relationName === relationName)) return false;
|
|
250
|
+
return true;
|
|
251
|
+
}
|
|
252
|
+
function getModelId(name) {
|
|
253
|
+
if (!modelToId[name]) {
|
|
254
|
+
for (const m of options.dmmf.datamodel.models) {
|
|
255
|
+
if (m.name !== name) continue;
|
|
256
|
+
for (const f of m.fields) {
|
|
257
|
+
if (f.isId) {
|
|
258
|
+
modelToId[m.name] = [f.name, f.type];
|
|
259
|
+
break;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
const remoteId = modelToId[name];
|
|
265
|
+
if (!remoteId) throw new Error(`Remote: Unable to find @id field for model, ${name}`);
|
|
266
|
+
return remoteId;
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
});
|
|
270
|
+
function generateReadonlyDeclaration(db) {
|
|
271
|
+
const traverse = (obj, level = 0) => {
|
|
272
|
+
const indent = " ".repeat(level);
|
|
273
|
+
const lines = [];
|
|
274
|
+
if (obj === null) return lines.join("\n");
|
|
275
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
276
|
+
if (typeof value === "object" && !Array.isArray(value)) {
|
|
277
|
+
lines.push(`${indent}readonly ${key}: {`);
|
|
278
|
+
lines.push(traverse(value, level + 1));
|
|
279
|
+
lines.push(`${indent}};`);
|
|
280
|
+
} else if (Array.isArray(value)) {
|
|
281
|
+
lines.push(`${indent}readonly ${key}: [${value.map((v) => `"${v}"`).join(", ")}];`);
|
|
282
|
+
} else {
|
|
283
|
+
lines.push(`${indent}readonly ${key}: "${value}";`);
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
return lines.join("\n");
|
|
287
|
+
};
|
|
288
|
+
return `declare const DB: {
|
|
289
|
+
${traverse(db, 1)}
|
|
290
|
+
};`;
|
|
291
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { SupportedProvider, Dialect } from './types.js';
|
|
2
|
+
export { SUPPORTED_PROVIDERS } from './types.js';
|
|
3
|
+
export { sqliteDialect as dialect, sqliteContextFns as dialectContextFns, sqliteDialect } from './sqlite.js';
|
|
4
|
+
export { mysqlDialect } from './mysql.js';
|
|
5
|
+
export { postgresqlDialect } from './postgresql.js';
|
|
6
|
+
import '../sql-expr-BaKWzJ-r.js';
|
|
7
|
+
import './shared.js';
|
|
8
|
+
import '../types-D84lxYVc.js';
|
|
9
|
+
import '@prisma/client/runtime/client';
|
|
10
|
+
|
|
11
|
+
declare function getDialect(provider: SupportedProvider): Dialect;
|
|
12
|
+
|
|
13
|
+
export { Dialect, SupportedProvider, getDialect };
|