@classytic/arc 2.8.5 → 2.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +88 -5
- package/dist/{BaseController-DAGGc5Xn.mjs → BaseController-Vu2yc56T.mjs} +188 -102
- package/dist/EventTransport-CqZ8FyM_.d.mts +293 -0
- package/dist/adapters/index.d.mts +2 -2
- package/dist/audit/index.d.mts +100 -11
- package/dist/audit/index.mjs +71 -18
- package/dist/auth/index.d.mts +16 -8
- package/dist/auth/index.mjs +13 -6
- package/dist/auth/redis-session.d.mts +1 -1
- package/dist/{betterAuthOpenApi-BuUcUEJq.mjs → betterAuthOpenApi--rdY15Ld.mjs} +1 -1
- package/dist/cache/index.d.mts +2 -2
- package/dist/cache/index.mjs +2 -2
- package/dist/cli/commands/docs.mjs +2 -2
- package/dist/cli/commands/introspect.mjs +1 -1
- package/dist/core/index.d.mts +3 -3
- package/dist/core/index.mjs +4 -5
- package/dist/{core-F0QoWBt2.mjs → core-DNncu0xF.mjs} +1 -1
- package/dist/{createActionRouter-BORM8f17.mjs → createActionRouter-DH1YFL9m.mjs} +3 -3
- package/dist/{createApp-B1EY8zxa.mjs → createApp-CBJUJKGP.mjs} +13 -12
- package/dist/{defineResource-tcgySDo1.mjs → defineResource-C__jkwvs.mjs} +22 -57
- package/dist/docs/index.d.mts +2 -2
- package/dist/docs/index.mjs +1 -1
- package/dist/dynamic/index.d.mts +1 -1
- package/dist/dynamic/index.mjs +3 -3
- package/dist/{elevation-DtFxrG0s.mjs → elevation-DxQ6ACbt.mjs} +21 -7
- package/dist/{errorHandler-f869_8PQ.mjs → errorHandler-CZDW4EXS.mjs} +59 -7
- package/dist/{errorHandler-Bah5JhBd.d.mts → errorHandler-DixGcttC.d.mts} +37 -2
- package/dist/{eventPlugin-D9DKB2zM.d.mts → eventPlugin-BxvaCIZF.d.mts} +14 -2
- package/dist/{eventPlugin-CDjVTM82.mjs → eventPlugin-Dl7MoVWH.mjs} +83 -5
- package/dist/events/index.d.mts +147 -36
- package/dist/events/index.mjs +338 -101
- package/dist/events/transports/redis-stream-entry.d.mts +1 -1
- package/dist/events/transports/redis.d.mts +1 -1
- package/dist/factory/index.d.mts +1 -1
- package/dist/factory/index.mjs +2 -2
- package/dist/{fields-DpZQa_Q3.d.mts → fields-BC7zcmI9.d.mts} +15 -3
- package/dist/{fields-ipsbIRPK.mjs → fields-CU6FlaDV.mjs} +18 -5
- package/dist/{filesUpload-C7r7HIeA.mjs → filesUpload-q8oHt--L.mjs} +65 -7
- package/dist/hooks/index.d.mts +1 -1
- package/dist/hooks/index.mjs +1 -1
- package/dist/idempotency/index.d.mts +29 -5
- package/dist/idempotency/index.mjs +111 -2
- package/dist/idempotency/redis.d.mts +1 -1
- package/dist/{index-BLXBmWud.d.mts → index-C-xjcA6F.d.mts} +1 -1
- package/dist/{index-DtDzOBn8.d.mts → index-Cibkchnx.d.mts} +3 -134
- package/dist/{index-C1meYuDn.d.mts → index-CtGKT0lf.d.mts} +1 -1
- package/dist/index.d.mts +7 -7
- package/dist/index.mjs +9 -9
- package/dist/integrations/event-gateway.d.mts +1 -1
- package/dist/integrations/event-gateway.mjs +1 -1
- package/dist/integrations/index.d.mts +1 -1
- package/dist/integrations/mcp/index.d.mts +26 -8
- package/dist/integrations/mcp/index.mjs +96 -17
- package/dist/integrations/mcp/testing.d.mts +1 -1
- package/dist/integrations/mcp/testing.mjs +1 -1
- package/dist/integrations/webhooks.d.mts +5 -0
- package/dist/integrations/webhooks.mjs +6 -0
- package/dist/{interface-CMRutPfe.d.mts → interface-YrWsmKqE.d.mts} +287 -179
- package/dist/{openapi-CbKUJY_m.mjs → openapi-CXuTG1M9.mjs} +2 -2
- package/dist/org/index.d.mts +1 -1
- package/dist/permissions/index.d.mts +2 -2
- package/dist/permissions/index.mjs +3 -3
- package/dist/{permissions-CH4cNwJi.mjs → permissions-oNZawnkR.mjs} +1 -1
- package/dist/plugins/index.d.mts +7 -7
- package/dist/plugins/index.mjs +11 -11
- package/dist/plugins/response-cache.mjs +1 -1
- package/dist/plugins/tracing-entry.d.mts +1 -1
- package/dist/plugins/tracing-entry.mjs +1 -1
- package/dist/policies/index.d.mts +25 -32
- package/dist/presets/filesUpload.d.mts +26 -4
- package/dist/presets/filesUpload.mjs +1 -1
- package/dist/presets/index.d.mts +3 -2
- package/dist/presets/index.mjs +4 -3
- package/dist/presets/multiTenant.d.mts +1 -1
- package/dist/presets/multiTenant.mjs +1 -1
- package/dist/presets/search.d.mts +91 -0
- package/dist/presets/search.mjs +150 -0
- package/dist/{presets-C2xgzW6x.mjs → presets-hM4WhNWY.mjs} +1 -1
- package/dist/{queryCachePlugin-BJJGBTlu.d.mts → queryCachePlugin-CnTZZTC5.d.mts} +1 -1
- package/dist/{queryCachePlugin-BH-fidlv.mjs → queryCachePlugin-DbUVroUG.mjs} +2 -2
- package/dist/{redis-BM00zaPB.d.mts → redis-MXLp1oOf.d.mts} +1 -1
- package/dist/{redis-stream-CrsfUmPt.d.mts → redis-stream-Bz-4q96t.d.mts} +1 -1
- package/dist/registry/index.d.mts +1 -1
- package/dist/registry/index.mjs +2 -2
- package/dist/{resourceToTools-8s-EsCCe.mjs → resourceToTools-C3cWymnW.mjs} +64 -47
- package/dist/rpc/index.d.mts +1 -1
- package/dist/rpc/index.mjs +1 -1
- package/dist/{schemaConverter-Y7nCYaLJ.mjs → schemaConverter-BxFDdtXu.mjs} +1 -1
- package/dist/scope/index.mjs +1 -1
- package/dist/{sse-Ad7ypl9e.mjs → sse-CJpt7LGI.mjs} +1 -1
- package/dist/store-helpers-DFiZl5TL.mjs +57 -0
- package/dist/testing/index.d.mts +5 -14
- package/dist/testing/index.mjs +21 -75
- package/dist/testing/storageContract.d.mts +1 -1
- package/dist/types/index.d.mts +2 -2
- package/dist/types/storage.d.mts +1 -1
- package/dist/{types-BsbNMEDR.d.mts → types-CoSzA-s-.d.mts} +1 -1
- package/dist/{types-Ch9pTQbf.d.mts → types-CunEX4UX.d.mts} +10 -8
- package/dist/utils/index.d.mts +4 -4
- package/dist/utils/index.mjs +6 -6
- package/dist/{utils-yYT3HDXt.mjs → utils-B7FuRr9w.mjs} +1 -1
- package/package.json +8 -11
- package/skills/arc/SKILL.md +92 -14
- package/skills/arc/references/auth.md +94 -0
- package/skills/arc/references/events.md +200 -12
- package/skills/arc/references/mcp.md +4 -17
- package/skills/arc/references/multi-tenancy.md +43 -0
- package/skills/arc/references/production.md +34 -19
- package/dist/EventTransport-BXja8NOc.d.mts +0 -135
- package/dist/audit/mongodb.d.mts +0 -2
- package/dist/audit/mongodb.mjs +0 -2
- package/dist/idempotency/mongodb.d.mts +0 -2
- package/dist/idempotency/mongodb.mjs +0 -123
- package/dist/mongodb-BsP-WbhN.d.mts +0 -127
- package/dist/mongodb-CTcp0hQZ.d.mts +0 -80
- package/dist/mongodb-Utc5k_-0.mjs +0 -90
- /package/dist/{HookSystem-HprTmvVY.mjs → HookSystem-BjFu7zf1.mjs} +0 -0
- /package/dist/{ResourceRegistry-C6uXlWe3.mjs → ResourceRegistry-Dq3_zBQP.mjs} +0 -0
- /package/dist/{applyPermissionResult-D6GPMsvh.mjs → applyPermissionResult-bqGpo9ML.mjs} +0 -0
- /package/dist/{caching-IMuYVjTL.mjs → caching-CjybdRwx.mjs} +0 -0
- /package/dist/{circuitBreaker-dTtG-UyS.d.mts → circuitBreaker-CvXkjfrW.d.mts} +0 -0
- /package/dist/{circuitBreaker-cmi5XDv5.mjs → circuitBreaker-l18oRgL5.mjs} +0 -0
- /package/dist/{errors-Ck2h67pm.d.mts → errors-BI8kEKsO.d.mts} +0 -0
- /package/dist/{errors-BF2bIOIS.mjs → errors-CqWnSqM-.mjs} +0 -0
- /package/dist/{externalPaths-BnkYrNzp.d.mts → externalPaths-Bapitwvd.d.mts} +0 -0
- /package/dist/{interface-DfLGcus7.d.mts → interface-B-pe8fhj.d.mts} +0 -0
- /package/dist/{interface-4y979v99.d.mts → interface-DplgQO2e.d.mts} +0 -0
- /package/dist/{loadResources-PWd0OCpV.mjs → loadResources-Bksk8ydA.mjs} +0 -0
- /package/dist/{logger-D1YrIImS.mjs → logger-CDjpjySd.mjs} +0 -0
- /package/dist/{memory-Cp7_cAko.mjs → memory-BFAYkf8H.mjs} +0 -0
- /package/dist/{metrics-B-PU4-Yu.mjs → metrics-TuOmguhi.mjs} +0 -0
- /package/dist/{queryParser-CgCtsjti.mjs → queryParser-Cs-6SHQK.mjs} +0 -0
- /package/dist/{registry-BiTKT1Dg.mjs → registry-B0Wl7uVV.mjs} +0 -0
- /package/dist/{replyHelpers-CxkYGT81.mjs → replyHelpers-BLojtuvR.mjs} +0 -0
- /package/dist/{requestContext-DYvHl113.mjs → requestContext-DYtmNpm5.mjs} +0 -0
- /package/dist/{sessionManager-DDCmiNIo.d.mts → sessionManager-D-oNWHz3.d.mts} +0 -0
- /package/dist/{storage-Dfzt4VTl.d.mts → storage-BwGQXUpd.d.mts} +0 -0
- /package/dist/{tracing-DdN2-wHJ.d.mts → tracing-xqXzWeaf.d.mts} +0 -0
- /package/dist/{typeGuards-CcFZXgU7.mjs → typeGuards-Cj5Rgvlg.mjs} +0 -0
- /package/dist/{versioning-CDugduqI.mjs → versioning-Cm8qoFDg.mjs} +0 -0
|
@@ -1,11 +1,42 @@
|
|
|
1
1
|
import { o as getOrgId, p as getUserId } from "./types-AOD8fxIw.mjs";
|
|
2
|
-
import { i as NotFoundError, u as ValidationError } from "./errors-
|
|
3
|
-
import { n as allowPublic, s as requireAuth } from "./permissions-
|
|
2
|
+
import { i as NotFoundError, u as ValidationError } from "./errors-CqWnSqM-.mjs";
|
|
3
|
+
import { n as allowPublic, s as requireAuth } from "./permissions-oNZawnkR.mjs";
|
|
4
4
|
//#region src/middleware/multipartBody.ts
|
|
5
5
|
const DEFAULT_MAX_FILE_SIZE$1 = 10 * 1024 * 1024;
|
|
6
6
|
const DEFAULT_MAX_FILES = 5;
|
|
7
7
|
const DEFAULT_FILES_KEY = "_files";
|
|
8
8
|
/**
|
|
9
|
+
* Build a matcher for MIME allow-lists that supports exact (e.g. `image/png`),
|
|
10
|
+
* subtype wildcards (e.g. `image/\*`), and total wildcards (`\*` or `\*\/\*`).
|
|
11
|
+
*
|
|
12
|
+
* Returns `undefined` when no filter is needed — either because the option
|
|
13
|
+
* was omitted or because a total wildcard was present.
|
|
14
|
+
*/
|
|
15
|
+
function buildMimeMatcher(allowed) {
|
|
16
|
+
if (!allowed || allowed.length === 0) return void 0;
|
|
17
|
+
const exact = /* @__PURE__ */ new Set();
|
|
18
|
+
const prefixes = [];
|
|
19
|
+
for (const entry of allowed) {
|
|
20
|
+
const value = entry.trim().toLowerCase();
|
|
21
|
+
if (!value) continue;
|
|
22
|
+
if (value === "*" || value === "*/*") return void 0;
|
|
23
|
+
if (value.endsWith("/*")) prefixes.push(value.slice(0, -1));
|
|
24
|
+
else exact.add(value);
|
|
25
|
+
}
|
|
26
|
+
if (exact.size === 0 && prefixes.length === 0) return void 0;
|
|
27
|
+
return {
|
|
28
|
+
matches(mime) {
|
|
29
|
+
const m = mime.toLowerCase();
|
|
30
|
+
if (exact.has(m)) return true;
|
|
31
|
+
for (const p of prefixes) if (m.startsWith(p)) return true;
|
|
32
|
+
return false;
|
|
33
|
+
},
|
|
34
|
+
describe() {
|
|
35
|
+
return [...exact, ...prefixes.map((p) => `${p}*`)].join(", ");
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
9
40
|
* Create a multipart body parsing middleware.
|
|
10
41
|
*
|
|
11
42
|
* When a request has `content-type: multipart/form-data`, this middleware:
|
|
@@ -20,7 +51,7 @@ const DEFAULT_FILES_KEY = "_files";
|
|
|
20
51
|
function multipartBody(options = {}) {
|
|
21
52
|
const maxFileSize = options.maxFileSize ?? DEFAULT_MAX_FILE_SIZE$1;
|
|
22
53
|
const maxFiles = options.maxFiles ?? DEFAULT_MAX_FILES;
|
|
23
|
-
const
|
|
54
|
+
const mimeMatcher = buildMimeMatcher(options.allowedMimeTypes);
|
|
24
55
|
const filesKey = options.filesKey ?? DEFAULT_FILES_KEY;
|
|
25
56
|
const requiredFields = options.requiredFields && options.requiredFields.length > 0 ? options.requiredFields : void 0;
|
|
26
57
|
return async function parseMultipartBody(request, reply) {
|
|
@@ -36,9 +67,9 @@ function multipartBody(options = {}) {
|
|
|
36
67
|
const parts = request.parts();
|
|
37
68
|
for await (const part of parts) if (part.type === "file") {
|
|
38
69
|
if (fileCount >= maxFiles) continue;
|
|
39
|
-
if (
|
|
70
|
+
if (mimeMatcher && !mimeMatcher.matches(part.mimetype)) return reply.code(415).send({
|
|
40
71
|
success: false,
|
|
41
|
-
error: `File type '${part.mimetype}' not allowed. Accepted: ${
|
|
72
|
+
error: `File type '${part.mimetype}' not allowed. Accepted: ${mimeMatcher.describe()}`
|
|
42
73
|
});
|
|
43
74
|
const buffer = await part.toBuffer();
|
|
44
75
|
if (buffer.length > maxFileSize) return reply.code(413).send({
|
|
@@ -155,14 +186,40 @@ function parseRangeHeader(header, totalSize) {
|
|
|
155
186
|
end
|
|
156
187
|
};
|
|
157
188
|
}
|
|
189
|
+
/**
|
|
190
|
+
* Strict policy — rejects filenames that could escape a storage root or
|
|
191
|
+
* confuse a filesystem. Safe default for disk/S3 adapters that compose
|
|
192
|
+
* `${prefix}/${filename}` or `path.join(root, filename)`.
|
|
193
|
+
*/
|
|
194
|
+
function strictFilenamePolicy(filename) {
|
|
195
|
+
if (filename.length === 0) throw new ValidationError("Upload filename is empty");
|
|
196
|
+
if (filename.length > 255) throw new ValidationError("Upload filename exceeds 255 characters");
|
|
197
|
+
if (filename.includes("\0")) throw new ValidationError("Upload filename contains a NUL byte");
|
|
198
|
+
if (filename.includes("/") || filename.includes("\\")) throw new ValidationError("Upload filename contains a path separator");
|
|
199
|
+
if (filename === "." || filename === "..") throw new ValidationError("Upload filename is a path traversal component");
|
|
200
|
+
return filename;
|
|
201
|
+
}
|
|
202
|
+
/** Resolve the user-supplied policy option into a concrete validator. */
|
|
203
|
+
function resolveFilenamePolicy(policy) {
|
|
204
|
+
if (policy === void 0 || policy === true) return strictFilenamePolicy;
|
|
205
|
+
if (policy === false || policy === "*") return (f) => f;
|
|
206
|
+
if (typeof policy === "function") return (filename) => {
|
|
207
|
+
const result = policy(filename);
|
|
208
|
+
if (result === false) throw new ValidationError(`Upload filename rejected: ${filename}`);
|
|
209
|
+
if (typeof result === "string") return result;
|
|
210
|
+
return filename;
|
|
211
|
+
};
|
|
212
|
+
return strictFilenamePolicy;
|
|
213
|
+
}
|
|
158
214
|
function makeUploadHandler(deps) {
|
|
159
215
|
return async function uploadHandler(request, reply) {
|
|
160
216
|
const file = (request.body?._files)?.[deps.fieldName];
|
|
161
217
|
if (!file) throw new ValidationError(`Missing file field '${deps.fieldName}' in multipart body`);
|
|
218
|
+
const filename = deps.applyFilenamePolicy(file.filename);
|
|
162
219
|
const ctx = buildStorageContext(request, deps.contextFrom);
|
|
163
220
|
const result = await deps.storage.upload({
|
|
164
221
|
buffer: file.buffer,
|
|
165
|
-
filename
|
|
222
|
+
filename,
|
|
166
223
|
mimeType: file.mimetype,
|
|
167
224
|
size: file.size
|
|
168
225
|
}, ctx);
|
|
@@ -263,7 +320,8 @@ function filesUploadPreset(options) {
|
|
|
263
320
|
const deps = {
|
|
264
321
|
storage: options.storage,
|
|
265
322
|
fieldName: options.fieldName ?? DEFAULT_FIELD_NAME,
|
|
266
|
-
contextFrom: options.contextFrom ?? defaultContextFrom
|
|
323
|
+
contextFrom: options.contextFrom ?? defaultContextFrom,
|
|
324
|
+
applyFilenamePolicy: resolveFilenamePolicy(options.sanitizeFilename)
|
|
267
325
|
};
|
|
268
326
|
const maxFileSize = options.maxFileSize ?? DEFAULT_MAX_FILE_SIZE;
|
|
269
327
|
const allowedMimeTypes = options.allowedMimeTypes;
|
package/dist/hooks/index.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { An as beforeCreate, Cn as HookPhase, Dn as afterCreate, En as HookSystemOptions, Mn as beforeUpdate, Nn as createHookSystem, On as afterDelete, Pn as defineHook, Sn as HookOperation, Tn as HookSystem, bn as HookContext, jn as beforeDelete, kn as afterUpdate, wn as HookRegistration, xn as HookHandler, yn as DefineHookOptions } from "../interface-
|
|
1
|
+
import { An as beforeCreate, Cn as HookPhase, Dn as afterCreate, En as HookSystemOptions, Mn as beforeUpdate, Nn as createHookSystem, On as afterDelete, Pn as defineHook, Sn as HookOperation, Tn as HookSystem, bn as HookContext, jn as beforeDelete, kn as afterUpdate, wn as HookRegistration, xn as HookHandler, yn as DefineHookOptions } from "../interface-YrWsmKqE.mjs";
|
|
2
2
|
export { type DefineHookOptions, type HookContext, type HookHandler, type HookOperation, type HookPhase, type HookRegistration, HookSystem, type HookSystemOptions, afterCreate, afterDelete, afterUpdate, beforeCreate, beforeDelete, beforeUpdate, createHookSystem, defineHook };
|
package/dist/hooks/index.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as beforeCreate, c as createHookSystem, i as afterUpdate, l as defineHook, n as afterCreate, o as beforeDelete, r as afterDelete, s as beforeUpdate, t as HookSystem } from "../HookSystem-
|
|
1
|
+
import { a as beforeCreate, c as createHookSystem, i as afterUpdate, l as defineHook, n as afterCreate, o as beforeDelete, r as afterDelete, s as beforeUpdate, t as HookSystem } from "../HookSystem-BjFu7zf1.mjs";
|
|
2
2
|
export { HookSystem, afterCreate, afterDelete, afterUpdate, beforeCreate, beforeDelete, beforeUpdate, createHookSystem, defineHook };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { n as
|
|
3
|
-
import { i as RedisIdempotencyStoreOptions, n as RedisClient } from "../redis-
|
|
1
|
+
import { o as RepositoryLike } from "../interface-YrWsmKqE.mjs";
|
|
2
|
+
import { i as createIdempotencyResult, n as IdempotencyResult, r as IdempotencyStore, t as IdempotencyLock } from "../interface-B-pe8fhj.mjs";
|
|
3
|
+
import { i as RedisIdempotencyStoreOptions, n as RedisClient } from "../redis-MXLp1oOf.mjs";
|
|
4
4
|
import { FastifyPluginAsync } from "fastify";
|
|
5
5
|
|
|
6
6
|
//#region src/idempotency/idempotencyPlugin.d.ts
|
|
@@ -19,10 +19,34 @@ interface IdempotencyPluginOptions {
|
|
|
19
19
|
include?: RegExp[];
|
|
20
20
|
/** URL patterns to exclude (regex). Excluded patterns take precedence */
|
|
21
21
|
exclude?: RegExp[];
|
|
22
|
-
/**
|
|
22
|
+
/**
|
|
23
|
+
* Repository managing the idempotency collection. Arc consumes it directly
|
|
24
|
+
* — no wrapper classes. Requires `getOne`, `deleteMany`, and
|
|
25
|
+
* `findOneAndUpdate` (mongokit ≥3.8 implements all three). Pass any
|
|
26
|
+
* `RepositoryLike` that matches.
|
|
27
|
+
*
|
|
28
|
+
* Use `store` (below) when your backend isn't a repository (Redis, memory
|
|
29
|
+
* for tests, custom). `repository` takes precedence when both are passed.
|
|
30
|
+
*/
|
|
31
|
+
repository?: RepositoryLike;
|
|
32
|
+
/**
|
|
33
|
+
* Non-repository store. Use for Redis (the canonical multi-instance
|
|
34
|
+
* backend when you don't already have a DB repository), memory (tests),
|
|
35
|
+
* or custom implementations of `IdempotencyStore`.
|
|
36
|
+
*
|
|
37
|
+
* Default: `MemoryIdempotencyStore`.
|
|
38
|
+
*/
|
|
23
39
|
store?: IdempotencyStore;
|
|
24
40
|
/** Retry-After header value in seconds when request is in-flight (default: 1) */
|
|
25
41
|
retryAfterSeconds?: number;
|
|
42
|
+
/**
|
|
43
|
+
* Namespace key folded into the fingerprint — use when two deployments share
|
|
44
|
+
* a single store but should not replay each other's responses (e.g. `api`
|
|
45
|
+
* vs `jobs` with the same Redis, or prod vs canary sharing one cluster).
|
|
46
|
+
*
|
|
47
|
+
* Omit for the common case where the store is per-deployment.
|
|
48
|
+
*/
|
|
49
|
+
namespace?: string;
|
|
26
50
|
}
|
|
27
51
|
declare module "fastify" {
|
|
28
52
|
interface FastifyRequest {
|
|
@@ -93,4 +117,4 @@ declare class MemoryIdempotencyStore implements IdempotencyStore {
|
|
|
93
117
|
private evictOldest;
|
|
94
118
|
}
|
|
95
119
|
//#endregion
|
|
96
|
-
export { type IdempotencyLock, type IdempotencyPluginOptions, type IdempotencyResult, type IdempotencyStore, MemoryIdempotencyStore, type MemoryIdempotencyStoreOptions, type
|
|
120
|
+
export { type IdempotencyLock, type IdempotencyPluginOptions, type IdempotencyResult, type IdempotencyStore, MemoryIdempotencyStore, type MemoryIdempotencyStoreOptions, type RedisClient, type RedisIdempotencyStoreOptions, createIdempotencyResult, _default as idempotencyPlugin, idempotencyPlugin as idempotencyPluginFn };
|
|
@@ -1,5 +1,113 @@
|
|
|
1
|
+
import { n as createSafeGetOne, t as createIsDuplicateKeyError } from "../store-helpers-DFiZl5TL.mjs";
|
|
1
2
|
import { createHash } from "node:crypto";
|
|
2
3
|
import fp from "fastify-plugin";
|
|
4
|
+
//#region src/idempotency/repository-idempotency-adapter.ts
|
|
5
|
+
function repositoryAsIdempotencyStore(repository, defaultTtlMs) {
|
|
6
|
+
const missing = [];
|
|
7
|
+
if (typeof repository.getOne !== "function") missing.push("getOne");
|
|
8
|
+
if (typeof repository.deleteMany !== "function") missing.push("deleteMany");
|
|
9
|
+
if (typeof repository.findOneAndUpdate !== "function") missing.push("findOneAndUpdate");
|
|
10
|
+
if (missing.length > 0) throw new Error(`idempotencyPlugin: repository is missing required methods: ${missing.join(", ")}. mongokit ≥3.8 satisfies these; other kits must implement them to back idempotency via a repository.`);
|
|
11
|
+
const r = repository;
|
|
12
|
+
const isDuplicateKeyError = createIsDuplicateKeyError(repository);
|
|
13
|
+
const safeGetOne = createSafeGetOne(repository);
|
|
14
|
+
const escapeRegex = (s) => s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
15
|
+
return {
|
|
16
|
+
name: "repository",
|
|
17
|
+
async get(key) {
|
|
18
|
+
const doc = await safeGetOne({ _id: key });
|
|
19
|
+
if (!doc?.result) return void 0;
|
|
20
|
+
if (new Date(doc.expiresAt) < /* @__PURE__ */ new Date()) return void 0;
|
|
21
|
+
return {
|
|
22
|
+
key,
|
|
23
|
+
statusCode: doc.result.statusCode,
|
|
24
|
+
headers: doc.result.headers,
|
|
25
|
+
body: doc.result.body,
|
|
26
|
+
createdAt: new Date(doc.createdAt),
|
|
27
|
+
expiresAt: new Date(doc.expiresAt)
|
|
28
|
+
};
|
|
29
|
+
},
|
|
30
|
+
async set(key, result) {
|
|
31
|
+
await r.findOneAndUpdate({ _id: key }, {
|
|
32
|
+
$set: {
|
|
33
|
+
result: {
|
|
34
|
+
statusCode: result.statusCode,
|
|
35
|
+
headers: result.headers,
|
|
36
|
+
body: result.body
|
|
37
|
+
},
|
|
38
|
+
createdAt: result.createdAt,
|
|
39
|
+
expiresAt: result.expiresAt
|
|
40
|
+
},
|
|
41
|
+
$unset: { lock: "" }
|
|
42
|
+
}, {
|
|
43
|
+
upsert: true,
|
|
44
|
+
returnDocument: "after"
|
|
45
|
+
});
|
|
46
|
+
},
|
|
47
|
+
async tryLock(key, requestId, ttlMs) {
|
|
48
|
+
const now = /* @__PURE__ */ new Date();
|
|
49
|
+
const lockExpiresAt = new Date(now.getTime() + ttlMs);
|
|
50
|
+
const docExpiresAt = new Date(now.getTime() + defaultTtlMs);
|
|
51
|
+
try {
|
|
52
|
+
const doc = await r.findOneAndUpdate({
|
|
53
|
+
_id: key,
|
|
54
|
+
$or: [{ lock: { $exists: false } }, { "lock.expiresAt": { $lt: now } }]
|
|
55
|
+
}, {
|
|
56
|
+
$set: { lock: {
|
|
57
|
+
requestId,
|
|
58
|
+
expiresAt: lockExpiresAt
|
|
59
|
+
} },
|
|
60
|
+
$setOnInsert: {
|
|
61
|
+
createdAt: now,
|
|
62
|
+
expiresAt: docExpiresAt
|
|
63
|
+
}
|
|
64
|
+
}, {
|
|
65
|
+
upsert: true,
|
|
66
|
+
returnDocument: "after"
|
|
67
|
+
});
|
|
68
|
+
return doc !== null && doc !== void 0;
|
|
69
|
+
} catch (err) {
|
|
70
|
+
if (isDuplicateKeyError(err)) return false;
|
|
71
|
+
throw err;
|
|
72
|
+
}
|
|
73
|
+
},
|
|
74
|
+
async unlock(key, requestId) {
|
|
75
|
+
await r.findOneAndUpdate({
|
|
76
|
+
_id: key,
|
|
77
|
+
"lock.requestId": requestId
|
|
78
|
+
}, { $unset: { lock: "" } });
|
|
79
|
+
},
|
|
80
|
+
async isLocked(key) {
|
|
81
|
+
const doc = await safeGetOne({ _id: key });
|
|
82
|
+
if (!doc?.lock) return false;
|
|
83
|
+
return new Date(doc.lock.expiresAt) > /* @__PURE__ */ new Date();
|
|
84
|
+
},
|
|
85
|
+
async delete(key) {
|
|
86
|
+
await r.deleteMany({ _id: key });
|
|
87
|
+
},
|
|
88
|
+
async deleteByPrefix(prefix) {
|
|
89
|
+
return (await r.deleteMany({ _id: { $regex: `^${escapeRegex(prefix)}` } })).deletedCount ?? 0;
|
|
90
|
+
},
|
|
91
|
+
async findByPrefix(prefix) {
|
|
92
|
+
const doc = await safeGetOne({
|
|
93
|
+
_id: { $regex: `^${escapeRegex(prefix)}` },
|
|
94
|
+
result: { $exists: true },
|
|
95
|
+
expiresAt: { $gt: /* @__PURE__ */ new Date() }
|
|
96
|
+
});
|
|
97
|
+
if (!doc?.result) return void 0;
|
|
98
|
+
return {
|
|
99
|
+
key: doc._id,
|
|
100
|
+
statusCode: doc.result.statusCode,
|
|
101
|
+
headers: doc.result.headers,
|
|
102
|
+
body: doc.result.body,
|
|
103
|
+
createdAt: new Date(doc.createdAt),
|
|
104
|
+
expiresAt: new Date(doc.expiresAt)
|
|
105
|
+
};
|
|
106
|
+
},
|
|
107
|
+
async close() {}
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
//#endregion
|
|
3
111
|
//#region src/idempotency/stores/interface.ts
|
|
4
112
|
/**
|
|
5
113
|
* Helper to create a result object
|
|
@@ -171,7 +279,8 @@ const idempotencyPlugin = async (fastify, opts = {}) => {
|
|
|
171
279
|
"POST",
|
|
172
280
|
"PUT",
|
|
173
281
|
"PATCH"
|
|
174
|
-
], include, exclude, store
|
|
282
|
+
], include, exclude, repository, store: explicitStore, retryAfterSeconds = 1, namespace } = opts;
|
|
283
|
+
const store = repository ? repositoryAsIdempotencyStore(repository, ttlMs) : explicitStore ?? new MemoryIdempotencyStore({ ttlMs });
|
|
175
284
|
if (!enabled) {
|
|
176
285
|
fastify.decorate("idempotency", {
|
|
177
286
|
invalidate: async () => {},
|
|
@@ -225,7 +334,7 @@ const idempotencyPlugin = async (fastify, opts = {}) => {
|
|
|
225
334
|
}
|
|
226
335
|
const user = request.user;
|
|
227
336
|
const userId = user?.id ?? user?._id ?? "anon";
|
|
228
|
-
return `${request.method}:${request.url}:${bodyHash}:u=${userId}`;
|
|
337
|
+
return `${namespace ? `n=${namespace}:` : ""}${request.method}:${request.url}:${bodyHash}:u=${userId}`;
|
|
229
338
|
}
|
|
230
339
|
const idempotencyMiddleware = async (request, reply) => {
|
|
231
340
|
if (!shouldApplyIdempotency(request)) return;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as UpstashRedisLike, i as RedisIdempotencyStoreOptions, n as RedisClient, o as ioredisAsIdempotencyClient, r as RedisIdempotencyStore, s as upstashAsIdempotencyClient, t as IoredisLike } from "../redis-
|
|
1
|
+
import { a as UpstashRedisLike, i as RedisIdempotencyStoreOptions, n as RedisClient, o as ioredisAsIdempotencyClient, r as RedisIdempotencyStore, s as upstashAsIdempotencyClient, t as IoredisLike } from "../redis-MXLp1oOf.mjs";
|
|
2
2
|
export { type IoredisLike, type RedisClient, RedisIdempotencyStore, type RedisIdempotencyStoreOptions, type UpstashRedisLike, ioredisAsIdempotencyClient, upstashAsIdempotencyClient };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { r as RequestScope } from "./types-BD85MlEK.mjs";
|
|
2
2
|
import { n as PermissionContext, r as PermissionResult, t as PermissionCheck } from "./types-DZi1aYhm.mjs";
|
|
3
|
-
import { i as CacheStore, t as CacheLogger } from "./interface-
|
|
3
|
+
import { i as CacheStore, t as CacheLogger } from "./interface-DplgQO2e.mjs";
|
|
4
4
|
import { FastifyRequest } from "fastify";
|
|
5
5
|
|
|
6
6
|
//#region src/permissions/applyPermissionResult.d.ts
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { r as RequestScope } from "./types-BD85MlEK.mjs";
|
|
2
|
-
import {
|
|
2
|
+
import { Bt as IController, E as CrudRouterOptions, Ht as IRequestContext, Kt as ResourceDefinition, M as FastifyWithDecorators, Vt as IControllerResponse, at as RequestContext, lt as ResourceConfig, p as AnyRecord, w as CrudController } from "./interface-YrWsmKqE.mjs";
|
|
3
3
|
import { t as PermissionCheck } from "./types-DZi1aYhm.mjs";
|
|
4
|
-
import {
|
|
4
|
+
import { FastifyReply, FastifyRequest, RouteHandlerMethod } from "fastify";
|
|
5
5
|
|
|
6
6
|
//#region src/constants.d.ts
|
|
7
7
|
/**
|
|
@@ -52,137 +52,6 @@ declare const MAX_FILTER_DEPTH: 10;
|
|
|
52
52
|
*/
|
|
53
53
|
declare const RESERVED_QUERY_PARAMS: Readonly<Set<string>>;
|
|
54
54
|
//#endregion
|
|
55
|
-
//#region src/core/createActionRouter.d.ts
|
|
56
|
-
/**
|
|
57
|
-
* Action handler function
|
|
58
|
-
* @param id - Resource ID
|
|
59
|
-
* @param data - Action-specific data from request body
|
|
60
|
-
* @param req - Full Fastify request object
|
|
61
|
-
* @returns Action result (will be wrapped in success response)
|
|
62
|
-
*/
|
|
63
|
-
type ActionHandler<TData = Record<string, unknown>, TResult = unknown> = (id: string, data: TData, req: RequestWithExtras) => Promise<TResult>;
|
|
64
|
-
/**
|
|
65
|
-
* Action router configuration
|
|
66
|
-
*/
|
|
67
|
-
interface ActionRouterConfig {
|
|
68
|
-
/**
|
|
69
|
-
* OpenAPI tag for grouping routes
|
|
70
|
-
*/
|
|
71
|
-
readonly tag?: string;
|
|
72
|
-
/**
|
|
73
|
-
* Action handlers map
|
|
74
|
-
* @example { approve: (id, data, req) => service.approve(id), ... }
|
|
75
|
-
*/
|
|
76
|
-
readonly actions: Record<string, ActionHandler>;
|
|
77
|
-
/**
|
|
78
|
-
* Per-action permission checks (PermissionCheck functions)
|
|
79
|
-
* @example { approve: requireRoles(['admin', 'manager']), cancel: requireRoles(['admin']) }
|
|
80
|
-
*/
|
|
81
|
-
readonly actionPermissions?: Record<string, PermissionCheck>;
|
|
82
|
-
/**
|
|
83
|
-
* Per-action schema for body validation.
|
|
84
|
-
*
|
|
85
|
-
* Accepted shapes per action:
|
|
86
|
-
*
|
|
87
|
-
* 1. **Full JSON Schema object** with `type: 'object'`, `properties`, `required` —
|
|
88
|
-
* used verbatim. Required fields ARE enforced by Fastify's AJV.
|
|
89
|
-
*
|
|
90
|
-
* 2. **Zod v4 schema** — auto-converted via `z.toJSONSchema()`. Required fields
|
|
91
|
-
* ARE enforced.
|
|
92
|
-
*
|
|
93
|
-
* 3. **Legacy field map** `{ fieldName: { type: 'string' } }` — each key becomes
|
|
94
|
-
* a property and is treated as REQUIRED unless the property schema has
|
|
95
|
-
* `nullable: true` or Arc's sentinel `required: false`. Kept for back-compat.
|
|
96
|
-
*
|
|
97
|
-
* All shapes are compiled into a single `oneOf` discriminator body schema
|
|
98
|
-
* so AJV can validate action-specific required fields at the HTTP layer.
|
|
99
|
-
*
|
|
100
|
-
* @example JSON Schema
|
|
101
|
-
* ```ts
|
|
102
|
-
* actionSchemas: {
|
|
103
|
-
* dispatch: {
|
|
104
|
-
* type: 'object',
|
|
105
|
-
* properties: { carrier: { type: 'string' } },
|
|
106
|
-
* required: ['carrier'],
|
|
107
|
-
* },
|
|
108
|
-
* }
|
|
109
|
-
* ```
|
|
110
|
-
*
|
|
111
|
-
* @example Zod v4
|
|
112
|
-
* ```ts
|
|
113
|
-
* actionSchemas: {
|
|
114
|
-
* dispatch: z.object({ carrier: z.string() }),
|
|
115
|
-
* }
|
|
116
|
-
* ```
|
|
117
|
-
*/
|
|
118
|
-
readonly actionSchemas?: Record<string, Record<string, unknown>>;
|
|
119
|
-
/**
|
|
120
|
-
* Global permission check applied to all actions (if action-specific not defined)
|
|
121
|
-
*/
|
|
122
|
-
readonly globalAuth?: PermissionCheck;
|
|
123
|
-
/**
|
|
124
|
-
* Optional idempotency service
|
|
125
|
-
* If provided, will handle idempotency-key header
|
|
126
|
-
*/
|
|
127
|
-
readonly idempotencyService?: IdempotencyService;
|
|
128
|
-
/**
|
|
129
|
-
* Custom error handler for action execution failures
|
|
130
|
-
* @param error - The error thrown by action handler
|
|
131
|
-
* @param action - The action that failed
|
|
132
|
-
* @param id - The resource ID
|
|
133
|
-
* @returns Status code and error response
|
|
134
|
-
*/
|
|
135
|
-
readonly onError?: (error: Error, action: string, id: string) => {
|
|
136
|
-
statusCode: number;
|
|
137
|
-
error: string;
|
|
138
|
-
code?: string;
|
|
139
|
-
};
|
|
140
|
-
}
|
|
141
|
-
/**
|
|
142
|
-
* Idempotency service interface
|
|
143
|
-
* Apps can provide their own implementation
|
|
144
|
-
*/
|
|
145
|
-
interface IdempotencyService {
|
|
146
|
-
check(key: string, payload: unknown): Promise<{
|
|
147
|
-
isNew: boolean;
|
|
148
|
-
existingResult?: unknown;
|
|
149
|
-
}>;
|
|
150
|
-
complete(key: string | undefined, result: unknown): Promise<void>;
|
|
151
|
-
fail(key: string | undefined, error: Error): Promise<void>;
|
|
152
|
-
}
|
|
153
|
-
/**
|
|
154
|
-
* Create action-based state transition endpoint
|
|
155
|
-
*
|
|
156
|
-
* Registers: POST /:id/action
|
|
157
|
-
* Body: { action: string, ...actionData }
|
|
158
|
-
*
|
|
159
|
-
* @param fastify - Fastify instance
|
|
160
|
-
* @param config - Action router configuration
|
|
161
|
-
*/
|
|
162
|
-
declare function createActionRouter(fastify: FastifyInstance, config: ActionRouterConfig): void;
|
|
163
|
-
/**
|
|
164
|
-
* Build a discriminated body schema for the unified action endpoint.
|
|
165
|
-
*
|
|
166
|
-
* Produces a schema of the form:
|
|
167
|
-
* ```json
|
|
168
|
-
* {
|
|
169
|
-
* "type": "object",
|
|
170
|
-
* "required": ["action"],
|
|
171
|
-
* "oneOf": [
|
|
172
|
-
* { "properties": { "action": { "const": "dispatch" }, "carrier": {...} }, "required": ["action", "carrier"] },
|
|
173
|
-
* { "properties": { "action": { "const": "approve" } }, "required": ["action"] }
|
|
174
|
-
* ]
|
|
175
|
-
* }
|
|
176
|
-
* ```
|
|
177
|
-
*
|
|
178
|
-
* AJV validates this natively, so an action call missing required fields is
|
|
179
|
-
* rejected with HTTP 400 before the handler ever runs.
|
|
180
|
-
*
|
|
181
|
-
* Exported so OpenAPI generation and MCP tool generation can reuse the same
|
|
182
|
-
* schema shape (single source of truth).
|
|
183
|
-
*/
|
|
184
|
-
declare function buildActionBodySchema(actionEnum: readonly string[], actionSchemas?: Record<string, Record<string, unknown>>): Record<string, unknown>;
|
|
185
|
-
//#endregion
|
|
186
55
|
//#region src/core/createCrudRouter.d.ts
|
|
187
56
|
/**
|
|
188
57
|
* Create CRUD routes for a controller
|
|
@@ -309,4 +178,4 @@ declare function createCrudHandlers<TDoc>(controller: IController<TDoc>): {
|
|
|
309
178
|
delete: (req: FastifyRequest, reply: FastifyReply) => Promise<void>;
|
|
310
179
|
};
|
|
311
180
|
//#endregion
|
|
312
|
-
export {
|
|
181
|
+
export { MAX_REGEX_LENGTH as C, RESERVED_QUERY_PARAMS as D, MutationOperation as E, SYSTEM_FIELDS as O, MAX_FILTER_DEPTH as S, MUTATION_OPERATIONS as T, DEFAULT_UPDATE_METHOD as _, getControllerScope as a, HookOperation as b, createCrudRouter as c, CrudOperation as d, DEFAULT_ID_FIELD as f, DEFAULT_TENANT_FIELD as g, DEFAULT_SORT as h, getControllerContext as i, createPermissionMiddleware as l, DEFAULT_MAX_LIMIT as m, createFastifyHandler as n, sendControllerResponse as o, DEFAULT_LIMIT as p, createRequestContext as r, defineResourceVariants as s, createCrudHandlers as t, CRUD_OPERATIONS as u, HOOK_OPERATIONS as v, MAX_SEARCH_LENGTH as w, HookPhase as x, HOOK_PHASES as y };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { J as OpenApiSchemas, X as ParsedQuery, Xt as CrudRepository, _t as RouteSchemaOptions, c as ValidationResult, n as AdapterSchemaContext, o as RepositoryLike, r as DataAdapter, s as SchemaMetadata, tt as QueryParserInterface } from "./interface-YrWsmKqE.mjs";
|
|
2
2
|
import { Model } from "mongoose";
|
|
3
3
|
|
|
4
4
|
//#region src/adapters/mongoose.d.ts
|
package/dist/index.d.mts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { $ as
|
|
2
|
-
import { a as applyFieldWritePermissions, i as applyFieldReadPermissions, n as FieldPermissionMap, o as fields, t as FieldPermission } from "./fields-
|
|
1
|
+
import { $t as DeleteResult, A as FastifyRequestExtras, At as BaseControllerOptions, B as IntrospectionData, Bt as IController, D as CrudSchemas, Dt as envelope, E as CrudRouterOptions, Et as ValidationResult$1, F as HealthCheck, G as MiddlewareConfig, H as JWTPayload, Ht as IRequestContext, I as HealthOptions, Jt as BulkWriteOperation, K as MiddlewareHandler, Kt as ResourceDefinition, L as InferAdapterDoc, M as FastifyWithDecorators, N as FieldRule, O as EventDefinition, P as GracefulShutdownOptions, Q as PresetFunction, Qt as DeleteOptions, R as InferDocType, Rt as ControllerLike, S as ConfigError, St as TypedResourceConfig, T as CrudRouteKey, Tt as ValidateOptions, Ut as RouteHandler, V as IntrospectionPluginOptions, Vt as IControllerResponse, Xt as CrudRepository, Y as OwnershipCheck, Yt as BulkWriteResult, Zt as DeleteManyResult, _ as ArcRequest, _n as PipelineStep, _t as RouteSchemaOptions, a as RelationMetadata, an as PaginationParams, at as RequestContext, bt as TypedController, c as ValidationResult, cn as RepositorySession, dn as Guard, et as PresetResult, fn as Interceptor, ft as ResourceMetadata, g as ArcInternalMetadata, gn as PipelineContext, hn as PipelineConfig, ht as RouteHandlerMethod, i as FieldMetadata, in as PaginatedResult, it as RegistryStats, j as FastifyWithAuth, kt as BaseController, ln as UpdateManyResult, lt as ResourceConfig, m as ApiResponse, mn as OperationFilter, nn as KeysetPaginatedResult, nt as RateLimitConfig, o as RepositoryLike, on as PaginationResult, ot as RequestIdOptions, p as AnyRecord, pn as NextFunction, qt as defineResource, r as DataAdapter, rn as OffsetPaginatedResult, rt as RegistryEntry, s as SchemaMetadata, sn as QueryOptions, st as RequestWithExtras, un as WriteOptions, vn as Transform, vt as ServiceContext, w as CrudController, wt as UserOrganization, xt as TypedRepository, y as AuthPluginOptions, z as InferResourceDoc } from "./interface-YrWsmKqE.mjs";
|
|
2
|
+
import { a as applyFieldWritePermissions, i as applyFieldReadPermissions, n as FieldPermissionMap, o as fields, t as FieldPermission } from "./fields-BC7zcmI9.mjs";
|
|
3
3
|
import { i as UserBase, n as PermissionContext, r as PermissionResult, t as PermissionCheck } from "./types-DZi1aYhm.mjs";
|
|
4
|
-
import { l as createMongooseAdapter, o as createPrismaAdapter, s as MongooseAdapter, t as PrismaAdapter } from "./index-
|
|
5
|
-
import {
|
|
6
|
-
import { C as authenticated, D as publicRead, E as presets_d_exports, O as publicReadAdminWrite, S as adminOnly, T as ownerWithAdminBypass, _ as requireScopeContext, a as allOf, c as createDynamicPermissionMatrix, d as requireAuth, f as requireOrgInScope, g as requireRoles, h as requireOwnership, k as readOnly, l as createOrgPermissions, m as requireOrgRole, n as DynamicPermissionMatrix, o as allowPublic, p as requireOrgMembership, r as DynamicPermissionMatrixConfig, s as anyOf, u as denyAll, v as requireServiceScope, w as fullPublic, x as when, y as requireTeamMembership } from "./index-
|
|
7
|
-
import { a as NotFoundError, d as ValidationError, f as createDomainError, i as ForbiddenError, t as ArcError, u as UnauthorizedError } from "./errors-
|
|
4
|
+
import { l as createMongooseAdapter, o as createPrismaAdapter, s as MongooseAdapter, t as PrismaAdapter } from "./index-CtGKT0lf.mjs";
|
|
5
|
+
import { C as MAX_REGEX_LENGTH, D as RESERVED_QUERY_PARAMS, E as MutationOperation, O as SYSTEM_FIELDS, S as MAX_FILTER_DEPTH, T as MUTATION_OPERATIONS, _ as DEFAULT_UPDATE_METHOD, a as getControllerScope, b as HookOperation, d as CrudOperation, f as DEFAULT_ID_FIELD, g as DEFAULT_TENANT_FIELD, h as DEFAULT_SORT, m as DEFAULT_MAX_LIMIT, p as DEFAULT_LIMIT, s as defineResourceVariants, u as CRUD_OPERATIONS, v as HOOK_OPERATIONS, w as MAX_SEARCH_LENGTH, x as HookPhase, y as HOOK_PHASES } from "./index-Cibkchnx.mjs";
|
|
6
|
+
import { C as authenticated, D as publicRead, E as presets_d_exports, O as publicReadAdminWrite, S as adminOnly, T as ownerWithAdminBypass, _ as requireScopeContext, a as allOf, c as createDynamicPermissionMatrix, d as requireAuth, f as requireOrgInScope, g as requireRoles, h as requireOwnership, k as readOnly, l as createOrgPermissions, m as requireOrgRole, n as DynamicPermissionMatrix, o as allowPublic, p as requireOrgMembership, r as DynamicPermissionMatrixConfig, s as anyOf, u as denyAll, v as requireServiceScope, w as fullPublic, x as when, y as requireTeamMembership } from "./index-C-xjcA6F.mjs";
|
|
7
|
+
import { a as NotFoundError, d as ValidationError, f as createDomainError, i as ForbiddenError, t as ArcError, u as UnauthorizedError } from "./errors-BI8kEKsO.mjs";
|
|
8
8
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
9
9
|
import { RouteHandlerMethod as RouteHandlerMethod$1 } from "fastify";
|
|
10
10
|
|
|
@@ -253,4 +253,4 @@ declare function arcLog(module: string): ArcLogger;
|
|
|
253
253
|
//#region src/index.d.ts
|
|
254
254
|
declare const version: string;
|
|
255
255
|
//#endregion
|
|
256
|
-
export { type ValidationResult as AdapterValidationResult, type
|
|
256
|
+
export { type ValidationResult as AdapterValidationResult, type AnyRecord, type ApiResponse, ArcError, type ArcInternalMetadata, type ArcLogWriter, type ArcLogger, type ArcLoggerOptions, type ArcRequest, type AuthPluginOptions, BaseController, type BaseControllerOptions, type BulkWriteOperation, type BulkWriteResult, CRUD_OPERATIONS, type ConfigError, type ControllerLike, type CrudController, CrudOperation, type CrudRepository, type CrudRouteKey, type CrudRouterOptions, type CrudSchemas, DEFAULT_ID_FIELD, DEFAULT_LIMIT, DEFAULT_MAX_LIMIT, DEFAULT_SORT, DEFAULT_TENANT_FIELD, DEFAULT_UPDATE_METHOD, type DataAdapter, type DeleteManyResult, type DeleteOptions, type DeleteResult, type DynamicPermissionMatrix, type DynamicPermissionMatrixConfig, type EventDefinition, type FastifyRequestExtras, type FastifyWithAuth, type FastifyWithDecorators, type FieldMetadata, type FieldPermission, type FieldPermissionMap, type FieldRule, ForbiddenError, type GracefulShutdownOptions, type Guard, HOOK_OPERATIONS, HOOK_PHASES, type HealthCheck, type HealthOptions, HookOperation, HookPhase, type IController, type IControllerResponse, type IRequestContext, type InferAdapterDoc, type InferDocType, type InferResourceDoc, type Interceptor, type IntrospectionData, type IntrospectionPluginOptions, type JWTPayload, type KeysetPaginatedResult, MAX_FILTER_DEPTH, MAX_REGEX_LENGTH, MAX_SEARCH_LENGTH, MUTATION_OPERATIONS, type MiddlewareConfig, MongooseAdapter, MutationOperation, type NamedMiddleware, NotFoundError, type OffsetPaginatedResult, type OwnershipCheck, type PaginatedResult, type PaginationParams, type PaginationResult, type PermissionCheck, type PermissionContext, type PermissionResult, type PipelineConfig, type PipelineContext, type PipelineStep, type PresetFunction, type PresetResult, PrismaAdapter, type QueryOptions, RESERVED_QUERY_PARAMS, type RateLimitConfig, type RegistryEntry, type RegistryStats, type RelationMetadata, type RepositoryLike, type RepositorySession, type RequestContext, type RequestIdOptions, type RequestStore, type RequestWithExtras, type ResourceConfig, ResourceDefinition, type ResourceMetadata, type RouteHandler, type RouteHandlerMethod, type RouteSchemaOptions, SYSTEM_FIELDS, type SchemaMetadata, type ServiceContext, type Transform, type TypedController, type TypedRepository, type TypedResourceConfig, UnauthorizedError, type UpdateManyResult, type UserBase, type UserOrganization, type ValidateOptions, ValidationError, type ValidationResult$1 as ValidationResult, type WriteOptions, adminOnly, allOf, allowPublic, anyOf, applyFieldReadPermissions, applyFieldWritePermissions, arcLog, assertValidConfig, authenticated, configureArcLogger, createDomainError, createDynamicPermissionMatrix, createMongooseAdapter, createOrgPermissions, createPrismaAdapter, defineResource, defineResourceVariants, denyAll, envelope, fields, formatValidationErrors, fullPublic, getControllerScope, guard, intercept, middleware, ownerWithAdminBypass, presets_d_exports as permissions, pipe, publicRead, publicReadAdminWrite, readOnly, requestContext, requireAuth, requireOrgInScope, requireOrgMembership, requireOrgRole, requireOwnership, requireRoles, requireScopeContext, requireServiceScope, requireTeamMembership, sortMiddlewares, transform, validateResourceConfig, version, when };
|
package/dist/index.mjs
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { a as DEFAULT_SORT, c as HOOK_OPERATIONS, d as MAX_REGEX_LENGTH, f as MAX_SEARCH_LENGTH, h as SYSTEM_FIELDS, i as DEFAULT_MAX_LIMIT, l as HOOK_PHASES, m as RESERVED_QUERY_PARAMS, n as DEFAULT_ID_FIELD, o as DEFAULT_TENANT_FIELD, p as MUTATION_OPERATIONS, r as DEFAULT_LIMIT, s as DEFAULT_UPDATE_METHOD, t as CRUD_OPERATIONS, u as MAX_FILTER_DEPTH } from "./constants-Cxde4rpC.mjs";
|
|
2
2
|
import { a as createMongooseAdapter, i as MongooseAdapter, r as createPrismaAdapter, t as PrismaAdapter } from "./adapters-BBqAVvPK.mjs";
|
|
3
|
-
import { t as BaseController } from "./BaseController-
|
|
3
|
+
import { t as BaseController } from "./BaseController-Vu2yc56T.mjs";
|
|
4
4
|
import { envelope } from "./types/index.mjs";
|
|
5
|
-
import { n as applyFieldWritePermissions, r as fields, t as applyFieldReadPermissions } from "./fields-
|
|
6
|
-
import { t as
|
|
7
|
-
import {
|
|
8
|
-
import { a as validateResourceConfig, f as getControllerScope, i as formatValidationErrors, m as pipe, n as defineResource, r as assertValidConfig, t as ResourceDefinition } from "./defineResource-
|
|
9
|
-
import { C as publicRead, S as presets_exports, T as readOnly, _ as when, a as createOrgPermissions, b as fullPublic, c as requireOrgInScope, d as requireOwnership, f as requireRoles, h as requireTeamMembership, i as createDynamicPermissionMatrix, l as requireOrgMembership, m as requireServiceScope, n as allowPublic, o as denyAll, p as requireScopeContext, r as anyOf, s as requireAuth, t as allOf, u as requireOrgRole, v as adminOnly, w as publicReadAdminWrite, x as ownerWithAdminBypass, y as authenticated } from "./permissions-
|
|
10
|
-
import { t as defineResourceVariants } from "./core-
|
|
11
|
-
import { n as configureArcLogger, t as arcLog } from "./logger-
|
|
5
|
+
import { n as applyFieldWritePermissions, r as fields, t as applyFieldReadPermissions } from "./fields-CU6FlaDV.mjs";
|
|
6
|
+
import { d as createDomainError, i as NotFoundError, l as UnauthorizedError, r as ForbiddenError, t as ArcError, u as ValidationError } from "./errors-CqWnSqM-.mjs";
|
|
7
|
+
import { t as requestContext } from "./requestContext-DYtmNpm5.mjs";
|
|
8
|
+
import { a as validateResourceConfig, f as getControllerScope, i as formatValidationErrors, m as pipe, n as defineResource, r as assertValidConfig, t as ResourceDefinition } from "./defineResource-C__jkwvs.mjs";
|
|
9
|
+
import { C as publicRead, S as presets_exports, T as readOnly, _ as when, a as createOrgPermissions, b as fullPublic, c as requireOrgInScope, d as requireOwnership, f as requireRoles, h as requireTeamMembership, i as createDynamicPermissionMatrix, l as requireOrgMembership, m as requireServiceScope, n as allowPublic, o as denyAll, p as requireScopeContext, r as anyOf, s as requireAuth, t as allOf, u as requireOrgRole, v as adminOnly, w as publicReadAdminWrite, x as ownerWithAdminBypass, y as authenticated } from "./permissions-oNZawnkR.mjs";
|
|
10
|
+
import { t as defineResourceVariants } from "./core-DNncu0xF.mjs";
|
|
11
|
+
import { n as configureArcLogger, t as arcLog } from "./logger-CDjpjySd.mjs";
|
|
12
12
|
//#region src/middleware/middleware.ts
|
|
13
13
|
/**
|
|
14
14
|
* Named Middleware — Priority-based, conditional middleware execution.
|
|
@@ -128,6 +128,6 @@ function transform(name, handlerOrOptions) {
|
|
|
128
128
|
}
|
|
129
129
|
//#endregion
|
|
130
130
|
//#region src/index.ts
|
|
131
|
-
const version = "2.
|
|
131
|
+
const version = "2.9.1";
|
|
132
132
|
//#endregion
|
|
133
133
|
export { ArcError, BaseController, CRUD_OPERATIONS, DEFAULT_ID_FIELD, DEFAULT_LIMIT, DEFAULT_MAX_LIMIT, DEFAULT_SORT, DEFAULT_TENANT_FIELD, DEFAULT_UPDATE_METHOD, ForbiddenError, HOOK_OPERATIONS, HOOK_PHASES, MAX_FILTER_DEPTH, MAX_REGEX_LENGTH, MAX_SEARCH_LENGTH, MUTATION_OPERATIONS, MongooseAdapter, NotFoundError, PrismaAdapter, RESERVED_QUERY_PARAMS, ResourceDefinition, SYSTEM_FIELDS, UnauthorizedError, ValidationError, adminOnly, allOf, allowPublic, anyOf, applyFieldReadPermissions, applyFieldWritePermissions, arcLog, assertValidConfig, authenticated, configureArcLogger, createDomainError, createDynamicPermissionMatrix, createMongooseAdapter, createOrgPermissions, createPrismaAdapter, defineResource, defineResourceVariants, denyAll, envelope, fields, formatValidationErrors, fullPublic, getControllerScope, guard, intercept, middleware, ownerWithAdminBypass, presets_exports as permissions, pipe, publicRead, publicReadAdminWrite, readOnly, requestContext, requireAuth, requireOrgInScope, requireOrgMembership, requireOrgRole, requireOwnership, requireRoles, requireScopeContext, requireServiceScope, requireTeamMembership, sortMiddlewares, transform, validateResourceConfig, version, when };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { n as DomainEvent } from "../EventTransport-CqZ8FyM_.mjs";
|
|
2
2
|
import { WebSocketClient, WebSocketMessage } from "./websocket.mjs";
|
|
3
3
|
import { FastifyPluginAsync, FastifyRequest } from "fastify";
|
|
4
4
|
|
|
@@ -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-CJpt7LGI.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
1
|
import { WebSocketClient, WebSocketMessage, WebSocketPluginOptions } from "./websocket.mjs";
|
|
2
2
|
import { EventGatewayOptions } from "./event-gateway.mjs";
|
|
3
3
|
import { JobDefinition, JobDispatchOptions, JobDispatcher, JobMeta, JobsPluginOptions, QueueStats } from "./jobs.mjs";
|
|
4
|
-
import { c as McpResourceConfig, f as ToolAnnotations, i as CrudOperation, l as PromptDefinition, m as ToolDefinition, n as CallToolResult, o as McpAuthResult, p as ToolContext, r as CreateMcpServerConfig, s as McpPluginOptions, t as BetterAuthHandler } from "../types-
|
|
4
|
+
import { c as McpResourceConfig, f as ToolAnnotations, i as CrudOperation, l as PromptDefinition, m as ToolDefinition, n as CallToolResult, o as McpAuthResult, p as ToolContext, r as CreateMcpServerConfig, s as McpPluginOptions, t as BetterAuthHandler } from "../types-CoSzA-s-.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, type CallToolResult, type CreateMcpServerConfig, type CrudOperation, type EventGatewayOptions, type JobDefinition, type JobDispatchOptions, type JobDispatcher, type JobMeta, type JobsPluginOptions, type McpAuthResult, type McpPluginOptions, type McpResourceConfig, type PromptDefinition, type QueueStats, type StreamlinePluginOptions, type ToolAnnotations, type ToolContext, type ToolDefinition, type WebSocketClient, type WebSocketMessage, type WebSocketPluginOptions, type WebhookDeliveryRecord, type WebhookManager, type WebhookPluginOptions, type WebhookStore, type WebhookSubscription, type WorkflowLike, type WorkflowRunLike };
|