@classytic/arc 2.23.0 → 2.28.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (147) hide show
  1. package/README.md +2 -0
  2. package/dist/{BaseController-BQ8KNvWC.mjs → BaseController-B65zbz9m.mjs} +94 -23
  3. package/dist/QueryCache-DOMT_iq7.d.mts +72 -0
  4. package/dist/actionPermissions-CAphcmUG.mjs +24 -0
  5. package/dist/{applyPermissionResult-Tw4iXtlf.mjs → applyPermissionResult-BnyVE9eD.mjs} +10 -0
  6. package/dist/audit/index.d.mts +32 -3
  7. package/dist/audit/index.mjs +7 -4
  8. package/dist/auth/index.d.mts +2 -2
  9. package/dist/auth/index.mjs +263 -259
  10. package/dist/{buildHandler-D_2ULWxZ.mjs → buildHandler-Dtwd8fdz.mjs} +1 -1
  11. package/dist/cache/index.d.mts +41 -3
  12. package/dist/cache/index.mjs +33 -4
  13. package/dist/cleanup/index.d.mts +313 -0
  14. package/dist/cleanup/index.mjs +1267 -0
  15. package/dist/cli/commands/describe.d.mts +1 -1
  16. package/dist/cli/commands/docs.mjs +1 -1
  17. package/dist/cli/commands/generate.mjs +1 -1
  18. package/dist/cli/commands/init.mjs +1 -1
  19. package/dist/cli/index.mjs +2 -2
  20. package/dist/context/index.mjs +2 -64
  21. package/dist/core/index.d.mts +3 -3
  22. package/dist/core/index.mjs +5 -4
  23. package/dist/core-BGa8TXJR.mjs +221 -0
  24. package/dist/{createActionRouter-BuOv-m4Y.mjs → createActionRouter-C-N7z2EL.mjs} +3 -2
  25. package/dist/{createAggregationRouter-CgJv_BU_.mjs → createAggregationRouter-wzwFa_dW.mjs} +3 -3
  26. package/dist/{createApp-CjOeWJ9_.mjs → createApp-Du5G54TM.mjs} +187 -96
  27. package/dist/{core-DQ6rDTyH.mjs → defineResource-2zvVVpxg.mjs} +297 -230
  28. package/dist/docs/index.d.mts +1 -1
  29. package/dist/docs/index.mjs +2 -2
  30. package/dist/{elevation-COpYKt2h.mjs → elevation-CIz1GjGm.mjs} +4 -3
  31. package/dist/{eventPlugin-A6EbthXR.d.mts → eventPlugin-Bg3cP2_u.d.mts} +38 -3
  32. package/dist/{eventPlugin-DJG2D7sy.mjs → eventPlugin-DrQ_FesK.mjs} +22 -4
  33. package/dist/events/index.d.mts +83 -314
  34. package/dist/events/index.mjs +183 -95
  35. package/dist/events/transports/redis-stream-entry.d.mts +1 -1
  36. package/dist/events/transports/redis-stream-entry.mjs +24 -2
  37. package/dist/factory/index.d.mts +5 -5
  38. package/dist/factory/index.mjs +30 -8
  39. package/dist/{fastify-augmentation-g_f9omSc.d.mts → fastify-augmentation-OzYGIiU1.d.mts} +26 -2
  40. package/dist/{generate-usRSdQmP.mjs → generate-D0wZupBg.mjs} +1 -1
  41. package/dist/headers-BvlQSDMB.mjs +45 -0
  42. package/dist/health-CB_m4S32.mjs +377 -0
  43. package/dist/hooks/index.d.mts +1 -1
  44. package/dist/idempotency/index.mjs +27 -3
  45. package/dist/{index-wMoWBLkn.d.mts → index-BMnbzvtO.d.mts} +3 -3
  46. package/dist/{integrations/jobs.d.mts → index-CG4yqMDB.d.mts} +82 -2
  47. package/dist/index-CZY4EGga.d.mts +107 -0
  48. package/dist/{index-CC5ruDGh.d.mts → index-CjVg-Epg.d.mts} +37 -5
  49. package/dist/{index-BBsvQt7U.d.mts → index-DPRH0Cme.d.mts} +36 -106
  50. package/dist/index.d.mts +6 -6
  51. package/dist/index.mjs +7 -6
  52. package/dist/{init-CjO4p_q1.mjs → init-tlRSt667.mjs} +206 -208
  53. package/dist/integrations/event-gateway.d.mts +1 -1
  54. package/dist/integrations/event-gateway.mjs +1 -1
  55. package/dist/integrations/index.d.mts +3 -3
  56. package/dist/integrations/jobs/index.d.mts +2 -0
  57. package/dist/integrations/{jobs.mjs → jobs/index.mjs} +110 -67
  58. package/dist/integrations/mcp/index.d.mts +4 -4
  59. package/dist/integrations/mcp/index.mjs +2 -2
  60. package/dist/integrations/mcp/testing.d.mts +1 -1
  61. package/dist/integrations/mcp/testing.mjs +1 -1
  62. package/dist/integrations/webhooks.d.mts +37 -30
  63. package/dist/integrations/webhooks.mjs +51 -62
  64. package/dist/integrations/websocket-redis.d.mts +1 -1
  65. package/dist/integrations/websocket.d.mts +1 -1
  66. package/dist/integrations/websocket.mjs +41 -14
  67. package/dist/{interface-C1_WLTMK.d.mts → interface-BGZCzOGL.d.mts} +24 -31
  68. package/dist/{mcpPlugin-BtzIL_kM.mjs → mcpPlugin-Cs6nRGCt.mjs} +12 -10
  69. package/dist/{memory-CLXA2VeJ.mjs → memory-CmnzXE5Z.mjs} +29 -0
  70. package/dist/middleware/index.d.mts +17 -1
  71. package/dist/middleware/index.mjs +1 -1
  72. package/dist/migrations/index.d.mts +94 -44
  73. package/dist/migrations/index.mjs +196 -44
  74. package/dist/module-_-M7C5ES.mjs +29 -0
  75. package/dist/{multipartBody-CHEQSZ6G.mjs → multipartBody-D0eBvkeq.mjs} +17 -0
  76. package/dist/{openapi-jSDx-VDv.mjs → openapi-BLV4OMXb.mjs} +3 -3
  77. package/dist/permissions/index.d.mts +2 -2
  78. package/dist/permissions/index.mjs +3 -3
  79. package/dist/{permissions-tbxFHxjZ.mjs → permissions-BrtiBKGs.mjs} +229 -229
  80. package/dist/pipeline/index.d.mts +1 -1
  81. package/dist/{actionPermissions-lszoJle1.mjs → pipeline-BGRnV-To.mjs} +4 -27
  82. package/dist/plugins/index.d.mts +6 -77
  83. package/dist/plugins/index.mjs +11 -95
  84. package/dist/plugins/response-cache.mjs +1 -0
  85. package/dist/plugins/tracing-entry.mjs +1 -1
  86. package/dist/{index-Ba10fdKp.d.mts → preloadResources-CM4uUaFv.d.mts} +51 -50
  87. package/dist/preloadResources-DSY5HGpS.mjs +45 -0
  88. package/dist/presets/filesUpload.d.mts +3 -3
  89. package/dist/presets/filesUpload.mjs +3 -3
  90. package/dist/presets/index.d.mts +2 -1
  91. package/dist/presets/index.mjs +1 -1
  92. package/dist/presets/multiTenant.d.mts +1 -1
  93. package/dist/presets/multiTenant.mjs +1 -1
  94. package/dist/presets/search.d.mts +2 -2
  95. package/dist/presets/search.mjs +1 -1
  96. package/dist/{presets-BOe4Ugkl.mjs → presets-DwFDVKP0.mjs} +2 -2
  97. package/dist/{queryCachePlugin-DzqLN904.mjs → queryCachePlugin-DSGuSVLW.mjs} +39 -8
  98. package/dist/{queryCachePlugin-CfYWq-Ak.d.mts → queryCachePlugin-br4otiqF.d.mts} +2 -2
  99. package/dist/{registerRoute-CWO6mdYe.mjs → rateLimit-DrED-C4v.mjs} +2 -109
  100. package/dist/{realtime-I8OrfnMR.mjs → realtime-DEuDu9io.mjs} +3 -3
  101. package/dist/{redis-stream-iVR2l7aS.d.mts → redis-stream-uIaauNpZ.d.mts} +22 -0
  102. package/dist/registerRoute-DTp18Ah_.mjs +108 -0
  103. package/dist/registry/index.d.mts +2 -2
  104. package/dist/registry/index.mjs +1 -1
  105. package/dist/{registry-vcOCtPij.mjs → registry-9km_w1aP.mjs} +15 -0
  106. package/dist/renewingLease-3cuQH7h8.mjs +44 -0
  107. package/dist/{requestContext-BZKOr13H.mjs → requestContext-MrlJwECf.mjs} +2 -2
  108. package/dist/schedules-CjOd2MG9.mjs +113 -0
  109. package/dist/schemas/index.d.mts +67 -67
  110. package/dist/schemas/index.mjs +2 -3
  111. package/dist/scim/index.mjs +1 -2
  112. package/dist/scope/index.d.mts +2 -2
  113. package/dist/scope/index.mjs +4 -4
  114. package/dist/{scope-LONQ3mfZ.mjs → scope-DfaPntpo.mjs} +4 -5
  115. package/dist/{sse-0u4P4-OI.mjs → sse-BQ1w0dfl.mjs} +1 -1
  116. package/dist/testing/cleanupStoreContract.d.mts +10 -0
  117. package/dist/testing/cleanupStoreContract.mjs +375 -0
  118. package/dist/testing/index.d.mts +5 -3
  119. package/dist/testing/index.mjs +4 -2
  120. package/dist/testing/outboxStoreContract.d.mts +13 -0
  121. package/dist/testing/outboxStoreContract.mjs +247 -0
  122. package/dist/transactionContext-PNdoyLLm.mjs +64 -0
  123. package/dist/types/index.d.mts +4 -4
  124. package/dist/{types-bHblZ9YN.mjs → types-CSyCxl2V.mjs} +38 -7
  125. package/dist/types-C_ZZRcD6.d.mts +450 -0
  126. package/dist/{module-B4u10iOJ.d.mts → types-Cu6vVJmh.d.mts} +196 -60
  127. package/dist/{types-DH0GupI7.d.mts → types-DjC-KUCz.d.mts} +118 -20
  128. package/dist/{types-Csxga7d3.d.mts → types-Dmw-6Qeo.d.mts} +96 -4
  129. package/dist/{types-5OuqeTDX.d.mts → types-QFGc3Cjv.d.mts} +1 -1
  130. package/dist/usage/index.d.mts +3 -52
  131. package/dist/usage/index.mjs +0 -0
  132. package/dist/userHelpers-Cg_y3fBz.mjs +29 -0
  133. package/dist/utils/index.d.mts +58 -85
  134. package/dist/utils/index.mjs +4 -2
  135. package/dist/{utils-CZyeRXTh.mjs → utils-taUVD4p3.mjs} +47 -337
  136. package/dist/{validate-C2mGgSXg.mjs → validate-Bk44F2yT.mjs} +1 -1
  137. package/dist/{versioning-D6PvCwpq.d.mts → versioning-DXgY5BUm.d.mts} +11 -29
  138. package/dist/{versioning-Dk-71iIz.mjs → versioning-gKWyryT3.mjs} +8 -1
  139. package/dist/{websocket-uuWqM6UY.d.mts → websocket-_Pd0CgR0.d.mts} +15 -1
  140. package/package.json +541 -513
  141. package/skills/arc/references/api-reference.md +3 -1
  142. package/skills/arc/references/integrations.md +20 -11
  143. package/dist/QueryCache-Z1B38koh.d.mts +0 -40
  144. package/dist/betterAuthOpenApi-CV1lxpRX.mjs +0 -2
  145. package/dist/health-ScyjIVo5.mjs +0 -202
  146. package/dist/requestId-5BhTVzBv.mjs +0 -113
  147. package/dist/types-XTApa8b6.mjs +0 -24
@@ -1,4 +1,3 @@
1
- import { t as __exportAll } from "./rolldown-runtime-8H4AJuhK.mjs";
2
1
  import * as fs from "node:fs/promises";
3
2
  import * as path from "node:path";
4
3
  import { dirname, join } from "node:path";
@@ -6,6 +5,206 @@ import { fileURLToPath } from "node:url";
6
5
  import { accessSync, existsSync, readFileSync } from "node:fs";
7
6
  import * as readline from "node:readline";
8
7
  import { execSync, spawn } from "node:child_process";
8
+ //#region src/cli/commands/init/dependency-plan.ts
9
+ /**
10
+ * Single source of truth for scaffolded project dependencies.
11
+ *
12
+ * Two layers keep the scaffold from ever contradicting the arc release
13
+ * that ships it:
14
+ *
15
+ * 1. The static table below — tracks published npm latest, bumped on
16
+ * release. Serves as the offline fallback.
17
+ * 2. A runtime overlay from arc's OWN package.json (version + declared
18
+ * peer floors). The 2.20.0 review found the static pins had drifted
19
+ * (`arc ^2.18.5` + `primitives ^0.6.0` while arc 2.20 peers demand
20
+ * >=0.9.0 → ERESOLVE on the first `arc init` a new user runs).
21
+ * Deriving from the installed package.json makes that class of
22
+ * breakage structurally impossible: the scaffold always pins the
23
+ * arc version actually running and ranges that satisfy its peers.
24
+ *
25
+ * Used by both `packageJsonTemplate` (declares the deps in the generated
26
+ * `package.json` so `npm install` works without a pre-pass) and
27
+ * `installDependencies` (runs the package manager's `install` against
28
+ * the declared ranges). One source — no drift.
29
+ */
30
+ const SCAFFOLD_DEP_VERSIONS = {
31
+ core: {
32
+ "@classytic/arc": "^2.20.0",
33
+ "@classytic/primitives": "^0.11.0",
34
+ "@classytic/repo-core": "^0.8.0",
35
+ "@fastify/cors": "^11.2.0",
36
+ "@fastify/helmet": "^13.0.2",
37
+ "@fastify/rate-limit": "^10.3.0",
38
+ "@fastify/sensible": "^6.0.4",
39
+ "@fastify/under-pressure": "^9.0.3",
40
+ dotenv: "^17.4.2",
41
+ fastify: "^5.8.5",
42
+ zod: "^4.3.6"
43
+ },
44
+ authJwt: {
45
+ "@fastify/jwt": "^10.1.0",
46
+ bcryptjs: "^3.0.3"
47
+ },
48
+ authBetterAuth: {
49
+ "better-auth": "^1.6.11",
50
+ mongodb: "^7.2.0"
51
+ },
52
+ authBetterAuthApiKey: { "@better-auth/api-key": "^1.6.11" },
53
+ adapterMongokit: {
54
+ "@classytic/mongokit": "^3.21.0",
55
+ mongoose: "^9.6.2"
56
+ },
57
+ devCommon: {
58
+ "@biomejs/biome": "^2.4.15",
59
+ "pino-pretty": "^13.1.3",
60
+ vitest: "^4.1.7"
61
+ },
62
+ devMongokit: { "mongodb-memory-server": "^11.1.0" },
63
+ devTypescript: {
64
+ "@types/node": "^22.10.0",
65
+ tsx: "^4.22.3",
66
+ typescript: "^7.0.2"
67
+ },
68
+ typesJwt: { "@types/bcryptjs": "^3.0.0" }
69
+ };
70
+ /**
71
+ * Locate arc's own package.json by walking up from the executing file.
72
+ * A path walk (vs `require.resolve('@classytic/arc/package.json')`) works
73
+ * regardless of bundle chunk layout and of package.json not being in the
74
+ * exports map. Returns undefined when not found — callers fall back to
75
+ * the static table.
76
+ */
77
+ function readOwnPackageJson() {
78
+ try {
79
+ let dir = dirname(fileURLToPath(import.meta.url));
80
+ for (let depth = 0; depth < 6; depth++) {
81
+ const candidate = join(dir, "package.json");
82
+ if (existsSync(candidate)) {
83
+ const parsed = JSON.parse(readFileSync(candidate, "utf8"));
84
+ if (parsed.name === "@classytic/arc") return parsed;
85
+ }
86
+ const parent = dirname(dir);
87
+ if (parent === dir) break;
88
+ dir = parent;
89
+ }
90
+ } catch {}
91
+ }
92
+ /** First x.y.z triple in a range string, or undefined. */
93
+ function parseFloor(range) {
94
+ const m = /(\d+)\.(\d+)\.(\d+)/.exec(range);
95
+ if (!m) return void 0;
96
+ return [
97
+ Number(m[1]),
98
+ Number(m[2]),
99
+ Number(m[3])
100
+ ];
101
+ }
102
+ function floorLessThan(a, b) {
103
+ if (a[0] !== b[0]) return a[0] < b[0];
104
+ if (a[1] !== b[1]) return a[1] < b[1];
105
+ return a[2] < b[2];
106
+ }
107
+ /**
108
+ * Overlay live truth from arc's own package.json onto the static pins:
109
+ * - `@classytic/arc` pins the exact running version (`^<version>`).
110
+ * - Any scaffolded dep that is also an arc peer gets raised to `^<peer
111
+ * floor>` when the static pin's floor is BELOW the declared peer floor
112
+ * (never lowered — static pins may legitimately be ahead of the floor).
113
+ */
114
+ const latestCache = /* @__PURE__ */ new Map();
115
+ function allScaffoldPackageNames() {
116
+ const names = /* @__PURE__ */ new Set();
117
+ for (const group of Object.values(SCAFFOLD_DEP_VERSIONS)) for (const name of Object.keys(group)) names.add(name);
118
+ return [...names];
119
+ }
120
+ async function primeLatestScaffoldVersions(options) {
121
+ const timeoutMs = options?.timeoutMs ?? 3500;
122
+ const registry = (options?.registry ?? process.env.npm_config_registry ?? "https://registry.npmjs.org").replace(/\/$/, "");
123
+ const names = allScaffoldPackageNames();
124
+ const results = await Promise.allSettled(names.map(async (name) => {
125
+ const res = await fetch(`${registry}/${name}/latest`, {
126
+ signal: AbortSignal.timeout(timeoutMs),
127
+ headers: { accept: "application/json" }
128
+ });
129
+ if (!res.ok) throw new Error(String(res.status));
130
+ const body = await res.json();
131
+ if (typeof body.version === "string" && /^\d+\.\d+\.\d+$/.test(body.version)) latestCache.set(name, body.version);
132
+ }));
133
+ return {
134
+ resolved: latestCache.size,
135
+ total: results.length
136
+ };
137
+ }
138
+ function parseBareVersion(v) {
139
+ const m = /^(\d+)\.(\d+)\.(\d+)$/.exec(v);
140
+ return m ? [
141
+ Number(m[1]),
142
+ Number(m[2]),
143
+ Number(m[3])
144
+ ] : void 0;
145
+ }
146
+ function applyLatestOverlay(dependencies) {
147
+ if (latestCache.size === 0) return;
148
+ for (const [name, currentRange] of Object.entries(dependencies)) {
149
+ const latest = latestCache.get(name);
150
+ if (!latest || latest.includes("-")) continue;
151
+ const latestV = parseBareVersion(latest);
152
+ const currentFloor = parseFloor(currentRange);
153
+ if (!latestV || !currentFloor) continue;
154
+ if (!floorLessThan(currentFloor, latestV)) continue;
155
+ if (latestV[0] !== currentFloor[0] && !name.startsWith("@classytic/")) continue;
156
+ dependencies[name] = `^${latest}`;
157
+ }
158
+ }
159
+ function overlayLiveArcVersions(dependencies) {
160
+ const own = readOwnPackageJson();
161
+ if (!own) return;
162
+ if (own.version && dependencies["@classytic/arc"]) dependencies["@classytic/arc"] = `^${own.version}`;
163
+ const peers = own.peerDependencies ?? {};
164
+ for (const [name, staticRange] of Object.entries(dependencies)) {
165
+ const peerRange = peers[name];
166
+ if (!peerRange) continue;
167
+ const peerFloor = parseFloor(peerRange);
168
+ const staticFloor = parseFloor(staticRange);
169
+ if (!peerFloor || !staticFloor) continue;
170
+ if (floorLessThan(staticFloor, peerFloor)) dependencies[name] = `^${peerFloor.join(".")}`;
171
+ }
172
+ }
173
+ /**
174
+ * Resolve the dependency manifest for a scaffold configuration.
175
+ *
176
+ * Returns sorted records (alphabetical by package name) so the generated
177
+ * `package.json` is deterministic — diffs across re-runs stay clean.
178
+ */
179
+ function resolveScaffoldDependencies(config) {
180
+ const dependencies = { ...SCAFFOLD_DEP_VERSIONS.core };
181
+ const devDependencies = { ...SCAFFOLD_DEP_VERSIONS.devCommon };
182
+ if (config.auth === "better-auth") {
183
+ Object.assign(dependencies, SCAFFOLD_DEP_VERSIONS.authBetterAuth);
184
+ devDependencies["@fastify/jwt"] = SCAFFOLD_DEP_VERSIONS.authJwt["@fastify/jwt"];
185
+ if (config.apiKey) Object.assign(dependencies, SCAFFOLD_DEP_VERSIONS.authBetterAuthApiKey);
186
+ } else {
187
+ Object.assign(dependencies, SCAFFOLD_DEP_VERSIONS.authJwt);
188
+ if (config.typescript) Object.assign(devDependencies, SCAFFOLD_DEP_VERSIONS.typesJwt);
189
+ }
190
+ if (config.adapter === "mongokit") {
191
+ Object.assign(dependencies, SCAFFOLD_DEP_VERSIONS.adapterMongokit);
192
+ Object.assign(devDependencies, SCAFFOLD_DEP_VERSIONS.devMongokit);
193
+ }
194
+ if (config.typescript) Object.assign(devDependencies, SCAFFOLD_DEP_VERSIONS.devTypescript);
195
+ applyLatestOverlay(dependencies);
196
+ applyLatestOverlay(devDependencies);
197
+ overlayLiveArcVersions(dependencies);
198
+ return {
199
+ dependencies: sortByKey(dependencies),
200
+ devDependencies: sortByKey(devDependencies)
201
+ };
202
+ }
203
+ /** Sort a record alphabetically by key — package.json convention. */
204
+ function sortByKey(record) {
205
+ return Object.fromEntries(Object.entries(record).sort(([a], [b]) => a.localeCompare(b)));
206
+ }
207
+ //#endregion
9
208
  //#region src/cli/commands/init/templates/adapter.ts
10
209
  function createAdapterTemplate(config) {
11
210
  const ts = config.typescript;
@@ -267,7 +466,10 @@ export async function createAppInstance()${ts ? ": Promise<FastifyInstance>" : "
267
466
  allowedHeaders: config.cors.allowedHeaders,
268
467
  credentials: config.cors.credentials,
269
468
  },
270
- trustProxy: true,
469
+ // One proxy hop (the typical LB / reverse-proxy deploy). Widen to a CIDR
470
+ // list or \`true\` only if you know every hop is yours; \`false\` if clients
471
+ // connect directly. Arc's production preset defaults to \`false\` (fail-closed).
472
+ trustProxy: 1,
271
473
  arcPlugins: {
272
474
  metrics: config.env === 'production', // Prometheus /_metrics endpoint
273
475
  ${config.adapter === "mongokit" ? ` // Readiness probe (/_health/ready) reports DOWN until Mongo connects —
@@ -1018,211 +1220,6 @@ ${config.adapter === "mongokit" ? ` await mongoose.connection.collection('use
1018
1220
  `;
1019
1221
  }
1020
1222
  //#endregion
1021
- //#region src/cli/commands/init/dependency-plan.ts
1022
- /**
1023
- * Single source of truth for scaffolded project dependencies.
1024
- *
1025
- * Two layers keep the scaffold from ever contradicting the arc release
1026
- * that ships it:
1027
- *
1028
- * 1. The static table below — tracks published npm latest, bumped on
1029
- * release. Serves as the offline fallback.
1030
- * 2. A runtime overlay from arc's OWN package.json (version + declared
1031
- * peer floors). The 2.20.0 review found the static pins had drifted
1032
- * (`arc ^2.18.5` + `primitives ^0.6.0` while arc 2.20 peers demand
1033
- * >=0.9.0 → ERESOLVE on the first `arc init` a new user runs).
1034
- * Deriving from the installed package.json makes that class of
1035
- * breakage structurally impossible: the scaffold always pins the
1036
- * arc version actually running and ranges that satisfy its peers.
1037
- *
1038
- * Used by both `packageJsonTemplate` (declares the deps in the generated
1039
- * `package.json` so `npm install` works without a pre-pass) and
1040
- * `installDependencies` (runs the package manager's `install` against
1041
- * the declared ranges). One source — no drift.
1042
- */
1043
- var dependency_plan_exports = /* @__PURE__ */ __exportAll({
1044
- SCAFFOLD_DEP_VERSIONS: () => SCAFFOLD_DEP_VERSIONS,
1045
- primeLatestScaffoldVersions: () => primeLatestScaffoldVersions,
1046
- resolveScaffoldDependencies: () => resolveScaffoldDependencies
1047
- });
1048
- const SCAFFOLD_DEP_VERSIONS = {
1049
- core: {
1050
- "@classytic/arc": "^2.20.0",
1051
- "@classytic/primitives": "^0.11.0",
1052
- "@classytic/repo-core": "^0.8.0",
1053
- "@fastify/cors": "^11.2.0",
1054
- "@fastify/helmet": "^13.0.2",
1055
- "@fastify/rate-limit": "^10.3.0",
1056
- "@fastify/sensible": "^6.0.4",
1057
- "@fastify/under-pressure": "^9.0.3",
1058
- dotenv: "^17.4.2",
1059
- fastify: "^5.8.5",
1060
- zod: "^4.3.6"
1061
- },
1062
- authJwt: {
1063
- "@fastify/jwt": "^10.1.0",
1064
- bcryptjs: "^3.0.3"
1065
- },
1066
- authBetterAuth: {
1067
- "better-auth": "^1.6.11",
1068
- mongodb: "^7.2.0"
1069
- },
1070
- authBetterAuthApiKey: { "@better-auth/api-key": "^1.6.11" },
1071
- adapterMongokit: {
1072
- "@classytic/mongokit": "^3.21.0",
1073
- mongoose: "^9.6.2"
1074
- },
1075
- devCommon: {
1076
- "@biomejs/biome": "^2.4.15",
1077
- "pino-pretty": "^13.1.3",
1078
- vitest: "^4.1.7"
1079
- },
1080
- devMongokit: { "mongodb-memory-server": "^11.1.0" },
1081
- devTypescript: {
1082
- "@types/node": "^22.10.0",
1083
- tsx: "^4.22.3",
1084
- typescript: "^7.0.2"
1085
- },
1086
- typesJwt: { "@types/bcryptjs": "^3.0.0" }
1087
- };
1088
- /**
1089
- * Locate arc's own package.json by walking up from the executing file.
1090
- * A path walk (vs `require.resolve('@classytic/arc/package.json')`) works
1091
- * regardless of bundle chunk layout and of package.json not being in the
1092
- * exports map. Returns undefined when not found — callers fall back to
1093
- * the static table.
1094
- */
1095
- function readOwnPackageJson() {
1096
- try {
1097
- let dir = dirname(fileURLToPath(import.meta.url));
1098
- for (let depth = 0; depth < 6; depth++) {
1099
- const candidate = join(dir, "package.json");
1100
- if (existsSync(candidate)) {
1101
- const parsed = JSON.parse(readFileSync(candidate, "utf8"));
1102
- if (parsed.name === "@classytic/arc") return parsed;
1103
- }
1104
- const parent = dirname(dir);
1105
- if (parent === dir) break;
1106
- dir = parent;
1107
- }
1108
- } catch {}
1109
- }
1110
- /** First x.y.z triple in a range string, or undefined. */
1111
- function parseFloor(range) {
1112
- const m = /(\d+)\.(\d+)\.(\d+)/.exec(range);
1113
- if (!m) return void 0;
1114
- return [
1115
- Number(m[1]),
1116
- Number(m[2]),
1117
- Number(m[3])
1118
- ];
1119
- }
1120
- function floorLessThan(a, b) {
1121
- if (a[0] !== b[0]) return a[0] < b[0];
1122
- if (a[1] !== b[1]) return a[1] < b[1];
1123
- return a[2] < b[2];
1124
- }
1125
- /**
1126
- * Overlay live truth from arc's own package.json onto the static pins:
1127
- * - `@classytic/arc` pins the exact running version (`^<version>`).
1128
- * - Any scaffolded dep that is also an arc peer gets raised to `^<peer
1129
- * floor>` when the static pin's floor is BELOW the declared peer floor
1130
- * (never lowered — static pins may legitimately be ahead of the floor).
1131
- */
1132
- const latestCache = /* @__PURE__ */ new Map();
1133
- function allScaffoldPackageNames() {
1134
- const names = /* @__PURE__ */ new Set();
1135
- for (const group of Object.values(SCAFFOLD_DEP_VERSIONS)) for (const name of Object.keys(group)) names.add(name);
1136
- return [...names];
1137
- }
1138
- async function primeLatestScaffoldVersions(options) {
1139
- const timeoutMs = options?.timeoutMs ?? 3500;
1140
- const registry = (options?.registry ?? process.env.npm_config_registry ?? "https://registry.npmjs.org").replace(/\/$/, "");
1141
- const names = allScaffoldPackageNames();
1142
- const results = await Promise.allSettled(names.map(async (name) => {
1143
- const res = await fetch(`${registry}/${name}/latest`, {
1144
- signal: AbortSignal.timeout(timeoutMs),
1145
- headers: { accept: "application/json" }
1146
- });
1147
- if (!res.ok) throw new Error(String(res.status));
1148
- const body = await res.json();
1149
- if (typeof body.version === "string" && /^\d+\.\d+\.\d+$/.test(body.version)) latestCache.set(name, body.version);
1150
- }));
1151
- return {
1152
- resolved: latestCache.size,
1153
- total: results.length
1154
- };
1155
- }
1156
- function parseBareVersion(v) {
1157
- const m = /^(\d+)\.(\d+)\.(\d+)$/.exec(v);
1158
- return m ? [
1159
- Number(m[1]),
1160
- Number(m[2]),
1161
- Number(m[3])
1162
- ] : void 0;
1163
- }
1164
- function applyLatestOverlay(dependencies) {
1165
- if (latestCache.size === 0) return;
1166
- for (const [name, currentRange] of Object.entries(dependencies)) {
1167
- const latest = latestCache.get(name);
1168
- if (!latest || latest.includes("-")) continue;
1169
- const latestV = parseBareVersion(latest);
1170
- const currentFloor = parseFloor(currentRange);
1171
- if (!latestV || !currentFloor) continue;
1172
- if (!floorLessThan(currentFloor, latestV)) continue;
1173
- if (latestV[0] !== currentFloor[0] && !name.startsWith("@classytic/")) continue;
1174
- dependencies[name] = `^${latest}`;
1175
- }
1176
- }
1177
- function overlayLiveArcVersions(dependencies) {
1178
- const own = readOwnPackageJson();
1179
- if (!own) return;
1180
- if (own.version && dependencies["@classytic/arc"]) dependencies["@classytic/arc"] = `^${own.version}`;
1181
- const peers = own.peerDependencies ?? {};
1182
- for (const [name, staticRange] of Object.entries(dependencies)) {
1183
- const peerRange = peers[name];
1184
- if (!peerRange) continue;
1185
- const peerFloor = parseFloor(peerRange);
1186
- const staticFloor = parseFloor(staticRange);
1187
- if (!peerFloor || !staticFloor) continue;
1188
- if (floorLessThan(staticFloor, peerFloor)) dependencies[name] = `^${peerFloor.join(".")}`;
1189
- }
1190
- }
1191
- /**
1192
- * Resolve the dependency manifest for a scaffold configuration.
1193
- *
1194
- * Returns sorted records (alphabetical by package name) so the generated
1195
- * `package.json` is deterministic — diffs across re-runs stay clean.
1196
- */
1197
- function resolveScaffoldDependencies(config) {
1198
- const dependencies = { ...SCAFFOLD_DEP_VERSIONS.core };
1199
- const devDependencies = { ...SCAFFOLD_DEP_VERSIONS.devCommon };
1200
- if (config.auth === "better-auth") {
1201
- Object.assign(dependencies, SCAFFOLD_DEP_VERSIONS.authBetterAuth);
1202
- devDependencies["@fastify/jwt"] = SCAFFOLD_DEP_VERSIONS.authJwt["@fastify/jwt"];
1203
- if (config.apiKey) Object.assign(dependencies, SCAFFOLD_DEP_VERSIONS.authBetterAuthApiKey);
1204
- } else {
1205
- Object.assign(dependencies, SCAFFOLD_DEP_VERSIONS.authJwt);
1206
- if (config.typescript) Object.assign(devDependencies, SCAFFOLD_DEP_VERSIONS.typesJwt);
1207
- }
1208
- if (config.adapter === "mongokit") {
1209
- Object.assign(dependencies, SCAFFOLD_DEP_VERSIONS.adapterMongokit);
1210
- Object.assign(devDependencies, SCAFFOLD_DEP_VERSIONS.devMongokit);
1211
- }
1212
- if (config.typescript) Object.assign(devDependencies, SCAFFOLD_DEP_VERSIONS.devTypescript);
1213
- applyLatestOverlay(dependencies);
1214
- applyLatestOverlay(devDependencies);
1215
- overlayLiveArcVersions(dependencies);
1216
- return {
1217
- dependencies: sortByKey(dependencies),
1218
- devDependencies: sortByKey(devDependencies)
1219
- };
1220
- }
1221
- /** Sort a record alphabetically by key — package.json convention. */
1222
- function sortByKey(record) {
1223
- return Object.fromEntries(Object.entries(record).sort(([a], [b]) => a.localeCompare(b)));
1224
- }
1225
- //#endregion
1226
1223
  //#region src/cli/commands/init/templates/config.ts
1227
1224
  /**
1228
1225
  * Project-level config templates — package.json, tsconfig, vitest, gitignore,
@@ -2059,6 +2056,8 @@ ${config.tenant === "multi" ? "import { flexibleMultiTenantPreset } from '#share
2059
2056
  import exampleRepository from './example.repository.js';
2060
2057
  import exampleController from './example.controller.js';
2061
2058
 
2059
+ // Fail-closed by default (mongokit >=3.25): invalid/blocked query input →
2060
+ // HTTP 400 instead of silently broadening the result set.
2062
2061
  const queryParser = new QueryParser({
2063
2062
  allowedFilterFields: ['isActive'],
2064
2063
  });
@@ -3441,7 +3440,6 @@ async function init(options = {}) {
3441
3440
  const packageManager = detectPackageManager();
3442
3441
  console.log(`Using package manager: ${packageManager}\n`);
3443
3442
  if (!process.env.VITEST && process.env.ARC_INIT_OFFLINE !== "1") {
3444
- const { primeLatestScaffoldVersions } = await Promise.resolve().then(() => dependency_plan_exports);
3445
3443
  const { resolved, total } = await primeLatestScaffoldVersions().catch(() => ({
3446
3444
  resolved: 0,
3447
3445
  total: 0
@@ -1,5 +1,5 @@
1
1
  import { n as DomainEvent } from "../EventTransport-QmY7A258.mjs";
2
- import { c as WebSocketClient, l as WebSocketMessage } from "../websocket-uuWqM6UY.mjs";
2
+ import { c as WebSocketClient, l as WebSocketMessage } from "../websocket-_Pd0CgR0.mjs";
3
3
  import { FastifyPluginAsync, FastifyRequest } from "fastify";
4
4
  //#region src/integrations/event-gateway.d.ts
5
5
  interface EventGatewayOptions {
@@ -4,7 +4,7 @@ const eventGatewayPluginImpl = async (fastify, opts = {}) => {
4
4
  const { auth = true, orgScoped = false, roomPolicy, maxMessageBytes, maxSubscriptionsPerClient, authenticate } = opts;
5
5
  if (auth && !authenticate && !fastify.hasDecorator("authenticate")) throw new Error("[arc-event-gateway] auth is true but fastify.authenticate is not registered. Register an auth plugin first, provide a custom authenticate function, or set auth: false.");
6
6
  if (opts.sse !== false) {
7
- const { default: ssePlugin } = await import("../sse-0u4P4-OI.mjs").then((n) => n.r);
7
+ const { default: ssePlugin } = await import("../sse-BQ1w0dfl.mjs").then((n) => n.r);
8
8
  await fastify.register(ssePlugin, {
9
9
  path: opts.sse?.path ?? "/events/stream",
10
10
  requireAuth: auth,
@@ -1,7 +1,7 @@
1
- import { c as WebSocketClient, l as WebSocketMessage, u as WebSocketPluginOptions } from "../websocket-uuWqM6UY.mjs";
1
+ import { c as WebSocketClient, l as WebSocketMessage, u as WebSocketPluginOptions } from "../websocket-_Pd0CgR0.mjs";
2
2
  import { EventGatewayOptions } from "./event-gateway.mjs";
3
- import { JobDefinition, JobDispatchOptions, JobDispatcher, JobMeta, JobsPluginOptions, QueueStats } from "./jobs.mjs";
4
- import { _ as ToolDefinition, c as McpAuthResult, d as McpResourceConfig, f as PromptDefinition, g as ToolContext, h as ToolAnnotations, n as CallToolResult, o as CrudOperation, r as CreateMcpServerConfig, t as BetterAuthHandler, u as McpPluginOptions } from "../types-5OuqeTDX.mjs";
3
+ import { a as JobMeta, c as JobsPluginOptions, i as JobDispatcher, l as QueueStats, n as JobDefinition, r as JobDispatchOptions } from "../index-CG4yqMDB.mjs";
4
+ import { _ as ToolDefinition, c as McpAuthResult, d as McpResourceConfig, f as PromptDefinition, g as ToolContext, h as ToolAnnotations, n as CallToolResult, o as CrudOperation, r as CreateMcpServerConfig, t as BetterAuthHandler, u as McpPluginOptions } from "../types-QFGc3Cjv.mjs";
5
5
  import { StreamlinePluginOptions, WorkflowLike, WorkflowRunLike } from "./streamline.mjs";
6
6
  import { WebhookDeliveryRecord, WebhookManager, WebhookPluginOptions, WebhookStore, WebhookSubscription } from "./webhooks.mjs";
7
7
  export type { BetterAuthHandler, CallToolResult, CreateMcpServerConfig, CrudOperation, EventGatewayOptions, JobDefinition, JobDispatchOptions, JobDispatcher, JobMeta, JobsPluginOptions, McpAuthResult, McpPluginOptions, McpResourceConfig, PromptDefinition, QueueStats, StreamlinePluginOptions, ToolAnnotations, ToolContext, ToolDefinition, WebSocketClient, WebSocketMessage, WebSocketPluginOptions, WebhookDeliveryRecord, WebhookManager, WebhookPluginOptions, WebhookStore, WebhookSubscription, WorkflowLike, WorkflowRunLike };
@@ -0,0 +1,2 @@
1
+ import { a as JobMeta, c as JobsPluginOptions, d as ExecuteTimedHandlerOptions, f as TimedHandlerLogger, i as JobDispatcher, l as QueueStats, n as JobDefinition, o as JobRepeatOptions, p as executeTimedHandler, r as JobDispatchOptions, s as JobStatus, t as jobsPlugin, u as defineJob } from "../../index-CG4yqMDB.mjs";
2
+ export { type ExecuteTimedHandlerOptions, type JobDefinition, type JobDispatchOptions, type JobDispatcher, type JobMeta, type JobRepeatOptions, type JobStatus, type JobsPluginOptions, type QueueStats, type TimedHandlerLogger, defineJob, executeTimedHandler, jobsPlugin };