@fitzzero/quickdraw-core 5.1.2 → 5.1.3
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 +793 -57
- package/dist/{admin-DWWrT1h6.d.ts → admin-CS7JB_UH.d.ts} +2 -2
- package/dist/{adminSchemas-D4bFKsrb.d.ts → adminSchemas-29cGgrg5.d.ts} +1 -1
- package/dist/{auth-DXiSJZaf.d.ts → auth-DtdYjrZ9.d.ts} +11 -7
- package/dist/{caller-BT-Mv4bD.d.ts → caller-BTwGl7vm.d.ts} +183 -15
- package/dist/chunk-2FDSKLBO.js +82 -0
- package/dist/chunk-2FDSKLBO.js.map +1 -0
- package/dist/{chunk-GSIPUNJL.js → chunk-64I6MYBC.js} +139 -792
- package/dist/chunk-64I6MYBC.js.map +1 -0
- package/dist/chunk-7473HK24.js +17 -0
- package/dist/chunk-7473HK24.js.map +1 -0
- package/dist/chunk-7Y5ROPXL.js +33 -0
- package/dist/chunk-7Y5ROPXL.js.map +1 -0
- package/dist/chunk-A2RBQD66.js +7 -0
- package/dist/chunk-A2RBQD66.js.map +1 -0
- package/dist/chunk-ASAMUGHG.js +651 -0
- package/dist/chunk-ASAMUGHG.js.map +1 -0
- package/dist/{chunk-B2P7AZ25.js → chunk-CYE4UBOB.js} +6 -4
- package/dist/chunk-CYE4UBOB.js.map +1 -0
- package/dist/chunk-DNP65TD5.js +832 -0
- package/dist/chunk-DNP65TD5.js.map +1 -0
- package/dist/{chunk-5CGO426C.js → chunk-GYLWEJHW.js} +5 -1
- package/dist/chunk-GYLWEJHW.js.map +1 -0
- package/dist/{chunk-AONAFOYU.js → chunk-I3JCFS7H.js} +25 -13
- package/dist/chunk-I3JCFS7H.js.map +1 -0
- package/dist/{chunk-X5CWPX7H.js → chunk-IIQ3WMJK.js} +13 -2
- package/dist/chunk-IIQ3WMJK.js.map +1 -0
- package/dist/{chunk-6K5BY47X.js → chunk-JVTONQFI.js} +1277 -277
- package/dist/chunk-JVTONQFI.js.map +1 -0
- package/dist/{chunk-RL4VKLBX.js → chunk-KKQANRLG.js} +2 -2
- package/dist/{chunk-RL4VKLBX.js.map → chunk-KKQANRLG.js.map} +1 -1
- package/dist/{chunk-GKH3LJ7N.js → chunk-MPQAT55F.js} +38 -205
- package/dist/chunk-MPQAT55F.js.map +1 -0
- package/dist/chunk-NX2V6SIL.js +202 -0
- package/dist/chunk-NX2V6SIL.js.map +1 -0
- package/dist/{chunk-7QCUX4TK.js → chunk-NZHA4TZD.js} +72 -175
- package/dist/chunk-NZHA4TZD.js.map +1 -0
- package/dist/{chunk-MBH6IDSM.js → chunk-OCZJ4EYV.js} +40 -17
- package/dist/chunk-OCZJ4EYV.js.map +1 -0
- package/dist/{chunk-RJ5I2VO3.js → chunk-PHCURHC7.js} +6 -6
- package/dist/chunk-PHCURHC7.js.map +1 -0
- package/dist/{chunk-4YO5H5ON.js → chunk-Q4OGQM5I.js} +4 -10
- package/dist/chunk-Q4OGQM5I.js.map +1 -0
- package/dist/chunk-QSU47XEX.js +13 -0
- package/dist/chunk-QSU47XEX.js.map +1 -0
- package/dist/{chunk-LCC7HNFP.js → chunk-RZXJTDH5.js} +2 -2
- package/dist/{chunk-Z2LZ7IZ7.js → chunk-SN3OZVEQ.js} +5 -31
- package/dist/chunk-SN3OZVEQ.js.map +1 -0
- package/dist/{chunk-Z5ILULF2.js → chunk-SQ5VUG77.js} +4 -3
- package/dist/{chunk-Z5ILULF2.js.map → chunk-SQ5VUG77.js.map} +1 -1
- package/dist/chunk-STH5DLQP.js +1192 -0
- package/dist/chunk-STH5DLQP.js.map +1 -0
- package/dist/{chunk-NMXYENH4.js → chunk-VZFJTKIW.js} +6 -6
- package/dist/{chunk-753VJIUP.js → chunk-X4ZU4QH5.js} +43 -9
- package/dist/chunk-X4ZU4QH5.js.map +1 -0
- package/dist/chunk-XD7SRDUY.js +188 -0
- package/dist/chunk-XD7SRDUY.js.map +1 -0
- package/dist/chunk-Z7I6SONO.js +825 -0
- package/dist/chunk-Z7I6SONO.js.map +1 -0
- package/dist/cli/quickdraw-docs.js +131 -113
- package/dist/cli/quickdraw-docs.js.map +1 -1
- package/dist/client/core.d.ts +387 -0
- package/dist/client/core.js +109 -0
- package/dist/client/core.js.map +1 -0
- package/dist/client/index.d.ts +30 -193
- package/dist/client/index.js +56 -217
- package/dist/client/index.js.map +1 -1
- package/dist/{clientTypes-hWcPUVS9.d.ts → clientTypes-CUUNJwWs.d.ts} +3 -3
- package/dist/{connection-CgijdGpT.d.ts → connection-2EeQ_Et0.d.ts} +16 -9
- package/dist/{createServer-Cp-Wk500.d.ts → createServer-Bx5HOcYK.d.ts} +37 -9
- package/dist/{createTestApp-BB_PkqQ7.d.ts → createTestApp-DAMANT79.d.ts} +36 -9
- package/dist/{envelope-DzWyIXjj.d.ts → envelope-BMBaxppV.d.ts} +200 -8
- package/dist/{http-DotQ5bj8.d.ts → http-YzLAar3w.d.ts} +15 -50
- package/dist/index.d.ts +7 -6
- package/dist/index.js +61 -28
- package/dist/index.js.map +1 -1
- package/dist/{infer-BmoZsL9a.d.ts → infer-Br62cnyW.d.ts} +39 -1
- package/dist/{metrics-DW80Exve.d.ts → metrics-CTVpw0gu.d.ts} +2 -2
- package/dist/parser.js +2 -1
- package/dist/prisma/index.d.ts +13 -6
- package/dist/prisma/index.js +155 -9
- package/dist/prisma/index.js.map +1 -1
- package/dist/remote-N7OUAGOW.js +15 -0
- package/dist/remote-N7OUAGOW.js.map +1 -0
- package/dist/server/auth/index.d.ts +3 -3
- package/dist/server/auth/index.js +5 -3
- package/dist/server/auth/index.js.map +1 -1
- package/dist/server/index.d.ts +140 -36
- package/dist/server/index.js +162 -55
- package/dist/server/index.js.map +1 -1
- package/dist/server/mcp/index.d.ts +34 -18
- package/dist/server/mcp/index.js +29 -12
- package/dist/server/mcp/index.js.map +1 -1
- package/dist/server/otel.d.ts +3 -3
- package/dist/{sharing-UDLn1049.d.ts → sharing-BrsmlDv_.d.ts} +3 -3
- package/dist/testing/client.d.ts +13 -13
- package/dist/testing/client.js +17 -10
- package/dist/testing/client.js.map +1 -1
- package/dist/testing/index.d.ts +49 -12
- package/dist/testing/index.js +102 -19
- package/dist/testing/index.js.map +1 -1
- package/dist/testing/mock.d.ts +5 -5
- package/dist/testing/mock.js +15 -9
- package/dist/tracked-BR5b2O-U.d.ts +43 -0
- package/dist/{types-CYliTP65.d.ts → types-CLRCQGnO.d.ts} +4 -3
- package/dist/types-tMagHbjy.d.ts +151 -0
- package/dist/utils/index.d.ts +16 -4
- package/dist/utils/index.js +6 -3
- package/package.json +5 -1
- package/dist/chunk-4YO5H5ON.js.map +0 -1
- package/dist/chunk-5CGO426C.js.map +0 -1
- package/dist/chunk-6K5BY47X.js.map +0 -1
- package/dist/chunk-753VJIUP.js.map +0 -1
- package/dist/chunk-7QCUX4TK.js.map +0 -1
- package/dist/chunk-AONAFOYU.js.map +0 -1
- package/dist/chunk-B2P7AZ25.js.map +0 -1
- package/dist/chunk-GKH3LJ7N.js.map +0 -1
- package/dist/chunk-GSIPUNJL.js.map +0 -1
- package/dist/chunk-MBH6IDSM.js.map +0 -1
- package/dist/chunk-RJ5I2VO3.js.map +0 -1
- package/dist/chunk-X5CWPX7H.js.map +0 -1
- package/dist/chunk-Z2LZ7IZ7.js.map +0 -1
- /package/dist/{chunk-LCC7HNFP.js.map → chunk-RZXJTDH5.js.map} +0 -0
- /package/dist/{chunk-NMXYENH4.js.map → chunk-VZFJTKIW.js.map} +0 -0
package/dist/prisma/index.js
CHANGED
|
@@ -4,8 +4,8 @@ import {
|
|
|
4
4
|
import {
|
|
5
5
|
createWriteTracker,
|
|
6
6
|
quietly
|
|
7
|
-
} from "../chunk-
|
|
8
|
-
import "../chunk-
|
|
7
|
+
} from "../chunk-SQ5VUG77.js";
|
|
8
|
+
import "../chunk-RZXJTDH5.js";
|
|
9
9
|
import {
|
|
10
10
|
STORAGE_KEY,
|
|
11
11
|
createInterestRegistry,
|
|
@@ -16,7 +16,8 @@ import {
|
|
|
16
16
|
import {
|
|
17
17
|
consoleLogger
|
|
18
18
|
} from "../chunk-DKE6QO26.js";
|
|
19
|
-
import "../chunk-
|
|
19
|
+
import "../chunk-Q4OGQM5I.js";
|
|
20
|
+
import "../chunk-QSU47XEX.js";
|
|
20
21
|
|
|
21
22
|
// src/prisma/links.ts
|
|
22
23
|
var UNREAD = /* @__PURE__ */ new WeakMap();
|
|
@@ -460,6 +461,143 @@ function delegates(runtime, operation, args) {
|
|
|
460
461
|
}
|
|
461
462
|
}
|
|
462
463
|
|
|
464
|
+
// src/prisma/schemaText.ts
|
|
465
|
+
var BLOCK_START = /^(\w+)\s+([A-Za-z_]\w*)\s*\{/;
|
|
466
|
+
var FIELD = /^([A-Za-z_]\w*)\s+([A-Za-z_]\w*)(\([^)]*\))?(\[\])?(\?)?(?=\s|$)/;
|
|
467
|
+
var IGNORED = /(?:^|\s)@ignore(?=\s|$|\()/;
|
|
468
|
+
var KEY_TYPES = /* @__PURE__ */ new Set(["String", "Int", "BigInt", "Float"]);
|
|
469
|
+
var COLUMN_KINDS = /* @__PURE__ */ new Set(["scalar", "enum"]);
|
|
470
|
+
function isObject(value) {
|
|
471
|
+
return (typeof value === "object" || typeof value === "function") && value !== null;
|
|
472
|
+
}
|
|
473
|
+
function withoutComment(line) {
|
|
474
|
+
let inString = false;
|
|
475
|
+
for (let index = 0; index < line.length; index += 1) {
|
|
476
|
+
const char = line[index];
|
|
477
|
+
if (char === '"' && line[index - 1] !== "\\") {
|
|
478
|
+
inString = !inString;
|
|
479
|
+
} else if (!inString && char === "/" && line[index + 1] === "/") {
|
|
480
|
+
return line.slice(0, index);
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
return line;
|
|
484
|
+
}
|
|
485
|
+
function blocksOf(text) {
|
|
486
|
+
const blocks = [];
|
|
487
|
+
let open;
|
|
488
|
+
for (const raw of text.split(/\r?\n/)) {
|
|
489
|
+
const line = withoutComment(raw).trim();
|
|
490
|
+
if (line === "") {
|
|
491
|
+
continue;
|
|
492
|
+
}
|
|
493
|
+
if (open !== void 0) {
|
|
494
|
+
if (line === "}") {
|
|
495
|
+
open = void 0;
|
|
496
|
+
} else {
|
|
497
|
+
open.lines.push(line);
|
|
498
|
+
}
|
|
499
|
+
continue;
|
|
500
|
+
}
|
|
501
|
+
const start = BLOCK_START.exec(line);
|
|
502
|
+
if (start !== null) {
|
|
503
|
+
const block = { kind: start[1] ?? "", name: start[2] ?? "", lines: [] };
|
|
504
|
+
blocks.push(block);
|
|
505
|
+
open = line.slice(start[0].length).trim() === "}" ? void 0 : block;
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
return blocks;
|
|
509
|
+
}
|
|
510
|
+
function kindsOf(runtimeDataModel, model) {
|
|
511
|
+
const models = isObject(runtimeDataModel) ? Reflect.get(runtimeDataModel, "models") : void 0;
|
|
512
|
+
const entry = isObject(models) && Object.hasOwn(models, model) ? Reflect.get(models, model) : void 0;
|
|
513
|
+
const fields = isObject(entry) ? Reflect.get(entry, "fields") : void 0;
|
|
514
|
+
if (!Array.isArray(fields)) {
|
|
515
|
+
return void 0;
|
|
516
|
+
}
|
|
517
|
+
const kinds = /* @__PURE__ */ new Map();
|
|
518
|
+
for (const field of fields) {
|
|
519
|
+
const name = isObject(field) ? Reflect.get(field, "name") : void 0;
|
|
520
|
+
const kind = isObject(field) ? Reflect.get(field, "kind") : void 0;
|
|
521
|
+
if (typeof name === "string" && typeof kind === "string") {
|
|
522
|
+
kinds.set(name, kind);
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
return kinds;
|
|
526
|
+
}
|
|
527
|
+
function isColumn(name, type, kinds, records) {
|
|
528
|
+
if (kinds !== void 0) {
|
|
529
|
+
return COLUMN_KINDS.has(kinds.get(name) ?? "");
|
|
530
|
+
}
|
|
531
|
+
return type !== "Unsupported" && !records.has(type);
|
|
532
|
+
}
|
|
533
|
+
function trackableOf(fields, kinds, enums) {
|
|
534
|
+
const id = fields.get("id");
|
|
535
|
+
if (id === void 0) {
|
|
536
|
+
return kinds !== void 0 && COLUMN_KINDS.has(kinds.get("id") ?? "") ? void 0 : false;
|
|
537
|
+
}
|
|
538
|
+
if (id.optional || id.list) {
|
|
539
|
+
return void 0;
|
|
540
|
+
}
|
|
541
|
+
return KEY_TYPES.has(id.type) || enums.has(id.type) ? true : void 0;
|
|
542
|
+
}
|
|
543
|
+
function modelOf(block, kinds, records, enums) {
|
|
544
|
+
const fields = /* @__PURE__ */ new Map();
|
|
545
|
+
for (const line of block.lines) {
|
|
546
|
+
const field = FIELD.exec(line);
|
|
547
|
+
const [, name = "", type = "", , list, optional] = field ?? [];
|
|
548
|
+
if (field !== null && !IGNORED.test(line) && isColumn(name, type, kinds, records)) {
|
|
549
|
+
fields.set(name, { type, optional: optional !== void 0, list: list !== void 0 });
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
return { fields, trackable: trackableOf(fields, kinds, enums) };
|
|
553
|
+
}
|
|
554
|
+
function parsePrismaSchema(text, runtimeDataModel) {
|
|
555
|
+
const blocks = blocksOf(text);
|
|
556
|
+
const named = (...kinds) => new Set(blocks.filter((block) => kinds.includes(block.kind)).map((block) => block.name));
|
|
557
|
+
const enums = named("enum");
|
|
558
|
+
const records = named("model", "view", "type");
|
|
559
|
+
const models = /* @__PURE__ */ new Map();
|
|
560
|
+
for (const block of blocks) {
|
|
561
|
+
const ignored = block.lines.some((line) => /^@@ignore\b/.test(line));
|
|
562
|
+
if ((block.kind === "model" || block.kind === "view") && !ignored) {
|
|
563
|
+
const kinds = kindsOf(runtimeDataModel, block.name);
|
|
564
|
+
models.set(modelKey(block.name), modelOf(block, kinds, records, enums));
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
return Object.freeze({
|
|
568
|
+
nullable(model, column) {
|
|
569
|
+
const field = models.get(modelKey(model))?.fields.get(column);
|
|
570
|
+
return field === void 0 ? void 0 : field.optional && !field.list;
|
|
571
|
+
},
|
|
572
|
+
trackable: (model) => models.get(modelKey(model))?.trackable
|
|
573
|
+
});
|
|
574
|
+
}
|
|
575
|
+
function schemaTextOf(client) {
|
|
576
|
+
try {
|
|
577
|
+
const config = isObject(client) ? Reflect.get(client, "_engineConfig") : void 0;
|
|
578
|
+
const text = isObject(config) ? Reflect.get(config, "inlineSchema") : void 0;
|
|
579
|
+
return typeof text === "string" && text !== "" ? text : void 0;
|
|
580
|
+
} catch {
|
|
581
|
+
return void 0;
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
function runtimeDataModelOf(client) {
|
|
585
|
+
try {
|
|
586
|
+
const own = isObject(client) ? Reflect.get(client, "_runtimeDataModel") : void 0;
|
|
587
|
+
if (own !== void 0) {
|
|
588
|
+
return own;
|
|
589
|
+
}
|
|
590
|
+
const config = isObject(client) ? Reflect.get(client, "_engineConfig") : void 0;
|
|
591
|
+
return isObject(config) ? Reflect.get(config, "runtimeDataModel") : void 0;
|
|
592
|
+
} catch {
|
|
593
|
+
return void 0;
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
function prismaSchemaOf(client) {
|
|
597
|
+
const text = schemaTextOf(client);
|
|
598
|
+
return text === void 0 ? void 0 : parsePrismaSchema(text, runtimeDataModelOf(client));
|
|
599
|
+
}
|
|
600
|
+
|
|
463
601
|
// src/prisma/trackPrisma.ts
|
|
464
602
|
function isClient(value) {
|
|
465
603
|
return (typeof value === "object" || typeof value === "function") && value !== null && typeof Reflect.get(value, "$extends") === "function";
|
|
@@ -513,9 +651,13 @@ async function transaction(tracker, hooked, arg, options) {
|
|
|
513
651
|
throw error;
|
|
514
652
|
}
|
|
515
653
|
}
|
|
516
|
-
function createNullability(delegate) {
|
|
654
|
+
function createNullability(delegate, schema) {
|
|
517
655
|
const known = /* @__PURE__ */ new Map();
|
|
518
656
|
return async (model, column) => {
|
|
657
|
+
const declared = schema?.nullable(model, column);
|
|
658
|
+
if (declared !== void 0) {
|
|
659
|
+
return declared;
|
|
660
|
+
}
|
|
519
661
|
const key = `${modelKey(model)}\0${column}`;
|
|
520
662
|
const kept = known.get(key);
|
|
521
663
|
if (kept !== void 0) {
|
|
@@ -534,7 +676,7 @@ function createNullability(delegate) {
|
|
|
534
676
|
return nullable;
|
|
535
677
|
};
|
|
536
678
|
}
|
|
537
|
-
function createTrackability(delegate) {
|
|
679
|
+
function createTrackability(delegate, schema) {
|
|
538
680
|
const known = /* @__PURE__ */ new Map();
|
|
539
681
|
const probe = async (key) => {
|
|
540
682
|
try {
|
|
@@ -549,6 +691,10 @@ function createTrackability(delegate) {
|
|
|
549
691
|
}
|
|
550
692
|
};
|
|
551
693
|
return async (model) => {
|
|
694
|
+
const declared = schema?.trackable(model);
|
|
695
|
+
if (declared !== void 0) {
|
|
696
|
+
return declared;
|
|
697
|
+
}
|
|
552
698
|
const key = modelKey(model);
|
|
553
699
|
let answer = known.get(key);
|
|
554
700
|
if (answer === void 0) {
|
|
@@ -561,7 +707,7 @@ function createTrackability(delegate) {
|
|
|
561
707
|
return await answer;
|
|
562
708
|
};
|
|
563
709
|
}
|
|
564
|
-
function createStorage(tracker, [interest, links], delegate) {
|
|
710
|
+
function createStorage(tracker, [interest, links], delegate, schema) {
|
|
565
711
|
return Object.freeze({
|
|
566
712
|
findMany: (model, args = {}) => quietly(() => delegate(modelKey(model)).findMany(args)),
|
|
567
713
|
count: (model, args = {}) => quietly(() => delegate(modelKey(model)).count(args)),
|
|
@@ -572,8 +718,8 @@ function createStorage(tracker, [interest, links], delegate) {
|
|
|
572
718
|
registerLinks: links.register,
|
|
573
719
|
linksOf: links.of,
|
|
574
720
|
inTransaction: () => tracker.transactionClient() !== void 0 || tracker.inBatch(),
|
|
575
|
-
nullable: createNullability(delegate),
|
|
576
|
-
trackable: createTrackability(delegate),
|
|
721
|
+
nullable: createNullability(delegate, schema),
|
|
722
|
+
trackable: createTrackability(delegate, schema),
|
|
577
723
|
unitOfWork: tracker.unitOfWork
|
|
578
724
|
});
|
|
579
725
|
}
|
|
@@ -608,7 +754,7 @@ function trackPrisma(client, options = {}) {
|
|
|
608
754
|
name: "quickdraw-transactions",
|
|
609
755
|
client: {
|
|
610
756
|
$transaction: (arg, txOptions) => transaction(tracker, hooked, arg, txOptions),
|
|
611
|
-
[STORAGE_KEY]: createStorage(tracker, [interest, links], delegate)
|
|
757
|
+
[STORAGE_KEY]: createStorage(tracker, [interest, links], delegate, prismaSchemaOf(client))
|
|
612
758
|
}
|
|
613
759
|
});
|
|
614
760
|
return tracked;
|
package/dist/prisma/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/prisma/links.ts","../../src/prisma/operations.ts","../../src/prisma/trackPrisma.ts"],"sourcesContent":["// The junction links a tracked delete of a via entry model reads first (RFC\n// 0003 sections 5.2 and 7.2; the 5.1 audit's COLL-3). A `via` collection\n// registers its junction as its entries' links (`registerLinks`); a `delete`\n// or `deleteMany` of an entry then reads the junction rows that link the\n// rows it deletes, through the open transaction, and records them in each\n// write's `links`, possibly none, so its flush tells only the scopes a\n// deleted entry was linked to. A junction the client does not have, or a\n// read that fails validation (a column it does not have), leaves the links\n// unknown, and warns once: such a delete's collections are told as for a\n// row nobody can place, and the model stays tracked.\n//\n// The links are read in a statement of their own just before the delete,\n// as `deleteMany` reads its ids: under the database's default isolation\n// (read committed), and always outside an interactive transaction, a link\n// another unit commits in between is removed by the delete's cascade\n// without being read, so the scope it put the entry in keeps the entry\n// until that scope is read again.\n\nimport { quietly } from \"../server/devWarnings\";\nimport type { WriteRecord } from \"../server/uow/types\";\nimport type { Delegate, Row, Runtime } from \"./operations\";\n\n/** Per entry id, per junction model: the junction rows linking it. */\nexport type Links = ReadonlyMap<string, Record<string, Row[]>>;\n\nconst UNREAD = new WeakMap<Runtime, Set<string>>();\n\n/** Says once per model and junction that a delete's links could not be read. */\nfunction warnUnread(runtime: Runtime, model: string, junction: string): void {\n const warned = UNREAD.get(runtime) ?? new Set<string>();\n UNREAD.set(runtime, warned);\n const key = `${model}\\u0000${junction}`;\n if (warned.has(key)) {\n return;\n }\n warned.add(key);\n runtime.tracker.logger.warn(\n `Reading the ${junction} rows that link a deleted ${model} failed, so its deletes tell every subscribed scope of its via lists, as for a row nobody can place`,\n { category: \"quickdraw.writes\", model, junction },\n );\n}\n\n/**\n * The junction rows that link each of `ids`, rows of `model` about to be\n * deleted: per id, per registered junction, possibly none. One statement\n * per junction. `undefined` when `model` has no links or `ids` is empty\n * (nothing is read), or when a read failed validation.\n */\nexport async function readLinks(\n runtime: Runtime,\n model: string,\n ids: readonly string[],\n): Promise<Links | undefined> {\n const links = runtime.linksOf(model);\n if (links.length === 0 || ids.length === 0) {\n return undefined;\n }\n const byId = new Map(\n ids.map((id) => [id, Object.fromEntries(links.map((link) => [link.model, [] as Row[]]))]),\n );\n for (const link of links) {\n const select = Object.fromEntries(\n [link.entry, ...link.columns].map((column) => [column, true]),\n );\n let delegate: Delegate;\n try {\n delegate = runtime.delegate(link.model);\n } catch {\n // A junction model the client does not have.\n warnUnread(runtime, model, link.model);\n return undefined;\n }\n let rows: Row[];\n try {\n rows = await quietly(() =>\n delegate.findMany({ where: { [link.entry]: { in: [...ids] } }, select }),\n );\n } catch (error) {\n if (error instanceof Error && error.name === \"PrismaClientValidationError\") {\n warnUnread(runtime, model, link.model);\n return undefined;\n }\n throw error;\n }\n for (const row of rows) {\n const entry = row[link.entry];\n if (typeof entry === \"string\") {\n byId.get(entry)?.[link.model]?.push(row);\n }\n }\n }\n return byId;\n}\n\n/** `writes`, each with its row's links when they were read. */\nexport function withLinks(writes: readonly WriteRecord[], links: Links | undefined): WriteRecord[] {\n return writes.map((write) => {\n const own = links?.get(write.id);\n return own === undefined ? write : { ...write, links: own };\n });\n}\n","// The Prisma operation table (RFC 0003 section 5.2): for each write, how the\n// tracking hook learns the ids it touched, the fields it set, and the\n// interested columns' values before and after, and what that costs.\n//\n// | Operation | Recorded as | Ids and values from | Extra statements |\n// |---------------------|-------------|------------------------------------|------------------------------|\n// | create | create | the result | none |\n// | upsert | create, or | the result; old values from a read | one read, only when `update` |\n// | | update when | that also says the row existed | sets an interested column or |\n// | | read found | | holds a nested write |\n// | update | update | the result; old values from a read | one read, only when `data` |\n// | | | | sets an interested column or |\n// | | | | holds a nested write |\n// | delete | delete | the result (the deleted row) | none; for a via entry model, |\n// | | | | one read per junction, and |\n// | | | | one for the id when `where` |\n// | | | | names no `id` |\n// | createMany | create | rewritten to createManyAndReturn | none |\n// | updateMany | update | rewritten to updateManyAndReturn | as updateManyAndReturn |\n// | createManyAndReturn | create | the result | none |\n// | updateManyAndReturn | update | the result; old values from a read | one read, only when `data` |\n// | | | | sets an interested column |\n// | deleteMany | delete | a read with the same `where` | one read; for a via entry |\n// | | | | model, one per junction more |\n// | | | | when the read found rows |\n//\n// A `delete` or `deleteMany` of a via entry model (one whose junction a\n// `via` collection registered: `registerLinks`) reads the junction rows that\n// link the rows it deletes first, through the open transaction, and records\n// them in each write's `links` (possibly none), so its flush tells only the\n// scopes the row was linked to (the 5.1 audit's COLL-3; `links.ts`).\n//\n// `fields` are the keys of `data` (for upsert, of `update` when the row\n// existed, of `create` when it did not, and of both when no read told; such\n// a create is marked `mayHaveExisted`). An `update` (or an upsert's\n// `update`) whose `data` holds a nested write may set a foreign key through\n// a relation (`project: { connect }`, `parent: { disconnect: true }`), which\n// its keys do not name: it reads every interested column first and lists\n// them all in `fields`, so an access change it makes is seen (the 5.1\n// audit's DATA-1). The rows the nested write itself creates, changes or\n// deletes are not seen.\n// When a `select` (or `omit`) would hide the `id` or an interested column,\n// the hook adds it and strips it from the result again, so the caller gets\n// exactly what it asked for. Reads go through the open interactive\n// transaction's client, so they see its uncommitted rows. A `deleteMany`\n// with a `limit` deletes exactly the rows its read found.\n//\n// Inside an array-form `$transaction([...])` an operation cannot be replaced\n// by another one, so `createMany` and `updateMany` run as they are there:\n// `updateMany` reads its ids first, and `createMany` is tracked only when\n// every row it creates has an explicit `id`. A batch has no transaction\n// client, so every read made first there (`deleteMany`'s and `updateMany`'s\n// ids, an `update`'s old values) runs on the root client, outside the batch,\n// and misses what the batch's earlier statements changed: a development\n// warning says so once per model and operation.\n//\n// A write that certainly changed nothing records nothing (finding F7.2 of\n// the quickdraw-chat review), so no frame, delta, topic change,\n// `refreshEntry` or `affects` hop follows it. Only the write itself tells:\n//\n// - a write that matched no row (`updateMany`, `updateManyAndReturn` or\n// `deleteMany`; in a batch, an `updateMany` answering count 0);\n// - a `data` (or an upsert's `update`) with nothing to write, `{}` or only\n// `undefined` values, for which Prisma writes nothing at all.\n//\n// A write that sets a column to the value it held is recorded like any\n// other. Comparing the values the hook read before the write with the ones\n// it returned cannot tell: that read is not atomic with the write (in an\n// array-form batch it runs before the whole batch, and elsewhere another\n// write may land between the two), so a real change would be lost and its\n// subscribers left on a value the database no longer holds. rc.5 skipped\n// such writes; the final review of the release candidates showed both.\n//\n// An upsert whose `update` sets nothing changes a row only when it creates\n// one, and nothing it returns tells which it did. Its read replaces it:\n// `findUnique` with its `where` and selection answers for a row that exists\n// (one statement, as the upsert was), and only a missing row runs the upsert\n// after it, recorded as a create (one statement more). In a batch, where no\n// operation can be replaced, it is still recorded as a create that may have\n// found its row.\n\nimport { quietly } from \"../server/devWarnings\";\nimport type { LinkInterest } from \"../server/storage\";\nimport type { WriteRecord } from \"../server/uow/types\";\nimport type { WriteTracker } from \"../server/uow/unitOfWork\";\nimport { readLinks, withLinks, type Links } from \"./links\";\nimport { findNestedWrites } from \"./nested\";\n\n/** A Prisma operation's arguments. */\nexport type Args = Readonly<Record<string, unknown>>;\n\n/** A row a Prisma operation returned. */\nexport type Row = Readonly<Record<string, unknown>>;\n\ntype Values = Readonly<Record<string, unknown>>;\n\n/** The model methods the hook's own queries use. */\nexport interface Delegate {\n findMany(args: Args): Promise<Row[]>;\n findUnique(args: Args): Promise<Row | null>;\n count(args: Args): Promise<number>;\n createManyAndReturn(args: Args): Promise<Row[]>;\n updateManyAndReturn(args: Args): Promise<Row[]>;\n}\n\n/** What every operation handler shares. */\nexport interface Runtime {\n readonly tracker: WriteTracker;\n /** The model's delegate on the open interactive transaction's client, or else the root client's. */\n delegate(model: string): Delegate;\n interestOf(model: string): readonly string[];\n /** The junctions whose links a delete of `model` reads first (`registerLinks`). */\n linksOf(model: string): readonly LinkInterest[];\n /** Models whose writes run untracked: no usable `id` column. */\n readonly untracked: Set<string>;\n}\n\n/** One write operation, as the hook received it. */\nexport interface Operation {\n readonly runtime: Runtime;\n /** The model, named as the client names it: `\"task\"`. */\n readonly model: string;\n /** The Prisma operation: `\"deleteMany\"`. */\n readonly operation: string;\n readonly args: Args;\n readonly query: (args: Args) => Promise<unknown>;\n}\n\n/**\n * Thrown when the hook's own read failed validation before the write ran;\n * the hook then runs the write as the caller wrote it (`runUntracked`).\n */\nexport class Untrackable extends Error {\n override readonly name = \"Untrackable\";\n}\n\nfunction isRecord(value: unknown): value is Readonly<Record<string, unknown>> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction isValidationError(error: unknown): boolean {\n return error instanceof Error && error.name === \"PrismaClientValidationError\";\n}\n\n/** Stops tracking `model` for the life of the process, and says why once. */\nfunction untrack(op: Operation, reason: string): void {\n if (op.runtime.untracked.has(op.model)) {\n return;\n }\n op.runtime.untracked.add(op.model);\n op.runtime.tracker.logger.warn(\n `Writes to ${op.model} are not tracked: ${reason}. Tracked models need a string id column named \"id\"`,\n { category: \"quickdraw.writes\", model: op.model },\n );\n}\n\n/**\n * Runs the operation as the caller wrote it, after a query the hook built\n * failed validation (a model without an `id` column, or an interested column\n * it does not have). The hook stops tracking the model only when the\n * caller's own query then works: an error in the caller's arguments is\n * theirs, and reaches them.\n */\nexport async function runUntracked(op: Operation, reason: string): Promise<unknown> {\n const result = await op.query(op.args);\n untrack(op, reason);\n return result;\n}\n\n/** A row's id as the tracker keys it: a string, or a number or bigint as a string. */\nexport function idOf(row: Row): string | undefined {\n const { id } = row;\n if (typeof id === \"string\") {\n return id;\n }\n return typeof id === \"number\" || typeof id === \"bigint\" ? String(id) : undefined;\n}\n\nfunction pick(row: Row, columns: readonly string[]): Values | undefined {\n const present = columns.filter((column) => Object.hasOwn(row, column));\n return present.length === 0\n ? undefined\n : Object.fromEntries(present.map((column) => [column, row[column]]));\n}\n\nfunction keysOf(data: unknown): string[] {\n if (Array.isArray(data)) {\n return [...new Set(data.flatMap((item) => keysOf(item)))];\n }\n return isRecord(data) ? Object.keys(data) : [];\n}\n\nfunction rowsOf(result: unknown): Row[] {\n if (Array.isArray(result)) {\n return result.filter(isRecord);\n }\n return isRecord(result) ? [result] : [];\n}\n\n/** The keys of `data` Prisma writes: those whose value is not `undefined`. */\nfunction writtenKeys(data: unknown): string[] {\n return isRecord(data)\n ? Object.entries(data)\n .filter(([, value]) => value !== undefined)\n .map(([key]) => key)\n : [];\n}\n\n/** True for a `data` Prisma writes nothing for: an object with no key whose value is set. */\nexport function writesNothing(data: unknown): boolean {\n return isRecord(data) && writtenKeys(data).length === 0;\n}\n\n/** Counts a statement the hook runs past itself (`op.query`), and hands it to the development checks. */\nfunction countOwn(op: Operation, operation: string, args: Args): void {\n op.runtime.tracker.countStatement();\n op.runtime.tracker.observe({ model: op.model, operation, args });\n}\n\n/**\n * Whether `data` holds a nested write, warning (in development) once per\n * write that the related rows are not tracked. It is found in every\n * environment: such a `data` may set a foreign key the tracker must read.\n */\nfunction warnNested(op: Operation, data: unknown): boolean {\n const nested = findNestedWrites(data);\n for (const { field, operation } of nested) {\n op.runtime.tracker.warn({\n kind: \"nested-write\",\n subject: `${op.model}.${field}.${operation}`,\n message: `A nested write (${op.model}.${field}: { ${operation} }) is not tracked: the related rows it creates, changes or deletes send no frames and revoke nothing. The ${op.model} row is tracked, and an update of it reads its access and scope columns first, so a foreign key a to-one connect or disconnect sets on it is seen. Write related rows through their own model, or set the foreign key column`,\n meta: { model: op.model, field, operation },\n });\n }\n return nested.length > 0;\n}\n\n/** The keys of `data` and `columns`, each once: the fields of a write that holds a nested write. */\nfunction withColumns(data: unknown, columns: readonly string[]): string[] {\n return [...new Set([...keysOf(data), ...columns])];\n}\n\n/** The interested columns `data` sets. */\nfunction touchedInterest(op: Operation, data: unknown): string[] {\n const keys = new Set(keysOf(data));\n return op.runtime.interestOf(op.model).filter((column) => keys.has(column));\n}\n\n/** `args` with `columns` added to its `select`, or no longer omitted, and the columns that were added. */\nfunction widen(args: Args, columns: readonly string[]): { args: Args; added: string[] } {\n const { select, omit } = args;\n if (isRecord(select)) {\n const added = columns.filter((column) => select[column] !== true);\n const widened = { ...select, ...Object.fromEntries(added.map((column) => [column, true])) };\n return { args: added.length === 0 ? args : { ...args, select: widened }, added };\n }\n if (isRecord(omit)) {\n const added = columns.filter((column) => omit[column] === true);\n const widened = { ...omit, ...Object.fromEntries(added.map((column) => [column, false])) };\n return { args: added.length === 0 ? args : { ...args, omit: widened }, added };\n }\n return { args, added: [] };\n}\n\nfunction strip(result: unknown, added: readonly string[]): unknown {\n const without = (row: unknown): unknown =>\n isRecord(row)\n ? Object.fromEntries(Object.entries(row).filter(([key]) => !added.includes(key)))\n : row;\n return Array.isArray(result) ? result.map(without) : without(result);\n}\n\n/**\n * Runs the operation with the `id` and interested columns in its result,\n * and returns the caller's result plus the rows to record. When adding them\n * fails validation (a model without an `id` column), the operation runs as\n * the caller wrote it and its rows are not recorded.\n */\nasync function runWidened(op: Operation): Promise<{ result: unknown; rows: Row[] }> {\n const { args, added } = widen(op.args, [\"id\", ...op.runtime.interestOf(op.model)]);\n if (added.length === 0) {\n const result = await op.query(op.args);\n return { result, rows: rowsOf(result) };\n }\n let result: unknown;\n try {\n result = await op.query(args);\n } catch (error) {\n if (!isValidationError(error)) {\n throw error;\n }\n return { result: await runUntracked(op, \"selecting its id failed\"), rows: [] };\n }\n return { result: strip(result, added), rows: rowsOf(result) };\n}\n\n/**\n * Warns once per model and operation that a read made first inside an\n * array-form `$transaction` runs on the root client: an array-form batch\n * has no transaction client to read through, so the read does not see what\n * the batch's earlier statements changed.\n */\nfunction warnBatchRead(op: Operation): void {\n if (!op.runtime.tracker.inBatch()) {\n return;\n }\n op.runtime.tracker.warn({\n kind: \"batch-read\",\n subject: `${op.model}.${op.operation}`,\n message: `${op.operation} on ${op.model} inside an array-form $transaction reads its rows first on the root client, outside the batch, so rows the batch's earlier statements changed may be missed; use an interactive transaction to read inside it`,\n meta: { model: op.model, operation: op.operation },\n });\n}\n\n/**\n * Reads `columns` of the rows `where` matches, by id, through the transaction\n * when one is open. The read is the tracker's own, not the app's, so the\n * development checks of statements leave it alone.\n */\nasync function readBefore(\n op: Operation,\n where: unknown,\n columns: readonly string[],\n options: { readonly unique: boolean; readonly take?: unknown },\n): Promise<Map<string, Values>> {\n warnBatchRead(op);\n const select = Object.fromEntries([\"id\", ...columns].map((column) => [column, true]));\n const delegate = op.runtime.delegate(op.model);\n let rows: Row[];\n try {\n if (options.unique) {\n const row = await quietly(() => delegate.findUnique({ where, select }));\n rows = row === null ? [] : [row];\n } else {\n rows = await quietly(() =>\n delegate.findMany({\n where,\n select,\n ...(options.take === undefined ? {} : { take: options.take }),\n }),\n );\n }\n } catch (error) {\n if (isValidationError(error)) {\n throw new Untrackable(\"reading its id failed\", { cause: error });\n }\n throw error;\n }\n const before = new Map<string, Values>();\n for (const row of rows) {\n const id = idOf(row);\n if (id !== undefined) {\n before.set(id, pick(row, columns) ?? {});\n }\n }\n return before;\n}\n\nfunction writesOf(\n op: Operation,\n kind: WriteRecord[\"op\"],\n rows: readonly Row[],\n fields: readonly string[],\n before?: ReadonlyMap<string, Values>,\n): WriteRecord[] {\n const interest = op.runtime.interestOf(op.model);\n const writes: WriteRecord[] = [];\n for (const row of rows) {\n const id = idOf(row);\n if (id === undefined) {\n untrack(op, \"its rows have no id\");\n return [];\n }\n const values = pick(row, interest);\n const old = kind === \"delete\" ? values : before?.get(id);\n const after = kind === \"delete\" ? undefined : values;\n writes.push({\n model: op.model,\n id,\n op: kind,\n fields,\n ...(old === undefined || Object.keys(old).length === 0 ? {} : { before: old }),\n ...(after === undefined ? {} : { after }),\n });\n }\n return writes;\n}\n\nfunction record(op: Operation, writes: readonly WriteRecord[]): void {\n op.runtime.tracker.record(writes);\n}\n\nasync function create(op: Operation): Promise<unknown> {\n warnNested(op, op.args.data);\n const { result, rows } = await runWidened(op);\n record(op, writesOf(op, \"create\", rows, keysOf(op.args.data)));\n return result;\n}\n\n/** The selection of a read that returns what `args` (an upsert's) would: its `select`, `include` and `omit`. */\nfunction selectionOf(args: Args): Args {\n return Object.fromEntries(\n [\"select\", \"include\", \"omit\"]\n .filter((key) => args[key] !== undefined)\n .map((key) => [key, args[key]]),\n );\n}\n\n/**\n * An upsert whose `update` sets nothing (see the top of this file): the\n * read that tells whether its row exists takes its place, and answers it\n * when the row is there; only a missing row runs the upsert.\n */\nasync function upsertWithoutUpdate(op: Operation): Promise<unknown> {\n warnNested(op, op.args.create);\n const { args, added } = widen(op.args, [\"id\", ...op.runtime.interestOf(op.model)]);\n let found: Row | null;\n try {\n // Through the hook, which counts it as this call's one statement.\n found = await op.runtime\n .delegate(op.model)\n .findUnique({ where: op.args.where, ...selectionOf(args) });\n } catch (error) {\n if (!isValidationError(error)) {\n throw error;\n }\n // The hook counted the read that failed; the upsert runs in its place.\n return runUntracked(op, \"reading its id failed\");\n }\n if (found !== null) {\n // Prisma writes nothing to a row that exists when `update` sets nothing: no change.\n return strip(found, added);\n }\n countOwn(op, op.operation, op.args);\n const { result, rows } = await runWidened(op);\n // Created, unless another transaction created the row in between: then it may have existed.\n const writes = writesOf(op, \"create\", rows, keysOf(op.args.create));\n record(\n op,\n writes.map((write) => ({ ...write, mayHaveExisted: true as const })),\n );\n return result;\n}\n\nasync function upsert(op: Operation): Promise<unknown> {\n if (writesNothing(op.args.update) && !op.runtime.tracker.inBatch()) {\n return upsertWithoutUpdate(op);\n }\n warnNested(op, op.args.create);\n // A nested write may set a foreign key through a relation: read every interested column.\n const nested = warnNested(op, op.args.update);\n const touched = nested\n ? [...op.runtime.interestOf(op.model)]\n : touchedInterest(op, op.args.update);\n // Reading the interested columns first also tells whether the row existed.\n const before =\n touched.length === 0\n ? undefined\n : await readBefore(op, op.args.where, touched, { unique: true });\n const { result, rows } = await runWidened(op);\n if (before !== undefined && before.size > 0) {\n const fields = nested ? withColumns(op.args.update, touched) : keysOf(op.args.update);\n record(op, writesOf(op, \"update\", rows, fields, before));\n } else if (before === undefined) {\n // Nothing read: the row may have existed, and been updated.\n const writes = writesOf(op, \"create\", rows, keysOf([op.args.create, op.args.update]));\n record(\n op,\n writes.map((write) => ({ ...write, mayHaveExisted: true as const })),\n );\n } else {\n record(op, writesOf(op, \"create\", rows, keysOf(op.args.create)));\n }\n return result;\n}\n\nasync function update(op: Operation): Promise<unknown> {\n if (writesNothing(op.args.data)) {\n // Prisma only reads the row (and answers NOT_FOUND without one): nothing to record.\n return op.query(op.args);\n }\n // A nested write may set a foreign key through a relation: read every interested column.\n const nested = warnNested(op, op.args.data);\n const touched = nested ? [...op.runtime.interestOf(op.model)] : touchedInterest(op, op.args.data);\n const before =\n touched.length === 0\n ? undefined\n : await readBefore(op, op.args.where, touched, { unique: true });\n const { result, rows } = await runWidened(op);\n const fields = nested ? withColumns(op.args.data, touched) : keysOf(op.args.data);\n record(op, writesOf(op, \"update\", rows, fields, before));\n return result;\n}\n\n/** The links of the row a `delete` names (`readLinks`): by its `where.id`, or a read of its id first. */\nasync function linksOfDelete(op: Operation): Promise<Links | undefined> {\n if (op.runtime.linksOf(op.model).length === 0) {\n return undefined;\n }\n warnBatchRead(op);\n const { where } = op.args;\n const ids =\n isRecord(where) && typeof where.id === \"string\"\n ? [where.id]\n : [...(await readBefore(op, where, [], { unique: true })).keys()];\n return await readLinks(op.runtime, op.model, ids);\n}\n\nasync function remove(op: Operation): Promise<unknown> {\n const links = await linksOfDelete(op);\n const { result, rows } = await runWidened(op);\n record(op, withLinks(writesOf(op, \"delete\", rows, []), links));\n return result;\n}\n\nasync function createManyAndReturn(op: Operation): Promise<unknown> {\n const { result, rows } = await runWidened(op);\n record(op, writesOf(op, \"create\", rows, keysOf(op.args.data)));\n return result;\n}\n\nasync function updateManyAndReturn(op: Operation): Promise<unknown> {\n if (writesNothing(op.args.data)) {\n // Prisma only reads the rows `where` matches: nothing to record.\n return op.query(op.args);\n }\n const touched = touchedInterest(op, op.args.data);\n const before =\n touched.length === 0\n ? undefined\n : await readBefore(op, op.args.where, touched, { unique: false });\n const { result, rows } = await runWidened(op);\n // Matching no row, it returns none, and records nothing.\n record(op, writesOf(op, \"update\", rows, keysOf(op.args.data), before));\n return result;\n}\n\n/** `createMany` inside an array-form transaction: tracked when every row names its id. */\nasync function createManyInBatch(op: Operation): Promise<unknown> {\n const items = (Array.isArray(op.args.data) ? op.args.data : [op.args.data]).filter(isRecord);\n const result = await op.query(op.args);\n const rows = items.filter((item) => idOf(item) !== undefined);\n if (rows.length === items.length) {\n record(op, writesOf(op, \"create\", rows, keysOf(op.args.data)));\n } else {\n op.runtime.tracker.warn({\n kind: \"batch-create-many\",\n subject: op.model,\n message: `createMany on ${op.model} inside an array-form $transaction cannot report the rows it created, so they are not tracked; give each row an id, or use an interactive transaction`,\n meta: { model: op.model },\n });\n }\n return result;\n}\n\n/**\n * `updateMany` inside an array-form transaction: its ids are read first,\n * before the batch runs. With a `limit`, every row the read found is\n * recorded, which may be more rows than were updated.\n */\nasync function updateManyInBatch(op: Operation): Promise<unknown> {\n if (writesNothing(op.args.data)) {\n return op.query(op.args);\n }\n const before = await readBefore(op, op.args.where, touchedInterest(op, op.args.data), {\n unique: false,\n });\n const result = await op.query(op.args);\n // Only a count comes back: 0 means it updated nothing, whatever the read found.\n if (isRecord(result) && result.count === 0) {\n return result;\n }\n const rows = [...before.keys()].map((id) => ({ id }));\n record(op, writesOf(op, \"update\", rows, keysOf(op.args.data), before));\n return result;\n}\n\n/**\n * `createMany` and `updateMany` outside a batch: the `...AndReturn` form,\n * through the transaction's client when one is open, which the hook then\n * records like any other call of it.\n */\nasync function rewrite(\n op: Operation,\n run: (delegate: Delegate, args: Args) => Promise<Row[]>,\n): Promise<unknown> {\n let rows: Row[];\n try {\n rows = await run(op.runtime.delegate(op.model), { ...op.args, select: { id: true } });\n } catch (error) {\n if (!isValidationError(error)) {\n throw error;\n }\n op.runtime.tracker.countStatement();\n return runUntracked(op, \"selecting its id failed\");\n }\n return { count: rows.length };\n}\n\nfunction createMany(op: Operation): Promise<unknown> {\n if (op.runtime.tracker.inBatch()) {\n return createManyInBatch(op);\n }\n return rewrite(op, (delegate, args) => delegate.createManyAndReturn(args));\n}\n\nfunction updateMany(op: Operation): Promise<unknown> {\n if (op.runtime.tracker.inBatch()) {\n return updateManyInBatch(op);\n }\n if (writesNothing(op.args.data)) {\n // As it is: Prisma writes nothing and answers count 0, which the rewrite would not.\n return op.query(op.args);\n }\n return rewrite(op, (delegate, args) => delegate.updateManyAndReturn(args));\n}\n\nasync function deleteMany(op: Operation): Promise<unknown> {\n const { where, limit } = op.args;\n const interest = op.runtime.interestOf(op.model);\n const before = await readBefore(op, where, interest, { unique: false, take: limit });\n const ids = [...before.keys()];\n const links = await readLinks(op.runtime, op.model, ids);\n // With a limit, which rows go is up to the database: delete the rows read.\n const args =\n limit === undefined\n ? op.args\n : { ...op.args, where: { AND: [where ?? {}, { id: { in: ids } }] } };\n const result = await op.query(args);\n const rows = ids.map((id) => ({ id, ...before.get(id) }));\n record(op, withLinks(writesOf(op, \"delete\", rows, []), links));\n return result;\n}\n\n/**\n * The write operations the hook tracks, by Prisma operation name. Every\n * other operation passes through untouched.\n */\nexport const WRITE_OPERATIONS: Readonly<Record<string, (op: Operation) => Promise<unknown>>> =\n Object.freeze({\n create,\n upsert,\n update,\n delete: remove,\n createMany,\n createManyAndReturn,\n updateMany,\n updateManyAndReturn,\n deleteMany,\n });\n\n/**\n * Whether a tracked operation hands its work to another one, which then\n * counts the statement (`createMany` and `updateMany` outside a batch, an\n * `upsert` whose `update` sets nothing outside a batch: its read): the hook\n * counts every other operation itself.\n */\nexport function delegates(runtime: Runtime, operation: string, args: Args | undefined): boolean {\n if (runtime.tracker.inBatch()) {\n return false;\n }\n switch (operation) {\n case \"createMany\":\n return true;\n case \"updateMany\":\n return !writesNothing(args?.data);\n case \"upsert\":\n return writesNothing(args?.update);\n default:\n return false;\n }\n}\n","// `trackPrisma` (RFC 0003 sections 5.2 and 5.4): wraps an app's Prisma\n// client so every write made through it is recorded into the unit of work it\n// runs in. In 4.1 only `BaseService.create/update/delete` were observed\n// (4.1 `src/server/BaseService.ts:769-827`); a raw `prisma.task.update`\n// was invisible, and every live update needed a hand-written emit.\n//\n// Two client extensions, both public Prisma API:\n//\n// 1. a `query` hook on every operation records writes (`operations.ts`) and\n// counts statements;\n// 2. a `client` extension replaces `$transaction`, so writes inside a\n// transaction are buffered and join the unit of work only once it commits.\n// It calls the `$transaction` of the client from step 1, so the\n// transaction's client carries the hook. Transactions are found through\n// that wrapper and `AsyncLocalStorage`, never through Prisma internals.\n//\n// Make it the last extension applied: an extension added after it still\n// runs outside transactions, but not on a transaction's client.\n\nimport { consoleLogger, type Logger } from \"../contract/logger\";\nimport { quietly } from \"../server/devWarnings\";\nimport {\n createInterestRegistry,\n createLinkRegistry,\n modelKey,\n STORAGE_KEY,\n storageOf,\n type CountArgs,\n type FindManyArgs,\n type StorageAdapter,\n} from \"../server/storage\";\nimport { createWriteTracker, type WriteTracker } from \"../server/uow/unitOfWork\";\nimport {\n delegates,\n idOf,\n runUntracked,\n Untrackable,\n WRITE_OPERATIONS,\n type Args,\n type Delegate,\n type Operation,\n type Runtime,\n} from \"./operations\";\n\n/** Options of {@link trackPrisma}. */\nexport interface TrackPrismaOptions {\n /**\n * Interested columns per model, whose values writes report in `before`\n * and `after`: `{ task: [\"projectId\", \"status\"] }`. The framework adds the\n * columns its collections and access policies need with\n * `storage.registerInterest`; this is for the app's own sinks.\n */\n readonly interest?: Readonly<Record<string, readonly string[]>>;\n /**\n * Receives warnings until a dispatcher is created with this client; then\n * the dispatcher's logger does. Default: the console logger.\n */\n readonly logger?: Logger;\n /**\n * Warn about writes outside any unit of work and about nested writes.\n * Default: on unless `NODE_ENV` is `\"production\"`.\n */\n readonly development?: boolean;\n}\n\n/** The part of a Prisma client `trackPrisma` relies on: client extensions. */\nexport interface PrismaClientLike {\n $extends(extension: never): unknown;\n}\n\n/** The client as `trackPrisma` calls it. */\ninterface ExtendableClient {\n $extends(extension: object): ExtendedClient;\n}\n\ninterface ExtendedClient extends ExtendableClient {\n $transaction(arg: unknown, options?: unknown): Promise<unknown>;\n}\n\n/** What a query extension's `$allOperations` hook receives. */\ninterface QueryHookArgs {\n readonly model?: string;\n readonly operation: string;\n readonly args: Args | undefined;\n readonly query: (args: Args | undefined) => Promise<unknown>;\n}\n\nfunction isClient(value: unknown): value is ExtendableClient {\n return (\n (typeof value === \"object\" || typeof value === \"function\") &&\n value !== null &&\n typeof Reflect.get(value, \"$extends\") === \"function\"\n );\n}\n\nfunction delegateOf(client: unknown, model: string): Delegate {\n const delegate: unknown =\n typeof client === \"object\" && client !== null ? Reflect.get(client, model) : undefined;\n if (typeof delegate !== \"object\" || delegate === null) {\n throw new TypeError(`The tracked Prisma client has no model \"${model}\"`);\n }\n return delegate as Delegate;\n}\n\n/** Counts one statement the hook is about to run, and hands a model's to the development checks. */\nfunction count(\n runtime: Runtime,\n model: string | undefined,\n operation: string,\n args: Args | undefined,\n): void {\n runtime.tracker.countStatement();\n if (model !== undefined) {\n runtime.tracker.observe({ model: modelKey(model), operation, args });\n }\n}\n\nfunction createHook(runtime: Runtime) {\n return async function track({ model, operation, args, query }: QueryHookArgs): Promise<unknown> {\n const handler = model === undefined ? undefined : WRITE_OPERATIONS[operation];\n if (model === undefined || handler === undefined || runtime.untracked.has(modelKey(model))) {\n count(runtime, model, operation, args);\n return query(args);\n }\n if (!delegates(runtime, operation, args)) {\n count(runtime, model, operation, args);\n }\n const op: Operation = { runtime, model: modelKey(model), operation, args: args ?? {}, query };\n try {\n return await handler(op);\n } catch (error) {\n if (error instanceof Untrackable) {\n return runUntracked(op, error.message);\n }\n throw error;\n }\n };\n}\n\n/** `$transaction`, in both forms, inside a transaction frame of the tracker. */\nasync function transaction(\n tracker: WriteTracker,\n hooked: ExtendedClient,\n arg: unknown,\n options: unknown,\n): Promise<unknown> {\n const interactive = typeof arg === \"function\";\n const frame = tracker.openTransaction(interactive ? \"interactive\" : \"batch\");\n try {\n const result = interactive\n ? await hooked.$transaction((client: unknown) => {\n frame.setClient(client);\n return frame.run(() => (arg as (client: unknown) => unknown)(client));\n }, options)\n : await frame.run(() => hooked.$transaction(arg, options));\n frame.commit();\n return result;\n } catch (error) {\n frame.rollback();\n throw error;\n }\n}\n\n/**\n * `StorageAdapter.nullable`: Prisma validates a filter against the schema\n * before sending it, and refuses `{ column: null }` on a required column. The\n * answer is kept for the life of the client: one statement per optional\n * column, none for a required one.\n */\nfunction createNullability(\n delegate: (model: string) => Delegate,\n): (model: string, column: string) => Promise<boolean> {\n const known = new Map<string, boolean>();\n return async (model, column) => {\n const key = `${modelKey(model)}\\u0000${column}`;\n const kept = known.get(key);\n if (kept !== undefined) {\n return kept;\n }\n let nullable = true;\n try {\n await quietly(() => delegate(modelKey(model)).count({ where: { [column]: null } }));\n } catch (error) {\n if (!(error instanceof Error && error.name === \"PrismaClientValidationError\")) {\n throw error;\n }\n nullable = false;\n }\n known.set(key, nullable);\n return nullable;\n };\n}\n\n/**\n * `StorageAdapter.trackable`: whether the tracker can key `model`'s writes,\n * that is whether its rows have an `id`. One read of one row's id per model,\n * kept for the life of the client: Prisma refuses the select of a model\n * without an `id` column (a composite `@@id`). Any other failure (the\n * database down) is thrown, and asked again next time.\n */\nfunction createTrackability(\n delegate: (model: string) => Delegate,\n): (model: string) => Promise<boolean> {\n const known = new Map<string, Promise<boolean>>();\n const probe = async (key: string): Promise<boolean> => {\n try {\n const rows = await quietly(() => delegate(key).findMany({ select: { id: true }, take: 1 }));\n const [row] = Array.isArray(rows) ? (rows as Readonly<Record<string, unknown>>[]) : [];\n return row === undefined || idOf(row) !== undefined;\n } catch (error) {\n if (error instanceof Error && error.name === \"PrismaClientValidationError\") {\n return false;\n }\n throw error;\n }\n };\n return async (model) => {\n const key = modelKey(model);\n let answer = known.get(key);\n if (answer === undefined) {\n answer = probe(key);\n known.set(key, answer);\n answer.catch(() => {\n known.delete(key);\n });\n }\n return await answer;\n };\n}\n\n/**\n * The adapter the framework reads through. Its reads are the framework's own\n * (access checks, subscriptions, flushes, kits), so the development checks\n * of statements leave them alone.\n */\nfunction createStorage(\n tracker: WriteTracker,\n [interest, links]: readonly [\n ReturnType<typeof createInterestRegistry>,\n ReturnType<typeof createLinkRegistry>,\n ],\n delegate: (model: string) => Delegate,\n): StorageAdapter {\n return Object.freeze({\n findMany: (model: string, args: FindManyArgs = {}) =>\n quietly(() => delegate(modelKey(model)).findMany(args as Args)),\n count: (model: string, args: CountArgs = {}) =>\n quietly(() => delegate(modelKey(model)).count(args as Args)),\n onWrite: tracker.onWrite,\n countStatements: tracker.countStatements,\n registerInterest: interest.register,\n interestOf: interest.of,\n registerLinks: links.register,\n linksOf: links.of,\n inTransaction: () => tracker.transactionClient() !== undefined || tracker.inBatch(),\n nullable: createNullability(delegate),\n trackable: createTrackability(delegate),\n unitOfWork: tracker.unitOfWork,\n });\n}\n\n/**\n * Wraps a Prisma client so the framework sees every write made through it:\n * `create`, `update`, `upsert`, `delete` and their `Many` forms, inside and\n * outside transactions. Pass the result as `db` to `initQuickdraw`'s app and\n * to `createServer`, which find its storage adapter on it (`storageOf`).\n * Nested writes, raw SQL and database cascades are not seen; record those\n * with `ctx.touch`.\n *\n * Prefer interactive transactions (`db.$transaction(async (tx) => ...)`). An\n * array-form `db.$transaction([...])` has no transaction client, so the rows\n * a `deleteMany` or `updateMany` there reads first (and an `update`'s old\n * values) are read on the root client, outside the batch: rows the batch's\n * earlier statements created or changed may be missed, and their frames\n * with them. A development warning names the model and operation once.\n *\n * @example\n * export const db = trackPrisma(new PrismaClient({ adapter }));\n * export const qd = initQuickdraw<{ db: typeof db; principal: AppPrincipal }>();\n * const server = qd.createServer({ app, services, db, auth });\n */\nexport function trackPrisma<C extends PrismaClientLike>(\n client: C,\n options: TrackPrismaOptions = {},\n): C {\n if (!isClient(client)) {\n throw new TypeError(\"trackPrisma: client must be a Prisma client\");\n }\n if (storageOf(client) !== undefined) {\n throw new TypeError(\"trackPrisma: this client is tracked already; pass the untracked client\");\n }\n const tracker = createWriteTracker({\n logger: options.logger ?? consoleLogger,\n development: options.development,\n });\n const interest = createInterestRegistry(options.interest);\n // The client with the hook; the hook's own reads use it outside transactions.\n let root: ExtendedClient | undefined;\n const delegate = (model: string): Delegate =>\n delegateOf(tracker.transactionClient() ?? root, model);\n const links = createLinkRegistry();\n const runtime: Runtime = {\n tracker,\n delegate,\n interestOf: interest.of,\n linksOf: links.of,\n untracked: new Set(),\n };\n const hooked = client.$extends({\n name: \"quickdraw-tracking\",\n query: { $allOperations: createHook(runtime) },\n });\n root = hooked;\n const tracked = hooked.$extends({\n name: \"quickdraw-transactions\",\n client: {\n $transaction: (arg: unknown, txOptions?: unknown) =>\n transaction(tracker, hooked, arg, txOptions),\n [STORAGE_KEY]: createStorage(tracker, [interest, links], delegate),\n },\n });\n return tracked as unknown as C;\n}\n"],"mappings":"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","names":["result"]}
|
|
1
|
+
{"version":3,"sources":["../../src/prisma/links.ts","../../src/prisma/operations.ts","../../src/prisma/schemaText.ts","../../src/prisma/trackPrisma.ts"],"sourcesContent":["// The junction links a tracked delete of a via entry model reads first (RFC\n// 0003 sections 5.2 and 7.2; the 5.1 audit's COLL-3). A `via` collection\n// registers its junction as its entries' links (`registerLinks`); a `delete`\n// or `deleteMany` of an entry then reads the junction rows that link the\n// rows it deletes, through the open transaction, and records them in each\n// write's `links`, possibly none, so its flush tells only the scopes a\n// deleted entry was linked to. A junction the client does not have, or a\n// read that fails validation (a column it does not have), leaves the links\n// unknown, and warns once: such a delete's collections are told as for a\n// row nobody can place, and the model stays tracked.\n//\n// The links are read in a statement of their own just before the delete,\n// as `deleteMany` reads its ids: under the database's default isolation\n// (read committed), and always outside an interactive transaction, a link\n// another unit commits in between is removed by the delete's cascade\n// without being read, so the scope it put the entry in keeps the entry\n// until that scope is read again.\n\nimport { quietly } from \"../server/devWarnings\";\nimport type { WriteRecord } from \"../server/uow/types\";\nimport type { Delegate, Row, Runtime } from \"./operations\";\n\n/** Per entry id, per junction model: the junction rows linking it. */\nexport type Links = ReadonlyMap<string, Record<string, Row[]>>;\n\nconst UNREAD = new WeakMap<Runtime, Set<string>>();\n\n/** Says once per model and junction that a delete's links could not be read. */\nfunction warnUnread(runtime: Runtime, model: string, junction: string): void {\n const warned = UNREAD.get(runtime) ?? new Set<string>();\n UNREAD.set(runtime, warned);\n const key = `${model}\\u0000${junction}`;\n if (warned.has(key)) {\n return;\n }\n warned.add(key);\n runtime.tracker.logger.warn(\n `Reading the ${junction} rows that link a deleted ${model} failed, so its deletes tell every subscribed scope of its via lists, as for a row nobody can place`,\n { category: \"quickdraw.writes\", model, junction },\n );\n}\n\n/**\n * The junction rows that link each of `ids`, rows of `model` about to be\n * deleted: per id, per registered junction, possibly none. One statement\n * per junction. `undefined` when `model` has no links or `ids` is empty\n * (nothing is read), or when a read failed validation.\n */\nexport async function readLinks(\n runtime: Runtime,\n model: string,\n ids: readonly string[],\n): Promise<Links | undefined> {\n const links = runtime.linksOf(model);\n if (links.length === 0 || ids.length === 0) {\n return undefined;\n }\n const byId = new Map(\n ids.map((id) => [id, Object.fromEntries(links.map((link) => [link.model, [] as Row[]]))]),\n );\n for (const link of links) {\n const select = Object.fromEntries(\n [link.entry, ...link.columns].map((column) => [column, true]),\n );\n let delegate: Delegate;\n try {\n delegate = runtime.delegate(link.model);\n } catch {\n // A junction model the client does not have.\n warnUnread(runtime, model, link.model);\n return undefined;\n }\n let rows: Row[];\n try {\n rows = await quietly(() =>\n delegate.findMany({ where: { [link.entry]: { in: [...ids] } }, select }),\n );\n } catch (error) {\n if (error instanceof Error && error.name === \"PrismaClientValidationError\") {\n warnUnread(runtime, model, link.model);\n return undefined;\n }\n throw error;\n }\n for (const row of rows) {\n const entry = row[link.entry];\n if (typeof entry === \"string\") {\n byId.get(entry)?.[link.model]?.push(row);\n }\n }\n }\n return byId;\n}\n\n/** `writes`, each with its row's links when they were read. */\nexport function withLinks(writes: readonly WriteRecord[], links: Links | undefined): WriteRecord[] {\n return writes.map((write) => {\n const own = links?.get(write.id);\n return own === undefined ? write : { ...write, links: own };\n });\n}\n","// The Prisma operation table (RFC 0003 section 5.2): for each write, how the\n// tracking hook learns the ids it touched, the fields it set, and the\n// interested columns' values before and after, and what that costs.\n//\n// | Operation | Recorded as | Ids and values from | Extra statements |\n// |---------------------|-------------|------------------------------------|------------------------------|\n// | create | create | the result | none |\n// | upsert | create, or | the result; old values from a read | one read, only when `update` |\n// | | update when | that also says the row existed | sets an interested column or |\n// | | read found | | holds a nested write |\n// | update | update | the result; old values from a read | one read, only when `data` |\n// | | | | sets an interested column or |\n// | | | | holds a nested write |\n// | delete | delete | the result (the deleted row) | none; for a via entry model, |\n// | | | | one read per junction, and |\n// | | | | one for the id when `where` |\n// | | | | names no `id` |\n// | createMany | create | rewritten to createManyAndReturn | none |\n// | updateMany | update | rewritten to updateManyAndReturn | as updateManyAndReturn |\n// | createManyAndReturn | create | the result | none |\n// | updateManyAndReturn | update | the result; old values from a read | one read, only when `data` |\n// | | | | sets an interested column |\n// | deleteMany | delete | a read with the same `where` | one read; for a via entry |\n// | | | | model, one per junction more |\n// | | | | when the read found rows |\n//\n// A `delete` or `deleteMany` of a via entry model (one whose junction a\n// `via` collection registered: `registerLinks`) reads the junction rows that\n// link the rows it deletes first, through the open transaction, and records\n// them in each write's `links` (possibly none), so its flush tells only the\n// scopes the row was linked to (the 5.1 audit's COLL-3; `links.ts`).\n//\n// `fields` are the keys of `data` (for upsert, of `update` when the row\n// existed, of `create` when it did not, and of both when no read told; such\n// a create is marked `mayHaveExisted`). An `update` (or an upsert's\n// `update`) whose `data` holds a nested write may set a foreign key through\n// a relation (`project: { connect }`, `parent: { disconnect: true }`), which\n// its keys do not name: it reads every interested column first and lists\n// them all in `fields`, so an access change it makes is seen (the 5.1\n// audit's DATA-1). The rows the nested write itself creates, changes or\n// deletes are not seen.\n// When a `select` (or `omit`) would hide the `id` or an interested column,\n// the hook adds it and strips it from the result again, so the caller gets\n// exactly what it asked for. Reads go through the open interactive\n// transaction's client, so they see its uncommitted rows. A `deleteMany`\n// with a `limit` deletes exactly the rows its read found.\n//\n// Inside an array-form `$transaction([...])` an operation cannot be replaced\n// by another one, so `createMany` and `updateMany` run as they are there:\n// `updateMany` reads its ids first, and `createMany` is tracked only when\n// every row it creates has an explicit `id`. A batch has no transaction\n// client, so every read made first there (`deleteMany`'s and `updateMany`'s\n// ids, an `update`'s old values) runs on the root client, outside the batch,\n// and misses what the batch's earlier statements changed: a development\n// warning says so once per model and operation.\n//\n// A write that certainly changed nothing records nothing (finding F7.2 of\n// the quickdraw-chat review), so no frame, delta, topic change,\n// `refreshEntry` or `affects` hop follows it. Only the write itself tells:\n//\n// - a write that matched no row (`updateMany`, `updateManyAndReturn` or\n// `deleteMany`; in a batch, an `updateMany` answering count 0);\n// - a `data` (or an upsert's `update`) with nothing to write, `{}` or only\n// `undefined` values, for which Prisma writes nothing at all.\n//\n// A write that sets a column to the value it held is recorded like any\n// other. Comparing the values the hook read before the write with the ones\n// it returned cannot tell: that read is not atomic with the write (in an\n// array-form batch it runs before the whole batch, and elsewhere another\n// write may land between the two), so a real change would be lost and its\n// subscribers left on a value the database no longer holds. rc.5 skipped\n// such writes; the final review of the release candidates showed both.\n//\n// An upsert whose `update` sets nothing changes a row only when it creates\n// one, and nothing it returns tells which it did. Its read replaces it:\n// `findUnique` with its `where` and selection answers for a row that exists\n// (one statement, as the upsert was), and only a missing row runs the upsert\n// after it, recorded as a create (one statement more). In a batch, where no\n// operation can be replaced, it is still recorded as a create that may have\n// found its row.\n\nimport { quietly } from \"../server/devWarnings\";\nimport type { LinkInterest } from \"../server/storage\";\nimport type { WriteRecord } from \"../server/uow/types\";\nimport type { WriteTracker } from \"../server/uow/unitOfWork\";\nimport { readLinks, withLinks, type Links } from \"./links\";\nimport { findNestedWrites } from \"./nested\";\n\n/** A Prisma operation's arguments. */\nexport type Args = Readonly<Record<string, unknown>>;\n\n/** A row a Prisma operation returned. */\nexport type Row = Readonly<Record<string, unknown>>;\n\ntype Values = Readonly<Record<string, unknown>>;\n\n/** The model methods the hook's own queries use. */\nexport interface Delegate {\n findMany(args: Args): Promise<Row[]>;\n findUnique(args: Args): Promise<Row | null>;\n count(args: Args): Promise<number>;\n createManyAndReturn(args: Args): Promise<Row[]>;\n updateManyAndReturn(args: Args): Promise<Row[]>;\n}\n\n/** What every operation handler shares. */\nexport interface Runtime {\n readonly tracker: WriteTracker;\n /** The model's delegate on the open interactive transaction's client, or else the root client's. */\n delegate(model: string): Delegate;\n interestOf(model: string): readonly string[];\n /** The junctions whose links a delete of `model` reads first (`registerLinks`). */\n linksOf(model: string): readonly LinkInterest[];\n /** Models whose writes run untracked: no usable `id` column. */\n readonly untracked: Set<string>;\n}\n\n/** One write operation, as the hook received it. */\nexport interface Operation {\n readonly runtime: Runtime;\n /** The model, named as the client names it: `\"task\"`. */\n readonly model: string;\n /** The Prisma operation: `\"deleteMany\"`. */\n readonly operation: string;\n readonly args: Args;\n readonly query: (args: Args) => Promise<unknown>;\n}\n\n/**\n * Thrown when the hook's own read failed validation before the write ran;\n * the hook then runs the write as the caller wrote it (`runUntracked`).\n */\nexport class Untrackable extends Error {\n override readonly name = \"Untrackable\";\n}\n\nfunction isRecord(value: unknown): value is Readonly<Record<string, unknown>> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction isValidationError(error: unknown): boolean {\n return error instanceof Error && error.name === \"PrismaClientValidationError\";\n}\n\n/** Stops tracking `model` for the life of the process, and says why once. */\nfunction untrack(op: Operation, reason: string): void {\n if (op.runtime.untracked.has(op.model)) {\n return;\n }\n op.runtime.untracked.add(op.model);\n op.runtime.tracker.logger.warn(\n `Writes to ${op.model} are not tracked: ${reason}. Tracked models need a string id column named \"id\"`,\n { category: \"quickdraw.writes\", model: op.model },\n );\n}\n\n/**\n * Runs the operation as the caller wrote it, after a query the hook built\n * failed validation (a model without an `id` column, or an interested column\n * it does not have). The hook stops tracking the model only when the\n * caller's own query then works: an error in the caller's arguments is\n * theirs, and reaches them.\n */\nexport async function runUntracked(op: Operation, reason: string): Promise<unknown> {\n const result = await op.query(op.args);\n untrack(op, reason);\n return result;\n}\n\n/** A row's id as the tracker keys it: a string, or a number or bigint as a string. */\nexport function idOf(row: Row): string | undefined {\n const { id } = row;\n if (typeof id === \"string\") {\n return id;\n }\n return typeof id === \"number\" || typeof id === \"bigint\" ? String(id) : undefined;\n}\n\nfunction pick(row: Row, columns: readonly string[]): Values | undefined {\n const present = columns.filter((column) => Object.hasOwn(row, column));\n return present.length === 0\n ? undefined\n : Object.fromEntries(present.map((column) => [column, row[column]]));\n}\n\nfunction keysOf(data: unknown): string[] {\n if (Array.isArray(data)) {\n return [...new Set(data.flatMap((item) => keysOf(item)))];\n }\n return isRecord(data) ? Object.keys(data) : [];\n}\n\nfunction rowsOf(result: unknown): Row[] {\n if (Array.isArray(result)) {\n return result.filter(isRecord);\n }\n return isRecord(result) ? [result] : [];\n}\n\n/** The keys of `data` Prisma writes: those whose value is not `undefined`. */\nfunction writtenKeys(data: unknown): string[] {\n return isRecord(data)\n ? Object.entries(data)\n .filter(([, value]) => value !== undefined)\n .map(([key]) => key)\n : [];\n}\n\n/** True for a `data` Prisma writes nothing for: an object with no key whose value is set. */\nexport function writesNothing(data: unknown): boolean {\n return isRecord(data) && writtenKeys(data).length === 0;\n}\n\n/** Counts a statement the hook runs past itself (`op.query`), and hands it to the development checks. */\nfunction countOwn(op: Operation, operation: string, args: Args): void {\n op.runtime.tracker.countStatement();\n op.runtime.tracker.observe({ model: op.model, operation, args });\n}\n\n/**\n * Whether `data` holds a nested write, warning (in development) once per\n * write that the related rows are not tracked. It is found in every\n * environment: such a `data` may set a foreign key the tracker must read.\n */\nfunction warnNested(op: Operation, data: unknown): boolean {\n const nested = findNestedWrites(data);\n for (const { field, operation } of nested) {\n op.runtime.tracker.warn({\n kind: \"nested-write\",\n subject: `${op.model}.${field}.${operation}`,\n message: `A nested write (${op.model}.${field}: { ${operation} }) is not tracked: the related rows it creates, changes or deletes send no frames and revoke nothing. The ${op.model} row is tracked, and an update of it reads its access and scope columns first, so a foreign key a to-one connect or disconnect sets on it is seen. Write related rows through their own model, or set the foreign key column`,\n meta: { model: op.model, field, operation },\n });\n }\n return nested.length > 0;\n}\n\n/** The keys of `data` and `columns`, each once: the fields of a write that holds a nested write. */\nfunction withColumns(data: unknown, columns: readonly string[]): string[] {\n return [...new Set([...keysOf(data), ...columns])];\n}\n\n/** The interested columns `data` sets. */\nfunction touchedInterest(op: Operation, data: unknown): string[] {\n const keys = new Set(keysOf(data));\n return op.runtime.interestOf(op.model).filter((column) => keys.has(column));\n}\n\n/** `args` with `columns` added to its `select`, or no longer omitted, and the columns that were added. */\nfunction widen(args: Args, columns: readonly string[]): { args: Args; added: string[] } {\n const { select, omit } = args;\n if (isRecord(select)) {\n const added = columns.filter((column) => select[column] !== true);\n const widened = { ...select, ...Object.fromEntries(added.map((column) => [column, true])) };\n return { args: added.length === 0 ? args : { ...args, select: widened }, added };\n }\n if (isRecord(omit)) {\n const added = columns.filter((column) => omit[column] === true);\n const widened = { ...omit, ...Object.fromEntries(added.map((column) => [column, false])) };\n return { args: added.length === 0 ? args : { ...args, omit: widened }, added };\n }\n return { args, added: [] };\n}\n\nfunction strip(result: unknown, added: readonly string[]): unknown {\n const without = (row: unknown): unknown =>\n isRecord(row)\n ? Object.fromEntries(Object.entries(row).filter(([key]) => !added.includes(key)))\n : row;\n return Array.isArray(result) ? result.map(without) : without(result);\n}\n\n/**\n * Runs the operation with the `id` and interested columns in its result,\n * and returns the caller's result plus the rows to record. When adding them\n * fails validation (a model without an `id` column), the operation runs as\n * the caller wrote it and its rows are not recorded.\n */\nasync function runWidened(op: Operation): Promise<{ result: unknown; rows: Row[] }> {\n const { args, added } = widen(op.args, [\"id\", ...op.runtime.interestOf(op.model)]);\n if (added.length === 0) {\n const result = await op.query(op.args);\n return { result, rows: rowsOf(result) };\n }\n let result: unknown;\n try {\n result = await op.query(args);\n } catch (error) {\n if (!isValidationError(error)) {\n throw error;\n }\n return { result: await runUntracked(op, \"selecting its id failed\"), rows: [] };\n }\n return { result: strip(result, added), rows: rowsOf(result) };\n}\n\n/**\n * Warns once per model and operation that a read made first inside an\n * array-form `$transaction` runs on the root client: an array-form batch\n * has no transaction client to read through, so the read does not see what\n * the batch's earlier statements changed.\n */\nfunction warnBatchRead(op: Operation): void {\n if (!op.runtime.tracker.inBatch()) {\n return;\n }\n op.runtime.tracker.warn({\n kind: \"batch-read\",\n subject: `${op.model}.${op.operation}`,\n message: `${op.operation} on ${op.model} inside an array-form $transaction reads its rows first on the root client, outside the batch, so rows the batch's earlier statements changed may be missed; use an interactive transaction to read inside it`,\n meta: { model: op.model, operation: op.operation },\n });\n}\n\n/**\n * Reads `columns` of the rows `where` matches, by id, through the transaction\n * when one is open. The read is the tracker's own, not the app's, so the\n * development checks of statements leave it alone.\n */\nasync function readBefore(\n op: Operation,\n where: unknown,\n columns: readonly string[],\n options: { readonly unique: boolean; readonly take?: unknown },\n): Promise<Map<string, Values>> {\n warnBatchRead(op);\n const select = Object.fromEntries([\"id\", ...columns].map((column) => [column, true]));\n const delegate = op.runtime.delegate(op.model);\n let rows: Row[];\n try {\n if (options.unique) {\n const row = await quietly(() => delegate.findUnique({ where, select }));\n rows = row === null ? [] : [row];\n } else {\n rows = await quietly(() =>\n delegate.findMany({\n where,\n select,\n ...(options.take === undefined ? {} : { take: options.take }),\n }),\n );\n }\n } catch (error) {\n if (isValidationError(error)) {\n throw new Untrackable(\"reading its id failed\", { cause: error });\n }\n throw error;\n }\n const before = new Map<string, Values>();\n for (const row of rows) {\n const id = idOf(row);\n if (id !== undefined) {\n before.set(id, pick(row, columns) ?? {});\n }\n }\n return before;\n}\n\nfunction writesOf(\n op: Operation,\n kind: WriteRecord[\"op\"],\n rows: readonly Row[],\n fields: readonly string[],\n before?: ReadonlyMap<string, Values>,\n): WriteRecord[] {\n const interest = op.runtime.interestOf(op.model);\n const writes: WriteRecord[] = [];\n for (const row of rows) {\n const id = idOf(row);\n if (id === undefined) {\n untrack(op, \"its rows have no id\");\n return [];\n }\n const values = pick(row, interest);\n const old = kind === \"delete\" ? values : before?.get(id);\n const after = kind === \"delete\" ? undefined : values;\n writes.push({\n model: op.model,\n id,\n op: kind,\n fields,\n ...(old === undefined || Object.keys(old).length === 0 ? {} : { before: old }),\n ...(after === undefined ? {} : { after }),\n });\n }\n return writes;\n}\n\nfunction record(op: Operation, writes: readonly WriteRecord[]): void {\n op.runtime.tracker.record(writes);\n}\n\nasync function create(op: Operation): Promise<unknown> {\n warnNested(op, op.args.data);\n const { result, rows } = await runWidened(op);\n record(op, writesOf(op, \"create\", rows, keysOf(op.args.data)));\n return result;\n}\n\n/** The selection of a read that returns what `args` (an upsert's) would: its `select`, `include` and `omit`. */\nfunction selectionOf(args: Args): Args {\n return Object.fromEntries(\n [\"select\", \"include\", \"omit\"]\n .filter((key) => args[key] !== undefined)\n .map((key) => [key, args[key]]),\n );\n}\n\n/**\n * An upsert whose `update` sets nothing (see the top of this file): the\n * read that tells whether its row exists takes its place, and answers it\n * when the row is there; only a missing row runs the upsert.\n */\nasync function upsertWithoutUpdate(op: Operation): Promise<unknown> {\n warnNested(op, op.args.create);\n const { args, added } = widen(op.args, [\"id\", ...op.runtime.interestOf(op.model)]);\n let found: Row | null;\n try {\n // Through the hook, which counts it as this call's one statement.\n found = await op.runtime\n .delegate(op.model)\n .findUnique({ where: op.args.where, ...selectionOf(args) });\n } catch (error) {\n if (!isValidationError(error)) {\n throw error;\n }\n // The hook counted the read that failed; the upsert runs in its place.\n return runUntracked(op, \"reading its id failed\");\n }\n if (found !== null) {\n // Prisma writes nothing to a row that exists when `update` sets nothing: no change.\n return strip(found, added);\n }\n countOwn(op, op.operation, op.args);\n const { result, rows } = await runWidened(op);\n // Created, unless another transaction created the row in between: then it may have existed.\n const writes = writesOf(op, \"create\", rows, keysOf(op.args.create));\n record(\n op,\n writes.map((write) => ({ ...write, mayHaveExisted: true as const })),\n );\n return result;\n}\n\nasync function upsert(op: Operation): Promise<unknown> {\n if (writesNothing(op.args.update) && !op.runtime.tracker.inBatch()) {\n return upsertWithoutUpdate(op);\n }\n warnNested(op, op.args.create);\n // A nested write may set a foreign key through a relation: read every interested column.\n const nested = warnNested(op, op.args.update);\n const touched = nested\n ? [...op.runtime.interestOf(op.model)]\n : touchedInterest(op, op.args.update);\n // Reading the interested columns first also tells whether the row existed.\n const before =\n touched.length === 0\n ? undefined\n : await readBefore(op, op.args.where, touched, { unique: true });\n const { result, rows } = await runWidened(op);\n if (before !== undefined && before.size > 0) {\n const fields = nested ? withColumns(op.args.update, touched) : keysOf(op.args.update);\n record(op, writesOf(op, \"update\", rows, fields, before));\n } else if (before === undefined) {\n // Nothing read: the row may have existed, and been updated.\n const writes = writesOf(op, \"create\", rows, keysOf([op.args.create, op.args.update]));\n record(\n op,\n writes.map((write) => ({ ...write, mayHaveExisted: true as const })),\n );\n } else {\n record(op, writesOf(op, \"create\", rows, keysOf(op.args.create)));\n }\n return result;\n}\n\nasync function update(op: Operation): Promise<unknown> {\n if (writesNothing(op.args.data)) {\n // Prisma only reads the row (and answers NOT_FOUND without one): nothing to record.\n return op.query(op.args);\n }\n // A nested write may set a foreign key through a relation: read every interested column.\n const nested = warnNested(op, op.args.data);\n const touched = nested ? [...op.runtime.interestOf(op.model)] : touchedInterest(op, op.args.data);\n const before =\n touched.length === 0\n ? undefined\n : await readBefore(op, op.args.where, touched, { unique: true });\n const { result, rows } = await runWidened(op);\n const fields = nested ? withColumns(op.args.data, touched) : keysOf(op.args.data);\n record(op, writesOf(op, \"update\", rows, fields, before));\n return result;\n}\n\n/** The links of the row a `delete` names (`readLinks`): by its `where.id`, or a read of its id first. */\nasync function linksOfDelete(op: Operation): Promise<Links | undefined> {\n if (op.runtime.linksOf(op.model).length === 0) {\n return undefined;\n }\n warnBatchRead(op);\n const { where } = op.args;\n const ids =\n isRecord(where) && typeof where.id === \"string\"\n ? [where.id]\n : [...(await readBefore(op, where, [], { unique: true })).keys()];\n return await readLinks(op.runtime, op.model, ids);\n}\n\nasync function remove(op: Operation): Promise<unknown> {\n const links = await linksOfDelete(op);\n const { result, rows } = await runWidened(op);\n record(op, withLinks(writesOf(op, \"delete\", rows, []), links));\n return result;\n}\n\nasync function createManyAndReturn(op: Operation): Promise<unknown> {\n const { result, rows } = await runWidened(op);\n record(op, writesOf(op, \"create\", rows, keysOf(op.args.data)));\n return result;\n}\n\nasync function updateManyAndReturn(op: Operation): Promise<unknown> {\n if (writesNothing(op.args.data)) {\n // Prisma only reads the rows `where` matches: nothing to record.\n return op.query(op.args);\n }\n const touched = touchedInterest(op, op.args.data);\n const before =\n touched.length === 0\n ? undefined\n : await readBefore(op, op.args.where, touched, { unique: false });\n const { result, rows } = await runWidened(op);\n // Matching no row, it returns none, and records nothing.\n record(op, writesOf(op, \"update\", rows, keysOf(op.args.data), before));\n return result;\n}\n\n/** `createMany` inside an array-form transaction: tracked when every row names its id. */\nasync function createManyInBatch(op: Operation): Promise<unknown> {\n const items = (Array.isArray(op.args.data) ? op.args.data : [op.args.data]).filter(isRecord);\n const result = await op.query(op.args);\n const rows = items.filter((item) => idOf(item) !== undefined);\n if (rows.length === items.length) {\n record(op, writesOf(op, \"create\", rows, keysOf(op.args.data)));\n } else {\n op.runtime.tracker.warn({\n kind: \"batch-create-many\",\n subject: op.model,\n message: `createMany on ${op.model} inside an array-form $transaction cannot report the rows it created, so they are not tracked; give each row an id, or use an interactive transaction`,\n meta: { model: op.model },\n });\n }\n return result;\n}\n\n/**\n * `updateMany` inside an array-form transaction: its ids are read first,\n * before the batch runs. With a `limit`, every row the read found is\n * recorded, which may be more rows than were updated.\n */\nasync function updateManyInBatch(op: Operation): Promise<unknown> {\n if (writesNothing(op.args.data)) {\n return op.query(op.args);\n }\n const before = await readBefore(op, op.args.where, touchedInterest(op, op.args.data), {\n unique: false,\n });\n const result = await op.query(op.args);\n // Only a count comes back: 0 means it updated nothing, whatever the read found.\n if (isRecord(result) && result.count === 0) {\n return result;\n }\n const rows = [...before.keys()].map((id) => ({ id }));\n record(op, writesOf(op, \"update\", rows, keysOf(op.args.data), before));\n return result;\n}\n\n/**\n * `createMany` and `updateMany` outside a batch: the `...AndReturn` form,\n * through the transaction's client when one is open, which the hook then\n * records like any other call of it.\n */\nasync function rewrite(\n op: Operation,\n run: (delegate: Delegate, args: Args) => Promise<Row[]>,\n): Promise<unknown> {\n let rows: Row[];\n try {\n rows = await run(op.runtime.delegate(op.model), { ...op.args, select: { id: true } });\n } catch (error) {\n if (!isValidationError(error)) {\n throw error;\n }\n op.runtime.tracker.countStatement();\n return runUntracked(op, \"selecting its id failed\");\n }\n return { count: rows.length };\n}\n\nfunction createMany(op: Operation): Promise<unknown> {\n if (op.runtime.tracker.inBatch()) {\n return createManyInBatch(op);\n }\n return rewrite(op, (delegate, args) => delegate.createManyAndReturn(args));\n}\n\nfunction updateMany(op: Operation): Promise<unknown> {\n if (op.runtime.tracker.inBatch()) {\n return updateManyInBatch(op);\n }\n if (writesNothing(op.args.data)) {\n // As it is: Prisma writes nothing and answers count 0, which the rewrite would not.\n return op.query(op.args);\n }\n return rewrite(op, (delegate, args) => delegate.updateManyAndReturn(args));\n}\n\nasync function deleteMany(op: Operation): Promise<unknown> {\n const { where, limit } = op.args;\n const interest = op.runtime.interestOf(op.model);\n const before = await readBefore(op, where, interest, { unique: false, take: limit });\n const ids = [...before.keys()];\n const links = await readLinks(op.runtime, op.model, ids);\n // With a limit, which rows go is up to the database: delete the rows read.\n const args =\n limit === undefined\n ? op.args\n : { ...op.args, where: { AND: [where ?? {}, { id: { in: ids } }] } };\n const result = await op.query(args);\n const rows = ids.map((id) => ({ id, ...before.get(id) }));\n record(op, withLinks(writesOf(op, \"delete\", rows, []), links));\n return result;\n}\n\n/**\n * The write operations the hook tracks, by Prisma operation name. Every\n * other operation passes through untouched.\n */\nexport const WRITE_OPERATIONS: Readonly<Record<string, (op: Operation) => Promise<unknown>>> =\n Object.freeze({\n create,\n upsert,\n update,\n delete: remove,\n createMany,\n createManyAndReturn,\n updateMany,\n updateManyAndReturn,\n deleteMany,\n });\n\n/**\n * Whether a tracked operation hands its work to another one, which then\n * counts the statement (`createMany` and `updateMany` outside a batch, an\n * `upsert` whose `update` sets nothing outside a batch: its read): the hook\n * counts every other operation itself.\n */\nexport function delegates(runtime: Runtime, operation: string, args: Args | undefined): boolean {\n if (runtime.tracker.inBatch()) {\n return false;\n }\n switch (operation) {\n case \"createMany\":\n return true;\n case \"updateMany\":\n return !writesNothing(args?.data);\n case \"upsert\":\n return writesNothing(args?.update);\n default:\n return false;\n }\n}\n","// What a Prisma client's own schema says about its models' fields, for the\n// storage adapter's `nullable` and `trackable` (`trackPrisma.ts`). Prisma 7's\n// generated client carries the schema's text (`config.inlineSchema`), which\n// its runtime keeps on every client, extended ones included, as\n// `_engineConfig.inlineSchema`. Its runtime data model (`_runtimeDataModel`)\n// names each field's kind but not whether the field is optional, and there is\n// no runtime DMMF. Reading the text answers with no statement; the probes it\n// replaces send a filter or select Prisma refuses, which a client created\n// with `log: [\"error\"]` prints as a `prisma:error` line. Whatever the text\n// does not answer (no text, or a model or field it does not declare) is left\n// to those probes.\n//\n// Only what the answers need is read: the field lines of `model` and `view`\n// blocks (`name Type`, `Type?` optional, `Type[]` a list), the names of\n// `enum`s, and `@ignore`. Comments, block attributes (`@@id`, `@@map`) and\n// the other field attributes (`@map`, `@default`) are skipped: the answers\n// are by Prisma field name, as the probes ask.\n\nimport { modelKey } from \"../server/storage\";\n\n/** What a client's schema says, by model (either spelling) and Prisma field name. */\nexport interface PrismaSchemaFacts {\n /** Whether `column` of `model` may hold null; `undefined` when the schema does not say. */\n nullable(model: string, column: string): boolean | undefined;\n /**\n * Whether the tracker can key `model`'s rows by an `id` field: false when\n * the model has none (a composite `@@id`), true for a required `String`,\n * `Int`, `BigInt`, `Float` or enum `id`; `undefined` when the schema does\n * not say, or the answer depends on the rows (an optional `id`).\n */\n trackable(model: string): boolean | undefined;\n}\n\n/** One scalar field of a model, as its schema declares it. */\ninterface SchemaField {\n readonly type: string;\n readonly optional: boolean;\n readonly list: boolean;\n}\n\ninterface SchemaModel {\n readonly fields: ReadonlyMap<string, SchemaField>;\n readonly trackable: boolean | undefined;\n}\n\ninterface Block {\n readonly kind: string;\n readonly name: string;\n readonly lines: string[];\n}\n\n/** The runtime data model's field kinds of one model: `scalar`, `enum`, `object` (a relation). */\ntype FieldKinds = ReadonlyMap<string, string>;\n\nconst BLOCK_START = /^(\\w+)\\s+([A-Za-z_]\\w*)\\s*\\{/;\n\nconst FIELD = /^([A-Za-z_]\\w*)\\s+([A-Za-z_]\\w*)(\\([^)]*\\))?(\\[\\])?(\\?)?(?=\\s|$)/;\n\nconst IGNORED = /(?:^|\\s)@ignore(?=\\s|$|\\()/;\n\n/** The `id` types whose values the tracker keys rows by (`idOf`). */\nconst KEY_TYPES: ReadonlySet<string> = new Set([\"String\", \"Int\", \"BigInt\", \"Float\"]);\n\nconst COLUMN_KINDS: ReadonlySet<string> = new Set([\"scalar\", \"enum\"]);\n\nfunction isObject(value: unknown): value is object {\n return (typeof value === \"object\" || typeof value === \"function\") && value !== null;\n}\n\n/** `line` without its `//` or `///` comment, which never starts inside a string. */\nfunction withoutComment(line: string): string {\n let inString = false;\n for (let index = 0; index < line.length; index += 1) {\n const char = line[index];\n if (char === '\"' && line[index - 1] !== \"\\\\\") {\n inString = !inString;\n } else if (!inString && char === \"/\" && line[index + 1] === \"/\") {\n return line.slice(0, index);\n }\n }\n return line;\n}\n\n/** The schema's top-level blocks, each with its lines, comments and blank lines dropped. */\nfunction blocksOf(text: string): Block[] {\n const blocks: Block[] = [];\n let open: Block | undefined;\n for (const raw of text.split(/\\r?\\n/)) {\n const line = withoutComment(raw).trim();\n if (line === \"\") {\n continue;\n }\n if (open !== undefined) {\n if (line === \"}\") {\n open = undefined;\n } else {\n open.lines.push(line);\n }\n continue;\n }\n const start = BLOCK_START.exec(line);\n if (start !== null) {\n const block: Block = { kind: start[1] ?? \"\", name: start[2] ?? \"\", lines: [] };\n blocks.push(block);\n // `model X {}` closes on the line it opens.\n open = line.slice(start[0].length).trim() === \"}\" ? undefined : block;\n }\n }\n return blocks;\n}\n\n/** The field kinds the runtime data model lists for `model`, or `undefined`. */\nfunction kindsOf(runtimeDataModel: unknown, model: string): FieldKinds | undefined {\n const models: unknown = isObject(runtimeDataModel)\n ? Reflect.get(runtimeDataModel, \"models\")\n : undefined;\n const entry: unknown =\n isObject(models) && Object.hasOwn(models, model) ? Reflect.get(models, model) : undefined;\n const fields: unknown = isObject(entry) ? Reflect.get(entry, \"fields\") : undefined;\n if (!Array.isArray(fields)) {\n return undefined;\n }\n const kinds = new Map<string, string>();\n for (const field of fields as unknown[]) {\n const name: unknown = isObject(field) ? Reflect.get(field, \"name\") : undefined;\n const kind: unknown = isObject(field) ? Reflect.get(field, \"kind\") : undefined;\n if (typeof name === \"string\" && typeof kind === \"string\") {\n kinds.set(name, kind);\n }\n }\n return kinds;\n}\n\n/**\n * Whether the field `name` of type `type` is a column: as the runtime data\n * model says when it lists the model (a relation is `object`), else unless\n * its type names a model, view or composite type, or is `Unsupported`.\n */\nfunction isColumn(\n name: string,\n type: string,\n kinds: FieldKinds | undefined,\n records: ReadonlySet<string>,\n): boolean {\n if (kinds !== undefined) {\n return COLUMN_KINDS.has(kinds.get(name) ?? \"\");\n }\n return type !== \"Unsupported\" && !records.has(type);\n}\n\nfunction trackableOf(\n fields: ReadonlyMap<string, SchemaField>,\n kinds: FieldKinds | undefined,\n enums: ReadonlySet<string>,\n): boolean | undefined {\n const id = fields.get(\"id\");\n if (id === undefined) {\n // The runtime knows an `id` column the text did not show: let the probe say.\n return kinds !== undefined && COLUMN_KINDS.has(kinds.get(\"id\") ?? \"\") ? undefined : false;\n }\n if (id.optional || id.list) {\n return undefined;\n }\n return KEY_TYPES.has(id.type) || enums.has(id.type) ? true : undefined;\n}\n\nfunction modelOf(\n block: Block,\n kinds: FieldKinds | undefined,\n records: ReadonlySet<string>,\n enums: ReadonlySet<string>,\n): SchemaModel {\n const fields = new Map<string, SchemaField>();\n for (const line of block.lines) {\n const field = FIELD.exec(line);\n const [, name = \"\", type = \"\", , list, optional] = field ?? [];\n if (field !== null && !IGNORED.test(line) && isColumn(name, type, kinds, records)) {\n fields.set(name, { type, optional: optional !== undefined, list: list !== undefined });\n }\n }\n return { fields, trackable: trackableOf(fields, kinds, enums) };\n}\n\n/**\n * Reads a Prisma schema's text: what each model's fields say about null, and\n * whether the model has an `id` the tracker can key. A relation field is not\n * a column: the runtime data model's kinds say so when given (a client's\n * `_runtimeDataModel`), else a field whose type is a model. A model the text\n * does not declare, or marks `@@ignore`, is not answered.\n */\nexport function parsePrismaSchema(text: string, runtimeDataModel?: unknown): PrismaSchemaFacts {\n const blocks = blocksOf(text);\n const named = (...kinds: string[]): Set<string> =>\n new Set(blocks.filter((block) => kinds.includes(block.kind)).map((block) => block.name));\n const enums = named(\"enum\");\n const records = named(\"model\", \"view\", \"type\");\n const models = new Map<string, SchemaModel>();\n for (const block of blocks) {\n const ignored = block.lines.some((line) => /^@@ignore\\b/.test(line));\n if ((block.kind === \"model\" || block.kind === \"view\") && !ignored) {\n const kinds = kindsOf(runtimeDataModel, block.name);\n models.set(modelKey(block.name), modelOf(block, kinds, records, enums));\n }\n }\n return Object.freeze({\n nullable(model: string, column: string): boolean | undefined {\n const field = models.get(modelKey(model))?.fields.get(column);\n return field === undefined ? undefined : field.optional && !field.list;\n },\n trackable: (model: string): boolean | undefined => models.get(modelKey(model))?.trackable,\n });\n}\n\n/**\n * The schema text a Prisma client carries (`_engineConfig.inlineSchema`, on\n * an extended client too), or `undefined`. Never throws.\n */\nexport function schemaTextOf(client: unknown): string | undefined {\n try {\n const config: unknown = isObject(client) ? Reflect.get(client, \"_engineConfig\") : undefined;\n const text: unknown = isObject(config) ? Reflect.get(config, \"inlineSchema\") : undefined;\n return typeof text === \"string\" && text !== \"\" ? text : undefined;\n } catch {\n return undefined;\n }\n}\n\n/** The runtime data model a Prisma client carries, or `undefined`. Never throws. */\nfunction runtimeDataModelOf(client: unknown): unknown {\n try {\n const own: unknown = isObject(client) ? Reflect.get(client, \"_runtimeDataModel\") : undefined;\n if (own !== undefined) {\n return own;\n }\n const config: unknown = isObject(client) ? Reflect.get(client, \"_engineConfig\") : undefined;\n return isObject(config) ? Reflect.get(config, \"runtimeDataModel\") : undefined;\n } catch {\n return undefined;\n }\n}\n\n/** What `client`'s own schema says, or `undefined` when it carries no schema text. */\nexport function prismaSchemaOf(client: unknown): PrismaSchemaFacts | undefined {\n const text = schemaTextOf(client);\n return text === undefined ? undefined : parsePrismaSchema(text, runtimeDataModelOf(client));\n}\n","// `trackPrisma` (RFC 0003 sections 5.2 and 5.4): wraps an app's Prisma\n// client so every write made through it is recorded into the unit of work it\n// runs in. In 4.1 only `BaseService.create/update/delete` were observed\n// (4.1 `src/server/BaseService.ts:769-827`); a raw `prisma.task.update`\n// was invisible, and every live update needed a hand-written emit.\n//\n// Two client extensions, both public Prisma API:\n//\n// 1. a `query` hook on every operation records writes (`operations.ts`) and\n// counts statements;\n// 2. a `client` extension replaces `$transaction`, so writes inside a\n// transaction are buffered and join the unit of work only once it commits.\n// It calls the `$transaction` of the client from step 1, so the\n// transaction's client carries the hook. Transactions are found through\n// that wrapper and `AsyncLocalStorage`, never through Prisma internals.\n//\n// Make it the last extension applied: an extension added after it still\n// runs outside transactions, but not on a transaction's client.\n//\n// The storage adapter's `nullable` and `trackable` read the one Prisma\n// internal used here, the schema text the client keeps\n// (`_engineConfig.inlineSchema`, `schemaText.ts`). Without it they ask the\n// database, as before: a statement Prisma refuses, which it logs as an error.\n\nimport { consoleLogger, type Logger } from \"../contract/logger\";\nimport { quietly } from \"../server/devWarnings\";\nimport {\n createInterestRegistry,\n createLinkRegistry,\n modelKey,\n STORAGE_KEY,\n storageOf,\n type CountArgs,\n type FindManyArgs,\n type StorageAdapter,\n} from \"../server/storage\";\nimport { createWriteTracker, type WriteTracker } from \"../server/uow/unitOfWork\";\nimport {\n delegates,\n idOf,\n runUntracked,\n Untrackable,\n WRITE_OPERATIONS,\n type Args,\n type Delegate,\n type Operation,\n type Runtime,\n} from \"./operations\";\nimport { prismaSchemaOf, type PrismaSchemaFacts } from \"./schemaText\";\nimport type { Tracked } from \"./tracked\";\n\n/** Options of {@link trackPrisma}. */\nexport interface TrackPrismaOptions {\n /**\n * Interested columns per model, whose values writes report in `before`\n * and `after`: `{ task: [\"projectId\", \"status\"] }`. The framework adds the\n * columns its collections and access policies need with\n * `storage.registerInterest`; this is for the app's own sinks.\n */\n readonly interest?: Readonly<Record<string, readonly string[]>>;\n /**\n * Receives warnings until a dispatcher is created with this client; then\n * the dispatcher's logger does. Default: the console logger.\n */\n readonly logger?: Logger;\n /**\n * Warn about writes outside any unit of work and about nested writes.\n * Default: on unless `NODE_ENV` is `\"production\"`.\n */\n readonly development?: boolean;\n}\n\n/** The part of a Prisma client `trackPrisma` relies on: client extensions. */\nexport interface PrismaClientLike {\n $extends(extension: never): unknown;\n}\n\n/** The client as `trackPrisma` calls it. */\ninterface ExtendableClient {\n $extends(extension: object): ExtendedClient;\n}\n\ninterface ExtendedClient extends ExtendableClient {\n $transaction(arg: unknown, options?: unknown): Promise<unknown>;\n}\n\n/** What a query extension's `$allOperations` hook receives. */\ninterface QueryHookArgs {\n readonly model?: string;\n readonly operation: string;\n readonly args: Args | undefined;\n readonly query: (args: Args | undefined) => Promise<unknown>;\n}\n\nfunction isClient(value: unknown): value is ExtendableClient {\n return (\n (typeof value === \"object\" || typeof value === \"function\") &&\n value !== null &&\n typeof Reflect.get(value, \"$extends\") === \"function\"\n );\n}\n\nfunction delegateOf(client: unknown, model: string): Delegate {\n const delegate: unknown =\n typeof client === \"object\" && client !== null ? Reflect.get(client, model) : undefined;\n if (typeof delegate !== \"object\" || delegate === null) {\n throw new TypeError(`The tracked Prisma client has no model \"${model}\"`);\n }\n return delegate as Delegate;\n}\n\n/** Counts one statement the hook is about to run, and hands a model's to the development checks. */\nfunction count(\n runtime: Runtime,\n model: string | undefined,\n operation: string,\n args: Args | undefined,\n): void {\n runtime.tracker.countStatement();\n if (model !== undefined) {\n runtime.tracker.observe({ model: modelKey(model), operation, args });\n }\n}\n\nfunction createHook(runtime: Runtime) {\n return async function track({ model, operation, args, query }: QueryHookArgs): Promise<unknown> {\n const handler = model === undefined ? undefined : WRITE_OPERATIONS[operation];\n if (model === undefined || handler === undefined || runtime.untracked.has(modelKey(model))) {\n count(runtime, model, operation, args);\n return query(args);\n }\n if (!delegates(runtime, operation, args)) {\n count(runtime, model, operation, args);\n }\n const op: Operation = { runtime, model: modelKey(model), operation, args: args ?? {}, query };\n try {\n return await handler(op);\n } catch (error) {\n if (error instanceof Untrackable) {\n return runUntracked(op, error.message);\n }\n throw error;\n }\n };\n}\n\n/** `$transaction`, in both forms, inside a transaction frame of the tracker. */\nasync function transaction(\n tracker: WriteTracker,\n hooked: ExtendedClient,\n arg: unknown,\n options: unknown,\n): Promise<unknown> {\n const interactive = typeof arg === \"function\";\n const frame = tracker.openTransaction(interactive ? \"interactive\" : \"batch\");\n try {\n const result = interactive\n ? await hooked.$transaction((client: unknown) => {\n frame.setClient(client);\n return frame.run(() => (arg as (client: unknown) => unknown)(client));\n }, options)\n : await frame.run(() => hooked.$transaction(arg, options));\n frame.commit();\n return result;\n } catch (error) {\n frame.rollback();\n throw error;\n }\n}\n\n/**\n * `StorageAdapter.nullable`: what the client's schema says (`Type?`), with\n * no statement (`schemaText.ts`). A column the schema does not answer for is\n * probed: Prisma validates a filter against the schema before sending it,\n * and refuses `{ column: null }` on a required column (a client that logs\n * errors prints that refusal). The probe's answer is kept for the life of the\n * client: one statement per optional column, none for a required one.\n */\nfunction createNullability(\n delegate: (model: string) => Delegate,\n schema: PrismaSchemaFacts | undefined,\n): (model: string, column: string) => Promise<boolean> {\n const known = new Map<string, boolean>();\n return async (model, column) => {\n const declared = schema?.nullable(model, column);\n if (declared !== undefined) {\n return declared;\n }\n const key = `${modelKey(model)}\\u0000${column}`;\n const kept = known.get(key);\n if (kept !== undefined) {\n return kept;\n }\n let nullable = true;\n try {\n await quietly(() => delegate(modelKey(model)).count({ where: { [column]: null } }));\n } catch (error) {\n if (!(error instanceof Error && error.name === \"PrismaClientValidationError\")) {\n throw error;\n }\n nullable = false;\n }\n known.set(key, nullable);\n return nullable;\n };\n}\n\n/**\n * `StorageAdapter.trackable`: whether the tracker can key `model`'s writes,\n * that is whether its rows have an `id`, as the client's schema says, with no\n * statement (`schemaText.ts`). A model the schema does not answer for is\n * probed: one read of one row's id per model, kept for the life of the\n * client, which Prisma refuses for a model without an `id` column (a\n * composite `@@id`). Any other failure (the database down) is thrown, and\n * asked again next time.\n */\nfunction createTrackability(\n delegate: (model: string) => Delegate,\n schema: PrismaSchemaFacts | undefined,\n): (model: string) => Promise<boolean> {\n const known = new Map<string, Promise<boolean>>();\n const probe = async (key: string): Promise<boolean> => {\n try {\n const rows = await quietly(() => delegate(key).findMany({ select: { id: true }, take: 1 }));\n const [row] = Array.isArray(rows) ? (rows as Readonly<Record<string, unknown>>[]) : [];\n return row === undefined || idOf(row) !== undefined;\n } catch (error) {\n if (error instanceof Error && error.name === \"PrismaClientValidationError\") {\n return false;\n }\n throw error;\n }\n };\n return async (model) => {\n const declared = schema?.trackable(model);\n if (declared !== undefined) {\n return declared;\n }\n const key = modelKey(model);\n let answer = known.get(key);\n if (answer === undefined) {\n answer = probe(key);\n known.set(key, answer);\n answer.catch(() => {\n known.delete(key);\n });\n }\n return await answer;\n };\n}\n\n/**\n * The adapter the framework reads through. Its reads are the framework's own\n * (access checks, subscriptions, flushes, kits), so the development checks\n * of statements leave them alone.\n */\nfunction createStorage(\n tracker: WriteTracker,\n [interest, links]: readonly [\n ReturnType<typeof createInterestRegistry>,\n ReturnType<typeof createLinkRegistry>,\n ],\n delegate: (model: string) => Delegate,\n schema: PrismaSchemaFacts | undefined,\n): StorageAdapter {\n return Object.freeze({\n findMany: (model: string, args: FindManyArgs = {}) =>\n quietly(() => delegate(modelKey(model)).findMany(args as Args)),\n count: (model: string, args: CountArgs = {}) =>\n quietly(() => delegate(modelKey(model)).count(args as Args)),\n onWrite: tracker.onWrite,\n countStatements: tracker.countStatements,\n registerInterest: interest.register,\n interestOf: interest.of,\n registerLinks: links.register,\n linksOf: links.of,\n inTransaction: () => tracker.transactionClient() !== undefined || tracker.inBatch(),\n nullable: createNullability(delegate, schema),\n trackable: createTrackability(delegate, schema),\n unitOfWork: tracker.unitOfWork,\n });\n}\n\n/**\n * Wraps a Prisma client so the framework sees every write made through it:\n * `create`, `update`, `upsert`, `delete` and their `Many` forms, inside and\n * outside transactions. Pass the result as `db` to `initQuickdraw`'s app and\n * to `createServer`, which find its storage adapter on it (`storageOf`).\n * Nested writes, raw SQL and database cascades are not seen; record those\n * with `ctx.touch`.\n *\n * The result is a `Tracked<C>` (`tracked.ts`): still a `C`, but the\n * untracked client is no `Tracked<C>`, so a helper that writes takes\n * `db: Tracked<Db>` (or `TrackedTransaction<Db>`, which a transaction's `tx`\n * is too) and the compiler refuses the untracked client there.\n *\n * Prefer interactive transactions (`db.$transaction(async (tx) => ...)`). An\n * array-form `db.$transaction([...])` has no transaction client, so the rows\n * a `deleteMany` or `updateMany` there reads first (and an `update`'s old\n * values) are read on the root client, outside the batch: rows the batch's\n * earlier statements created or changed may be missed, and their frames\n * with them. A development warning names the model and operation once.\n *\n * @example\n * export const db = trackPrisma(new PrismaClient({ adapter }));\n * export const qd = initQuickdraw<{ db: typeof db; principal: AppPrincipal }>();\n * const server = qd.createServer({ app, services, db, auth });\n */\nexport function trackPrisma<C extends PrismaClientLike>(\n client: C,\n options: TrackPrismaOptions = {},\n): Tracked<C> {\n if (!isClient(client)) {\n throw new TypeError(\"trackPrisma: client must be a Prisma client\");\n }\n if (storageOf(client) !== undefined) {\n throw new TypeError(\"trackPrisma: this client is tracked already; pass the untracked client\");\n }\n const tracker = createWriteTracker({\n logger: options.logger ?? consoleLogger,\n development: options.development,\n });\n const interest = createInterestRegistry(options.interest);\n // The client with the hook; the hook's own reads use it outside transactions.\n let root: ExtendedClient | undefined;\n const delegate = (model: string): Delegate =>\n delegateOf(tracker.transactionClient() ?? root, model);\n const links = createLinkRegistry();\n const runtime: Runtime = {\n tracker,\n delegate,\n interestOf: interest.of,\n linksOf: links.of,\n untracked: new Set(),\n };\n const hooked = client.$extends({\n name: \"quickdraw-tracking\",\n query: { $allOperations: createHook(runtime) },\n });\n root = hooked;\n const tracked = hooked.$extends({\n name: \"quickdraw-transactions\",\n client: {\n $transaction: (arg: unknown, txOptions?: unknown) =>\n transaction(tracker, hooked, arg, txOptions),\n [STORAGE_KEY]: createStorage(tracker, [interest, links], delegate, prismaSchemaOf(client)),\n },\n });\n // `Tracked<C>` is a type: the client carries no mark at run time.\n return tracked as unknown as Tracked<C>;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAyBA,IAAM,SAAS,oBAAI,QAA8B;AAGjD,SAAS,WAAW,SAAkB,OAAe,UAAwB;AAC3E,QAAM,SAAS,OAAO,IAAI,OAAO,KAAK,oBAAI,IAAY;AACtD,SAAO,IAAI,SAAS,MAAM;AAC1B,QAAM,MAAM,GAAG,KAAK,KAAS,QAAQ;AACrC,MAAI,OAAO,IAAI,GAAG,GAAG;AACnB;AAAA,EACF;AACA,SAAO,IAAI,GAAG;AACd,UAAQ,QAAQ,OAAO;AAAA,IACrB,eAAe,QAAQ,6BAA6B,KAAK;AAAA,IACzD,EAAE,UAAU,oBAAoB,OAAO,SAAS;AAAA,EAClD;AACF;AAQA,eAAsB,UACpB,SACA,OACA,KAC4B;AAC5B,QAAM,QAAQ,QAAQ,QAAQ,KAAK;AACnC,MAAI,MAAM,WAAW,KAAK,IAAI,WAAW,GAAG;AAC1C,WAAO;AAAA,EACT;AACA,QAAM,OAAO,IAAI;AAAA,IACf,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,OAAO,YAAY,MAAM,IAAI,CAAC,SAAS,CAAC,KAAK,OAAO,CAAC,CAAU,CAAC,CAAC,CAAC,CAAC;AAAA,EAC1F;AACA,aAAW,QAAQ,OAAO;AACxB,UAAM,SAAS,OAAO;AAAA,MACpB,CAAC,KAAK,OAAO,GAAG,KAAK,OAAO,EAAE,IAAI,CAAC,WAAW,CAAC,QAAQ,IAAI,CAAC;AAAA,IAC9D;AACA,QAAI;AACJ,QAAI;AACF,iBAAW,QAAQ,SAAS,KAAK,KAAK;AAAA,IACxC,QAAQ;AAEN,iBAAW,SAAS,OAAO,KAAK,KAAK;AACrC,aAAO;AAAA,IACT;AACA,QAAI;AACJ,QAAI;AACF,aAAO,MAAM;AAAA,QAAQ,MACnB,SAAS,SAAS,EAAE,OAAO,EAAE,CAAC,KAAK,KAAK,GAAG,EAAE,IAAI,CAAC,GAAG,GAAG,EAAE,EAAE,GAAG,OAAO,CAAC;AAAA,MACzE;AAAA,IACF,SAAS,OAAO;AACd,UAAI,iBAAiB,SAAS,MAAM,SAAS,+BAA+B;AAC1E,mBAAW,SAAS,OAAO,KAAK,KAAK;AACrC,eAAO;AAAA,MACT;AACA,YAAM;AAAA,IACR;AACA,eAAW,OAAO,MAAM;AACtB,YAAM,QAAQ,IAAI,KAAK,KAAK;AAC5B,UAAI,OAAO,UAAU,UAAU;AAC7B,aAAK,IAAI,KAAK,IAAI,KAAK,KAAK,GAAG,KAAK,GAAG;AAAA,MACzC;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAGO,SAAS,UAAU,QAAgC,OAAyC;AACjG,SAAO,OAAO,IAAI,CAAC,UAAU;AAC3B,UAAM,MAAM,OAAO,IAAI,MAAM,EAAE;AAC/B,WAAO,QAAQ,SAAY,QAAQ,EAAE,GAAG,OAAO,OAAO,IAAI;AAAA,EAC5D,CAAC;AACH;;;ACgCO,IAAM,cAAN,cAA0B,MAAM;AAAA,EACnB,OAAO;AAC3B;AAEA,SAAS,SAAS,OAA4D;AAC5E,SAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAC5E;AAEA,SAAS,kBAAkB,OAAyB;AAClD,SAAO,iBAAiB,SAAS,MAAM,SAAS;AAClD;AAGA,SAAS,QAAQ,IAAe,QAAsB;AACpD,MAAI,GAAG,QAAQ,UAAU,IAAI,GAAG,KAAK,GAAG;AACtC;AAAA,EACF;AACA,KAAG,QAAQ,UAAU,IAAI,GAAG,KAAK;AACjC,KAAG,QAAQ,QAAQ,OAAO;AAAA,IACxB,aAAa,GAAG,KAAK,qBAAqB,MAAM;AAAA,IAChD,EAAE,UAAU,oBAAoB,OAAO,GAAG,MAAM;AAAA,EAClD;AACF;AASA,eAAsB,aAAa,IAAe,QAAkC;AAClF,QAAM,SAAS,MAAM,GAAG,MAAM,GAAG,IAAI;AACrC,UAAQ,IAAI,MAAM;AAClB,SAAO;AACT;AAGO,SAAS,KAAK,KAA8B;AACjD,QAAM,EAAE,GAAG,IAAI;AACf,MAAI,OAAO,OAAO,UAAU;AAC1B,WAAO;AAAA,EACT;AACA,SAAO,OAAO,OAAO,YAAY,OAAO,OAAO,WAAW,OAAO,EAAE,IAAI;AACzE;AAEA,SAAS,KAAK,KAAU,SAAgD;AACtE,QAAM,UAAU,QAAQ,OAAO,CAAC,WAAW,OAAO,OAAO,KAAK,MAAM,CAAC;AACrE,SAAO,QAAQ,WAAW,IACtB,SACA,OAAO,YAAY,QAAQ,IAAI,CAAC,WAAW,CAAC,QAAQ,IAAI,MAAM,CAAC,CAAC,CAAC;AACvE;AAEA,SAAS,OAAO,MAAyB;AACvC,MAAI,MAAM,QAAQ,IAAI,GAAG;AACvB,WAAO,CAAC,GAAG,IAAI,IAAI,KAAK,QAAQ,CAAC,SAAS,OAAO,IAAI,CAAC,CAAC,CAAC;AAAA,EAC1D;AACA,SAAO,SAAS,IAAI,IAAI,OAAO,KAAK,IAAI,IAAI,CAAC;AAC/C;AAEA,SAAS,OAAO,QAAwB;AACtC,MAAI,MAAM,QAAQ,MAAM,GAAG;AACzB,WAAO,OAAO,OAAO,QAAQ;AAAA,EAC/B;AACA,SAAO,SAAS,MAAM,IAAI,CAAC,MAAM,IAAI,CAAC;AACxC;AAGA,SAAS,YAAY,MAAyB;AAC5C,SAAO,SAAS,IAAI,IAChB,OAAO,QAAQ,IAAI,EAChB,OAAO,CAAC,CAAC,EAAE,KAAK,MAAM,UAAU,MAAS,EACzC,IAAI,CAAC,CAAC,GAAG,MAAM,GAAG,IACrB,CAAC;AACP;AAGO,SAAS,cAAc,MAAwB;AACpD,SAAO,SAAS,IAAI,KAAK,YAAY,IAAI,EAAE,WAAW;AACxD;AAGA,SAAS,SAAS,IAAe,WAAmB,MAAkB;AACpE,KAAG,QAAQ,QAAQ,eAAe;AAClC,KAAG,QAAQ,QAAQ,QAAQ,EAAE,OAAO,GAAG,OAAO,WAAW,KAAK,CAAC;AACjE;AAOA,SAAS,WAAW,IAAe,MAAwB;AACzD,QAAM,SAAS,iBAAiB,IAAI;AACpC,aAAW,EAAE,OAAO,UAAU,KAAK,QAAQ;AACzC,OAAG,QAAQ,QAAQ,KAAK;AAAA,MACtB,MAAM;AAAA,MACN,SAAS,GAAG,GAAG,KAAK,IAAI,KAAK,IAAI,SAAS;AAAA,MAC1C,SAAS,mBAAmB,GAAG,KAAK,IAAI,KAAK,OAAO,SAAS,8GAA8G,GAAG,KAAK;AAAA,MACnL,MAAM,EAAE,OAAO,GAAG,OAAO,OAAO,UAAU;AAAA,IAC5C,CAAC;AAAA,EACH;AACA,SAAO,OAAO,SAAS;AACzB;AAGA,SAAS,YAAY,MAAe,SAAsC;AACxE,SAAO,CAAC,GAAG,oBAAI,IAAI,CAAC,GAAG,OAAO,IAAI,GAAG,GAAG,OAAO,CAAC,CAAC;AACnD;AAGA,SAAS,gBAAgB,IAAe,MAAyB;AAC/D,QAAM,OAAO,IAAI,IAAI,OAAO,IAAI,CAAC;AACjC,SAAO,GAAG,QAAQ,WAAW,GAAG,KAAK,EAAE,OAAO,CAAC,WAAW,KAAK,IAAI,MAAM,CAAC;AAC5E;AAGA,SAAS,MAAM,MAAY,SAA6D;AACtF,QAAM,EAAE,QAAQ,KAAK,IAAI;AACzB,MAAI,SAAS,MAAM,GAAG;AACpB,UAAM,QAAQ,QAAQ,OAAO,CAAC,WAAW,OAAO,MAAM,MAAM,IAAI;AAChE,UAAM,UAAU,EAAE,GAAG,QAAQ,GAAG,OAAO,YAAY,MAAM,IAAI,CAAC,WAAW,CAAC,QAAQ,IAAI,CAAC,CAAC,EAAE;AAC1F,WAAO,EAAE,MAAM,MAAM,WAAW,IAAI,OAAO,EAAE,GAAG,MAAM,QAAQ,QAAQ,GAAG,MAAM;AAAA,EACjF;AACA,MAAI,SAAS,IAAI,GAAG;AAClB,UAAM,QAAQ,QAAQ,OAAO,CAAC,WAAW,KAAK,MAAM,MAAM,IAAI;AAC9D,UAAM,UAAU,EAAE,GAAG,MAAM,GAAG,OAAO,YAAY,MAAM,IAAI,CAAC,WAAW,CAAC,QAAQ,KAAK,CAAC,CAAC,EAAE;AACzF,WAAO,EAAE,MAAM,MAAM,WAAW,IAAI,OAAO,EAAE,GAAG,MAAM,MAAM,QAAQ,GAAG,MAAM;AAAA,EAC/E;AACA,SAAO,EAAE,MAAM,OAAO,CAAC,EAAE;AAC3B;AAEA,SAAS,MAAM,QAAiB,OAAmC;AACjE,QAAM,UAAU,CAAC,QACf,SAAS,GAAG,IACR,OAAO,YAAY,OAAO,QAAQ,GAAG,EAAE,OAAO,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,CAAC,IAC9E;AACN,SAAO,MAAM,QAAQ,MAAM,IAAI,OAAO,IAAI,OAAO,IAAI,QAAQ,MAAM;AACrE;AAQA,eAAe,WAAW,IAA0D;AAClF,QAAM,EAAE,MAAM,MAAM,IAAI,MAAM,GAAG,MAAM,CAAC,MAAM,GAAG,GAAG,QAAQ,WAAW,GAAG,KAAK,CAAC,CAAC;AACjF,MAAI,MAAM,WAAW,GAAG;AACtB,UAAMA,UAAS,MAAM,GAAG,MAAM,GAAG,IAAI;AACrC,WAAO,EAAE,QAAAA,SAAQ,MAAM,OAAOA,OAAM,EAAE;AAAA,EACxC;AACA,MAAI;AACJ,MAAI;AACF,aAAS,MAAM,GAAG,MAAM,IAAI;AAAA,EAC9B,SAAS,OAAO;AACd,QAAI,CAAC,kBAAkB,KAAK,GAAG;AAC7B,YAAM;AAAA,IACR;AACA,WAAO,EAAE,QAAQ,MAAM,aAAa,IAAI,yBAAyB,GAAG,MAAM,CAAC,EAAE;AAAA,EAC/E;AACA,SAAO,EAAE,QAAQ,MAAM,QAAQ,KAAK,GAAG,MAAM,OAAO,MAAM,EAAE;AAC9D;AAQA,SAAS,cAAc,IAAqB;AAC1C,MAAI,CAAC,GAAG,QAAQ,QAAQ,QAAQ,GAAG;AACjC;AAAA,EACF;AACA,KAAG,QAAQ,QAAQ,KAAK;AAAA,IACtB,MAAM;AAAA,IACN,SAAS,GAAG,GAAG,KAAK,IAAI,GAAG,SAAS;AAAA,IACpC,SAAS,GAAG,GAAG,SAAS,OAAO,GAAG,KAAK;AAAA,IACvC,MAAM,EAAE,OAAO,GAAG,OAAO,WAAW,GAAG,UAAU;AAAA,EACnD,CAAC;AACH;AAOA,eAAe,WACb,IACA,OACA,SACA,SAC8B;AAC9B,gBAAc,EAAE;AAChB,QAAM,SAAS,OAAO,YAAY,CAAC,MAAM,GAAG,OAAO,EAAE,IAAI,CAAC,WAAW,CAAC,QAAQ,IAAI,CAAC,CAAC;AACpF,QAAM,WAAW,GAAG,QAAQ,SAAS,GAAG,KAAK;AAC7C,MAAI;AACJ,MAAI;AACF,QAAI,QAAQ,QAAQ;AAClB,YAAM,MAAM,MAAM,QAAQ,MAAM,SAAS,WAAW,EAAE,OAAO,OAAO,CAAC,CAAC;AACtE,aAAO,QAAQ,OAAO,CAAC,IAAI,CAAC,GAAG;AAAA,IACjC,OAAO;AACL,aAAO,MAAM;AAAA,QAAQ,MACnB,SAAS,SAAS;AAAA,UAChB;AAAA,UACA;AAAA,UACA,GAAI,QAAQ,SAAS,SAAY,CAAC,IAAI,EAAE,MAAM,QAAQ,KAAK;AAAA,QAC7D,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF,SAAS,OAAO;AACd,QAAI,kBAAkB,KAAK,GAAG;AAC5B,YAAM,IAAI,YAAY,yBAAyB,EAAE,OAAO,MAAM,CAAC;AAAA,IACjE;AACA,UAAM;AAAA,EACR;AACA,QAAM,SAAS,oBAAI,IAAoB;AACvC,aAAW,OAAO,MAAM;AACtB,UAAM,KAAK,KAAK,GAAG;AACnB,QAAI,OAAO,QAAW;AACpB,aAAO,IAAI,IAAI,KAAK,KAAK,OAAO,KAAK,CAAC,CAAC;AAAA,IACzC;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,SACP,IACA,MACA,MACA,QACA,QACe;AACf,QAAM,WAAW,GAAG,QAAQ,WAAW,GAAG,KAAK;AAC/C,QAAM,SAAwB,CAAC;AAC/B,aAAW,OAAO,MAAM;AACtB,UAAM,KAAK,KAAK,GAAG;AACnB,QAAI,OAAO,QAAW;AACpB,cAAQ,IAAI,qBAAqB;AACjC,aAAO,CAAC;AAAA,IACV;AACA,UAAM,SAAS,KAAK,KAAK,QAAQ;AACjC,UAAM,MAAM,SAAS,WAAW,SAAS,QAAQ,IAAI,EAAE;AACvD,UAAM,QAAQ,SAAS,WAAW,SAAY;AAC9C,WAAO,KAAK;AAAA,MACV,OAAO,GAAG;AAAA,MACV;AAAA,MACA,IAAI;AAAA,MACJ;AAAA,MACA,GAAI,QAAQ,UAAa,OAAO,KAAK,GAAG,EAAE,WAAW,IAAI,CAAC,IAAI,EAAE,QAAQ,IAAI;AAAA,MAC5E,GAAI,UAAU,SAAY,CAAC,IAAI,EAAE,MAAM;AAAA,IACzC,CAAC;AAAA,EACH;AACA,SAAO;AACT;AAEA,SAAS,OAAO,IAAe,QAAsC;AACnE,KAAG,QAAQ,QAAQ,OAAO,MAAM;AAClC;AAEA,eAAe,OAAO,IAAiC;AACrD,aAAW,IAAI,GAAG,KAAK,IAAI;AAC3B,QAAM,EAAE,QAAQ,KAAK,IAAI,MAAM,WAAW,EAAE;AAC5C,SAAO,IAAI,SAAS,IAAI,UAAU,MAAM,OAAO,GAAG,KAAK,IAAI,CAAC,CAAC;AAC7D,SAAO;AACT;AAGA,SAAS,YAAY,MAAkB;AACrC,SAAO,OAAO;AAAA,IACZ,CAAC,UAAU,WAAW,MAAM,EACzB,OAAO,CAAC,QAAQ,KAAK,GAAG,MAAM,MAAS,EACvC,IAAI,CAAC,QAAQ,CAAC,KAAK,KAAK,GAAG,CAAC,CAAC;AAAA,EAClC;AACF;AAOA,eAAe,oBAAoB,IAAiC;AAClE,aAAW,IAAI,GAAG,KAAK,MAAM;AAC7B,QAAM,EAAE,MAAM,MAAM,IAAI,MAAM,GAAG,MAAM,CAAC,MAAM,GAAG,GAAG,QAAQ,WAAW,GAAG,KAAK,CAAC,CAAC;AACjF,MAAI;AACJ,MAAI;AAEF,YAAQ,MAAM,GAAG,QACd,SAAS,GAAG,KAAK,EACjB,WAAW,EAAE,OAAO,GAAG,KAAK,OAAO,GAAG,YAAY,IAAI,EAAE,CAAC;AAAA,EAC9D,SAAS,OAAO;AACd,QAAI,CAAC,kBAAkB,KAAK,GAAG;AAC7B,YAAM;AAAA,IACR;AAEA,WAAO,aAAa,IAAI,uBAAuB;AAAA,EACjD;AACA,MAAI,UAAU,MAAM;AAElB,WAAO,MAAM,OAAO,KAAK;AAAA,EAC3B;AACA,WAAS,IAAI,GAAG,WAAW,GAAG,IAAI;AAClC,QAAM,EAAE,QAAQ,KAAK,IAAI,MAAM,WAAW,EAAE;AAE5C,QAAM,SAAS,SAAS,IAAI,UAAU,MAAM,OAAO,GAAG,KAAK,MAAM,CAAC;AAClE;AAAA,IACE;AAAA,IACA,OAAO,IAAI,CAAC,WAAW,EAAE,GAAG,OAAO,gBAAgB,KAAc,EAAE;AAAA,EACrE;AACA,SAAO;AACT;AAEA,eAAe,OAAO,IAAiC;AACrD,MAAI,cAAc,GAAG,KAAK,MAAM,KAAK,CAAC,GAAG,QAAQ,QAAQ,QAAQ,GAAG;AAClE,WAAO,oBAAoB,EAAE;AAAA,EAC/B;AACA,aAAW,IAAI,GAAG,KAAK,MAAM;AAE7B,QAAM,SAAS,WAAW,IAAI,GAAG,KAAK,MAAM;AAC5C,QAAM,UAAU,SACZ,CAAC,GAAG,GAAG,QAAQ,WAAW,GAAG,KAAK,CAAC,IACnC,gBAAgB,IAAI,GAAG,KAAK,MAAM;AAEtC,QAAM,SACJ,QAAQ,WAAW,IACf,SACA,MAAM,WAAW,IAAI,GAAG,KAAK,OAAO,SAAS,EAAE,QAAQ,KAAK,CAAC;AACnE,QAAM,EAAE,QAAQ,KAAK,IAAI,MAAM,WAAW,EAAE;AAC5C,MAAI,WAAW,UAAa,OAAO,OAAO,GAAG;AAC3C,UAAM,SAAS,SAAS,YAAY,GAAG,KAAK,QAAQ,OAAO,IAAI,OAAO,GAAG,KAAK,MAAM;AACpF,WAAO,IAAI,SAAS,IAAI,UAAU,MAAM,QAAQ,MAAM,CAAC;AAAA,EACzD,WAAW,WAAW,QAAW;AAE/B,UAAM,SAAS,SAAS,IAAI,UAAU,MAAM,OAAO,CAAC,GAAG,KAAK,QAAQ,GAAG,KAAK,MAAM,CAAC,CAAC;AACpF;AAAA,MACE;AAAA,MACA,OAAO,IAAI,CAAC,WAAW,EAAE,GAAG,OAAO,gBAAgB,KAAc,EAAE;AAAA,IACrE;AAAA,EACF,OAAO;AACL,WAAO,IAAI,SAAS,IAAI,UAAU,MAAM,OAAO,GAAG,KAAK,MAAM,CAAC,CAAC;AAAA,EACjE;AACA,SAAO;AACT;AAEA,eAAe,OAAO,IAAiC;AACrD,MAAI,cAAc,GAAG,KAAK,IAAI,GAAG;AAE/B,WAAO,GAAG,MAAM,GAAG,IAAI;AAAA,EACzB;AAEA,QAAM,SAAS,WAAW,IAAI,GAAG,KAAK,IAAI;AAC1C,QAAM,UAAU,SAAS,CAAC,GAAG,GAAG,QAAQ,WAAW,GAAG,KAAK,CAAC,IAAI,gBAAgB,IAAI,GAAG,KAAK,IAAI;AAChG,QAAM,SACJ,QAAQ,WAAW,IACf,SACA,MAAM,WAAW,IAAI,GAAG,KAAK,OAAO,SAAS,EAAE,QAAQ,KAAK,CAAC;AACnE,QAAM,EAAE,QAAQ,KAAK,IAAI,MAAM,WAAW,EAAE;AAC5C,QAAM,SAAS,SAAS,YAAY,GAAG,KAAK,MAAM,OAAO,IAAI,OAAO,GAAG,KAAK,IAAI;AAChF,SAAO,IAAI,SAAS,IAAI,UAAU,MAAM,QAAQ,MAAM,CAAC;AACvD,SAAO;AACT;AAGA,eAAe,cAAc,IAA2C;AACtE,MAAI,GAAG,QAAQ,QAAQ,GAAG,KAAK,EAAE,WAAW,GAAG;AAC7C,WAAO;AAAA,EACT;AACA,gBAAc,EAAE;AAChB,QAAM,EAAE,MAAM,IAAI,GAAG;AACrB,QAAM,MACJ,SAAS,KAAK,KAAK,OAAO,MAAM,OAAO,WACnC,CAAC,MAAM,EAAE,IACT,CAAC,IAAI,MAAM,WAAW,IAAI,OAAO,CAAC,GAAG,EAAE,QAAQ,KAAK,CAAC,GAAG,KAAK,CAAC;AACpE,SAAO,MAAM,UAAU,GAAG,SAAS,GAAG,OAAO,GAAG;AAClD;AAEA,eAAe,OAAO,IAAiC;AACrD,QAAM,QAAQ,MAAM,cAAc,EAAE;AACpC,QAAM,EAAE,QAAQ,KAAK,IAAI,MAAM,WAAW,EAAE;AAC5C,SAAO,IAAI,UAAU,SAAS,IAAI,UAAU,MAAM,CAAC,CAAC,GAAG,KAAK,CAAC;AAC7D,SAAO;AACT;AAEA,eAAe,oBAAoB,IAAiC;AAClE,QAAM,EAAE,QAAQ,KAAK,IAAI,MAAM,WAAW,EAAE;AAC5C,SAAO,IAAI,SAAS,IAAI,UAAU,MAAM,OAAO,GAAG,KAAK,IAAI,CAAC,CAAC;AAC7D,SAAO;AACT;AAEA,eAAe,oBAAoB,IAAiC;AAClE,MAAI,cAAc,GAAG,KAAK,IAAI,GAAG;AAE/B,WAAO,GAAG,MAAM,GAAG,IAAI;AAAA,EACzB;AACA,QAAM,UAAU,gBAAgB,IAAI,GAAG,KAAK,IAAI;AAChD,QAAM,SACJ,QAAQ,WAAW,IACf,SACA,MAAM,WAAW,IAAI,GAAG,KAAK,OAAO,SAAS,EAAE,QAAQ,MAAM,CAAC;AACpE,QAAM,EAAE,QAAQ,KAAK,IAAI,MAAM,WAAW,EAAE;AAE5C,SAAO,IAAI,SAAS,IAAI,UAAU,MAAM,OAAO,GAAG,KAAK,IAAI,GAAG,MAAM,CAAC;AACrE,SAAO;AACT;AAGA,eAAe,kBAAkB,IAAiC;AAChE,QAAM,SAAS,MAAM,QAAQ,GAAG,KAAK,IAAI,IAAI,GAAG,KAAK,OAAO,CAAC,GAAG,KAAK,IAAI,GAAG,OAAO,QAAQ;AAC3F,QAAM,SAAS,MAAM,GAAG,MAAM,GAAG,IAAI;AACrC,QAAM,OAAO,MAAM,OAAO,CAAC,SAAS,KAAK,IAAI,MAAM,MAAS;AAC5D,MAAI,KAAK,WAAW,MAAM,QAAQ;AAChC,WAAO,IAAI,SAAS,IAAI,UAAU,MAAM,OAAO,GAAG,KAAK,IAAI,CAAC,CAAC;AAAA,EAC/D,OAAO;AACL,OAAG,QAAQ,QAAQ,KAAK;AAAA,MACtB,MAAM;AAAA,MACN,SAAS,GAAG;AAAA,MACZ,SAAS,iBAAiB,GAAG,KAAK;AAAA,MAClC,MAAM,EAAE,OAAO,GAAG,MAAM;AAAA,IAC1B,CAAC;AAAA,EACH;AACA,SAAO;AACT;AAOA,eAAe,kBAAkB,IAAiC;AAChE,MAAI,cAAc,GAAG,KAAK,IAAI,GAAG;AAC/B,WAAO,GAAG,MAAM,GAAG,IAAI;AAAA,EACzB;AACA,QAAM,SAAS,MAAM,WAAW,IAAI,GAAG,KAAK,OAAO,gBAAgB,IAAI,GAAG,KAAK,IAAI,GAAG;AAAA,IACpF,QAAQ;AAAA,EACV,CAAC;AACD,QAAM,SAAS,MAAM,GAAG,MAAM,GAAG,IAAI;AAErC,MAAI,SAAS,MAAM,KAAK,OAAO,UAAU,GAAG;AAC1C,WAAO;AAAA,EACT;AACA,QAAM,OAAO,CAAC,GAAG,OAAO,KAAK,CAAC,EAAE,IAAI,CAAC,QAAQ,EAAE,GAAG,EAAE;AACpD,SAAO,IAAI,SAAS,IAAI,UAAU,MAAM,OAAO,GAAG,KAAK,IAAI,GAAG,MAAM,CAAC;AACrE,SAAO;AACT;AAOA,eAAe,QACb,IACA,KACkB;AAClB,MAAI;AACJ,MAAI;AACF,WAAO,MAAM,IAAI,GAAG,QAAQ,SAAS,GAAG,KAAK,GAAG,EAAE,GAAG,GAAG,MAAM,QAAQ,EAAE,IAAI,KAAK,EAAE,CAAC;AAAA,EACtF,SAAS,OAAO;AACd,QAAI,CAAC,kBAAkB,KAAK,GAAG;AAC7B,YAAM;AAAA,IACR;AACA,OAAG,QAAQ,QAAQ,eAAe;AAClC,WAAO,aAAa,IAAI,yBAAyB;AAAA,EACnD;AACA,SAAO,EAAE,OAAO,KAAK,OAAO;AAC9B;AAEA,SAAS,WAAW,IAAiC;AACnD,MAAI,GAAG,QAAQ,QAAQ,QAAQ,GAAG;AAChC,WAAO,kBAAkB,EAAE;AAAA,EAC7B;AACA,SAAO,QAAQ,IAAI,CAAC,UAAU,SAAS,SAAS,oBAAoB,IAAI,CAAC;AAC3E;AAEA,SAAS,WAAW,IAAiC;AACnD,MAAI,GAAG,QAAQ,QAAQ,QAAQ,GAAG;AAChC,WAAO,kBAAkB,EAAE;AAAA,EAC7B;AACA,MAAI,cAAc,GAAG,KAAK,IAAI,GAAG;AAE/B,WAAO,GAAG,MAAM,GAAG,IAAI;AAAA,EACzB;AACA,SAAO,QAAQ,IAAI,CAAC,UAAU,SAAS,SAAS,oBAAoB,IAAI,CAAC;AAC3E;AAEA,eAAe,WAAW,IAAiC;AACzD,QAAM,EAAE,OAAO,MAAM,IAAI,GAAG;AAC5B,QAAM,WAAW,GAAG,QAAQ,WAAW,GAAG,KAAK;AAC/C,QAAM,SAAS,MAAM,WAAW,IAAI,OAAO,UAAU,EAAE,QAAQ,OAAO,MAAM,MAAM,CAAC;AACnF,QAAM,MAAM,CAAC,GAAG,OAAO,KAAK,CAAC;AAC7B,QAAM,QAAQ,MAAM,UAAU,GAAG,SAAS,GAAG,OAAO,GAAG;AAEvD,QAAM,OACJ,UAAU,SACN,GAAG,OACH,EAAE,GAAG,GAAG,MAAM,OAAO,EAAE,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,IAAI,IAAI,EAAE,CAAC,EAAE,EAAE;AACvE,QAAM,SAAS,MAAM,GAAG,MAAM,IAAI;AAClC,QAAM,OAAO,IAAI,IAAI,CAAC,QAAQ,EAAE,IAAI,GAAG,OAAO,IAAI,EAAE,EAAE,EAAE;AACxD,SAAO,IAAI,UAAU,SAAS,IAAI,UAAU,MAAM,CAAC,CAAC,GAAG,KAAK,CAAC;AAC7D,SAAO;AACT;AAMO,IAAM,mBACX,OAAO,OAAO;AAAA,EACZ;AAAA,EACA;AAAA,EACA;AAAA,EACA,QAAQ;AAAA,EACR;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAQI,SAAS,UAAU,SAAkB,WAAmB,MAAiC;AAC9F,MAAI,QAAQ,QAAQ,QAAQ,GAAG;AAC7B,WAAO;AAAA,EACT;AACA,UAAQ,WAAW;AAAA,IACjB,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO,CAAC,cAAc,MAAM,IAAI;AAAA,IAClC,KAAK;AACH,aAAO,cAAc,MAAM,MAAM;AAAA,IACnC;AACE,aAAO;AAAA,EACX;AACF;;;ACzmBA,IAAM,cAAc;AAEpB,IAAM,QAAQ;AAEd,IAAM,UAAU;AAGhB,IAAM,YAAiC,oBAAI,IAAI,CAAC,UAAU,OAAO,UAAU,OAAO,CAAC;AAEnF,IAAM,eAAoC,oBAAI,IAAI,CAAC,UAAU,MAAM,CAAC;AAEpE,SAAS,SAAS,OAAiC;AACjD,UAAQ,OAAO,UAAU,YAAY,OAAO,UAAU,eAAe,UAAU;AACjF;AAGA,SAAS,eAAe,MAAsB;AAC5C,MAAI,WAAW;AACf,WAAS,QAAQ,GAAG,QAAQ,KAAK,QAAQ,SAAS,GAAG;AACnD,UAAM,OAAO,KAAK,KAAK;AACvB,QAAI,SAAS,OAAO,KAAK,QAAQ,CAAC,MAAM,MAAM;AAC5C,iBAAW,CAAC;AAAA,IACd,WAAW,CAAC,YAAY,SAAS,OAAO,KAAK,QAAQ,CAAC,MAAM,KAAK;AAC/D,aAAO,KAAK,MAAM,GAAG,KAAK;AAAA,IAC5B;AAAA,EACF;AACA,SAAO;AACT;AAGA,SAAS,SAAS,MAAuB;AACvC,QAAM,SAAkB,CAAC;AACzB,MAAI;AACJ,aAAW,OAAO,KAAK,MAAM,OAAO,GAAG;AACrC,UAAM,OAAO,eAAe,GAAG,EAAE,KAAK;AACtC,QAAI,SAAS,IAAI;AACf;AAAA,IACF;AACA,QAAI,SAAS,QAAW;AACtB,UAAI,SAAS,KAAK;AAChB,eAAO;AAAA,MACT,OAAO;AACL,aAAK,MAAM,KAAK,IAAI;AAAA,MACtB;AACA;AAAA,IACF;AACA,UAAM,QAAQ,YAAY,KAAK,IAAI;AACnC,QAAI,UAAU,MAAM;AAClB,YAAM,QAAe,EAAE,MAAM,MAAM,CAAC,KAAK,IAAI,MAAM,MAAM,CAAC,KAAK,IAAI,OAAO,CAAC,EAAE;AAC7E,aAAO,KAAK,KAAK;AAEjB,aAAO,KAAK,MAAM,MAAM,CAAC,EAAE,MAAM,EAAE,KAAK,MAAM,MAAM,SAAY;AAAA,IAClE;AAAA,EACF;AACA,SAAO;AACT;AAGA,SAAS,QAAQ,kBAA2B,OAAuC;AACjF,QAAM,SAAkB,SAAS,gBAAgB,IAC7C,QAAQ,IAAI,kBAAkB,QAAQ,IACtC;AACJ,QAAM,QACJ,SAAS,MAAM,KAAK,OAAO,OAAO,QAAQ,KAAK,IAAI,QAAQ,IAAI,QAAQ,KAAK,IAAI;AAClF,QAAM,SAAkB,SAAS,KAAK,IAAI,QAAQ,IAAI,OAAO,QAAQ,IAAI;AACzE,MAAI,CAAC,MAAM,QAAQ,MAAM,GAAG;AAC1B,WAAO;AAAA,EACT;AACA,QAAM,QAAQ,oBAAI,IAAoB;AACtC,aAAW,SAAS,QAAqB;AACvC,UAAM,OAAgB,SAAS,KAAK,IAAI,QAAQ,IAAI,OAAO,MAAM,IAAI;AACrE,UAAM,OAAgB,SAAS,KAAK,IAAI,QAAQ,IAAI,OAAO,MAAM,IAAI;AACrE,QAAI,OAAO,SAAS,YAAY,OAAO,SAAS,UAAU;AACxD,YAAM,IAAI,MAAM,IAAI;AAAA,IACtB;AAAA,EACF;AACA,SAAO;AACT;AAOA,SAAS,SACP,MACA,MACA,OACA,SACS;AACT,MAAI,UAAU,QAAW;AACvB,WAAO,aAAa,IAAI,MAAM,IAAI,IAAI,KAAK,EAAE;AAAA,EAC/C;AACA,SAAO,SAAS,iBAAiB,CAAC,QAAQ,IAAI,IAAI;AACpD;AAEA,SAAS,YACP,QACA,OACA,OACqB;AACrB,QAAM,KAAK,OAAO,IAAI,IAAI;AAC1B,MAAI,OAAO,QAAW;AAEpB,WAAO,UAAU,UAAa,aAAa,IAAI,MAAM,IAAI,IAAI,KAAK,EAAE,IAAI,SAAY;AAAA,EACtF;AACA,MAAI,GAAG,YAAY,GAAG,MAAM;AAC1B,WAAO;AAAA,EACT;AACA,SAAO,UAAU,IAAI,GAAG,IAAI,KAAK,MAAM,IAAI,GAAG,IAAI,IAAI,OAAO;AAC/D;AAEA,SAAS,QACP,OACA,OACA,SACA,OACa;AACb,QAAM,SAAS,oBAAI,IAAyB;AAC5C,aAAW,QAAQ,MAAM,OAAO;AAC9B,UAAM,QAAQ,MAAM,KAAK,IAAI;AAC7B,UAAM,CAAC,EAAE,OAAO,IAAI,OAAO,IAAI,EAAE,MAAM,QAAQ,IAAI,SAAS,CAAC;AAC7D,QAAI,UAAU,QAAQ,CAAC,QAAQ,KAAK,IAAI,KAAK,SAAS,MAAM,MAAM,OAAO,OAAO,GAAG;AACjF,aAAO,IAAI,MAAM,EAAE,MAAM,UAAU,aAAa,QAAW,MAAM,SAAS,OAAU,CAAC;AAAA,IACvF;AAAA,EACF;AACA,SAAO,EAAE,QAAQ,WAAW,YAAY,QAAQ,OAAO,KAAK,EAAE;AAChE;AASO,SAAS,kBAAkB,MAAc,kBAA+C;AAC7F,QAAM,SAAS,SAAS,IAAI;AAC5B,QAAM,QAAQ,IAAI,UAChB,IAAI,IAAI,OAAO,OAAO,CAAC,UAAU,MAAM,SAAS,MAAM,IAAI,CAAC,EAAE,IAAI,CAAC,UAAU,MAAM,IAAI,CAAC;AACzF,QAAM,QAAQ,MAAM,MAAM;AAC1B,QAAM,UAAU,MAAM,SAAS,QAAQ,MAAM;AAC7C,QAAM,SAAS,oBAAI,IAAyB;AAC5C,aAAW,SAAS,QAAQ;AAC1B,UAAM,UAAU,MAAM,MAAM,KAAK,CAAC,SAAS,cAAc,KAAK,IAAI,CAAC;AACnE,SAAK,MAAM,SAAS,WAAW,MAAM,SAAS,WAAW,CAAC,SAAS;AACjE,YAAM,QAAQ,QAAQ,kBAAkB,MAAM,IAAI;AAClD,aAAO,IAAI,SAAS,MAAM,IAAI,GAAG,QAAQ,OAAO,OAAO,SAAS,KAAK,CAAC;AAAA,IACxE;AAAA,EACF;AACA,SAAO,OAAO,OAAO;AAAA,IACnB,SAAS,OAAe,QAAqC;AAC3D,YAAM,QAAQ,OAAO,IAAI,SAAS,KAAK,CAAC,GAAG,OAAO,IAAI,MAAM;AAC5D,aAAO,UAAU,SAAY,SAAY,MAAM,YAAY,CAAC,MAAM;AAAA,IACpE;AAAA,IACA,WAAW,CAAC,UAAuC,OAAO,IAAI,SAAS,KAAK,CAAC,GAAG;AAAA,EAClF,CAAC;AACH;AAMO,SAAS,aAAa,QAAqC;AAChE,MAAI;AACF,UAAM,SAAkB,SAAS,MAAM,IAAI,QAAQ,IAAI,QAAQ,eAAe,IAAI;AAClF,UAAM,OAAgB,SAAS,MAAM,IAAI,QAAQ,IAAI,QAAQ,cAAc,IAAI;AAC/E,WAAO,OAAO,SAAS,YAAY,SAAS,KAAK,OAAO;AAAA,EAC1D,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAGA,SAAS,mBAAmB,QAA0B;AACpD,MAAI;AACF,UAAM,MAAe,SAAS,MAAM,IAAI,QAAQ,IAAI,QAAQ,mBAAmB,IAAI;AACnF,QAAI,QAAQ,QAAW;AACrB,aAAO;AAAA,IACT;AACA,UAAM,SAAkB,SAAS,MAAM,IAAI,QAAQ,IAAI,QAAQ,eAAe,IAAI;AAClF,WAAO,SAAS,MAAM,IAAI,QAAQ,IAAI,QAAQ,kBAAkB,IAAI;AAAA,EACtE,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAGO,SAAS,eAAe,QAAgD;AAC7E,QAAM,OAAO,aAAa,MAAM;AAChC,SAAO,SAAS,SAAY,SAAY,kBAAkB,MAAM,mBAAmB,MAAM,CAAC;AAC5F;;;ACvJA,SAAS,SAAS,OAA2C;AAC3D,UACG,OAAO,UAAU,YAAY,OAAO,UAAU,eAC/C,UAAU,QACV,OAAO,QAAQ,IAAI,OAAO,UAAU,MAAM;AAE9C;AAEA,SAAS,WAAW,QAAiB,OAAyB;AAC5D,QAAM,WACJ,OAAO,WAAW,YAAY,WAAW,OAAO,QAAQ,IAAI,QAAQ,KAAK,IAAI;AAC/E,MAAI,OAAO,aAAa,YAAY,aAAa,MAAM;AACrD,UAAM,IAAI,UAAU,2CAA2C,KAAK,GAAG;AAAA,EACzE;AACA,SAAO;AACT;AAGA,SAAS,MACP,SACA,OACA,WACA,MACM;AACN,UAAQ,QAAQ,eAAe;AAC/B,MAAI,UAAU,QAAW;AACvB,YAAQ,QAAQ,QAAQ,EAAE,OAAO,SAAS,KAAK,GAAG,WAAW,KAAK,CAAC;AAAA,EACrE;AACF;AAEA,SAAS,WAAW,SAAkB;AACpC,SAAO,eAAe,MAAM,EAAE,OAAO,WAAW,MAAM,MAAM,GAAoC;AAC9F,UAAM,UAAU,UAAU,SAAY,SAAY,iBAAiB,SAAS;AAC5E,QAAI,UAAU,UAAa,YAAY,UAAa,QAAQ,UAAU,IAAI,SAAS,KAAK,CAAC,GAAG;AAC1F,YAAM,SAAS,OAAO,WAAW,IAAI;AACrC,aAAO,MAAM,IAAI;AAAA,IACnB;AACA,QAAI,CAAC,UAAU,SAAS,WAAW,IAAI,GAAG;AACxC,YAAM,SAAS,OAAO,WAAW,IAAI;AAAA,IACvC;AACA,UAAM,KAAgB,EAAE,SAAS,OAAO,SAAS,KAAK,GAAG,WAAW,MAAM,QAAQ,CAAC,GAAG,MAAM;AAC5F,QAAI;AACF,aAAO,MAAM,QAAQ,EAAE;AAAA,IACzB,SAAS,OAAO;AACd,UAAI,iBAAiB,aAAa;AAChC,eAAO,aAAa,IAAI,MAAM,OAAO;AAAA,MACvC;AACA,YAAM;AAAA,IACR;AAAA,EACF;AACF;AAGA,eAAe,YACb,SACA,QACA,KACA,SACkB;AAClB,QAAM,cAAc,OAAO,QAAQ;AACnC,QAAM,QAAQ,QAAQ,gBAAgB,cAAc,gBAAgB,OAAO;AAC3E,MAAI;AACF,UAAM,SAAS,cACX,MAAM,OAAO,aAAa,CAAC,WAAoB;AAC7C,YAAM,UAAU,MAAM;AACtB,aAAO,MAAM,IAAI,MAAO,IAAqC,MAAM,CAAC;AAAA,IACtE,GAAG,OAAO,IACV,MAAM,MAAM,IAAI,MAAM,OAAO,aAAa,KAAK,OAAO,CAAC;AAC3D,UAAM,OAAO;AACb,WAAO;AAAA,EACT,SAAS,OAAO;AACd,UAAM,SAAS;AACf,UAAM;AAAA,EACR;AACF;AAUA,SAAS,kBACP,UACA,QACqD;AACrD,QAAM,QAAQ,oBAAI,IAAqB;AACvC,SAAO,OAAO,OAAO,WAAW;AAC9B,UAAM,WAAW,QAAQ,SAAS,OAAO,MAAM;AAC/C,QAAI,aAAa,QAAW;AAC1B,aAAO;AAAA,IACT;AACA,UAAM,MAAM,GAAG,SAAS,KAAK,CAAC,KAAS,MAAM;AAC7C,UAAM,OAAO,MAAM,IAAI,GAAG;AAC1B,QAAI,SAAS,QAAW;AACtB,aAAO;AAAA,IACT;AACA,QAAI,WAAW;AACf,QAAI;AACF,YAAM,QAAQ,MAAM,SAAS,SAAS,KAAK,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,MAAM,GAAG,KAAK,EAAE,CAAC,CAAC;AAAA,IACpF,SAAS,OAAO;AACd,UAAI,EAAE,iBAAiB,SAAS,MAAM,SAAS,gCAAgC;AAC7E,cAAM;AAAA,MACR;AACA,iBAAW;AAAA,IACb;AACA,UAAM,IAAI,KAAK,QAAQ;AACvB,WAAO;AAAA,EACT;AACF;AAWA,SAAS,mBACP,UACA,QACqC;AACrC,QAAM,QAAQ,oBAAI,IAA8B;AAChD,QAAM,QAAQ,OAAO,QAAkC;AACrD,QAAI;AACF,YAAM,OAAO,MAAM,QAAQ,MAAM,SAAS,GAAG,EAAE,SAAS,EAAE,QAAQ,EAAE,IAAI,KAAK,GAAG,MAAM,EAAE,CAAC,CAAC;AAC1F,YAAM,CAAC,GAAG,IAAI,MAAM,QAAQ,IAAI,IAAK,OAA+C,CAAC;AACrF,aAAO,QAAQ,UAAa,KAAK,GAAG,MAAM;AAAA,IAC5C,SAAS,OAAO;AACd,UAAI,iBAAiB,SAAS,MAAM,SAAS,+BAA+B;AAC1E,eAAO;AAAA,MACT;AACA,YAAM;AAAA,IACR;AAAA,EACF;AACA,SAAO,OAAO,UAAU;AACtB,UAAM,WAAW,QAAQ,UAAU,KAAK;AACxC,QAAI,aAAa,QAAW;AAC1B,aAAO;AAAA,IACT;AACA,UAAM,MAAM,SAAS,KAAK;AAC1B,QAAI,SAAS,MAAM,IAAI,GAAG;AAC1B,QAAI,WAAW,QAAW;AACxB,eAAS,MAAM,GAAG;AAClB,YAAM,IAAI,KAAK,MAAM;AACrB,aAAO,MAAM,MAAM;AACjB,cAAM,OAAO,GAAG;AAAA,MAClB,CAAC;AAAA,IACH;AACA,WAAO,MAAM;AAAA,EACf;AACF;AAOA,SAAS,cACP,SACA,CAAC,UAAU,KAAK,GAIhB,UACA,QACgB;AAChB,SAAO,OAAO,OAAO;AAAA,IACnB,UAAU,CAAC,OAAe,OAAqB,CAAC,MAC9C,QAAQ,MAAM,SAAS,SAAS,KAAK,CAAC,EAAE,SAAS,IAAY,CAAC;AAAA,IAChE,OAAO,CAAC,OAAe,OAAkB,CAAC,MACxC,QAAQ,MAAM,SAAS,SAAS,KAAK,CAAC,EAAE,MAAM,IAAY,CAAC;AAAA,IAC7D,SAAS,QAAQ;AAAA,IACjB,iBAAiB,QAAQ;AAAA,IACzB,kBAAkB,SAAS;AAAA,IAC3B,YAAY,SAAS;AAAA,IACrB,eAAe,MAAM;AAAA,IACrB,SAAS,MAAM;AAAA,IACf,eAAe,MAAM,QAAQ,kBAAkB,MAAM,UAAa,QAAQ,QAAQ;AAAA,IAClF,UAAU,kBAAkB,UAAU,MAAM;AAAA,IAC5C,WAAW,mBAAmB,UAAU,MAAM;AAAA,IAC9C,YAAY,QAAQ;AAAA,EACtB,CAAC;AACH;AA2BO,SAAS,YACd,QACA,UAA8B,CAAC,GACnB;AACZ,MAAI,CAAC,SAAS,MAAM,GAAG;AACrB,UAAM,IAAI,UAAU,6CAA6C;AAAA,EACnE;AACA,MAAI,UAAU,MAAM,MAAM,QAAW;AACnC,UAAM,IAAI,UAAU,wEAAwE;AAAA,EAC9F;AACA,QAAM,UAAU,mBAAmB;AAAA,IACjC,QAAQ,QAAQ,UAAU;AAAA,IAC1B,aAAa,QAAQ;AAAA,EACvB,CAAC;AACD,QAAM,WAAW,uBAAuB,QAAQ,QAAQ;AAExD,MAAI;AACJ,QAAM,WAAW,CAAC,UAChB,WAAW,QAAQ,kBAAkB,KAAK,MAAM,KAAK;AACvD,QAAM,QAAQ,mBAAmB;AACjC,QAAM,UAAmB;AAAA,IACvB;AAAA,IACA;AAAA,IACA,YAAY,SAAS;AAAA,IACrB,SAAS,MAAM;AAAA,IACf,WAAW,oBAAI,IAAI;AAAA,EACrB;AACA,QAAM,SAAS,OAAO,SAAS;AAAA,IAC7B,MAAM;AAAA,IACN,OAAO,EAAE,gBAAgB,WAAW,OAAO,EAAE;AAAA,EAC/C,CAAC;AACD,SAAO;AACP,QAAM,UAAU,OAAO,SAAS;AAAA,IAC9B,MAAM;AAAA,IACN,QAAQ;AAAA,MACN,cAAc,CAAC,KAAc,cAC3B,YAAY,SAAS,QAAQ,KAAK,SAAS;AAAA,MAC7C,CAAC,WAAW,GAAG,cAAc,SAAS,CAAC,UAAU,KAAK,GAAG,UAAU,eAAe,MAAM,CAAC;AAAA,IAC3F;AAAA,EACF,CAAC;AAED,SAAO;AACT;","names":["result"]}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createPeerLink
|
|
3
|
+
} from "./chunk-DNP65TD5.js";
|
|
4
|
+
import {
|
|
5
|
+
controlOf
|
|
6
|
+
} from "./chunk-ASAMUGHG.js";
|
|
7
|
+
import "./chunk-2FDSKLBO.js";
|
|
8
|
+
import "./chunk-X4ZU4QH5.js";
|
|
9
|
+
import "./chunk-7Y5ROPXL.js";
|
|
10
|
+
import "./chunk-QSU47XEX.js";
|
|
11
|
+
export {
|
|
12
|
+
controlOf,
|
|
13
|
+
createPeerLink
|
|
14
|
+
};
|
|
15
|
+
//# sourceMappingURL=remote-N7OUAGOW.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { L as Logger } from '../../logger-Yz93KzdV.js';
|
|
2
2
|
import { IncomingHttpHeaders, IncomingMessage, ServerResponse } from 'node:http';
|
|
3
|
-
import { M as MaybePromise, P as Principal } from '../../types-
|
|
3
|
+
import { M as MaybePromise, P as Principal } from '../../types-CLRCQGnO.js';
|
|
4
4
|
import { A as AllowedOrigin } from '../../origins-kvpxnVcW.js';
|
|
5
|
-
import { b as AuthenticateRequest, H as HttpRequest } from '../../auth-
|
|
6
|
-
import '../../infer-
|
|
5
|
+
import { b as AuthenticateRequest, H as HttpRequest } from '../../auth-DtdYjrZ9.js';
|
|
6
|
+
import '../../infer-Br62cnyW.js';
|
|
7
7
|
import 'socket.io';
|
|
8
8
|
|
|
9
9
|
/**
|
|
@@ -28,18 +28,20 @@ import {
|
|
|
28
28
|
setSessionCookie,
|
|
29
29
|
transportCookieNaming,
|
|
30
30
|
verifyJWT
|
|
31
|
-
} from "../../chunk-
|
|
31
|
+
} from "../../chunk-PHCURHC7.js";
|
|
32
32
|
import "../../chunk-DUBU3BB3.js";
|
|
33
|
-
import "../../chunk-Z2LZ7IZ7.js";
|
|
34
33
|
import {
|
|
35
34
|
consoleLogger,
|
|
36
35
|
errorText
|
|
37
36
|
} from "../../chunk-DKE6QO26.js";
|
|
37
|
+
import "../../chunk-SN3OZVEQ.js";
|
|
38
|
+
import "../../chunk-7Y5ROPXL.js";
|
|
38
39
|
import {
|
|
39
40
|
INTERNAL_MESSAGE,
|
|
40
41
|
QuickdrawError,
|
|
41
42
|
httpStatus
|
|
42
|
-
} from "../../chunk-
|
|
43
|
+
} from "../../chunk-Q4OGQM5I.js";
|
|
44
|
+
import "../../chunk-QSU47XEX.js";
|
|
43
45
|
|
|
44
46
|
// src/server/auth/oauth.ts
|
|
45
47
|
function createOAuthURL(provider, config, state) {
|