@classytic/arc 2.23.0 → 2.25.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.
- package/dist/{BaseController-BQ8KNvWC.mjs → BaseController--M8EMzt0.mjs} +90 -21
- package/dist/QueryCache-DOMT_iq7.d.mts +72 -0
- package/dist/actionPermissions-CAphcmUG.mjs +24 -0
- package/dist/audit/index.d.mts +32 -3
- package/dist/audit/index.mjs +7 -4
- package/dist/auth/index.d.mts +2 -2
- package/dist/auth/index.mjs +263 -259
- package/dist/{buildHandler-D_2ULWxZ.mjs → buildHandler-Dtwd8fdz.mjs} +1 -1
- package/dist/cache/index.d.mts +41 -3
- package/dist/cache/index.mjs +33 -4
- package/dist/cli/commands/describe.d.mts +1 -1
- package/dist/cli/commands/docs.mjs +1 -1
- package/dist/cli/commands/generate.mjs +1 -1
- package/dist/cli/commands/init.mjs +1 -1
- package/dist/cli/index.mjs +2 -2
- package/dist/context/index.mjs +2 -64
- package/dist/core/index.d.mts +3 -3
- package/dist/core/index.mjs +4 -4
- package/dist/{core-DQ6rDTyH.mjs → core-EUNu0u07.mjs} +296 -11
- package/dist/{createActionRouter-BuOv-m4Y.mjs → createActionRouter-B6GvAuAX.mjs} +3 -2
- package/dist/{createAggregationRouter-CgJv_BU_.mjs → createAggregationRouter-wzwFa_dW.mjs} +3 -3
- package/dist/docs/index.d.mts +1 -1
- package/dist/docs/index.mjs +2 -2
- package/dist/{elevation-COpYKt2h.mjs → elevation-CIz1GjGm.mjs} +4 -3
- package/dist/{eventPlugin-A6EbthXR.d.mts → eventPlugin-Bg3cP2_u.d.mts} +38 -3
- package/dist/{eventPlugin-DJG2D7sy.mjs → eventPlugin-DrQ_FesK.mjs} +22 -4
- package/dist/events/index.d.mts +57 -314
- package/dist/events/index.mjs +163 -91
- package/dist/events/transports/redis-stream-entry.d.mts +1 -1
- package/dist/events/transports/redis-stream-entry.mjs +24 -2
- package/dist/factory/index.d.mts +4 -5
- package/dist/factory/index.mjs +28 -8
- package/dist/{fastify-augmentation-g_f9omSc.d.mts → fastify-augmentation-dPNBVeIj.d.mts} +25 -2
- package/dist/{generate-usRSdQmP.mjs → generate-D0wZupBg.mjs} +1 -1
- package/dist/headers-BvlQSDMB.mjs +45 -0
- package/dist/health-CB_m4S32.mjs +377 -0
- package/dist/hooks/index.d.mts +1 -1
- package/dist/idempotency/index.mjs +27 -3
- package/dist/{index-wMoWBLkn.d.mts → index-BMnbzvtO.d.mts} +3 -3
- package/dist/{integrations/jobs.d.mts → index-CG4yqMDB.d.mts} +82 -2
- package/dist/{index-BBsvQt7U.d.mts → index-DPRH0Cme.d.mts} +36 -106
- package/dist/{module-B4u10iOJ.d.mts → index-KUoxjIq1.d.mts} +263 -23
- package/dist/{index-CC5ruDGh.d.mts → index-f4PTrk3B.d.mts} +37 -5
- package/dist/index.d.mts +6 -6
- package/dist/index.mjs +5 -5
- package/dist/{init-CjO4p_q1.mjs → init-tlRSt667.mjs} +206 -208
- package/dist/integrations/event-gateway.d.mts +1 -1
- package/dist/integrations/event-gateway.mjs +1 -1
- package/dist/integrations/index.d.mts +3 -3
- package/dist/integrations/jobs/index.d.mts +2 -0
- package/dist/integrations/{jobs.mjs → jobs/index.mjs} +110 -67
- package/dist/integrations/mcp/index.d.mts +4 -4
- package/dist/integrations/mcp/index.mjs +2 -2
- package/dist/integrations/mcp/testing.d.mts +1 -1
- package/dist/integrations/mcp/testing.mjs +1 -1
- package/dist/integrations/webhooks.d.mts +37 -30
- package/dist/integrations/webhooks.mjs +51 -62
- package/dist/integrations/websocket-redis.d.mts +1 -1
- package/dist/integrations/websocket.d.mts +1 -1
- package/dist/integrations/websocket.mjs +41 -14
- package/dist/{interface-C1_WLTMK.d.mts → interface-BGZCzOGL.d.mts} +24 -31
- package/dist/{mcpPlugin-BtzIL_kM.mjs → mcpPlugin-Cb7olw0j.mjs} +11 -9
- package/dist/{memory-CLXA2VeJ.mjs → memory-CmnzXE5Z.mjs} +29 -0
- package/dist/middleware/index.d.mts +17 -1
- package/dist/middleware/index.mjs +1 -1
- package/dist/migrations/index.d.mts +94 -44
- package/dist/migrations/index.mjs +196 -44
- package/dist/{multipartBody-CHEQSZ6G.mjs → multipartBody-D0eBvkeq.mjs} +17 -0
- package/dist/{openapi-jSDx-VDv.mjs → openapi-DrLtog_B.mjs} +3 -3
- package/dist/permissions/index.d.mts +2 -2
- package/dist/permissions/index.mjs +2 -2
- package/dist/{permissions-tbxFHxjZ.mjs → permissions-BrtiBKGs.mjs} +229 -229
- package/dist/pipeline/index.d.mts +1 -1
- package/dist/{actionPermissions-lszoJle1.mjs → pipeline-BN5G05rd.mjs} +3 -26
- package/dist/plugins/index.d.mts +6 -77
- package/dist/plugins/index.mjs +11 -95
- package/dist/plugins/response-cache.mjs +1 -0
- package/dist/plugins/tracing-entry.mjs +1 -1
- package/dist/{index-Ba10fdKp.d.mts → preloadResources-0oe-JSSS.d.mts} +50 -50
- package/dist/{createApp-CjOeWJ9_.mjs → preloadResources-DfyngIN9.mjs} +233 -70
- package/dist/presets/filesUpload.d.mts +3 -3
- package/dist/presets/filesUpload.mjs +3 -3
- package/dist/presets/index.d.mts +2 -1
- package/dist/presets/index.mjs +1 -1
- package/dist/presets/multiTenant.d.mts +1 -1
- package/dist/presets/multiTenant.mjs +1 -1
- package/dist/presets/search.d.mts +2 -2
- package/dist/presets/search.mjs +1 -1
- package/dist/{presets-BOe4Ugkl.mjs → presets-DwFDVKP0.mjs} +2 -2
- package/dist/{queryCachePlugin-DzqLN904.mjs → queryCachePlugin-DSGuSVLW.mjs} +39 -8
- package/dist/{queryCachePlugin-CfYWq-Ak.d.mts → queryCachePlugin-br4otiqF.d.mts} +2 -2
- package/dist/{registerRoute-CWO6mdYe.mjs → rateLimit-DrED-C4v.mjs} +2 -109
- package/dist/{realtime-I8OrfnMR.mjs → realtime-Cuw_deA-.mjs} +2 -2
- package/dist/{redis-stream-iVR2l7aS.d.mts → redis-stream-uIaauNpZ.d.mts} +22 -0
- package/dist/registerRoute-v0Wb6Plt.mjs +108 -0
- package/dist/registry/index.d.mts +2 -2
- package/dist/renewingLease-3cuQH7h8.mjs +44 -0
- package/dist/{requestContext-BZKOr13H.mjs → requestContext-MrlJwECf.mjs} +2 -2
- package/dist/schedules-CjOd2MG9.mjs +113 -0
- package/dist/schemas/index.d.mts +67 -67
- package/dist/schemas/index.mjs +2 -3
- package/dist/scim/index.mjs +1 -2
- package/dist/scope/index.d.mts +2 -2
- package/dist/scope/index.mjs +4 -4
- package/dist/{scope-LONQ3mfZ.mjs → scope-DfaPntpo.mjs} +4 -5
- package/dist/{sse-0u4P4-OI.mjs → sse-BQ1w0dfl.mjs} +1 -1
- package/dist/testing/index.d.mts +4 -3
- package/dist/testing/index.mjs +2 -2
- package/dist/transactionContext-PNdoyLLm.mjs +64 -0
- package/dist/types/index.d.mts +4 -4
- package/dist/{types-bHblZ9YN.mjs → types-CSyCxl2V.mjs} +38 -7
- package/dist/{types-DH0GupI7.d.mts → types-DjC-KUCz.d.mts} +118 -20
- package/dist/{types-Csxga7d3.d.mts → types-Dmw-6Qeo.d.mts} +96 -4
- package/dist/{types-5OuqeTDX.d.mts → types-QFGc3Cjv.d.mts} +1 -1
- package/dist/usage/index.d.mts +3 -52
- package/dist/usage/index.mjs +0 -0
- package/dist/userHelpers-Cg_y3fBz.mjs +29 -0
- package/dist/utils/index.d.mts +58 -85
- package/dist/utils/index.mjs +4 -2
- package/dist/{utils-CZyeRXTh.mjs → utils-taUVD4p3.mjs} +47 -337
- package/dist/{validate-C2mGgSXg.mjs → validate-Bk44F2yT.mjs} +1 -1
- package/dist/{versioning-D6PvCwpq.d.mts → versioning-DXgY5BUm.d.mts} +11 -29
- package/dist/{versioning-Dk-71iIz.mjs → versioning-gKWyryT3.mjs} +8 -1
- package/dist/{websocket-uuWqM6UY.d.mts → websocket-_Pd0CgR0.d.mts} +15 -1
- package/package.json +526 -513
- package/skills/arc/references/api-reference.md +3 -1
- package/skills/arc/references/integrations.md +20 -11
- package/dist/QueryCache-Z1B38koh.d.mts +0 -40
- package/dist/betterAuthOpenApi-CV1lxpRX.mjs +0 -2
- package/dist/health-ScyjIVo5.mjs +0 -202
- package/dist/requestId-5BhTVzBv.mjs +0 -113
- 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
|
-
|
|
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-
|
|
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-
|
|
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-
|
|
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 {
|
|
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-
|
|
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 };
|