@farm.js/core 0.1.17 → 0.1.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/after.cjs +12 -225
- package/dist/agent-runtime.cjs +83 -2800
- package/dist/api/client.cjs +17 -4060
- package/dist/api/route-manager.cjs +34 -4354
- package/dist/api/runtime.cjs +29 -2696
- package/dist/api.cjs +88 -8434
- package/dist/app-markdown.cjs +39 -280
- package/dist/app-markdown.mjs +3 -3
- package/dist/cache.cjs +38 -1560
- package/dist/chunk-22GUSVNJ.cjs +351 -0
- package/dist/{chunk-EN7WTEAY.mjs → chunk-2ANEVVF7.mjs} +1 -1
- package/dist/chunk-2CQ74SP6.cjs +13 -0
- package/dist/{chunk-YD4J4XCI.mjs → chunk-2GNATDDE.mjs} +1 -1
- package/dist/chunk-2SJ4RQ6P.cjs +57 -0
- package/dist/chunk-3376ZTRC.cjs +1 -0
- package/dist/chunk-4PNUXIVU.cjs +472 -0
- package/dist/chunk-4PPEPOZZ.cjs +21 -0
- package/dist/chunk-4ZFL5GFN.cjs +520 -0
- package/dist/chunk-5OVTOKGH.cjs +65 -0
- package/dist/chunk-5QIKR7RR.cjs +224 -0
- package/dist/chunk-5ZSWG4UX.cjs +127 -0
- package/dist/chunk-62YJ2IEB.cjs +238 -0
- package/dist/chunk-6EODJYCX.cjs +183 -0
- package/dist/chunk-6EXBPJ24.cjs +434 -0
- package/dist/chunk-6QQDAAAZ.cjs +38 -0
- package/dist/chunk-6V4TDWEC.cjs +455 -0
- package/dist/chunk-72ADZ6GQ.cjs +19 -0
- package/dist/chunk-75BRBIFP.cjs +172 -0
- package/dist/{chunk-ZCNJKLA2.mjs → chunk-7BC6GAL7.mjs} +1 -1
- package/dist/chunk-7W3CPVXS.cjs +24 -0
- package/dist/chunk-A6WIQH5Z.cjs +31 -0
- package/dist/chunk-A777V5WU.cjs +725 -0
- package/dist/chunk-AFOD3LYZ.cjs +377 -0
- package/dist/chunk-AH7HOAQ3.cjs +151 -0
- package/dist/chunk-AMDMVWMI.cjs +39 -0
- package/dist/chunk-AORPIPNB.cjs +552 -0
- package/dist/chunk-ARJWXNQL.cjs +256 -0
- package/dist/chunk-AYJR42WX.cjs +711 -0
- package/dist/chunk-BBVSJVBZ.cjs +600 -0
- package/dist/chunk-BIDYX3SL.cjs +91 -0
- package/dist/chunk-BYODCJD6.cjs +663 -0
- package/dist/chunk-C3VRMB6H.cjs +85 -0
- package/dist/chunk-C5GUTBZK.cjs +173 -0
- package/dist/chunk-CIAGU2X4.cjs +337 -0
- package/dist/chunk-CMGMGHUZ.cjs +27 -0
- package/dist/chunk-CXP5U3RW.cjs +54 -0
- package/dist/chunk-D2ULAULS.cjs +166 -0
- package/dist/chunk-D7JTOLFK.cjs +285 -0
- package/dist/chunk-DVM4FKZL.cjs +169 -0
- package/dist/chunk-DYEJQTDN.cjs +49 -0
- package/dist/chunk-E2ROOWQC.cjs +2225 -0
- package/dist/chunk-E3UK5IIB.cjs +593 -0
- package/dist/chunk-EM6SBQKM.cjs +470 -0
- package/dist/chunk-FJSWYIR7.cjs +482 -0
- package/dist/chunk-FK6GO24V.cjs +54 -0
- package/dist/{chunk-MVIWBEJF.mjs → chunk-FVZGEVTO.mjs} +7 -7
- package/dist/chunk-FXUUWYAX.cjs +654 -0
- package/dist/chunk-G3HRIVEY.cjs +395 -0
- package/dist/chunk-G643DQCH.cjs +13 -0
- package/dist/chunk-G7HXGLEC.cjs +175 -0
- package/dist/chunk-GDSHDTJ4.cjs +152 -0
- package/dist/chunk-GPVTX3HT.cjs +1415 -0
- package/dist/chunk-H6G5INWM.cjs +1094 -0
- package/dist/{chunk-DHDVMXYK.mjs → chunk-HALDNTIV.mjs} +30 -4
- package/dist/chunk-HBTUGXHS.cjs +180 -0
- package/dist/chunk-HREOKQWT.cjs +45 -0
- package/dist/{chunk-5QOEPUYE.mjs → chunk-HSDL2AUR.mjs} +1 -1
- package/dist/chunk-I4J452B7.cjs +435 -0
- package/dist/chunk-I57LW5VZ.cjs +94 -0
- package/dist/chunk-I5YBCWQ6.cjs +40 -0
- package/dist/chunk-I7PUUDGY.cjs +389 -0
- package/dist/chunk-IAMRBF3Z.cjs +86 -0
- package/dist/chunk-IQXFRNY2.cjs +169 -0
- package/dist/chunk-ISTFC3MZ.cjs +1357 -0
- package/dist/chunk-IXTFU4PL.cjs +2355 -0
- package/dist/chunk-J3LOGE4T.cjs +42 -0
- package/dist/chunk-J7FSKED3.cjs +93 -0
- package/dist/chunk-JDNHKPTD.cjs +22 -0
- package/dist/chunk-JSROZYYO.cjs +164 -0
- package/dist/chunk-K6FNHVDR.cjs +696 -0
- package/dist/chunk-KGZIORNL.cjs +43 -0
- package/dist/chunk-KR6CKSXT.cjs +15 -0
- package/dist/chunk-KROWKCUH.cjs +185 -0
- package/dist/chunk-KVFPGF2M.cjs +46 -0
- package/dist/{chunk-TNBAYAWO.mjs → chunk-L4DVIHOC.mjs} +1 -1
- package/dist/chunk-LCCBO7PJ.cjs +46 -0
- package/dist/chunk-LIUGYUX3.cjs +22 -0
- package/dist/chunk-LTNGXMQ6.cjs +55 -0
- package/dist/chunk-M2L4MYDQ.cjs +14 -0
- package/dist/chunk-MCJLA63J.cjs +1 -0
- package/dist/chunk-MKB2EGIR.cjs +148 -0
- package/dist/chunk-MQ3H6LT5.cjs +202 -0
- package/dist/chunk-MT763TDW.cjs +43 -0
- package/dist/{chunk-XWAYMDLB.mjs → chunk-MVUREHPN.mjs} +1 -1
- package/dist/chunk-MWSK6C4J.cjs +18 -0
- package/dist/chunk-MWWVKDW3.cjs +169 -0
- package/dist/{chunk-6VQIKZZO.mjs → chunk-N255VYFP.mjs} +1 -1
- package/dist/chunk-NBAHDVOJ.cjs +2040 -0
- package/dist/chunk-NO3WWW3N.cjs +192 -0
- package/dist/chunk-NSFC3LHB.cjs +10244 -0
- package/dist/chunk-NZKJGRB3.cjs +230 -0
- package/dist/chunk-OAVTUMJP.cjs +1496 -0
- package/dist/{chunk-SXHV42UQ.mjs → chunk-OFEY6KHO.mjs} +88 -13
- package/dist/chunk-OHY2ZWUG.cjs +25 -0
- package/dist/chunk-OI6CMLWX.cjs +47 -0
- package/dist/chunk-OWOUTKIJ.cjs +558 -0
- package/dist/chunk-OX6O6WVA.cjs +74 -0
- package/dist/chunk-OXSIH4D6.cjs +476 -0
- package/dist/chunk-OYDRPBBV.cjs +453 -0
- package/dist/chunk-OYEUREB6.cjs +35 -0
- package/dist/chunk-PCOTGFSM.cjs +139 -0
- package/dist/{chunk-76DG3LF3.mjs → chunk-PGQBL5DN.mjs} +1 -1
- package/dist/chunk-PZYCPSCC.cjs +35 -0
- package/dist/chunk-QBK2AA4U.cjs +445 -0
- package/dist/{chunk-UTBVHYS3.mjs → chunk-QBPKKQTD.mjs} +2 -2
- package/dist/chunk-QBPXNZGV.cjs +487 -0
- package/dist/chunk-QNPEUFHQ.cjs +27 -0
- package/dist/chunk-QZRVZSPN.cjs +236 -0
- package/dist/chunk-R5A5KNVX.cjs +20 -0
- package/dist/chunk-R5JIFR6B.cjs +42 -0
- package/dist/chunk-R6AIILII.cjs +193 -0
- package/dist/chunk-RFYO7QUD.cjs +9 -0
- package/dist/chunk-RG3ZOTG5.cjs +34 -0
- package/dist/chunk-ROUTX2E5.cjs +390 -0
- package/dist/chunk-RTHIVJ2G.cjs +54 -0
- package/dist/chunk-S27FMYAM.cjs +644 -0
- package/dist/chunk-S3A45T7F.cjs +166 -0
- package/dist/chunk-S3JO3N4H.cjs +17 -0
- package/dist/chunk-SK35NQKK.cjs +27 -0
- package/dist/chunk-SU7MH53P.cjs +180 -0
- package/dist/chunk-SVRTJOUF.cjs +113 -0
- package/dist/chunk-SWN467MP.cjs +18 -0
- package/dist/chunk-SYQ3MOWW.cjs +73 -0
- package/dist/chunk-T5CERMEH.cjs +417 -0
- package/dist/chunk-TFAXUHWX.cjs +206 -0
- package/dist/chunk-TIWHTW3Q.cjs +24 -0
- package/dist/chunk-TKJZFIML.cjs +20 -0
- package/dist/chunk-TKNSDBBN.cjs +193 -0
- package/dist/chunk-U4KT7QP3.cjs +23 -0
- package/dist/chunk-U5BMPGS3.cjs +862 -0
- package/dist/chunk-UJ2C4ICS.cjs +277 -0
- package/dist/chunk-UQZ4AYTH.cjs +168 -0
- package/dist/chunk-US2QVW3E.cjs +36 -0
- package/dist/{chunk-QGVJVSNX.mjs → chunk-V4AICMQA.mjs} +2 -2
- package/dist/chunk-VB6UCX3V.cjs +421 -0
- package/dist/chunk-VEKFLAQM.cjs +300 -0
- package/dist/chunk-VQDBNVOO.cjs +14 -0
- package/dist/chunk-W4E7WMXE.cjs +71 -0
- package/dist/chunk-WJ3HK3LJ.cjs +1102 -0
- package/dist/chunk-WMAPPDMM.cjs +28 -0
- package/dist/chunk-WMOGFOUJ.cjs +223 -0
- package/dist/chunk-WPYFSQKK.cjs +37 -0
- package/dist/{chunk-56DAX2BE.mjs → chunk-WZXN4R5Y.mjs} +24 -13
- package/dist/chunk-XDGMADQM.cjs +14225 -0
- package/dist/chunk-XGC343EY.cjs +443 -0
- package/dist/chunk-XSKZORAS.cjs +727 -0
- package/dist/chunk-XWAWFQFS.cjs +82 -0
- package/dist/chunk-Y4YMF2NQ.cjs +460 -0
- package/dist/chunk-Y4YWHNKU.cjs +250 -0
- package/dist/chunk-Y53ZSFN6.cjs +504 -0
- package/dist/chunk-YA6LLTIJ.cjs +411 -0
- package/dist/chunk-YFPGHF5F.cjs +202 -0
- package/dist/chunk-YJRZR7VU.cjs +28 -0
- package/dist/chunk-YTAABQEV.cjs +1 -0
- package/dist/chunk-YX3DBN4M.cjs +18 -0
- package/dist/chunk-YZTASLPQ.cjs +64 -0
- package/dist/chunk-Z5HIWVDP.cjs +2173 -0
- package/dist/chunk-ZEG3OPIB.cjs +93 -0
- package/dist/chunk-ZMN3H73H.cjs +155 -0
- package/dist/client/lifecycle.cjs +6 -35
- package/dist/client-plugins.cjs +7 -448
- package/dist/client.cjs +171 -9808
- package/dist/config.cjs +8 -36
- package/dist/cron.cjs +24 -491
- package/dist/deferred.cjs +26 -475
- package/dist/deployment.cjs +39 -210
- package/dist/devtools-5KGPDVKL.cjs +388 -0
- package/dist/{devtools-UFVTMQX5.mjs → devtools-FY5R7TQ4.mjs} +3 -3
- package/dist/devtools-client-4WAPJY5L.cjs +254 -0
- package/dist/devtools-ui-5GBDIGMK.cjs +1296 -0
- package/dist/docs.cjs +46 -5657
- package/dist/docs.mjs +5 -5
- package/dist/env-types.cjs +5 -226
- package/dist/env.cjs +21 -338
- package/dist/environment/vite.cjs +8 -372
- package/dist/environment.cjs +12 -94
- package/dist/font.cjs +13 -63
- package/dist/headers.cjs +7 -123
- package/dist/i18n/client.cjs +55 -294
- package/dist/i18n/index.cjs +22 -209
- package/dist/i18n/server.cjs +22 -745
- package/dist/image/server.cjs +13 -729
- package/dist/image/sharp.cjs +33 -171
- package/dist/image.cjs +41 -85
- package/dist/index.cjs +1151 -68080
- package/dist/index.mjs +14 -14
- package/dist/instrumentation.cjs +12 -138
- package/dist/integration-orm-55F7CII5.cjs +13 -0
- package/dist/integrations.cjs +55 -4090
- package/dist/internal/app-markdown-runtime.cjs +27 -224
- package/dist/internal/app-markdown-runtime.mjs +2 -2
- package/dist/internal/build-runtime.cjs +120 -52259
- package/dist/internal/build-runtime.mjs +13 -13
- package/dist/internal/cli-runtime.cjs +67 -13811
- package/dist/internal/cli-runtime.mjs +7 -7
- package/dist/internal/client-error-overlay.cjs +80 -733
- package/dist/internal/client-error-overlay.mjs +1 -1
- package/dist/internal/client-runtime.cjs +81 -913
- package/dist/internal/compression-runtime.cjs +8 -214
- package/dist/internal/config-runtime.cjs +42 -6547
- package/dist/internal/config-runtime.mjs +3 -3
- package/dist/internal/docs-precompiled-runtime.cjs +26 -46
- package/dist/internal/infra-analytics-runtime.cjs +10 -536
- package/dist/internal/isolated-boundary.cjs +14 -414
- package/dist/internal/metadata-image-runtime.cjs +7 -285
- package/dist/internal/product-telemetry-runtime.cjs +42 -97
- package/dist/internal/product-telemetry-runtime.mjs +1 -1
- package/dist/internal/production-node-env.cjs +6 -63
- package/dist/internal/production-runtime.cjs +418 -7133
- package/dist/internal/production-runtime.mjs +3 -3
- package/dist/internal/request-cookies.cjs +6 -54
- package/dist/json-ld.cjs +24 -50
- package/dist/layers-E4WPJNY5.cjs +17 -0
- package/dist/manager-G4B2IPYE.cjs +14 -0
- package/dist/markdown.cjs +21 -547
- package/dist/markdown.mjs +1 -1
- package/dist/middleware.cjs +36 -2995
- package/dist/navigation.cjs +22 -2588
- package/dist/nitro-4I2MYLY2.cjs +652 -0
- package/dist/observability.cjs +22 -614
- package/dist/og.cjs +5 -28
- package/dist/plugin.cjs +106 -37442
- package/dist/plugin.mjs +9 -9
- package/dist/query/client.cjs +113 -449
- package/dist/query/index.cjs +26 -288
- package/dist/query/parsers.cjs +23 -247
- package/dist/query/server.cjs +36 -298
- package/dist/renderer/react/client.cjs +9 -43
- package/dist/renderer/react/server.cjs +40 -103
- package/dist/renderer/react/vite.cjs +7 -29
- package/dist/renderer-client.cjs +126 -4295
- package/dist/renderer.cjs +31 -249
- package/dist/request.cjs +5 -68
- package/dist/router.cjs +11 -474
- package/dist/routes.cjs +42 -2461
- package/dist/{schema-dev-notice-2IE2F2XI.mjs → schema-dev-notice-O67CPXJ6.mjs} +1 -1
- package/dist/schema-dev-notice-Y7MQEFGN.cjs +56 -0
- package/dist/schema.cjs +6 -33
- package/dist/search-client-G3RICOFU.cjs +13 -0
- package/dist/server-action-security.cjs +25 -541
- package/dist/server-fn-client.cjs +6 -337
- package/dist/server-fn.cjs +32 -1841
- package/dist/server-plugins.cjs +15 -884
- package/dist/server-query-client.cjs +15 -1883
- package/dist/server-query.cjs +16 -1838
- package/dist/server.cjs +296 -44681
- package/dist/server.mjs +11 -11
- package/dist/storage.cjs +57 -576
- package/dist/testing.cjs +89 -3186
- package/dist/theme/client.cjs +13 -108
- package/dist/theme/index.cjs +6 -68
- package/dist/theme/runtime.cjs +13 -78
- package/dist/theme/server.cjs +10 -179
- package/dist/version.cjs +4 -32
- package/dist/version.mjs +1 -1
- package/dist/vite.cjs +119 -37773
- package/dist/vite.mjs +9 -9
- package/dist/workflows.cjs +19 -1040
- package/package.json +1 -1
|
@@ -0,0 +1,725 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
|
|
2
|
+
|
|
3
|
+
var _chunkD2ULAULScjs = require('./chunk-D2ULAULS.cjs');
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
var _chunkE2ROOWQCcjs = require('./chunk-E2ROOWQC.cjs');
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
var _chunkJSROZYYOcjs = require('./chunk-JSROZYYO.cjs');
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
var _chunkZ5HIWVDPcjs = require('./chunk-Z5HIWVDP.cjs');
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
var _chunkS3JO3N4Hcjs = require('./chunk-S3JO3N4H.cjs');
|
|
34
|
+
|
|
35
|
+
// src/schema-dependencies.ts
|
|
36
|
+
function collectSchemaDependencies(owners) {
|
|
37
|
+
const names = new Set(owners.map((owner) => owner.name));
|
|
38
|
+
const known = /* @__PURE__ */ new Map();
|
|
39
|
+
const creators = /* @__PURE__ */ new Map();
|
|
40
|
+
const claimedKeys = /* @__PURE__ */ new Map();
|
|
41
|
+
for (const owner of owners) {
|
|
42
|
+
try {
|
|
43
|
+
known.set(owner.name, _chunkJSROZYYOcjs.resolveSchemaModels.call(void 0, owner.name, owner.schema));
|
|
44
|
+
for (const model of _chunkE2ROOWQCcjs.collectSchemaModels.call(void 0, [[owner.name, owner.schema, owner.models]])) {
|
|
45
|
+
creators.set(model.modelName.toLowerCase(), owner.name);
|
|
46
|
+
claimedKeys.set(model.modelKey, owner.name);
|
|
47
|
+
}
|
|
48
|
+
} catch (e) {
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
const referencedTable = /* @__PURE__ */ _chunkS3JO3N4Hcjs.__name.call(void 0, (owner, model) => {
|
|
52
|
+
const own = _optionalChain([known, 'access', _2 => _2.get, 'call', _3 => _3(owner), 'optionalAccess', _4 => _4[model]]);
|
|
53
|
+
if (own && Object.prototype.hasOwnProperty.call(known.get(owner), model)) return own.name;
|
|
54
|
+
const creator = claimedKeys.get(model);
|
|
55
|
+
return creator && _optionalChain([known, 'access', _5 => _5.get, 'call', _6 => _6(creator), 'optionalAccess', _7 => _7[model], 'optionalAccess', _8 => _8.name]) || model;
|
|
56
|
+
}, "referencedTable");
|
|
57
|
+
const dependencies = /* @__PURE__ */ new Map();
|
|
58
|
+
for (const owner of owners) {
|
|
59
|
+
const needs = new Set(
|
|
60
|
+
(_nullishCoalesce(owner.dependsOn, () => ( []))).filter((name) => names.has(name) && name !== owner.name)
|
|
61
|
+
);
|
|
62
|
+
dependencies.set(owner.name, needs);
|
|
63
|
+
const add = /* @__PURE__ */ _chunkS3JO3N4Hcjs.__name.call(void 0, (table) => {
|
|
64
|
+
const creator = creators.get(table.toLowerCase());
|
|
65
|
+
if (creator && creator !== owner.name) needs.add(creator);
|
|
66
|
+
}, "add");
|
|
67
|
+
try {
|
|
68
|
+
for (const model of _chunkE2ROOWQCcjs.collectSchemaModels.call(void 0, [[owner.name, owner.schema, owner.models]])) {
|
|
69
|
+
for (const field of Object.values(model.model.fields)) {
|
|
70
|
+
if (field.reference) add(referencedTable(owner.name, field.reference.model));
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
for (const extension of _chunkE2ROOWQCcjs.collectSchemaExtensions.call(void 0, owner.name, owner.schema, owner.models)) {
|
|
74
|
+
add(extension.table);
|
|
75
|
+
}
|
|
76
|
+
} catch (e2) {
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return dependencies;
|
|
80
|
+
}
|
|
81
|
+
_chunkS3JO3N4Hcjs.__name.call(void 0, collectSchemaDependencies, "collectSchemaDependencies");
|
|
82
|
+
function orderSchemaOwners(owners, dependencies = collectSchemaDependencies(owners)) {
|
|
83
|
+
const byName = new Map(owners.map((owner) => [owner.name, owner]));
|
|
84
|
+
const ordered = [];
|
|
85
|
+
const state = /* @__PURE__ */ new Map();
|
|
86
|
+
const visit = /* @__PURE__ */ _chunkS3JO3N4Hcjs.__name.call(void 0, (owner) => {
|
|
87
|
+
if (state.has(owner.name)) return;
|
|
88
|
+
state.set(owner.name, "visiting");
|
|
89
|
+
for (const name of _nullishCoalesce(dependencies.get(owner.name), () => ( []))) {
|
|
90
|
+
const dependency = byName.get(name);
|
|
91
|
+
if (dependency && state.get(name) !== "visiting") visit(dependency);
|
|
92
|
+
}
|
|
93
|
+
state.set(owner.name, "done");
|
|
94
|
+
ordered.push(owner);
|
|
95
|
+
}, "visit");
|
|
96
|
+
for (const owner of owners) visit(owner);
|
|
97
|
+
return ordered;
|
|
98
|
+
}
|
|
99
|
+
_chunkS3JO3N4Hcjs.__name.call(void 0, orderSchemaOwners, "orderSchemaOwners");
|
|
100
|
+
|
|
101
|
+
// src/schema-check.ts
|
|
102
|
+
var DEFAULT_TIMEOUT_MS = 1e4;
|
|
103
|
+
async function withTimeout(work, timeoutMs) {
|
|
104
|
+
let timer;
|
|
105
|
+
const timeout = new Promise((_, reject) => {
|
|
106
|
+
timer = setTimeout(
|
|
107
|
+
() => reject(new Error(`no answer within ${formatSeconds(timeoutMs)}`)),
|
|
108
|
+
timeoutMs
|
|
109
|
+
);
|
|
110
|
+
_optionalChain([timer, 'access', _9 => _9.unref, 'optionalCall', _10 => _10()]);
|
|
111
|
+
});
|
|
112
|
+
try {
|
|
113
|
+
return await Promise.race([Promise.resolve().then(work), timeout]);
|
|
114
|
+
} finally {
|
|
115
|
+
clearTimeout(timer);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
_chunkS3JO3N4Hcjs.__name.call(void 0, withTimeout, "withTimeout");
|
|
119
|
+
var formatSeconds = /* @__PURE__ */ _chunkS3JO3N4Hcjs.__name.call(void 0, (ms) => ms < 1e3 ? `${ms}ms` : `${Number((ms / 1e3).toFixed(1))}s`, "formatSeconds");
|
|
120
|
+
function collectSchemaOwners(config) {
|
|
121
|
+
const owners = [];
|
|
122
|
+
const integrationSchemas = _chunkZ5HIWVDPcjs.getIntegrationSchemas.call(void 0, config.integrations);
|
|
123
|
+
let integrationClient;
|
|
124
|
+
for (const [name, schema] of Object.entries(integrationSchemas)) {
|
|
125
|
+
owners.push({
|
|
126
|
+
name,
|
|
127
|
+
kind: "integration",
|
|
128
|
+
schema,
|
|
129
|
+
resolveClient: /* @__PURE__ */ _chunkS3JO3N4Hcjs.__name.call(void 0, (resolved) => _nullishCoalesce(integrationClient, () => ( (integrationClient = _chunkD2ULAULScjs.resolveIntegrationOrmRuntimeClient.call(void 0, { config: resolved })))), "resolveClient")
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
for (const declaration of _chunkE2ROOWQCcjs.findSchemaTableOwners.call(void 0, config)) {
|
|
133
|
+
if (owners.some((owner) => owner.name === declaration.name)) continue;
|
|
134
|
+
owners.push({
|
|
135
|
+
name: declaration.name,
|
|
136
|
+
kind: "plugin",
|
|
137
|
+
schema: declaration.schema,
|
|
138
|
+
models: declaration.models,
|
|
139
|
+
dialect: declaration.dialect,
|
|
140
|
+
dependsOn: declaration.dependsOn,
|
|
141
|
+
version: declaration.version,
|
|
142
|
+
migrations: declaration.migrations,
|
|
143
|
+
resolveClient: /* @__PURE__ */ _chunkS3JO3N4Hcjs.__name.call(void 0, (resolved) => declaration.resolveClient(resolved), "resolveClient")
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
return owners;
|
|
147
|
+
}
|
|
148
|
+
_chunkS3JO3N4Hcjs.__name.call(void 0, collectSchemaOwners, "collectSchemaOwners");
|
|
149
|
+
var errorMessage = /* @__PURE__ */ _chunkS3JO3N4Hcjs.__name.call(void 0, (error) => (error instanceof Error ? error.message : String(error)).replace(
|
|
150
|
+
/(\/\/[^/\s:@]+):[^@\s]+@/gu,
|
|
151
|
+
"$1:***@"
|
|
152
|
+
), "errorMessage");
|
|
153
|
+
function migrateHint(owner) {
|
|
154
|
+
return owner.kind === "plugin" ? `Run \`farm ${owner.name} migrate\` to see the SQL, then \`--apply\` it.` : "Create it with your migration tool: `farm generate` writes the integration's tables into your Prisma or Drizzle schema.";
|
|
155
|
+
}
|
|
156
|
+
_chunkS3JO3N4Hcjs.__name.call(void 0, migrateHint, "migrateHint");
|
|
157
|
+
function resolveSchemaExecutor(client, owner, timeoutMs) {
|
|
158
|
+
for (const candidate of [client, client.$client]) {
|
|
159
|
+
if (candidate === void 0 || candidate === null) continue;
|
|
160
|
+
let adapter;
|
|
161
|
+
try {
|
|
162
|
+
adapter = _chunkE2ROOWQCcjs.createSchemaExecutor.call(void 0, candidate, owner);
|
|
163
|
+
} catch (e3) {
|
|
164
|
+
continue;
|
|
165
|
+
}
|
|
166
|
+
if (!adapter) return null;
|
|
167
|
+
const { executor } = adapter;
|
|
168
|
+
return {
|
|
169
|
+
...adapter,
|
|
170
|
+
client: candidate,
|
|
171
|
+
// Each query is bounded, not the whole check, so a large schema on a
|
|
172
|
+
// slow link still finishes while a dead connection fails fast.
|
|
173
|
+
executor: {
|
|
174
|
+
execute: /* @__PURE__ */ _chunkS3JO3N4Hcjs.__name.call(void 0, (sql) => withTimeout(() => executor.execute(sql), timeoutMs), "execute"),
|
|
175
|
+
query: /* @__PURE__ */ _chunkS3JO3N4Hcjs.__name.call(void 0, (sql, params) => withTimeout(() => executor.query(sql, params), timeoutMs), "query")
|
|
176
|
+
}
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
return void 0;
|
|
180
|
+
}
|
|
181
|
+
_chunkS3JO3N4Hcjs.__name.call(void 0, resolveSchemaExecutor, "resolveSchemaExecutor");
|
|
182
|
+
var describeReferencedTable = /* @__PURE__ */ _chunkS3JO3N4Hcjs.__name.call(void 0, (database, table) => _chunkE2ROOWQCcjs.describeSchemaTable.call(void 0, database.executor, database.dialect, table), "describeReferencedTable");
|
|
183
|
+
async function checkSchema(config, options = {}) {
|
|
184
|
+
const timeoutMs = _nullishCoalesce(options.timeoutMs, () => ( DEFAULT_TIMEOUT_MS));
|
|
185
|
+
if (!Number.isFinite(timeoutMs) || timeoutMs <= 0) {
|
|
186
|
+
throw new TypeError("timeoutMs must be a positive number of milliseconds.");
|
|
187
|
+
}
|
|
188
|
+
const timeoutHint = `Check that the database is reachable from here, or allow longer than ${formatSeconds(timeoutMs)} with \`--timeout <ms>\`.`;
|
|
189
|
+
const dependencies = collectSchemaDependencies(collectSchemaOwners(config));
|
|
190
|
+
const owners = orderSchemaOwners(collectSchemaOwners(config), dependencies);
|
|
191
|
+
const issues = [];
|
|
192
|
+
const declared = /* @__PURE__ */ new Map();
|
|
193
|
+
for (const candidate of _nullishCoalesce(config.plugins, () => ( []))) {
|
|
194
|
+
const declaration = _chunkE2ROOWQCcjs.readSchemaTables.call(void 0, candidate);
|
|
195
|
+
if (!declaration) continue;
|
|
196
|
+
const schemas = _nullishCoalesce(declared.get(declaration.name), () => ( []));
|
|
197
|
+
if (!schemas.includes(declaration.schema)) schemas.push(declaration.schema);
|
|
198
|
+
declared.set(declaration.name, schemas);
|
|
199
|
+
}
|
|
200
|
+
for (const [name, schemas] of declared) {
|
|
201
|
+
if (schemas.length < 2) continue;
|
|
202
|
+
issues.push({
|
|
203
|
+
severity: "error",
|
|
204
|
+
code: "owner-conflict",
|
|
205
|
+
owner: name,
|
|
206
|
+
message: `${schemas.length} plugins declare tables under the name "${name}", so \`farm ${name} migrate\` and this check only see the first.`,
|
|
207
|
+
hint: "Rename one of the plugins: the part of its name after the last `:` or `/` is its migrate command."
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
const summaries = [];
|
|
211
|
+
const knownModels = /* @__PURE__ */ new Map();
|
|
212
|
+
const ownedModels = /* @__PURE__ */ new Map();
|
|
213
|
+
for (const owner of owners) {
|
|
214
|
+
try {
|
|
215
|
+
knownModels.set(owner.name, _chunkJSROZYYOcjs.resolveSchemaModels.call(void 0, owner.name, owner.schema));
|
|
216
|
+
ownedModels.set(owner.name, _chunkE2ROOWQCcjs.collectSchemaModels.call(void 0, [[owner.name, owner.schema, owner.models]]));
|
|
217
|
+
} catch (error) {
|
|
218
|
+
issues.push({
|
|
219
|
+
severity: "error",
|
|
220
|
+
code: "schema-invalid",
|
|
221
|
+
owner: owner.name,
|
|
222
|
+
message: errorMessage(error)
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
const resolveTarget = /* @__PURE__ */ _chunkS3JO3N4Hcjs.__name.call(void 0, (ownerName, field) => {
|
|
227
|
+
const reference = field.reference;
|
|
228
|
+
if (!reference) return void 0;
|
|
229
|
+
const own = _optionalChain([knownModels, 'access', _11 => _11.get, 'call', _12 => _12(ownerName), 'optionalAccess', _13 => _13[reference.model]]);
|
|
230
|
+
const other = own ? void 0 : owners.find(
|
|
231
|
+
(owner) => owner.name !== ownerName && (_nullishCoalesce(ownedModels.get(owner.name), () => ( []))).some((entry) => entry.modelKey === reference.model)
|
|
232
|
+
);
|
|
233
|
+
const model = _nullishCoalesce(own, () => ( (other && _optionalChain([knownModels, 'access', _14 => _14.get, 'call', _15 => _15(other.name), 'optionalAccess', _16 => _16[reference.model]]))));
|
|
234
|
+
if (model) {
|
|
235
|
+
const claimedBy = _optionalChain([[...ownedModels], 'access', _17 => _17.find, 'call', _18 => _18(
|
|
236
|
+
([, models]) => models.some((entry) => entry.modelName === model.name)
|
|
237
|
+
), 'optionalAccess', _19 => _19[0]]);
|
|
238
|
+
return {
|
|
239
|
+
table: model.name,
|
|
240
|
+
column: _nullishCoalesce(_optionalChain([model, 'access', _20 => _20.fields, 'access', _21 => _21[reference.field], 'optionalAccess', _22 => _22.name]), () => ( reference.field)),
|
|
241
|
+
owner: claimedBy
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
return { table: reference.model, column: reference.field };
|
|
245
|
+
}, "resolveTarget");
|
|
246
|
+
const databases = /* @__PURE__ */ new Map();
|
|
247
|
+
for (const owner of owners) {
|
|
248
|
+
const models = ownedModels.get(owner.name);
|
|
249
|
+
if (!models) continue;
|
|
250
|
+
const summary = {
|
|
251
|
+
name: owner.name,
|
|
252
|
+
kind: owner.kind,
|
|
253
|
+
relational: true,
|
|
254
|
+
tables: models.map((model) => model.modelName),
|
|
255
|
+
dependsOn: [..._nullishCoalesce(dependencies.get(owner.name), () => ( []))]
|
|
256
|
+
};
|
|
257
|
+
summaries.push(summary);
|
|
258
|
+
let client;
|
|
259
|
+
try {
|
|
260
|
+
client = await withTimeout(() => owner.resolveClient(config), timeoutMs);
|
|
261
|
+
} catch (error) {
|
|
262
|
+
issues.push({
|
|
263
|
+
severity: "error",
|
|
264
|
+
code: "client-unavailable",
|
|
265
|
+
owner: owner.name,
|
|
266
|
+
message: `Could not connect to ${owner.name}'s database: ${errorMessage(error)}`,
|
|
267
|
+
hint: timeoutHint
|
|
268
|
+
});
|
|
269
|
+
continue;
|
|
270
|
+
}
|
|
271
|
+
if (client === void 0 || client === null) {
|
|
272
|
+
issues.push({
|
|
273
|
+
severity: "error",
|
|
274
|
+
code: "client-missing",
|
|
275
|
+
owner: owner.name,
|
|
276
|
+
message: `${owner.name} declares tables but has no database client.`,
|
|
277
|
+
hint: owner.kind === "integration" ? "Set `storage.client` in farm.config to your database client." : `Pass a database client to the ${owner.name} plugin.`
|
|
278
|
+
});
|
|
279
|
+
continue;
|
|
280
|
+
}
|
|
281
|
+
const adapter = resolveSchemaExecutor(client, owner.name, timeoutMs);
|
|
282
|
+
if (adapter === null) {
|
|
283
|
+
summary.relational = false;
|
|
284
|
+
continue;
|
|
285
|
+
}
|
|
286
|
+
if (adapter === void 0) {
|
|
287
|
+
issues.push({
|
|
288
|
+
severity: "warning",
|
|
289
|
+
code: "client-unsupported",
|
|
290
|
+
owner: owner.name,
|
|
291
|
+
message: `${owner.name}'s database client cannot be inspected, so its tables were not checked.`,
|
|
292
|
+
hint: "Farm reads pg, mysql2, and sqlite connections, and Drizzle databases built on them. Check these tables with your ORM's migration status instead."
|
|
293
|
+
});
|
|
294
|
+
continue;
|
|
295
|
+
}
|
|
296
|
+
const dialect = _nullishCoalesce(owner.dialect, () => ( adapter.dialect));
|
|
297
|
+
summary.dialect = dialect;
|
|
298
|
+
databases.set(owner.name, { client: adapter.client, executor: adapter.executor, dialect });
|
|
299
|
+
}
|
|
300
|
+
const claims = /* @__PURE__ */ new Map();
|
|
301
|
+
for (const [ownerName, models] of ownedModels) {
|
|
302
|
+
for (const model of models) {
|
|
303
|
+
const key = model.modelName.toLowerCase();
|
|
304
|
+
const previous = claims.get(key);
|
|
305
|
+
if (!previous || previous === ownerName) {
|
|
306
|
+
claims.set(key, ownerName);
|
|
307
|
+
continue;
|
|
308
|
+
}
|
|
309
|
+
const mine = databases.get(ownerName);
|
|
310
|
+
const theirs = databases.get(previous);
|
|
311
|
+
if (mine && theirs && mine.dialect !== theirs.dialect) continue;
|
|
312
|
+
if (_optionalChain([mine, 'optionalAccess', _23 => _23.dialect]) === "postgres" && _optionalChain([theirs, 'optionalAccess', _24 => _24.dialect]) === "postgres" && !(_nullishCoalesce(ownedModels.get(previous), () => ( []))).some((entry) => entry.modelName === model.modelName)) {
|
|
313
|
+
continue;
|
|
314
|
+
}
|
|
315
|
+
const shared = Boolean(mine && theirs && mine.client === theirs.client);
|
|
316
|
+
issues.push({
|
|
317
|
+
severity: shared ? "error" : "warning",
|
|
318
|
+
code: "table-conflict",
|
|
319
|
+
owner: ownerName,
|
|
320
|
+
table: model.modelName,
|
|
321
|
+
message: shared ? `"${model.modelName}" is claimed by both ${previous} and ${ownerName}.` : `"${model.modelName}" is claimed by both ${previous} and ${ownerName}. If they share a database, they write to the same table.`,
|
|
322
|
+
hint: "Give one of the models a different table name with `name`, or narrow one owner's `models`."
|
|
323
|
+
});
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
const allowExtend = _optionalChain([config, 'access', _25 => _25.schema, 'optionalAccess', _26 => _26.allowExtend]);
|
|
327
|
+
const extensions = /* @__PURE__ */ new Map();
|
|
328
|
+
const addedColumns = /* @__PURE__ */ new Map();
|
|
329
|
+
for (const owner of owners) {
|
|
330
|
+
if (!ownedModels.has(owner.name)) continue;
|
|
331
|
+
try {
|
|
332
|
+
const owned = _chunkE2ROOWQCcjs.collectSchemaExtensions.call(void 0, owner.name, owner.schema, owner.models);
|
|
333
|
+
extensions.set(owner.name, owned);
|
|
334
|
+
for (const extension of owned) {
|
|
335
|
+
for (const { field } of extension.fields) {
|
|
336
|
+
const key = `${extension.table}.${field.name}`.toLowerCase();
|
|
337
|
+
const other = addedColumns.get(key);
|
|
338
|
+
if (other && other !== owner.name) {
|
|
339
|
+
issues.push({
|
|
340
|
+
severity: "warning",
|
|
341
|
+
code: "extend-column-shared",
|
|
342
|
+
owner: owner.name,
|
|
343
|
+
table: extension.table,
|
|
344
|
+
column: field.name,
|
|
345
|
+
message: `${other} and ${owner.name} both add "${extension.table}.${field.name}", so they will share one column.`
|
|
346
|
+
});
|
|
347
|
+
} else {
|
|
348
|
+
addedColumns.set(key, owner.name);
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
} catch (error) {
|
|
353
|
+
issues.push({
|
|
354
|
+
severity: "error",
|
|
355
|
+
code: "extend-invalid",
|
|
356
|
+
owner: owner.name,
|
|
357
|
+
message: errorMessage(error)
|
|
358
|
+
});
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
const databaseForTable = /* @__PURE__ */ _chunkS3JO3N4Hcjs.__name.call(void 0, (table) => {
|
|
362
|
+
const creator = _optionalChain([[...ownedModels], 'access', _27 => _27.find, 'call', _28 => _28(
|
|
363
|
+
([, models]) => models.some((model) => model.modelName === table)
|
|
364
|
+
), 'optionalAccess', _29 => _29[0]]);
|
|
365
|
+
return creator ? databases.get(creator) : void 0;
|
|
366
|
+
}, "databaseForTable");
|
|
367
|
+
for (const owner of owners) {
|
|
368
|
+
const models = ownedModels.get(owner.name);
|
|
369
|
+
const database = databases.get(owner.name);
|
|
370
|
+
if (!models || !database) continue;
|
|
371
|
+
try {
|
|
372
|
+
const crossOwner = await _chunkE2ROOWQCcjs.planCrossOwnerReferences.call(void 0,
|
|
373
|
+
owner,
|
|
374
|
+
_chunkE2ROOWQCcjs.findSchemaTableOwners.call(void 0, config),
|
|
375
|
+
database.dialect,
|
|
376
|
+
database.executor
|
|
377
|
+
);
|
|
378
|
+
for (const reference of crossOwner.eligible) {
|
|
379
|
+
const model = models.find((candidate) => candidate.modelKey === reference.modelKey);
|
|
380
|
+
if (!model) continue;
|
|
381
|
+
(_nullishCoalesce(model.foreignKeys, () => ( (model.foreignKeys = {}))))[reference.fieldKey] = {
|
|
382
|
+
table: reference.referencedTable,
|
|
383
|
+
column: reference.referencedColumn,
|
|
384
|
+
onDelete: reference.onDelete
|
|
385
|
+
};
|
|
386
|
+
}
|
|
387
|
+
const stepPlan = _optionalChain([owner, 'access', _30 => _30.migrations, 'optionalAccess', _31 => _31.length]) ? await _chunkE2ROOWQCcjs.planOwnerSchemaSteps.call(void 0, {
|
|
388
|
+
owner: owner.name,
|
|
389
|
+
schema: owner.schema,
|
|
390
|
+
steps: owner.migrations,
|
|
391
|
+
tables: models.map((model) => model.modelName),
|
|
392
|
+
dialect: database.dialect,
|
|
393
|
+
executor: database.executor,
|
|
394
|
+
othersTables: new Set(
|
|
395
|
+
[...ownedModels].filter(([name]) => name !== owner.name).flatMap(([, entries]) => entries.map((entry) => entry.modelName))
|
|
396
|
+
)
|
|
397
|
+
}) : void 0;
|
|
398
|
+
checkSteps(owner, stepPlan, issues);
|
|
399
|
+
const plan = await checkOwnerTables(
|
|
400
|
+
owner,
|
|
401
|
+
// What a pending rename will produce is not missing yet.
|
|
402
|
+
_chunkE2ROOWQCcjs.withoutRenameTargets.call(void 0, models, stepPlan),
|
|
403
|
+
database.dialect,
|
|
404
|
+
database.executor,
|
|
405
|
+
issues
|
|
406
|
+
);
|
|
407
|
+
const pending = plan.statements.length + (_nullishCoalesce(_optionalChain([plan, 'access', _32 => _32.upgrades, 'optionalAccess', _33 => _33.length]), () => ( 0)));
|
|
408
|
+
const state = pending > 0 ? await _chunkE2ROOWQCcjs.readSchemaState.call(void 0, database.executor, database.dialect, owner.name) : void 0;
|
|
409
|
+
const changes = state ? _chunkE2ROOWQCcjs.diffSchemaSnapshots.call(void 0, state.snapshot, _chunkE2ROOWQCcjs.createSchemaSnapshot.call(void 0, models)) : void 0;
|
|
410
|
+
if (state && changes && _chunkE2ROOWQCcjs.hasSchemaChanges.call(void 0, changes)) {
|
|
411
|
+
const versions = state.version && owner.version && state.version !== owner.version ? `upgraded ${state.version} \u2192 ${owner.version}` : "changed since it was last migrated";
|
|
412
|
+
issues.push({
|
|
413
|
+
severity: "warning",
|
|
414
|
+
code: "schema-upgrade",
|
|
415
|
+
owner: owner.name,
|
|
416
|
+
message: `${owner.name} ${versions}, and ${pending} change(s) are not applied yet.`,
|
|
417
|
+
hint: owner.kind === "plugin" ? `Run \`farm ${owner.name} migrate\` to review and apply them.` : "Apply them with your migration tool."
|
|
418
|
+
});
|
|
419
|
+
}
|
|
420
|
+
await checkReferences(owner, models, database, databases, resolveTarget, issues);
|
|
421
|
+
await checkExtensions(
|
|
422
|
+
owner,
|
|
423
|
+
_nullishCoalesce(extensions.get(owner.name), () => ( [])),
|
|
424
|
+
databaseForTable,
|
|
425
|
+
database,
|
|
426
|
+
allowExtend,
|
|
427
|
+
issues
|
|
428
|
+
);
|
|
429
|
+
} catch (error) {
|
|
430
|
+
issues.push({
|
|
431
|
+
severity: "error",
|
|
432
|
+
code: "client-unavailable",
|
|
433
|
+
owner: owner.name,
|
|
434
|
+
message: `Could not read ${owner.name}'s tables: ${errorMessage(error)}`,
|
|
435
|
+
hint: timeoutHint
|
|
436
|
+
});
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
return {
|
|
440
|
+
owners: summaries,
|
|
441
|
+
issues,
|
|
442
|
+
ok: !issues.some((issue) => issue.severity === "error")
|
|
443
|
+
};
|
|
444
|
+
}
|
|
445
|
+
_chunkS3JO3N4Hcjs.__name.call(void 0, checkSchema, "checkSchema");
|
|
446
|
+
async function checkOwnerTables(owner, models, dialect, executor, issues) {
|
|
447
|
+
const plan = await _chunkE2ROOWQCcjs.planSchemaMigration.call(void 0, models, dialect, executor);
|
|
448
|
+
const present = /* @__PURE__ */ new Set([
|
|
449
|
+
...plan.upToDate,
|
|
450
|
+
...plan.drift.map((drift) => drift.table),
|
|
451
|
+
...(_nullishCoalesce(plan.upgrades, () => ( []))).map((upgrade) => upgrade.table)
|
|
452
|
+
]);
|
|
453
|
+
const command = owner.kind === "plugin" ? `\`farm ${owner.name} migrate\`` : "your migration tool";
|
|
454
|
+
for (const upgrade of _nullishCoalesce(plan.upgrades, () => ( []))) {
|
|
455
|
+
const column = upgrade.kind === "column" ? upgrade.target.slice(upgrade.table.length + 1) : void 0;
|
|
456
|
+
issues.push({
|
|
457
|
+
severity: column ? "error" : "warning",
|
|
458
|
+
code: column ? "column-missing" : "index-missing",
|
|
459
|
+
owner: owner.name,
|
|
460
|
+
table: upgrade.table,
|
|
461
|
+
...column ? { column } : {},
|
|
462
|
+
message: column ? `"${upgrade.table}" has no column "${column}".` : `"${upgrade.table}" is missing the index ${upgrade.target}.`,
|
|
463
|
+
hint: `Add it with ${command}.`
|
|
464
|
+
});
|
|
465
|
+
}
|
|
466
|
+
for (const model of models) {
|
|
467
|
+
if (present.has(model.modelName)) continue;
|
|
468
|
+
issues.push({
|
|
469
|
+
severity: "error",
|
|
470
|
+
code: "table-missing",
|
|
471
|
+
owner: owner.name,
|
|
472
|
+
table: model.modelName,
|
|
473
|
+
message: `Table "${model.modelName}" does not exist.`,
|
|
474
|
+
hint: migrateHint(owner)
|
|
475
|
+
});
|
|
476
|
+
}
|
|
477
|
+
for (const drift of plan.drift) {
|
|
478
|
+
for (const column of drift.missingColumns) {
|
|
479
|
+
issues.push({
|
|
480
|
+
severity: "error",
|
|
481
|
+
code: "column-missing",
|
|
482
|
+
owner: owner.name,
|
|
483
|
+
table: drift.table,
|
|
484
|
+
column,
|
|
485
|
+
message: `"${drift.table}" has no column "${column}".`,
|
|
486
|
+
hint: "It is required with no default, so Farm cannot add it to a table that may have rows. Add it with a migration step or your migration tool."
|
|
487
|
+
});
|
|
488
|
+
}
|
|
489
|
+
for (const change of drift.changedColumns) {
|
|
490
|
+
const typeChanged = change.differences.includes("type");
|
|
491
|
+
issues.push({
|
|
492
|
+
severity: typeChanged ? "error" : "warning",
|
|
493
|
+
code: typeChanged ? "column-type" : "column-definition",
|
|
494
|
+
owner: owner.name,
|
|
495
|
+
table: drift.table,
|
|
496
|
+
column: change.column,
|
|
497
|
+
message: typeChanged ? `"${drift.table}.${change.column}" is ${change.actual.type}; the schema expects ${change.expected.type}.` : `"${drift.table}.${change.column}" differs from the schema (${change.differences.join(", ")}).`
|
|
498
|
+
});
|
|
499
|
+
}
|
|
500
|
+
for (const index of drift.missingIndexes) {
|
|
501
|
+
issues.push({
|
|
502
|
+
severity: "warning",
|
|
503
|
+
code: "index-missing",
|
|
504
|
+
owner: owner.name,
|
|
505
|
+
table: drift.table,
|
|
506
|
+
message: `"${drift.table}" is missing the ${index.unique ? "unique " : ""}index on (${index.columns.join(", ")}).`
|
|
507
|
+
});
|
|
508
|
+
}
|
|
509
|
+
for (const reference of _nullishCoalesce(drift.missingReferences, () => ( []))) {
|
|
510
|
+
issues.push({
|
|
511
|
+
severity: "warning",
|
|
512
|
+
code: "foreign-key-missing",
|
|
513
|
+
owner: owner.name,
|
|
514
|
+
table: drift.table,
|
|
515
|
+
column: reference.column,
|
|
516
|
+
message: `"${drift.table}.${reference.column}" has no foreign key to "${reference.referencedTable}.${reference.referencedColumn}".`
|
|
517
|
+
});
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
for (const key of _nullishCoalesce(plan.addableForeignKeys, () => ( []))) {
|
|
521
|
+
issues.push({
|
|
522
|
+
severity: "warning",
|
|
523
|
+
code: "foreign-key-missing",
|
|
524
|
+
owner: owner.name,
|
|
525
|
+
table: key.table,
|
|
526
|
+
column: key.column,
|
|
527
|
+
message: `"${key.table}.${key.column}" has no foreign key to "${key.referencedTable}.${key.referencedColumn}", which ${owner.name} could have.`,
|
|
528
|
+
hint: dialect === "sqlite" ? "SQLite can only add a foreign key when it creates the table." : `Allow it with \`${_chunkE2ROOWQCcjs.describeForeignKeyApproval.call(void 0, { owner: owner.name, modelKey: key.modelKey })}\` in farm.config, then run \`farm ${owner.name} migrate --apply\`. Rows that point at nothing are checked first.`
|
|
529
|
+
});
|
|
530
|
+
}
|
|
531
|
+
return plan;
|
|
532
|
+
}
|
|
533
|
+
_chunkS3JO3N4Hcjs.__name.call(void 0, checkOwnerTables, "checkOwnerTables");
|
|
534
|
+
function checkSteps(owner, stepPlan, issues) {
|
|
535
|
+
if (!stepPlan) return;
|
|
536
|
+
const command = `\`farm ${owner.name} migrate\``;
|
|
537
|
+
const blockedAt = stepPlan.steps.findIndex((planned) => planned.state === "blocked");
|
|
538
|
+
const pending = stepPlan.steps.slice(0, blockedAt === -1 ? void 0 : blockedAt).filter((planned) => planned.state === "run");
|
|
539
|
+
if (pending.length > 0) {
|
|
540
|
+
issues.push({
|
|
541
|
+
severity: "warning",
|
|
542
|
+
code: "migration-step-pending",
|
|
543
|
+
owner: owner.name,
|
|
544
|
+
message: `${owner.name} has ${pending.length} migration step(s) not run yet: ${pending.map((planned) => `${planned.summary}${planned.destructive ? " (deletes data)" : ""}`).join("; ")}.`,
|
|
545
|
+
hint: `Run ${command} to review and apply them.`
|
|
546
|
+
});
|
|
547
|
+
}
|
|
548
|
+
if (blockedAt !== -1) {
|
|
549
|
+
const blocked = stepPlan.steps[blockedAt];
|
|
550
|
+
issues.push({
|
|
551
|
+
severity: "error",
|
|
552
|
+
code: "migration-step-blocked",
|
|
553
|
+
owner: owner.name,
|
|
554
|
+
message: `${owner.name}'s migration step "${blocked.step.id}" (${blocked.summary}) cannot run: ${blocked.reason}`,
|
|
555
|
+
hint: "Later steps wait for it. Fix the database, then run migrate again."
|
|
556
|
+
});
|
|
557
|
+
}
|
|
558
|
+
for (const id of stepPlan.edited) {
|
|
559
|
+
issues.push({
|
|
560
|
+
severity: "warning",
|
|
561
|
+
code: "migration-step-edited",
|
|
562
|
+
owner: owner.name,
|
|
563
|
+
message: `${owner.name}'s migration step "${id}" changed after it ran here; it will not run again.`
|
|
564
|
+
});
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
_chunkS3JO3N4Hcjs.__name.call(void 0, checkSteps, "checkSteps");
|
|
568
|
+
async function checkReferences(owner, models, database, databases, resolveTarget, issues) {
|
|
569
|
+
const ownTables = new Set(models.map((model) => model.modelName));
|
|
570
|
+
const described = /* @__PURE__ */ new Map();
|
|
571
|
+
for (const model of models) {
|
|
572
|
+
for (const field of Object.values(model.model.fields)) {
|
|
573
|
+
const target = resolveTarget(owner.name, field);
|
|
574
|
+
if (!target || ownTables.has(target.table)) continue;
|
|
575
|
+
const targetDatabase = target.owner ? databases.get(target.owner) : database;
|
|
576
|
+
if (!targetDatabase) continue;
|
|
577
|
+
const key = `${_nullishCoalesce(target.owner, () => ( ""))}\0${target.table}`;
|
|
578
|
+
if (!described.has(key)) {
|
|
579
|
+
described.set(key, await describeReferencedTable(targetDatabase, target.table));
|
|
580
|
+
}
|
|
581
|
+
const table = described.get(key);
|
|
582
|
+
const dialect = targetDatabase.dialect;
|
|
583
|
+
const where = `"${model.modelName}.${field.name}" references "${target.table}.${target.column}"`;
|
|
584
|
+
if (!table) {
|
|
585
|
+
issues.push({
|
|
586
|
+
severity: "error",
|
|
587
|
+
code: "reference-table-missing",
|
|
588
|
+
owner: owner.name,
|
|
589
|
+
table: model.modelName,
|
|
590
|
+
column: field.name,
|
|
591
|
+
message: `${where}, but "${target.table}" does not exist.`,
|
|
592
|
+
hint: target.owner ? `It belongs to ${target.owner}; migrate it first.` : "Farm does not manage that table. Run the migration that creates it (your ORM's, or a library's such as Better Auth) first."
|
|
593
|
+
});
|
|
594
|
+
continue;
|
|
595
|
+
}
|
|
596
|
+
const column = table.columns.find(
|
|
597
|
+
(candidate) => dialect === "postgres" ? candidate.name === target.column : candidate.name.toLowerCase() === target.column.toLowerCase()
|
|
598
|
+
);
|
|
599
|
+
if (!column) {
|
|
600
|
+
issues.push({
|
|
601
|
+
severity: "error",
|
|
602
|
+
code: "reference-column-missing",
|
|
603
|
+
owner: owner.name,
|
|
604
|
+
table: model.modelName,
|
|
605
|
+
column: field.name,
|
|
606
|
+
message: `${where}, but "${target.table}" has no column "${target.column}".`,
|
|
607
|
+
hint: `Columns there: ${table.columns.map((candidate) => candidate.name).join(", ")}.`
|
|
608
|
+
});
|
|
609
|
+
continue;
|
|
610
|
+
}
|
|
611
|
+
if (database.dialect === "sqlite" || dialect === "sqlite") continue;
|
|
612
|
+
const expected = _chunkE2ROOWQCcjs.getSqlColumnType.call(void 0, field, database.dialect);
|
|
613
|
+
const mine = _chunkE2ROOWQCcjs.columnTypeFamily.call(void 0, expected);
|
|
614
|
+
const theirs = _chunkE2ROOWQCcjs.columnTypeFamily.call(void 0, column.type);
|
|
615
|
+
if (mine && theirs && mine !== theirs) {
|
|
616
|
+
issues.push({
|
|
617
|
+
severity: "warning",
|
|
618
|
+
code: "reference-type",
|
|
619
|
+
owner: owner.name,
|
|
620
|
+
table: model.modelName,
|
|
621
|
+
column: field.name,
|
|
622
|
+
message: `${where}, but the types differ: ${expected.toLowerCase()} here, ${column.type} there. Lookups by value work; a SQL join needs a cast and a foreign key is not possible.`,
|
|
623
|
+
hint: theirs === "uuid" && mine === "text" ? 'Farm stores "uuid" fields as text in Postgres. Cast in joins, for example "users"."id"::text.' : `Change "${field.name}" to match "${target.table}.${target.column}" if you join on it.`
|
|
624
|
+
});
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
_chunkS3JO3N4Hcjs.__name.call(void 0, checkReferences, "checkReferences");
|
|
630
|
+
async function checkExtensions(owner, extensions, databaseForTable, ownDatabase, allowExtend, issues) {
|
|
631
|
+
for (const extension of extensions) {
|
|
632
|
+
const database = _nullishCoalesce(databaseForTable(extension.table), () => ( ownDatabase));
|
|
633
|
+
const table = await _chunkE2ROOWQCcjs.describeSchemaTable.call(void 0, database.executor, database.dialect, extension.table);
|
|
634
|
+
const columns = extension.fields.map(({ field }) => field.name);
|
|
635
|
+
if (!table) {
|
|
636
|
+
issues.push({
|
|
637
|
+
severity: "error",
|
|
638
|
+
code: "extend-table-missing",
|
|
639
|
+
owner: owner.name,
|
|
640
|
+
table: extension.table,
|
|
641
|
+
message: `${owner.name} adds ${columns.map((column) => `"${column}"`).join(", ")} to "${extension.table}", which does not exist.`,
|
|
642
|
+
hint: "Run the migration that creates it (your ORM's, or a library's such as Better Auth) first."
|
|
643
|
+
});
|
|
644
|
+
continue;
|
|
645
|
+
}
|
|
646
|
+
const allowed = _chunkE2ROOWQCcjs.isSchemaExtensionAllowed.call(void 0, allowExtend, extension);
|
|
647
|
+
for (const { field } of extension.fields) {
|
|
648
|
+
const existing = table.columns.find(
|
|
649
|
+
(column) => database.dialect === "postgres" ? column.name === field.name : column.name.toLowerCase() === field.name.toLowerCase()
|
|
650
|
+
);
|
|
651
|
+
if (!existing) {
|
|
652
|
+
const command = owner.kind === "plugin" ? `\`farm ${owner.name} migrate --apply\`` : "your migration tool";
|
|
653
|
+
issues.push({
|
|
654
|
+
severity: "error",
|
|
655
|
+
code: "extend-column-missing",
|
|
656
|
+
owner: owner.name,
|
|
657
|
+
table: extension.table,
|
|
658
|
+
column: field.name,
|
|
659
|
+
message: `${owner.name} needs "${extension.table}.${field.name}", which does not exist.`,
|
|
660
|
+
hint: allowed ? `Add it with ${command}. If your ORM owns "${extension.table}", add the column to its schema instead.` : `Allow it in farm.config with \`${_chunkE2ROOWQCcjs.describeSchemaExtensionApproval.call(void 0, extension)}\`, then add it with ${command}. If your ORM owns "${extension.table}", add the column to its schema instead.`
|
|
661
|
+
});
|
|
662
|
+
continue;
|
|
663
|
+
}
|
|
664
|
+
if (database.dialect === "sqlite") continue;
|
|
665
|
+
const expected = _chunkE2ROOWQCcjs.getSqlColumnType.call(void 0, field, database.dialect);
|
|
666
|
+
const mine = _chunkE2ROOWQCcjs.columnTypeFamily.call(void 0, expected);
|
|
667
|
+
const theirs = _chunkE2ROOWQCcjs.columnTypeFamily.call(void 0, existing.type);
|
|
668
|
+
if (mine && theirs && mine !== theirs) {
|
|
669
|
+
issues.push({
|
|
670
|
+
severity: "warning",
|
|
671
|
+
code: "extend-column-type",
|
|
672
|
+
owner: owner.name,
|
|
673
|
+
table: extension.table,
|
|
674
|
+
column: field.name,
|
|
675
|
+
message: `"${extension.table}.${field.name}" is ${existing.type}; ${owner.name} expects ${expected.toLowerCase()}.`
|
|
676
|
+
});
|
|
677
|
+
}
|
|
678
|
+
}
|
|
679
|
+
}
|
|
680
|
+
}
|
|
681
|
+
_chunkS3JO3N4Hcjs.__name.call(void 0, checkExtensions, "checkExtensions");
|
|
682
|
+
function formatSchemaCheck(report) {
|
|
683
|
+
if (report.owners.length === 0) {
|
|
684
|
+
return "No integration or plugin declares database tables.";
|
|
685
|
+
}
|
|
686
|
+
const lines = [];
|
|
687
|
+
for (const owner of report.owners) {
|
|
688
|
+
const ownIssues = report.issues.filter((issue) => issue.owner === owner.name);
|
|
689
|
+
const details = [
|
|
690
|
+
owner.kind,
|
|
691
|
+
...owner.dialect ? [owner.dialect] : [],
|
|
692
|
+
..._optionalChain([owner, 'access', _34 => _34.dependsOn, 'optionalAccess', _35 => _35.length]) ? [`needs ${owner.dependsOn.join(", ")}`] : []
|
|
693
|
+
];
|
|
694
|
+
const label = `${owner.name} (${details.join(", ")})`;
|
|
695
|
+
if (!owner.relational) {
|
|
696
|
+
lines.push(`- ${label}: stores data in a key/value mount, nothing to check`);
|
|
697
|
+
continue;
|
|
698
|
+
}
|
|
699
|
+
lines.push(
|
|
700
|
+
ownIssues.length === 0 ? `\u2713 ${label}: ${owner.tables.length} table(s) match` : `${ownIssues.some((issue) => issue.severity === "error") ? "\u2717" : "!"} ${label}`
|
|
701
|
+
);
|
|
702
|
+
for (const issue of ownIssues) {
|
|
703
|
+
lines.push(` ${issue.severity === "error" ? "error " : "warning"} ${issue.message}`);
|
|
704
|
+
if (issue.hint) lines.push(` ${issue.hint}`);
|
|
705
|
+
}
|
|
706
|
+
}
|
|
707
|
+
for (const issue of report.issues.filter(
|
|
708
|
+
(candidate) => !report.owners.some((owner) => owner.name === candidate.owner)
|
|
709
|
+
)) {
|
|
710
|
+
lines.push(`\u2717 ${issue.owner}: ${issue.message}`);
|
|
711
|
+
}
|
|
712
|
+
const errors = report.issues.filter((issue) => issue.severity === "error").length;
|
|
713
|
+
const warnings = report.issues.length - errors;
|
|
714
|
+
lines.push("", `${errors} error(s), ${warnings} warning(s)`);
|
|
715
|
+
return lines.join("\n");
|
|
716
|
+
}
|
|
717
|
+
_chunkS3JO3N4Hcjs.__name.call(void 0, formatSchemaCheck, "formatSchemaCheck");
|
|
718
|
+
|
|
719
|
+
|
|
720
|
+
|
|
721
|
+
|
|
722
|
+
|
|
723
|
+
|
|
724
|
+
|
|
725
|
+
exports.collectSchemaDependencies = collectSchemaDependencies; exports.orderSchemaOwners = orderSchemaOwners; exports.collectSchemaOwners = collectSchemaOwners; exports.checkSchema = checkSchema; exports.formatSchemaCheck = formatSchemaCheck;
|