@autonoma-ai/sdk-prisma 0.1.2 → 0.1.4
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/README.md +1 -1
- package/dist/index.d.ts +14 -9
- package/dist/index.js +15 -292
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -31,7 +31,7 @@ export const POST = createHandler({
|
|
|
31
31
|
signingSecret: process.env.AUTONOMA_SIGNING_SECRET!,
|
|
32
32
|
auth: async (user) => {
|
|
33
33
|
const session = await createSession(user.id as string)
|
|
34
|
-
return {
|
|
34
|
+
return { headers: { Authorization: `Bearer ${session.token}` } }
|
|
35
35
|
},
|
|
36
36
|
})
|
|
37
37
|
```
|
package/dist/index.d.ts
CHANGED
|
@@ -1,20 +1,25 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { SQLExecutor } from '@autonoma-ai/sdk';
|
|
2
2
|
|
|
3
|
-
interface
|
|
4
|
-
|
|
3
|
+
interface PrismaClient {
|
|
4
|
+
$queryRawUnsafe<T = unknown>(query: string, ...values: unknown[]): Promise<T>;
|
|
5
|
+
$transaction<T>(fn: (tx: PrismaClient) => Promise<T>): Promise<T>;
|
|
5
6
|
}
|
|
6
|
-
|
|
7
7
|
/**
|
|
8
|
-
* Create a
|
|
8
|
+
* Create a SQLExecutor from a Prisma client.
|
|
9
9
|
*
|
|
10
10
|
* @example
|
|
11
11
|
* ```ts
|
|
12
|
-
* import {
|
|
12
|
+
* import { prismaExecutor } from '@autonoma-ai/sdk-prisma'
|
|
13
13
|
* import { prisma } from './db'
|
|
14
14
|
*
|
|
15
|
-
* const
|
|
15
|
+
* const handler = createHandler({
|
|
16
|
+
* executor: prismaExecutor(prisma),
|
|
17
|
+
* scopeField: 'organizationId',
|
|
18
|
+
* sharedSecret: process.env.AUTONOMA_SECRET!,
|
|
19
|
+
* signingSecret: process.env.AUTONOMA_SIGNING_SECRET!,
|
|
20
|
+
* })
|
|
16
21
|
* ```
|
|
17
22
|
*/
|
|
18
|
-
declare function
|
|
23
|
+
declare function prismaExecutor(prisma: PrismaClient): SQLExecutor;
|
|
19
24
|
|
|
20
|
-
export {
|
|
25
|
+
export { prismaExecutor };
|
package/dist/index.js
CHANGED
|
@@ -1,301 +1,24 @@
|
|
|
1
|
-
// src/introspect.ts
|
|
2
|
-
function introspectPrisma(prisma, config) {
|
|
3
|
-
const dmmfModels = getDMMFModels(prisma);
|
|
4
|
-
const hasDMMFRelationMeta = dmmfModels.some(
|
|
5
|
-
(m) => m.fields.some((f) => f.kind === "object" && f.relationFromFields !== void 0)
|
|
6
|
-
);
|
|
7
|
-
const models = [];
|
|
8
|
-
const edges = [];
|
|
9
|
-
const relations = [];
|
|
10
|
-
for (const model of dmmfModels) {
|
|
11
|
-
const fields = [];
|
|
12
|
-
for (const field of model.fields) {
|
|
13
|
-
if (field.kind !== "scalar" && field.kind !== "enum") continue;
|
|
14
|
-
const { isId, hasDefault, isRequired } = hasDMMFRelationMeta ? {
|
|
15
|
-
isId: field.isId ?? false,
|
|
16
|
-
hasDefault: field.hasDefaultValue || !!field.isUpdatedAt || !!field.isGenerated || false,
|
|
17
|
-
isRequired: field.isRequired ?? true
|
|
18
|
-
} : inferFieldMetadata(field);
|
|
19
|
-
fields.push({ name: field.name, type: field.type, isRequired, isId, hasDefault });
|
|
20
|
-
}
|
|
21
|
-
models.push({ name: model.name, fields });
|
|
22
|
-
}
|
|
23
|
-
if (hasDMMFRelationMeta) {
|
|
24
|
-
buildEdgesFromDMMF(dmmfModels, edges);
|
|
25
|
-
buildRelationsFromDMMF(dmmfModels, edges, relations);
|
|
26
|
-
} else {
|
|
27
|
-
buildEdgesFromInference(dmmfModels, edges);
|
|
28
|
-
buildRelationsFromInference(dmmfModels, edges, relations);
|
|
29
|
-
}
|
|
30
|
-
return { models, edges, relations, scopeField: config.scopeField };
|
|
31
|
-
}
|
|
32
|
-
function inferFieldMetadata(field) {
|
|
33
|
-
const isId = field.name === "id";
|
|
34
|
-
const isAutoTimestamp = (field.name === "createdAt" || field.name === "updatedAt" || field.name.endsWith("At")) && field.type === "DateTime";
|
|
35
|
-
const hasDefault = isId || isAutoTimestamp;
|
|
36
|
-
return { isId, hasDefault, isRequired: !hasDefault };
|
|
37
|
-
}
|
|
38
|
-
function buildEdgesFromInference(dmmfModels, edges) {
|
|
39
|
-
for (const model of dmmfModels) {
|
|
40
|
-
const scalarNames = new Set(
|
|
41
|
-
model.fields.filter((f) => f.kind === "scalar" || f.kind === "enum").map((f) => f.name)
|
|
42
|
-
);
|
|
43
|
-
for (const field of model.fields) {
|
|
44
|
-
if (field.kind !== "object") continue;
|
|
45
|
-
const fkField = findFKField(field, scalarNames);
|
|
46
|
-
if (fkField) {
|
|
47
|
-
edges.push({
|
|
48
|
-
from: model.name,
|
|
49
|
-
to: field.type,
|
|
50
|
-
localField: fkField,
|
|
51
|
-
foreignField: "id",
|
|
52
|
-
nullable: false
|
|
53
|
-
});
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
function buildRelationsFromInference(dmmfModels, edges, relations) {
|
|
59
|
-
for (const model of dmmfModels) {
|
|
60
|
-
const scalarNames = new Set(
|
|
61
|
-
model.fields.filter((f) => f.kind === "scalar" || f.kind === "enum").map((f) => f.name)
|
|
62
|
-
);
|
|
63
|
-
for (const field of model.fields) {
|
|
64
|
-
if (field.kind !== "object") continue;
|
|
65
|
-
const fkField = findFKField(field, scalarNames);
|
|
66
|
-
if (fkField) {
|
|
67
|
-
relations.push({
|
|
68
|
-
parentModel: model.name,
|
|
69
|
-
childModel: field.type,
|
|
70
|
-
parentField: field.name,
|
|
71
|
-
childField: fkField
|
|
72
|
-
});
|
|
73
|
-
} else {
|
|
74
|
-
const childEdge = edges.find((e) => e.from === field.type && e.to === model.name);
|
|
75
|
-
if (childEdge) {
|
|
76
|
-
relations.push({
|
|
77
|
-
parentModel: model.name,
|
|
78
|
-
childModel: field.type,
|
|
79
|
-
parentField: field.name,
|
|
80
|
-
childField: childEdge.localField
|
|
81
|
-
});
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
function findFKField(field, scalarNames) {
|
|
88
|
-
const byFieldName = `${field.name}Id`;
|
|
89
|
-
if (scalarNames.has(byFieldName)) return byFieldName;
|
|
90
|
-
const byTypeName = `${lowerFirst(field.type)}Id`;
|
|
91
|
-
if (scalarNames.has(byTypeName)) return byTypeName;
|
|
92
|
-
return null;
|
|
93
|
-
}
|
|
94
|
-
function lowerFirst(str) {
|
|
95
|
-
return str.charAt(0).toLowerCase() + str.slice(1);
|
|
96
|
-
}
|
|
97
|
-
function buildEdgesFromDMMF(dmmfModels, edges) {
|
|
98
|
-
for (const model of dmmfModels) {
|
|
99
|
-
for (const field of model.fields) {
|
|
100
|
-
if (field.kind === "object" && field.relationFromFields?.length) {
|
|
101
|
-
edges.push({
|
|
102
|
-
from: model.name,
|
|
103
|
-
to: field.type,
|
|
104
|
-
localField: field.relationFromFields[0],
|
|
105
|
-
foreignField: field.relationToFields?.[0] ?? "id",
|
|
106
|
-
nullable: !field.isRequired
|
|
107
|
-
});
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
function buildRelationsFromDMMF(dmmfModels, edges, relations) {
|
|
113
|
-
for (const model of dmmfModels) {
|
|
114
|
-
for (const field of model.fields) {
|
|
115
|
-
if (field.kind === "object" && !field.relationFromFields?.length) {
|
|
116
|
-
const childEdge = edges.find(
|
|
117
|
-
(e) => e.from === field.type && e.to === model.name && e.foreignField === "id"
|
|
118
|
-
);
|
|
119
|
-
const childEdgeByRelation = !childEdge ? edges.find((e) => {
|
|
120
|
-
if (e.from !== field.type || e.to !== model.name) return false;
|
|
121
|
-
const childModel = dmmfModels.find((m) => m.name === field.type);
|
|
122
|
-
if (!childModel) return false;
|
|
123
|
-
const childField = childModel.fields.find(
|
|
124
|
-
(f) => f.kind === "object" && f.relationName === field.relationName && f.relationFromFields?.length
|
|
125
|
-
);
|
|
126
|
-
return childField?.relationFromFields?.[0] === e.localField;
|
|
127
|
-
}) : null;
|
|
128
|
-
const edge = childEdge ?? childEdgeByRelation;
|
|
129
|
-
if (edge) {
|
|
130
|
-
relations.push({
|
|
131
|
-
parentModel: model.name,
|
|
132
|
-
childModel: field.type,
|
|
133
|
-
parentField: field.name,
|
|
134
|
-
childField: edge.localField
|
|
135
|
-
});
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
for (const model of dmmfModels) {
|
|
141
|
-
for (const field of model.fields) {
|
|
142
|
-
if (field.kind === "object" && !field.isList && field.relationFromFields?.length) {
|
|
143
|
-
const localField = field.relationFromFields[0];
|
|
144
|
-
const alreadyCovered = relations.some(
|
|
145
|
-
(r) => r.parentModel === model.name && r.parentField === field.name
|
|
146
|
-
);
|
|
147
|
-
if (!alreadyCovered) {
|
|
148
|
-
relations.push({
|
|
149
|
-
parentModel: model.name,
|
|
150
|
-
childModel: field.type,
|
|
151
|
-
parentField: field.name,
|
|
152
|
-
childField: localField
|
|
153
|
-
});
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
function getDMMFModels(prisma) {
|
|
160
|
-
if (prisma._runtimeDataModel?.models) {
|
|
161
|
-
return Object.entries(prisma._runtimeDataModel.models).map(([name, model]) => ({
|
|
162
|
-
...model,
|
|
163
|
-
name
|
|
164
|
-
}));
|
|
165
|
-
}
|
|
166
|
-
if (prisma._baseDmmf?.datamodel?.models) {
|
|
167
|
-
return prisma._baseDmmf.datamodel.models;
|
|
168
|
-
}
|
|
169
|
-
throw new Error(
|
|
170
|
-
"Cannot introspect Prisma schema. Ensure @prisma/client is generated."
|
|
171
|
-
);
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
// src/create.ts
|
|
175
|
-
async function createEntities(prisma, spec, _context) {
|
|
176
|
-
const results = {};
|
|
177
|
-
await prisma.$transaction(async (tx) => {
|
|
178
|
-
for (const [model, entitySpec] of Object.entries(spec)) {
|
|
179
|
-
const delegate = tx[camelCase(model)];
|
|
180
|
-
if (!delegate) {
|
|
181
|
-
throw new Error(`Prisma model '${model}' not found. Check model name casing.`);
|
|
182
|
-
}
|
|
183
|
-
if (entitySpec.batch) {
|
|
184
|
-
await delegate.createMany({ data: entitySpec.fields });
|
|
185
|
-
results[model] = [];
|
|
186
|
-
} else {
|
|
187
|
-
const created = [];
|
|
188
|
-
for (const fields of entitySpec.fields) {
|
|
189
|
-
const record = await delegate.create({ data: fields });
|
|
190
|
-
created.push(record);
|
|
191
|
-
}
|
|
192
|
-
results[model] = created;
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
});
|
|
196
|
-
return results;
|
|
197
|
-
}
|
|
198
|
-
function camelCase(str) {
|
|
199
|
-
return str.charAt(0).toLowerCase() + str.slice(1);
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
// src/teardown.ts
|
|
203
|
-
import { topoSort, findDeferrableEdge } from "@autonoma-ai/sdk";
|
|
204
|
-
async function teardown(prisma, schema, scopeValue, refs) {
|
|
205
|
-
let scopeRootModel = null;
|
|
206
|
-
for (const edge of schema.edges) {
|
|
207
|
-
if (edge.localField.toLowerCase() === schema.scopeField.toLowerCase() && edge.to !== edge.from) {
|
|
208
|
-
scopeRootModel = edge.to;
|
|
209
|
-
break;
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
const scopeFieldByModel = /* @__PURE__ */ new Map();
|
|
213
|
-
if (scopeRootModel) {
|
|
214
|
-
for (const edge of schema.edges) {
|
|
215
|
-
if (edge.to === scopeRootModel && edge.from !== scopeRootModel) {
|
|
216
|
-
scopeFieldByModel.set(edge.from, edge.localField);
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
const modelNames = schema.models.map((m) => m.name);
|
|
221
|
-
const { sorted, cycles } = topoSort(modelNames, schema.edges);
|
|
222
|
-
await prisma.$transaction(async (tx) => {
|
|
223
|
-
for (const cycle of cycles) {
|
|
224
|
-
const edge = findDeferrableEdge(cycle, schema.edges);
|
|
225
|
-
if (edge) {
|
|
226
|
-
const scopeFK = scopeFieldByModel.get(edge.from);
|
|
227
|
-
if (scopeFK) {
|
|
228
|
-
const delegate = tx[camelCase2(edge.from)];
|
|
229
|
-
if (delegate) {
|
|
230
|
-
await delegate.updateMany({
|
|
231
|
-
where: { [scopeFK]: scopeValue },
|
|
232
|
-
data: { [edge.localField]: null }
|
|
233
|
-
});
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
}
|
|
238
|
-
for (const cycle of cycles) {
|
|
239
|
-
for (const model of cycle) {
|
|
240
|
-
await deleteModel(tx, model, scopeValue, scopeFieldByModel, refs);
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
const reversed = [...sorted].reverse();
|
|
244
|
-
for (const model of reversed) {
|
|
245
|
-
if (model === scopeRootModel) continue;
|
|
246
|
-
await deleteModel(tx, model, scopeValue, scopeFieldByModel, refs);
|
|
247
|
-
}
|
|
248
|
-
if (scopeRootModel) {
|
|
249
|
-
const delegate = tx[camelCase2(scopeRootModel)];
|
|
250
|
-
if (delegate) {
|
|
251
|
-
await delegate.deleteMany({ where: { id: scopeValue } });
|
|
252
|
-
}
|
|
253
|
-
}
|
|
254
|
-
});
|
|
255
|
-
}
|
|
256
|
-
async function deleteModel(tx, model, scopeValue, scopeFieldByModel, refs) {
|
|
257
|
-
const delegate = tx[camelCase2(model)];
|
|
258
|
-
if (!delegate) {
|
|
259
|
-
return;
|
|
260
|
-
}
|
|
261
|
-
const scopeFK = scopeFieldByModel.get(model);
|
|
262
|
-
if (scopeFK) {
|
|
263
|
-
await delegate.deleteMany({ where: { [scopeFK]: scopeValue } });
|
|
264
|
-
} else if (refs?.[model]) {
|
|
265
|
-
const ids = refs[model].map((r) => r.id).filter((id) => typeof id === "string");
|
|
266
|
-
if (ids.length > 0) {
|
|
267
|
-
await delegate.deleteMany({ where: { id: { in: ids } } });
|
|
268
|
-
}
|
|
269
|
-
}
|
|
270
|
-
}
|
|
271
|
-
function camelCase2(str) {
|
|
272
|
-
return str.charAt(0).toLowerCase() + str.slice(1);
|
|
273
|
-
}
|
|
274
|
-
|
|
275
1
|
// src/index.ts
|
|
276
|
-
function
|
|
277
|
-
let cachedSchema = null;
|
|
2
|
+
function prismaExecutor(prisma) {
|
|
278
3
|
return {
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
}
|
|
283
|
-
return cachedSchema;
|
|
284
|
-
},
|
|
285
|
-
async createEntities(spec, context) {
|
|
286
|
-
return createEntities(prisma, spec, context);
|
|
287
|
-
},
|
|
288
|
-
async teardown(scopeValue, refs) {
|
|
289
|
-
const schema = this.getSchema();
|
|
290
|
-
return teardown(prisma, schema, scopeValue, refs);
|
|
4
|
+
async query(sql, params) {
|
|
5
|
+
const result = await prisma.$queryRawUnsafe(sql, ...params ?? []);
|
|
6
|
+
return result;
|
|
291
7
|
},
|
|
292
|
-
async
|
|
293
|
-
|
|
294
|
-
|
|
8
|
+
async transaction(fn) {
|
|
9
|
+
return prisma.$transaction(async (txClient) => {
|
|
10
|
+
const txExecutor = {
|
|
11
|
+
async query(sql, params) {
|
|
12
|
+
return txClient.$queryRawUnsafe(sql, ...params ?? []);
|
|
13
|
+
},
|
|
14
|
+
transaction: (innerFn) => innerFn(txExecutor)
|
|
15
|
+
};
|
|
16
|
+
return fn(txExecutor);
|
|
17
|
+
});
|
|
295
18
|
}
|
|
296
19
|
};
|
|
297
20
|
}
|
|
298
21
|
export {
|
|
299
|
-
|
|
22
|
+
prismaExecutor
|
|
300
23
|
};
|
|
301
24
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/introspect.ts","../src/create.ts","../src/teardown.ts","../src/index.ts"],"sourcesContent":["import type { SchemaInfo, ModelInfo, FieldInfo, FKEdge, SchemaRelation } from '@autonoma-ai/sdk'\n\ninterface PrismaClient {\n _runtimeDataModel?: { models: Record<string, DMMFModel> }\n _baseDmmf?: { datamodel: { models: DMMFModel[] } }\n}\n\ninterface DMMFModel {\n name: string\n fields: DMMFField[]\n}\n\ninterface DMMFField {\n name: string\n type: string\n kind: string\n isList?: boolean\n isRequired?: boolean\n isId?: boolean\n hasDefaultValue?: boolean\n isUpdatedAt?: boolean\n isGenerated?: boolean\n relationFromFields?: string[]\n relationToFields?: string[]\n relationName?: string\n}\n\nexport interface PrismaAdapterConfig {\n scopeField: string\n}\n\n/**\n * Introspect Prisma DMMF to extract schema metadata.\n * Supports Prisma 5/6 (full DMMF) and Prisma 7+ (stripped _runtimeDataModel, uses inference).\n */\nexport function introspectPrisma(\n prisma: PrismaClient,\n config: PrismaAdapterConfig,\n): SchemaInfo {\n const dmmfModels = getDMMFModels(prisma)\n\n // Prisma 7+ stripped relationFromFields/relationToFields from _runtimeDataModel.\n // Detect by checking if any object field still carries that metadata.\n const hasDMMFRelationMeta = dmmfModels.some((m) =>\n m.fields.some((f) => f.kind === 'object' && f.relationFromFields !== undefined),\n )\n\n const models: ModelInfo[] = []\n const edges: FKEdge[] = []\n const relations: SchemaRelation[] = []\n\n // Extract scalar/enum fields for every model\n for (const model of dmmfModels) {\n const fields: FieldInfo[] = []\n for (const field of model.fields) {\n if (field.kind !== 'scalar' && field.kind !== 'enum') continue\n const { isId, hasDefault, isRequired } = hasDMMFRelationMeta\n ? {\n isId: field.isId ?? false,\n hasDefault:\n field.hasDefaultValue || !!field.isUpdatedAt || !!field.isGenerated || false,\n isRequired: field.isRequired ?? true,\n }\n : inferFieldMetadata(field)\n fields.push({ name: field.name, type: field.type, isRequired, isId, hasDefault })\n }\n models.push({ name: model.name, fields })\n }\n\n if (hasDMMFRelationMeta) {\n buildEdgesFromDMMF(dmmfModels, edges)\n buildRelationsFromDMMF(dmmfModels, edges, relations)\n } else {\n buildEdgesFromInference(dmmfModels, edges)\n buildRelationsFromInference(dmmfModels, edges, relations)\n }\n\n return { models, edges, relations, scopeField: config.scopeField }\n}\n\n// ---------------------------------------------------------------------------\n// Prisma 7+: inference-based FK detection\n// ---------------------------------------------------------------------------\n\n/**\n * Infer isId / hasDefault / isRequired from field name + type conventions.\n * Used when Prisma 7 strips those attributes from _runtimeDataModel.\n */\nfunction inferFieldMetadata(field: DMMFField): {\n isId: boolean\n hasDefault: boolean\n isRequired: boolean\n} {\n const isId = field.name === 'id'\n const isAutoTimestamp =\n (field.name === 'createdAt' ||\n field.name === 'updatedAt' ||\n field.name.endsWith('At')) &&\n field.type === 'DateTime'\n const hasDefault = isId || isAutoTimestamp\n return { isId, hasDefault, isRequired: !hasDefault }\n}\n\n/**\n * Infer FK edges from scalar field names.\n * For an object field `organization: Organization`, if the same model has a scalar\n * field named `organizationId` or `organizationId` (lowerFirst(type) + \"Id\"),\n * that scalar is the FK.\n */\nfunction buildEdgesFromInference(dmmfModels: DMMFModel[], edges: FKEdge[]): void {\n for (const model of dmmfModels) {\n const scalarNames = new Set(\n model.fields.filter((f) => f.kind === 'scalar' || f.kind === 'enum').map((f) => f.name),\n )\n\n for (const field of model.fields) {\n if (field.kind !== 'object') continue\n const fkField = findFKField(field, scalarNames)\n if (fkField) {\n edges.push({\n from: model.name,\n to: field.type,\n localField: fkField,\n foreignField: 'id',\n nullable: false,\n })\n }\n }\n }\n}\n\n/**\n * Build parent→child relation mappings using inferred edges.\n * - Child side (has scalar FK): parentModel=thisModel, childModel=field.type\n * - Parent side (no scalar FK): find the edge on the child model pointing back here\n */\nfunction buildRelationsFromInference(\n dmmfModels: DMMFModel[],\n edges: FKEdge[],\n relations: SchemaRelation[],\n): void {\n for (const model of dmmfModels) {\n const scalarNames = new Set(\n model.fields.filter((f) => f.kind === 'scalar' || f.kind === 'enum').map((f) => f.name),\n )\n\n for (const field of model.fields) {\n if (field.kind !== 'object') continue\n const fkField = findFKField(field, scalarNames)\n\n if (fkField) {\n // This model is the child — it holds the FK pointing to field.type\n relations.push({\n parentModel: model.name,\n childModel: field.type,\n parentField: field.name,\n childField: fkField,\n })\n } else {\n // This model is the parent — the child holds the FK back to this model\n const childEdge = edges.find((e) => e.from === field.type && e.to === model.name)\n if (childEdge) {\n relations.push({\n parentModel: model.name,\n childModel: field.type,\n parentField: field.name,\n childField: childEdge.localField,\n })\n }\n }\n }\n }\n}\n\n/**\n * Given an object field and the set of scalar field names on the same model,\n * return the FK scalar field name if one can be found, or null.\n *\n * Tries (in order):\n * 1. `${fieldName}Id` e.g. organization → organizationId\n * 2. `${lowerFirst(type)}Id` e.g. Organization → organizationId\n */\nfunction findFKField(field: DMMFField, scalarNames: Set<string>): string | null {\n const byFieldName = `${field.name}Id`\n if (scalarNames.has(byFieldName)) return byFieldName\n\n const byTypeName = `${lowerFirst(field.type)}Id`\n if (scalarNames.has(byTypeName)) return byTypeName\n\n return null\n}\n\nfunction lowerFirst(str: string): string {\n return str.charAt(0).toLowerCase() + str.slice(1)\n}\n\n// ---------------------------------------------------------------------------\n// Prisma ≤6: DMMF-based FK detection (unchanged original logic)\n// ---------------------------------------------------------------------------\n\nfunction buildEdgesFromDMMF(dmmfModels: DMMFModel[], edges: FKEdge[]): void {\n for (const model of dmmfModels) {\n for (const field of model.fields) {\n if (field.kind === 'object' && field.relationFromFields?.length) {\n edges.push({\n from: model.name,\n to: field.type,\n localField: field.relationFromFields[0]!,\n foreignField: field.relationToFields?.[0] ?? 'id',\n nullable: !field.isRequired,\n })\n }\n }\n }\n}\n\nfunction buildRelationsFromDMMF(\n dmmfModels: DMMFModel[],\n edges: FKEdge[],\n relations: SchemaRelation[],\n): void {\n // Parent side: object fields with no relationFromFields (they don't hold the FK)\n for (const model of dmmfModels) {\n for (const field of model.fields) {\n if (field.kind === 'object' && !field.relationFromFields?.length) {\n const childEdge = edges.find(\n (e) => e.from === field.type && e.to === model.name && e.foreignField === 'id',\n )\n const childEdgeByRelation =\n !childEdge\n ? edges.find((e) => {\n if (e.from !== field.type || e.to !== model.name) return false\n const childModel = dmmfModels.find((m) => m.name === field.type)\n if (!childModel) return false\n const childField = childModel.fields.find(\n (f) =>\n f.kind === 'object' &&\n f.relationName === field.relationName &&\n f.relationFromFields?.length,\n )\n return childField?.relationFromFields?.[0] === e.localField\n })\n : null\n\n const edge = childEdge ?? childEdgeByRelation\n if (edge) {\n relations.push({\n parentModel: model.name,\n childModel: field.type,\n parentField: field.name,\n childField: edge.localField,\n })\n }\n }\n }\n }\n\n // Child-side singular relations: object fields that DO hold the FK\n for (const model of dmmfModels) {\n for (const field of model.fields) {\n if (field.kind === 'object' && !field.isList && field.relationFromFields?.length) {\n const localField = field.relationFromFields[0]!\n const alreadyCovered = relations.some(\n (r) => r.parentModel === model.name && r.parentField === field.name,\n )\n if (!alreadyCovered) {\n relations.push({\n parentModel: model.name,\n childModel: field.type,\n parentField: field.name,\n childField: localField,\n })\n }\n }\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// DMMF model extraction\n// ---------------------------------------------------------------------------\n\nfunction getDMMFModels(prisma: PrismaClient): DMMFModel[] {\n if (prisma._runtimeDataModel?.models) {\n return Object.entries(prisma._runtimeDataModel.models).map(([name, model]) => ({\n ...model,\n name,\n }))\n }\n\n if (prisma._baseDmmf?.datamodel?.models) {\n return prisma._baseDmmf.datamodel.models\n }\n\n throw new Error(\n 'Cannot introspect Prisma schema. Ensure @prisma/client is generated.',\n )\n}\n","import type { ResolvedEntitySpec, CreateContext } from '@autonoma-ai/sdk'\n\ntype PrismaClient = Record<string, any>\n\n/**\n * Create entities using Prisma client.\n *\n * - Normal mode: individual create() calls, returns all created records (available in refs)\n * - Batch mode: single createMany() call, much faster for large counts but returns empty array\n */\nexport async function createEntities(\n prisma: PrismaClient,\n spec: Record<string, ResolvedEntitySpec>,\n _context: CreateContext,\n): Promise<Record<string, Record<string, unknown>[]>> {\n const results: Record<string, Record<string, unknown>[]> = {}\n\n await prisma.$transaction(async (tx: PrismaClient) => {\n for (const [model, entitySpec] of Object.entries(spec)) {\n const delegate = tx[camelCase(model)]\n if (!delegate) {\n throw new Error(`Prisma model '${model}' not found. Check model name casing.`)\n }\n\n if (entitySpec.batch) {\n // Batch: single createMany call — fast, but no records returned\n await delegate.createMany({ data: entitySpec.fields })\n results[model] = []\n } else {\n // Normal: individual creates — returns records for refs\n const created: Record<string, unknown>[] = []\n for (const fields of entitySpec.fields) {\n const record = await delegate.create({ data: fields })\n created.push(record)\n }\n results[model] = created\n }\n }\n })\n\n return results\n}\n\nfunction camelCase(str: string): string {\n return str.charAt(0).toLowerCase() + str.slice(1)\n}\n","import type { SchemaInfo, FKEdge } from '@autonoma-ai/sdk'\nimport { topoSort, findDeferrableEdge } from '@autonoma-ai/sdk'\n\ntype PrismaClient = Record<string, any>\n\n/**\n * Tear down all data scoped to a value, in reverse topological order.\n *\n * Strategy:\n * 1. Find the scope root model (e.g. Organization) from FK edges\n * 2. Any model with a FK pointing to the scope root is a \"scoped model\"\n * 3. Delete scoped models by their FK = scopeValue (regardless of field name casing)\n * 4. Delete non-scoped models by their record IDs from refs\n * 5. Delete the scope root entity last by id = scopeValue\n */\nexport async function teardown(\n prisma: PrismaClient,\n schema: SchemaInfo,\n scopeValue: string,\n refs?: Record<string, Record<string, unknown>[]>,\n): Promise<void> {\n // Find scope root: the model that the scopeField FK points TO\n // e.g. scopeField = \"organizationID\", edges have { to: \"Organization\" } → root is Organization\n let scopeRootModel: string | null = null\n for (const edge of schema.edges) {\n if (edge.localField.toLowerCase() === schema.scopeField.toLowerCase() && edge.to !== edge.from) {\n scopeRootModel = edge.to\n break\n }\n }\n\n // Build map: model → FK field name that points to the scope root\n // Handles mixed casing (organizationId vs organizationID)\n const scopeFieldByModel = new Map<string, string>()\n if (scopeRootModel) {\n for (const edge of schema.edges) {\n if (edge.to === scopeRootModel && edge.from !== scopeRootModel) {\n scopeFieldByModel.set(edge.from, edge.localField)\n }\n }\n }\n\n const modelNames = schema.models.map((m) => m.name)\n const { sorted, cycles } = topoSort(modelNames, schema.edges)\n\n await prisma.$transaction(async (tx: PrismaClient) => {\n // Break cycles\n for (const cycle of cycles) {\n const edge = findDeferrableEdge(cycle, schema.edges)\n if (edge) {\n const scopeFK = scopeFieldByModel.get(edge.from)\n if (scopeFK) {\n const delegate = tx[camelCase(edge.from)]\n if (delegate) {\n await delegate.updateMany({\n where: { [scopeFK]: scopeValue },\n data: { [edge.localField]: null },\n })\n }\n }\n }\n }\n\n // Delete cycle nodes\n for (const cycle of cycles) {\n for (const model of cycle) {\n await deleteModel(tx, model, scopeValue, scopeFieldByModel, refs)\n }\n }\n\n // Delete in reverse topo order (dependents first)\n const reversed = [...sorted].reverse()\n for (const model of reversed) {\n if (model === scopeRootModel) continue // deleted last\n await deleteModel(tx, model, scopeValue, scopeFieldByModel, refs)\n }\n\n // Delete the scope root entity last\n if (scopeRootModel) {\n const delegate = tx[camelCase(scopeRootModel)]\n if (delegate) {\n await delegate.deleteMany({ where: { id: scopeValue } })\n }\n }\n })\n}\n\nasync function deleteModel(\n tx: PrismaClient,\n model: string,\n scopeValue: string,\n scopeFieldByModel: Map<string, string>,\n refs?: Record<string, Record<string, unknown>[]>,\n): Promise<void> {\n const delegate = tx[camelCase(model)]\n if (!delegate) {\n return\n }\n\n const scopeFK = scopeFieldByModel.get(model)\n if (scopeFK) {\n // Has FK to scope root → delete by that FK\n await delegate.deleteMany({ where: { [scopeFK]: scopeValue } })\n } else if (refs?.[model]) {\n // No FK to scope root, but we created records → delete by IDs\n const ids = refs[model]\n .map((r) => r.id)\n .filter((id): id is string => typeof id === 'string')\n if (ids.length > 0) {\n await delegate.deleteMany({ where: { id: { in: ids } } })\n }\n }\n}\n\nfunction camelCase(str: string): string {\n return str.charAt(0).toLowerCase() + str.slice(1)\n}\n","import type { OrmAdapter, SchemaInfo, ResolvedEntitySpec, CreateContext } from '@autonoma-ai/sdk'\nimport { introspectPrisma, type PrismaAdapterConfig } from './introspect'\nimport { createEntities } from './create'\nimport { teardown } from './teardown'\n\nexport type { PrismaAdapterConfig }\n\n/**\n * Create a Prisma ORM adapter for the Autonoma SDK.\n *\n * @example\n * ```ts\n * import { prismaAdapter } from '@autonoma-ai/sdk-prisma'\n * import { prisma } from './db'\n *\n * const adapter = prismaAdapter(prisma, { scopeField: 'organizationId' })\n * ```\n */\nexport function prismaAdapter(\n prisma: any,\n config: PrismaAdapterConfig,\n): OrmAdapter {\n let cachedSchema: SchemaInfo | null = null\n\n return {\n getSchema() {\n if (!cachedSchema) {\n cachedSchema = introspectPrisma(prisma, config)\n }\n return cachedSchema\n },\n\n async createEntities(\n spec: Record<string, ResolvedEntitySpec>,\n context: CreateContext,\n ) {\n return createEntities(prisma, spec, context)\n },\n\n async teardown(scopeValue: string, refs?: Record<string, Record<string, unknown>[]>) {\n const schema = this.getSchema()\n return teardown(prisma, schema, scopeValue, refs)\n },\n\n async updateEntity(model: string, id: string, fields: Record<string, unknown>) {\n const delegate = prisma[model.charAt(0).toLowerCase() + model.slice(1)]\n await delegate.update({ where: { id }, data: fields })\n },\n }\n}\n"],"mappings":"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","names":["camelCase"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import type { SQLExecutor } from '@autonoma-ai/sdk'\n\ninterface PrismaClient {\n $queryRawUnsafe<T = unknown>(query: string, ...values: unknown[]): Promise<T>\n $transaction<T>(fn: (tx: PrismaClient) => Promise<T>): Promise<T>\n}\n\n/**\n * Create a SQLExecutor from a Prisma client.\n *\n * @example\n * ```ts\n * import { prismaExecutor } from '@autonoma-ai/sdk-prisma'\n * import { prisma } from './db'\n *\n * const handler = createHandler({\n * executor: prismaExecutor(prisma),\n * scopeField: 'organizationId',\n * sharedSecret: process.env.AUTONOMA_SECRET!,\n * signingSecret: process.env.AUTONOMA_SIGNING_SECRET!,\n * })\n * ```\n */\nexport function prismaExecutor(prisma: PrismaClient): SQLExecutor {\n return {\n async query<T = Record<string, unknown>>(sql: string, params?: unknown[]): Promise<T[]> {\n const result = await prisma.$queryRawUnsafe<T[]>(sql, ...(params ?? []))\n return result\n },\n\n async transaction<T>(fn: (tx: SQLExecutor) => Promise<T>): Promise<T> {\n return prisma.$transaction(async (txClient) => {\n const txExecutor: SQLExecutor = {\n async query<U = Record<string, unknown>>(sql: string, params?: unknown[]): Promise<U[]> {\n return txClient.$queryRawUnsafe<U[]>(sql, ...(params ?? []))\n },\n transaction: (innerFn) => innerFn(txExecutor),\n }\n return fn(txExecutor)\n })\n },\n }\n}\n"],"mappings":";AAuBO,SAAS,eAAe,QAAmC;AAChE,SAAO;AAAA,IACL,MAAM,MAAmC,KAAa,QAAkC;AACtF,YAAM,SAAS,MAAM,OAAO,gBAAqB,KAAK,GAAI,UAAU,CAAC,CAAE;AACvE,aAAO;AAAA,IACT;AAAA,IAEA,MAAM,YAAe,IAAiD;AACpE,aAAO,OAAO,aAAa,OAAO,aAAa;AAC7C,cAAM,aAA0B;AAAA,UAC9B,MAAM,MAAmC,KAAa,QAAkC;AACtF,mBAAO,SAAS,gBAAqB,KAAK,GAAI,UAAU,CAAC,CAAE;AAAA,UAC7D;AAAA,UACA,aAAa,CAAC,YAAY,QAAQ,UAAU;AAAA,QAC9C;AACA,eAAO,GAAG,UAAU;AAAA,MACtB,CAAC;AAAA,IACH;AAAA,EACF;AACF;","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@autonoma-ai/sdk-prisma",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.4",
|
|
4
4
|
"description": "Prisma adapter for Autonoma SDK",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"access": "public"
|
|
17
17
|
},
|
|
18
18
|
"dependencies": {
|
|
19
|
-
"@autonoma-ai/sdk": "0.1.
|
|
19
|
+
"@autonoma-ai/sdk": "0.1.4"
|
|
20
20
|
},
|
|
21
21
|
"peerDependencies": {
|
|
22
22
|
"@prisma/client": ">=5.0.0"
|
|
@@ -34,8 +34,8 @@
|
|
|
34
34
|
},
|
|
35
35
|
"scripts": {
|
|
36
36
|
"build": "tsup",
|
|
37
|
-
"test": "vitest run",
|
|
38
|
-
"test:unit": "vitest run",
|
|
37
|
+
"test": "vitest run --passWithNoTests",
|
|
38
|
+
"test:unit": "vitest run --passWithNoTests",
|
|
39
39
|
"clean": "rm -rf dist"
|
|
40
40
|
}
|
|
41
41
|
}
|