@classytic/arc 2.10.3 → 2.10.8

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 (135) hide show
  1. package/README.md +1 -1
  2. package/dist/{BaseController-CbKKIflT.mjs → BaseController-DVNKvoX4.mjs} +151 -131
  3. package/dist/actionPermissions-TUVR3uiZ.mjs +22 -0
  4. package/dist/adapters/index.d.mts +2 -2
  5. package/dist/audit/index.d.mts +2 -2
  6. package/dist/audit/index.mjs +15 -17
  7. package/dist/auth/index.d.mts +4 -4
  8. package/dist/auth/index.mjs +5 -5
  9. package/dist/auth/redis-session.d.mts +1 -1
  10. package/dist/cache/index.d.mts +2 -2
  11. package/dist/cache/index.mjs +3 -3
  12. package/dist/cli/commands/docs.mjs +2 -2
  13. package/dist/cli/commands/generate.mjs +1 -1
  14. package/dist/cli/commands/init.mjs +1 -1
  15. package/dist/cli/commands/introspect.mjs +1 -1
  16. package/dist/context/index.d.mts +58 -0
  17. package/dist/context/index.mjs +2 -0
  18. package/dist/core/index.d.mts +2 -2
  19. package/dist/core/index.mjs +2 -2
  20. package/dist/{core-CcR01lup.mjs → core-3MWJosCH.mjs} +139 -91
  21. package/dist/{createApp-BuvPma24.mjs → createApp-BwnEAO2h.mjs} +54 -20
  22. package/dist/docs/index.d.mts +2 -2
  23. package/dist/docs/index.mjs +2 -2
  24. package/dist/{elevation-C7hgL_aI.mjs → elevation-Dci0AYLT.mjs} +2 -2
  25. package/dist/errorHandler-2ii4RIYr.d.mts +114 -0
  26. package/dist/{errorHandler-Bb49BvPD.mjs → errorHandler-CSxe7KIM.mjs} +1 -1
  27. package/dist/{eventPlugin-DCUjuiQT.mjs → eventPlugin-ByU4Cv0e.mjs} +1 -1
  28. package/dist/{eventPlugin-CxWgpd6K.d.mts → eventPlugin-D1ThQ1Pp.d.mts} +1 -1
  29. package/dist/events/index.d.mts +4 -4
  30. package/dist/events/index.mjs +69 -51
  31. package/dist/events/transports/redis-stream-entry.d.mts +1 -1
  32. package/dist/events/transports/redis.d.mts +1 -1
  33. package/dist/factory/index.d.mts +1 -1
  34. package/dist/factory/index.mjs +2 -2
  35. package/dist/{fields-Lo1VUDpt.d.mts → fields-C8Y0XLAu.d.mts} +1 -1
  36. package/dist/hooks/index.d.mts +1 -1
  37. package/dist/hooks/index.mjs +1 -1
  38. package/dist/idempotency/index.d.mts +3 -3
  39. package/dist/idempotency/index.mjs +38 -27
  40. package/dist/idempotency/redis.d.mts +1 -1
  41. package/dist/{index-Cl0uoKd5.d.mts → index-BGbpGVyM.d.mts} +2362 -2155
  42. package/dist/{index-DStwgFUK.d.mts → index-BziRPS4H.d.mts} +1 -1
  43. package/dist/{index-ChIw3776.d.mts → index-C_Noptz-.d.mts} +3 -3
  44. package/dist/{index-8qw4y6ff.d.mts → index-EqQN6p0W.d.mts} +3 -3
  45. package/dist/index.d.mts +7 -219
  46. package/dist/index.mjs +8 -128
  47. package/dist/integrations/event-gateway.d.mts +1 -1
  48. package/dist/integrations/event-gateway.mjs +1 -1
  49. package/dist/integrations/index.d.mts +1 -1
  50. package/dist/integrations/mcp/index.d.mts +2 -2
  51. package/dist/integrations/mcp/index.mjs +1 -1
  52. package/dist/integrations/mcp/testing.d.mts +1 -1
  53. package/dist/integrations/mcp/testing.mjs +1 -1
  54. package/dist/logger/index.d.mts +81 -0
  55. package/dist/{logger-DLg8-Ueg.mjs → logger/index.mjs} +1 -6
  56. package/dist/middleware/index.d.mts +109 -0
  57. package/dist/middleware/index.mjs +70 -0
  58. package/dist/multipartBody-CUQGVlM_.mjs +123 -0
  59. package/dist/{openapi-B5F8AddX.mjs → openapi-DpNpqBmo.mjs} +9 -7
  60. package/dist/org/index.d.mts +2 -2
  61. package/dist/permissions/index.d.mts +2 -2
  62. package/dist/permissions/index.mjs +3 -3
  63. package/dist/{permissions-Dk6mshja.mjs → permissions-wkqRwicB.mjs} +2 -2
  64. package/dist/pipe-CGJxqDGx.mjs +62 -0
  65. package/dist/pipeline/index.d.mts +62 -0
  66. package/dist/pipeline/index.mjs +53 -0
  67. package/dist/plugins/index.d.mts +25 -5
  68. package/dist/plugins/index.mjs +9 -9
  69. package/dist/plugins/tracing-entry.d.mts +1 -1
  70. package/dist/plugins/tracing-entry.mjs +1 -1
  71. package/dist/presets/filesUpload.d.mts +4 -4
  72. package/dist/presets/filesUpload.mjs +255 -1
  73. package/dist/presets/index.d.mts +1 -1
  74. package/dist/presets/index.mjs +2 -2
  75. package/dist/presets/multiTenant.d.mts +1 -1
  76. package/dist/presets/multiTenant.mjs +42 -8
  77. package/dist/presets/search.d.mts +2 -2
  78. package/dist/presets/search.mjs +1 -1
  79. package/dist/{presets-fLJVXdVn.mjs → presets-CrwOvuXI.mjs} +1 -1
  80. package/dist/{queryCachePlugin-DQCEfJis.mjs → queryCachePlugin-ChLNZvFT.mjs} +2 -2
  81. package/dist/{queryCachePlugin-BKbWjgDG.d.mts → queryCachePlugin-Dumka73q.d.mts} +1 -1
  82. package/dist/{queryParser-DBqBB6AC.mjs → queryParser-NR__Qiju.mjs} +68 -1
  83. package/dist/{redis-DqyeggCa.d.mts → redis-MXLp1oOf.d.mts} +1 -1
  84. package/dist/{redis-stream-CakIQmwR.d.mts → redis-stream-bkO88VHx.d.mts} +1 -1
  85. package/dist/registry/index.d.mts +1 -1
  86. package/dist/registry/index.mjs +2 -2
  87. package/dist/{requestContext-xHIKedG6.mjs → requestContext-C38GskNt.mjs} +1 -1
  88. package/dist/{resourceToTools-BElv3xPT.mjs → resourceToTools-BhF3JV5p.mjs} +8 -3
  89. package/dist/scope/index.d.mts +2 -2
  90. package/dist/scope/index.mjs +2 -2
  91. package/dist/{sse-yBCgOLGu.mjs → sse-D8UeDwis.mjs} +1 -1
  92. package/dist/{store-helpers-ZCSMJJAX.mjs → store-helpers-DYYUQbQN.mjs} +4 -0
  93. package/dist/testing/index.d.mts +2 -2
  94. package/dist/testing/index.mjs +11 -2
  95. package/dist/testing/storageContract.d.mts +1 -1
  96. package/dist/types/index.d.mts +4 -4
  97. package/dist/types/index.mjs +1 -1
  98. package/dist/types/storage.d.mts +1 -1
  99. package/dist/{types-Btdda02s.d.mts → types-CVKBssX5.d.mts} +1 -1
  100. package/dist/{types-Co8k3NyS.d.mts → types-CVdgPXBW.d.mts} +22 -9
  101. package/dist/utils/index.d.mts +73 -3
  102. package/dist/utils/index.mjs +4 -4
  103. package/dist/{utils-B2fNOD_i.mjs → utils-LMwVidKy.mjs} +20 -2
  104. package/dist/versioning-CeUXHfjw.d.mts +117 -0
  105. package/package.json +22 -6
  106. package/skills/arc/SKILL.md +1 -1
  107. package/dist/errorHandler-DRQ3EqfL.d.mts +0 -218
  108. package/dist/filesUpload-t21LS-py.mjs +0 -377
  109. /package/dist/{EventTransport-CUw5NNWe.d.mts → EventTransport-CfVEGaEl.d.mts} +0 -0
  110. /package/dist/{HookSystem-BNYKnrXF.mjs → HookSystem-BjFu7zf1.mjs} +0 -0
  111. /package/dist/{ResourceRegistry-BPd6NQDm.mjs → ResourceRegistry-CcN2LVrc.mjs} +0 -0
  112. /package/dist/{betterAuthOpenApi-BBRVhjQN.mjs → betterAuthOpenApi--rdY15Ld.mjs} +0 -0
  113. /package/dist/{caching-CBpK_SCM.mjs → caching-3h93rkJM.mjs} +0 -0
  114. /package/dist/{createActionRouter-Bp_5c_2b.mjs → createActionRouter-C8UUB3Px.mjs} +0 -0
  115. /package/dist/{elevation-C5SwtkAn.d.mts → elevation-s5ykdNHr.d.mts} +0 -0
  116. /package/dist/{errors-CCSsMpXE.d.mts → errors-BI8kEKsO.d.mts} +0 -0
  117. /package/dist/{errors-D5c-5BJL.mjs → errors-BqdUDja_.mjs} +0 -0
  118. /package/dist/{externalPaths-BQ8QijNH.d.mts → externalPaths-Bapitwvd.d.mts} +0 -0
  119. /package/dist/{fields-bxkeltzz.mjs → fields-CTMWOUDt.mjs} +0 -0
  120. /package/dist/{interface-CSbZdv_3.d.mts → interface-B-pe8fhj.d.mts} +0 -0
  121. /package/dist/{interface-D218ikEo.d.mts → interface-yhyb_pLY.d.mts} +0 -0
  122. /package/dist/{keys-qcD-TVJl.mjs → keys-nWQGUTu1.mjs} +0 -0
  123. /package/dist/{loadResources-BAzJItAJ.mjs → loadResources-Bksk8ydA.mjs} +0 -0
  124. /package/dist/{memory-B5Amv9A1.mjs → memory-DqI-449b.mjs} +0 -0
  125. /package/dist/{metrics-DuhiSEZI.mjs → metrics-TuOmguhi.mjs} +0 -0
  126. /package/dist/{pluralize-A0tWEl1K.mjs → pluralize-CWP6MB39.mjs} +0 -0
  127. /package/dist/{registry-B3lRFBWo.mjs → registry-B0Wl7uVV.mjs} +0 -0
  128. /package/dist/{replyHelpers-CXtJDAZ0.mjs → replyHelpers-BLojtuvR.mjs} +0 -0
  129. /package/dist/{sessionManager-BkzVU8h2.d.mts → sessionManager-D-oNWHz3.d.mts} +0 -0
  130. /package/dist/{storage-CVk_SEn2.d.mts → storage-BwGQXUpd.d.mts} +0 -0
  131. /package/dist/{tracing-65B51Dw3.d.mts → tracing-xqXzWeaf.d.mts} +0 -0
  132. /package/dist/{types-Csi3FLfq.mjs → types-CDnTEpga.mjs} +0 -0
  133. /package/dist/{types-DV9WDfeg.mjs → types-D57iXYb8.mjs} +0 -0
  134. /package/dist/{types-BD85MlEK.d.mts → types-tgR4Pt8F.d.mts} +0 -0
  135. /package/dist/{versioning-C2U_bLY0.mjs → versioning-B6mimogM.mjs} +0 -0
@@ -0,0 +1,109 @@
1
+ import { I as MiddlewareHandler, L as RequestWithExtras, pt as MiddlewareConfig } from "../index-BGbpGVyM.mjs";
2
+ import { RouteHandlerMethod } from "fastify";
3
+
4
+ //#region src/middleware/middleware.d.ts
5
+ interface NamedMiddleware {
6
+ /** Unique name for debugging/introspection */
7
+ readonly name: string;
8
+ /** Operations this middleware applies to (default: all) */
9
+ readonly operations?: Array<"list" | "get" | "create" | "update" | "delete" | string>;
10
+ /** Priority — lower numbers run first (default: 10) */
11
+ readonly priority: number;
12
+ /** Conditional execution — return true to run, false to skip */
13
+ readonly when?: (request: RequestWithExtras) => boolean | Promise<boolean>;
14
+ /** The middleware handler */
15
+ readonly handler: MiddlewareHandler;
16
+ }
17
+ interface MiddlewareOptions {
18
+ operations?: NamedMiddleware["operations"];
19
+ priority?: number;
20
+ when?: NamedMiddleware["when"];
21
+ handler: MiddlewareHandler;
22
+ }
23
+ /**
24
+ * Create a named middleware with priority and conditions.
25
+ */
26
+ declare function middleware(name: string, options: MiddlewareOptions): NamedMiddleware;
27
+ /**
28
+ * Sort named middlewares by priority (ascending — lower runs first).
29
+ * Returns a MiddlewareConfig map keyed by operation, ready to pass to `defineResource()`.
30
+ */
31
+ declare function sortMiddlewares(middlewares: NamedMiddleware[]): MiddlewareConfig;
32
+ //#endregion
33
+ //#region src/middleware/multipartBody.d.ts
34
+ /** Parsed file from multipart form-data */
35
+ interface ParsedFile {
36
+ /** Original filename */
37
+ filename: string;
38
+ /** MIME type */
39
+ mimetype: string;
40
+ /** File contents as Buffer */
41
+ buffer: Buffer;
42
+ /** File size in bytes */
43
+ size: number;
44
+ /** Form field name */
45
+ fieldname: string;
46
+ }
47
+ interface MultipartBodyOptions {
48
+ /**
49
+ * Maximum file size in bytes (default: 10MB).
50
+ * Files exceeding this are rejected with 413.
51
+ */
52
+ maxFileSize?: number;
53
+ /**
54
+ * Maximum number of files (default: 5).
55
+ * Extra files are silently ignored.
56
+ */
57
+ maxFiles?: number;
58
+ /**
59
+ * Allowed MIME types (default: all).
60
+ * Files with disallowed types are rejected with 415.
61
+ *
62
+ * Supports three forms in a single list:
63
+ * - Exact: `image/png`
64
+ * - Subtype wildcard: `image/\*` — any `image/…`
65
+ * - Any: `\*` or `\*\/\*` — equivalent to omitting the option
66
+ *
67
+ * @example ['image/jpeg', 'image/png', 'application/pdf']
68
+ * @example ['image/*', 'application/pdf']
69
+ * @example ['*'] // accept any type explicitly
70
+ */
71
+ allowedMimeTypes?: string[];
72
+ /**
73
+ * Key on `req.body` where parsed files are attached (default: '_files').
74
+ * Set to a custom key if '_files' conflicts with your schema.
75
+ *
76
+ * Note: this is the **destination** key — it controls where parsed files
77
+ * land on `req.body`, not which form fields are required. To enforce that
78
+ * a specific file field must be present in the request, use `requiredFields`.
79
+ */
80
+ filesKey?: string;
81
+ /**
82
+ * Multipart form field names that MUST be present in the request.
83
+ * Returns 400 with `{ success: false, error, code: 'MISSING_FILE_FIELDS' }`
84
+ * when any listed field is absent from the uploaded files.
85
+ *
86
+ * Only enforced when the request IS multipart — JSON requests still pass
87
+ * through as no-ops so the same middleware stays safe to add to shared
88
+ * create/update routes that accept both content types.
89
+ *
90
+ * @example ['file'] // single-field upload (OCR, classify)
91
+ * @example ['avatar', 'cover'] // multi-field upload (profile editor)
92
+ */
93
+ requiredFields?: string[];
94
+ }
95
+ /**
96
+ * Create a multipart body parsing middleware.
97
+ *
98
+ * When a request has `content-type: multipart/form-data`, this middleware:
99
+ * 1. Reads all parts (fields + files)
100
+ * 2. Sets text fields on `req.body` as a plain object
101
+ * 3. Attaches file buffers to `req.body[filesKey]` (default: `req.body._files`)
102
+ *
103
+ * For non-multipart requests (regular JSON), this is a no-op — the request
104
+ * passes through unchanged. This makes it safe to add to create/update
105
+ * middlewares without breaking JSON clients.
106
+ */
107
+ declare function multipartBody(options?: MultipartBodyOptions): RouteHandlerMethod;
108
+ //#endregion
109
+ export { type MultipartBodyOptions, type NamedMiddleware, type ParsedFile, middleware, multipartBody, sortMiddlewares };
@@ -0,0 +1,70 @@
1
+ import { t as CRUD_OPERATIONS } from "../constants-BhY1OHoH.mjs";
2
+ import { t as multipartBody } from "../multipartBody-CUQGVlM_.mjs";
3
+ //#region src/middleware/middleware.ts
4
+ /**
5
+ * Named Middleware — Priority-based, conditional middleware execution.
6
+ *
7
+ * Named middleware replaces flat arrays with structured, inspectable middleware
8
+ * that runs in priority order and supports conditional execution.
9
+ *
10
+ * @example
11
+ * ```typescript
12
+ * import { middleware } from '@classytic/arc/middleware';
13
+ *
14
+ * const verifyEmail = middleware('verifyEmail', {
15
+ * operations: ['create', 'update'],
16
+ * priority: 5,
17
+ * when: (req) => !req.user?.emailVerified,
18
+ * handler: async (req, reply) => {
19
+ * reply.code(403).send({ error: 'Email verification required' });
20
+ * },
21
+ * });
22
+ *
23
+ * const rateLimit = middleware('rateLimit', {
24
+ * priority: 1,
25
+ * handler: async (req, reply) => {
26
+ * // rate limit logic
27
+ * },
28
+ * });
29
+ *
30
+ * const productResource = defineResource({
31
+ * name: 'product',
32
+ * adapter,
33
+ * middlewares: sortMiddlewares([verifyEmail, rateLimit]),
34
+ * });
35
+ * ```
36
+ */
37
+ /**
38
+ * Create a named middleware with priority and conditions.
39
+ */
40
+ function middleware(name, options) {
41
+ return {
42
+ name,
43
+ operations: options.operations,
44
+ priority: options.priority ?? 10,
45
+ when: options.when,
46
+ handler: options.handler
47
+ };
48
+ }
49
+ /**
50
+ * Sort named middlewares by priority (ascending — lower runs first).
51
+ * Returns a MiddlewareConfig map keyed by operation, ready to pass to `defineResource()`.
52
+ */
53
+ function sortMiddlewares(middlewares) {
54
+ const sorted = [...middlewares].sort((a, b) => a.priority - b.priority);
55
+ const operations = CRUD_OPERATIONS;
56
+ const result = {};
57
+ for (const op of operations) {
58
+ const applicable = sorted.filter((m) => !m.operations || m.operations.length === 0 || m.operations.includes(op));
59
+ if (applicable.length > 0) result[op] = applicable.map((m) => {
60
+ if (!m.when) return m.handler;
61
+ const wrapped = async (request, reply) => {
62
+ if (await m.when?.(request)) return m.handler(request, reply);
63
+ };
64
+ return wrapped;
65
+ });
66
+ }
67
+ return result;
68
+ }
69
+ //#endregion
70
+ export { middleware, multipartBody, sortMiddlewares };
@@ -0,0 +1,123 @@
1
+ //#region src/middleware/multipartBody.ts
2
+ const DEFAULT_MAX_FILE_SIZE = 10 * 1024 * 1024;
3
+ const DEFAULT_MAX_FILES = 5;
4
+ const DEFAULT_FILES_KEY = "_files";
5
+ /**
6
+ * Build a matcher for MIME allow-lists that supports exact (e.g. `image/png`),
7
+ * subtype wildcards (e.g. `image/\*`), and total wildcards (`\*` or `\*\/\*`).
8
+ *
9
+ * Returns `undefined` when no filter is needed — either because the option
10
+ * was omitted or because a total wildcard was present.
11
+ */
12
+ function buildMimeMatcher(allowed) {
13
+ if (!allowed || allowed.length === 0) return void 0;
14
+ const exact = /* @__PURE__ */ new Set();
15
+ const prefixes = [];
16
+ for (const entry of allowed) {
17
+ const value = entry.trim().toLowerCase();
18
+ if (!value) continue;
19
+ if (value === "*" || value === "*/*") return void 0;
20
+ if (value.endsWith("/*")) prefixes.push(value.slice(0, -1));
21
+ else exact.add(value);
22
+ }
23
+ if (exact.size === 0 && prefixes.length === 0) return void 0;
24
+ return {
25
+ matches(mime) {
26
+ const m = mime.toLowerCase();
27
+ if (exact.has(m)) return true;
28
+ for (const p of prefixes) if (m.startsWith(p)) return true;
29
+ return false;
30
+ },
31
+ describe() {
32
+ return [...exact, ...prefixes.map((p) => `${p}*`)].join(", ");
33
+ }
34
+ };
35
+ }
36
+ /**
37
+ * Create a multipart body parsing middleware.
38
+ *
39
+ * When a request has `content-type: multipart/form-data`, this middleware:
40
+ * 1. Reads all parts (fields + files)
41
+ * 2. Sets text fields on `req.body` as a plain object
42
+ * 3. Attaches file buffers to `req.body[filesKey]` (default: `req.body._files`)
43
+ *
44
+ * For non-multipart requests (regular JSON), this is a no-op — the request
45
+ * passes through unchanged. This makes it safe to add to create/update
46
+ * middlewares without breaking JSON clients.
47
+ */
48
+ function multipartBody(options = {}) {
49
+ const maxFileSize = options.maxFileSize ?? DEFAULT_MAX_FILE_SIZE;
50
+ const maxFiles = options.maxFiles ?? DEFAULT_MAX_FILES;
51
+ const mimeMatcher = buildMimeMatcher(options.allowedMimeTypes);
52
+ const filesKey = options.filesKey ?? DEFAULT_FILES_KEY;
53
+ const requiredFields = options.requiredFields && options.requiredFields.length > 0 ? options.requiredFields : void 0;
54
+ return async function parseMultipartBody(request, reply) {
55
+ if (!(request.headers["content-type"] ?? "").includes("multipart/form-data")) return;
56
+ if (typeof request.parts !== "function") {
57
+ request.log.warn("multipartBody middleware: @fastify/multipart not registered. Ensure createApp() has multipart enabled (default) or install @fastify/multipart.");
58
+ return;
59
+ }
60
+ const body = {};
61
+ const files = {};
62
+ let fileCount = 0;
63
+ try {
64
+ const parts = request.parts();
65
+ for await (const part of parts) if (part.type === "file") {
66
+ if (fileCount >= maxFiles) continue;
67
+ if (mimeMatcher && !mimeMatcher.matches(part.mimetype)) return reply.code(415).send({
68
+ success: false,
69
+ error: `File type '${part.mimetype}' not allowed. Accepted: ${mimeMatcher.describe()}`
70
+ });
71
+ const buffer = await part.toBuffer();
72
+ if (buffer.length > maxFileSize) return reply.code(413).send({
73
+ success: false,
74
+ error: `File '${part.filename}' exceeds maximum size of ${Math.round(maxFileSize / 1024 / 1024)}MB`
75
+ });
76
+ files[part.fieldname] = {
77
+ filename: part.filename,
78
+ mimetype: part.mimetype,
79
+ buffer,
80
+ size: buffer.length,
81
+ fieldname: part.fieldname
82
+ };
83
+ fileCount++;
84
+ } else body[part.fieldname] = tryParseValue(part.value);
85
+ } catch (err) {
86
+ request.log.error({ err }, "multipartBody: failed to parse multipart form");
87
+ return reply.code(400).send({
88
+ success: false,
89
+ error: "Failed to parse multipart form data"
90
+ });
91
+ }
92
+ if (requiredFields) {
93
+ const missing = requiredFields.filter((name) => !(name in files));
94
+ if (missing.length > 0) return reply.code(400).send({
95
+ success: false,
96
+ error: `Missing required file field${missing.length > 1 ? "s" : ""}: ${missing.join(", ")}`,
97
+ code: "MISSING_FILE_FIELDS",
98
+ details: { missing }
99
+ });
100
+ }
101
+ if (fileCount > 0) body[filesKey] = files;
102
+ request.body = body;
103
+ };
104
+ }
105
+ /**
106
+ * Try to parse a form field value as JSON, number, or boolean.
107
+ * Falls back to the raw string if parsing fails.
108
+ */
109
+ function tryParseValue(value) {
110
+ if (value === "true") return true;
111
+ if (value === "false") return false;
112
+ if (value === "null") return null;
113
+ if (/^-?\d+(\.\d+)?$/.test(value) && value.length < 16) {
114
+ const num = Number(value);
115
+ if (Number.isFinite(num)) return num;
116
+ }
117
+ if (value.startsWith("{") && value.endsWith("}") || value.startsWith("[") && value.endsWith("]")) try {
118
+ return JSON.parse(value);
119
+ } catch {}
120
+ return value;
121
+ }
122
+ //#endregion
123
+ export { multipartBody as t };
@@ -1,6 +1,7 @@
1
- import { t as getUserRoles } from "./types-DV9WDfeg.mjs";
1
+ import { t as getUserRoles } from "./types-D57iXYb8.mjs";
2
2
  import { n as convertRouteSchema } from "./schemaConverter-BxFDdtXu.mjs";
3
- import { t as buildActionBodySchema } from "./createActionRouter-Bp_5c_2b.mjs";
3
+ import { t as resolveActionPermission } from "./actionPermissions-TUVR3uiZ.mjs";
4
+ import { t as buildActionBodySchema } from "./createActionRouter-C8UUB3Px.mjs";
4
5
  import fp from "fastify-plugin";
5
6
  //#region src/docs/openapi.ts
6
7
  const openApiPlugin = async (fastify, opts = {}) => {
@@ -327,12 +328,13 @@ function generateResourcePaths(resource, apiPrefix = "", additionalSecurity = []
327
328
  const descStr = a.description ? ` — ${a.description}` : "";
328
329
  descLines.push(`- \`${a.name}\`${roleStr}${descStr}`);
329
330
  }
330
- const fallbackPerm = resource.actionPermissions;
331
- const fallbackRequiresAuth = typeof fallbackPerm === "function" && !fallbackPerm._isPublic;
332
331
  const anyAuthRequired = resource.actions.some((a) => {
333
- const p = a.permissions;
334
- if (typeof p === "function") return !p._isPublic;
335
- return fallbackRequiresAuth;
332
+ const effective = resolveActionPermission({
333
+ action: { permissions: a.permissions },
334
+ resourcePermissions: resource.permissions,
335
+ resourceActionPermissions: resource.actionPermissions
336
+ });
337
+ return typeof effective === "function" && !effective._isPublic;
336
338
  });
337
339
  if (!paths[actionPath]) paths[actionPath] = {};
338
340
  paths[actionPath].post = createOperation(resource, "action", `Perform action (${actionEnum.join(" / ")})`, {
@@ -1,5 +1,5 @@
1
- import { d as UserBase } from "../fields-Lo1VUDpt.mjs";
2
- import { Ct as RouteHandler } from "../index-Cl0uoKd5.mjs";
1
+ import { Pt as RouteHandler } from "../index-BGbpGVyM.mjs";
2
+ import { d as UserBase } from "../fields-C8Y0XLAu.mjs";
3
3
  import { InvitationAdapter, InvitationDoc, MemberDoc, OrgAdapter, OrgDoc, OrgPermissionStatement, OrgRole, OrganizationPluginOptions } from "./types.mjs";
4
4
  import { FastifyPluginAsync, RouteHandlerMethod } from "fastify";
5
5
 
@@ -1,3 +1,3 @@
1
- import { a as applyFieldWritePermissions, c as PermissionCheck, d as UserBase, f as getUserRoles, i as applyFieldReadPermissions, l as PermissionContext, n as FieldPermissionMap, o as fields, p as normalizeRoles, r as FieldPermissionType, s as resolveEffectiveRoles, t as FieldPermission, u as PermissionResult } from "../fields-Lo1VUDpt.mjs";
2
- import { A as requireRoles, C as allOf, D as not, E as denyAll, M as when, N as applyPermissionResult, O as requireAuth, P as normalizePermissionResult, S as createOrgPermissions, T as anyOf, _ as ConnectEventsOptions, a as presets_d_exports, b as PermissionEventBus, c as readOnly, d as requireOrgRole, f as requireScopeContext, g as createRoleHierarchy, h as RoleHierarchy, i as ownerWithAdminBypass, j as roles, k as requireOwnership, l as requireOrgInScope, m as requireTeamMembership, n as authenticated, o as publicRead, p as requireServiceScope, r as fullPublic, s as publicReadAdminWrite, t as adminOnly, u as requireOrgMembership, v as DynamicPermissionMatrix, w as allowPublic, x as createDynamicPermissionMatrix, y as DynamicPermissionMatrixConfig } from "../index-ChIw3776.mjs";
1
+ import { a as applyFieldWritePermissions, c as PermissionCheck, d as UserBase, f as getUserRoles, i as applyFieldReadPermissions, l as PermissionContext, n as FieldPermissionMap, o as fields, p as normalizeRoles, r as FieldPermissionType, s as resolveEffectiveRoles, t as FieldPermission, u as PermissionResult } from "../fields-C8Y0XLAu.mjs";
2
+ import { A as requireRoles, C as allOf, D as not, E as denyAll, M as when, N as applyPermissionResult, O as requireAuth, P as normalizePermissionResult, S as createOrgPermissions, T as anyOf, _ as ConnectEventsOptions, a as presets_d_exports, b as PermissionEventBus, c as readOnly, d as requireOrgRole, f as requireScopeContext, g as createRoleHierarchy, h as RoleHierarchy, i as ownerWithAdminBypass, j as roles, k as requireOwnership, l as requireOrgInScope, m as requireTeamMembership, n as authenticated, o as publicRead, p as requireServiceScope, r as fullPublic, s as publicReadAdminWrite, t as adminOnly, u as requireOrgMembership, v as DynamicPermissionMatrix, w as allowPublic, x as createDynamicPermissionMatrix, y as DynamicPermissionMatrixConfig } from "../index-C_Noptz-.mjs";
3
3
  export { ConnectEventsOptions, DynamicPermissionMatrix, DynamicPermissionMatrixConfig, FieldPermission, FieldPermissionMap, FieldPermissionType, PermissionCheck, PermissionContext, PermissionEventBus, PermissionResult, RoleHierarchy, UserBase, adminOnly, allOf, allowPublic, anyOf, applyFieldReadPermissions, applyFieldWritePermissions, applyPermissionResult, authenticated, createDynamicPermissionMatrix, createOrgPermissions, createRoleHierarchy, denyAll, fields, fullPublic, getUserRoles, normalizePermissionResult, normalizeRoles, not, ownerWithAdminBypass, presets_d_exports as permissions, publicRead, publicReadAdminWrite, readOnly, requireAuth, requireOrgInScope, requireOrgMembership, requireOrgRole, requireOwnership, requireRoles, requireScopeContext, requireServiceScope, requireTeamMembership, resolveEffectiveRoles, roles, when };
@@ -1,5 +1,5 @@
1
- import { i as resolveEffectiveRoles, n as applyFieldWritePermissions, r as fields, t as applyFieldReadPermissions } from "../fields-bxkeltzz.mjs";
2
- import { n as normalizeRoles, t as getUserRoles } from "../types-DV9WDfeg.mjs";
1
+ import { i as resolveEffectiveRoles, n as applyFieldWritePermissions, r as fields, t as applyFieldReadPermissions } from "../fields-CTMWOUDt.mjs";
2
+ import { n as normalizeRoles, t as getUserRoles } from "../types-D57iXYb8.mjs";
3
3
  import { n as normalizePermissionResult, t as applyPermissionResult } from "../applyPermissionResult-QhV1Pa-g.mjs";
4
- import { C as requireAuth, D as when, E as roles, S as not, T as requireRoles, _ as requireTeamMembership, a as presets_exports, b as anyOf, c as readOnly, d as createOrgPermissions, f as requireOrgInScope, g as requireServiceScope, h as requireScopeContext, i as ownerWithAdminBypass, l as createRoleHierarchy, m as requireOrgRole, n as authenticated, o as publicRead, p as requireOrgMembership, r as fullPublic, s as publicReadAdminWrite, t as adminOnly, u as createDynamicPermissionMatrix, v as allOf, w as requireOwnership, x as denyAll, y as allowPublic } from "../permissions-Dk6mshja.mjs";
4
+ import { C as requireAuth, D as when, E as roles, S as not, T as requireRoles, _ as requireTeamMembership, a as presets_exports, b as anyOf, c as readOnly, d as createOrgPermissions, f as requireOrgInScope, g as requireServiceScope, h as requireScopeContext, i as ownerWithAdminBypass, l as createRoleHierarchy, m as requireOrgRole, n as authenticated, o as publicRead, p as requireOrgMembership, r as fullPublic, s as publicReadAdminWrite, t as adminOnly, u as createDynamicPermissionMatrix, v as allOf, w as requireOwnership, x as denyAll, y as allowPublic } from "../permissions-wkqRwicB.mjs";
5
5
  export { adminOnly, allOf, allowPublic, anyOf, applyFieldReadPermissions, applyFieldWritePermissions, applyPermissionResult, authenticated, createDynamicPermissionMatrix, createOrgPermissions, createRoleHierarchy, denyAll, fields, fullPublic, getUserRoles, normalizePermissionResult, normalizeRoles, not, ownerWithAdminBypass, presets_exports as permissions, publicRead, publicReadAdminWrite, readOnly, requireAuth, requireOrgInScope, requireOrgMembership, requireOrgRole, requireOwnership, requireRoles, requireScopeContext, requireServiceScope, requireTeamMembership, resolveEffectiveRoles, roles, when };
@@ -1,7 +1,7 @@
1
1
  import { t as __exportAll } from "./chunk-BpYLSNr0.mjs";
2
2
  import { _ as isElevated, b as isService, c as getRequestScope, d as getServiceScopes, f as getTeamId, h as hasOrgAccess, l as getScopeContext, p as getUserId, u as getScopeContextMap, v as isMember, y as isOrgInScope } from "./types-AOD8fxIw.mjs";
3
- import { t as getUserRoles } from "./types-DV9WDfeg.mjs";
4
- import { t as MemoryCacheStore } from "./memory-B5Amv9A1.mjs";
3
+ import { t as getUserRoles } from "./types-D57iXYb8.mjs";
4
+ import { t as MemoryCacheStore } from "./memory-DqI-449b.mjs";
5
5
  import { randomUUID } from "node:crypto";
6
6
  //#region src/permissions/core.ts
7
7
  /**
@@ -0,0 +1,62 @@
1
+ import { r as ForbiddenError } from "./errors-BqdUDja_.mjs";
2
+ //#region src/pipeline/pipe.ts
3
+ /**
4
+ * Compose pipeline steps into an ordered array.
5
+ * Accepts guards, transforms, and interceptors in any order.
6
+ */
7
+ function pipe(...steps) {
8
+ return steps;
9
+ }
10
+ /**
11
+ * Check if a step applies to the given operation.
12
+ */
13
+ function appliesTo(step, operation) {
14
+ if (!step.operations || step.operations.length === 0) return true;
15
+ return step.operations.includes(operation);
16
+ }
17
+ /**
18
+ * Execute a pipeline against a request context.
19
+ *
20
+ * This is the core runtime that createCrudRouter uses to execute pipelines.
21
+ * External usage is not needed — this is wired automatically when `pipe` is set.
22
+ *
23
+ * @param steps - Pipeline steps to execute
24
+ * @param ctx - The pipeline context (extends IRequestContext)
25
+ * @param handler - The actual controller method to call
26
+ * @param operation - The CRUD operation name
27
+ * @returns The controller response (possibly modified by interceptors)
28
+ */
29
+ async function executePipeline(steps, ctx, handler, operation) {
30
+ const guards = [];
31
+ const transforms = [];
32
+ const interceptors = [];
33
+ for (const step of steps) {
34
+ if (!appliesTo(step, operation)) continue;
35
+ switch (step._type) {
36
+ case "guard":
37
+ guards.push(step);
38
+ break;
39
+ case "transform":
40
+ transforms.push(step);
41
+ break;
42
+ case "interceptor":
43
+ interceptors.push(step);
44
+ break;
45
+ }
46
+ }
47
+ for (const g of guards) if (!await g.handler(ctx)) throw new ForbiddenError(`Guard '${g.name}' denied access`);
48
+ let currentCtx = ctx;
49
+ for (const t of transforms) {
50
+ const result = await t.handler(currentCtx);
51
+ if (result) currentCtx = result;
52
+ }
53
+ let chain = () => handler(currentCtx);
54
+ for (let i = interceptors.length - 1; i >= 0; i--) {
55
+ const interceptor = interceptors[i];
56
+ const next = chain;
57
+ chain = () => interceptor.handler(currentCtx, next);
58
+ }
59
+ return chain();
60
+ }
61
+ //#endregion
62
+ export { pipe as n, executePipeline as t };
@@ -0,0 +1,62 @@
1
+ import { Bt as PipelineContext, Ft as Guard, Ht as Transform, It as Interceptor, Lt as NextFunction, Mt as IControllerResponse, Rt as OperationFilter, Vt as PipelineStep, zt as PipelineConfig } from "../index-BGbpGVyM.mjs";
2
+
3
+ //#region src/pipeline/guard.d.ts
4
+ interface GuardOptions {
5
+ operations?: OperationFilter;
6
+ handler: (ctx: PipelineContext) => boolean | Promise<boolean>;
7
+ }
8
+ /**
9
+ * Create a named guard.
10
+ *
11
+ * @param name - Guard name (for debugging/introspection)
12
+ * @param handlerOrOptions - Handler function or options object
13
+ */
14
+ declare function guard(name: string, handlerOrOptions: ((ctx: PipelineContext) => boolean | Promise<boolean>) | GuardOptions): Guard;
15
+ //#endregion
16
+ //#region src/pipeline/intercept.d.ts
17
+ interface InterceptOptions {
18
+ operations?: OperationFilter;
19
+ handler: (ctx: PipelineContext, next: NextFunction) => Promise<IControllerResponse<unknown>>;
20
+ }
21
+ /**
22
+ * Create a named interceptor.
23
+ *
24
+ * @param name - Interceptor name (for debugging/introspection)
25
+ * @param handlerOrOptions - Handler function or options object
26
+ */
27
+ declare function intercept(name: string, handlerOrOptions: ((ctx: PipelineContext, next: NextFunction) => Promise<IControllerResponse<unknown>>) | InterceptOptions): Interceptor;
28
+ //#endregion
29
+ //#region src/pipeline/pipe.d.ts
30
+ /**
31
+ * Compose pipeline steps into an ordered array.
32
+ * Accepts guards, transforms, and interceptors in any order.
33
+ */
34
+ declare function pipe(...steps: PipelineStep[]): PipelineStep[];
35
+ /**
36
+ * Execute a pipeline against a request context.
37
+ *
38
+ * This is the core runtime that createCrudRouter uses to execute pipelines.
39
+ * External usage is not needed — this is wired automatically when `pipe` is set.
40
+ *
41
+ * @param steps - Pipeline steps to execute
42
+ * @param ctx - The pipeline context (extends IRequestContext)
43
+ * @param handler - The actual controller method to call
44
+ * @param operation - The CRUD operation name
45
+ * @returns The controller response (possibly modified by interceptors)
46
+ */
47
+ declare function executePipeline(steps: PipelineStep[], ctx: PipelineContext, handler: (ctx: PipelineContext) => Promise<IControllerResponse<unknown>>, operation: string): Promise<IControllerResponse<unknown>>;
48
+ //#endregion
49
+ //#region src/pipeline/transform.d.ts
50
+ interface TransformOptions {
51
+ operations?: OperationFilter;
52
+ handler: (ctx: PipelineContext) => PipelineContext | undefined | Promise<PipelineContext | undefined>;
53
+ }
54
+ /**
55
+ * Create a named transform.
56
+ *
57
+ * @param name - Transform name (for debugging/introspection)
58
+ * @param handlerOrOptions - Handler function or options object
59
+ */
60
+ declare function transform(name: string, handlerOrOptions: ((ctx: PipelineContext) => PipelineContext | undefined | Promise<PipelineContext | undefined>) | TransformOptions): Transform;
61
+ //#endregion
62
+ export { type Guard, type Interceptor, type NextFunction, type OperationFilter, type PipelineConfig, type PipelineContext, type PipelineStep, type Transform, executePipeline, guard, intercept, pipe, transform };
@@ -0,0 +1,53 @@
1
+ import { n as pipe, t as executePipeline } from "../pipe-CGJxqDGx.mjs";
2
+ //#region src/pipeline/guard.ts
3
+ /**
4
+ * Create a named guard.
5
+ *
6
+ * @param name - Guard name (for debugging/introspection)
7
+ * @param handlerOrOptions - Handler function or options object
8
+ */
9
+ function guard(name, handlerOrOptions) {
10
+ const opts = typeof handlerOrOptions === "function" ? { handler: handlerOrOptions } : handlerOrOptions;
11
+ return {
12
+ _type: "guard",
13
+ name,
14
+ operations: opts.operations,
15
+ handler: opts.handler
16
+ };
17
+ }
18
+ //#endregion
19
+ //#region src/pipeline/intercept.ts
20
+ /**
21
+ * Create a named interceptor.
22
+ *
23
+ * @param name - Interceptor name (for debugging/introspection)
24
+ * @param handlerOrOptions - Handler function or options object
25
+ */
26
+ function intercept(name, handlerOrOptions) {
27
+ const opts = typeof handlerOrOptions === "function" ? { handler: handlerOrOptions } : handlerOrOptions;
28
+ return {
29
+ _type: "interceptor",
30
+ name,
31
+ operations: opts.operations,
32
+ handler: opts.handler
33
+ };
34
+ }
35
+ //#endregion
36
+ //#region src/pipeline/transform.ts
37
+ /**
38
+ * Create a named transform.
39
+ *
40
+ * @param name - Transform name (for debugging/introspection)
41
+ * @param handlerOrOptions - Handler function or options object
42
+ */
43
+ function transform(name, handlerOrOptions) {
44
+ const opts = typeof handlerOrOptions === "function" ? { handler: handlerOrOptions } : handlerOrOptions;
45
+ return {
46
+ _type: "transform",
47
+ name,
48
+ operations: opts.operations,
49
+ handler: opts.handler
50
+ };
51
+ }
52
+ //#endregion
53
+ export { executePipeline, guard, intercept, pipe, transform };
@@ -1,7 +1,8 @@
1
- import { W as ResourceRegistry, at as PresetHook, dn as AnyRecord, gt as RouteSchemaOptions, nt as MiddlewareConfig, pt as RouteDefinition, tn as HookSystem } from "../index-Cl0uoKd5.mjs";
2
- import { t as ExternalOpenApiPaths } from "../externalPaths-BQ8QijNH.mjs";
3
- import { _ as CachingRule, a as VersioningOptions, c as MetricEntry, d as _default$4, f as metricsPlugin, g as CachingOptions, h as ssePlugin, i as errorHandlerPlugin, l as MetricsCollector, m as _default$6, n as ErrorMapper, o as _default$7, p as SSEOptions, r as defaultIsDuplicateKeyError, s as versioningPlugin, t as ErrorHandlerOptions, u as MetricsOptions, v as _default$1, y as cachingPlugin } from "../errorHandler-DRQ3EqfL.mjs";
4
- import { t as TracingOptions } from "../tracing-65B51Dw3.mjs";
1
+ import { Dt as RouteSchemaOptions, J as HookSystem, Yt as AnyRecord, gt as PresetHook, pt as MiddlewareConfig, wt as RouteDefinition, z as ResourceRegistry } from "../index-BGbpGVyM.mjs";
2
+ import { t as ExternalOpenApiPaths } from "../externalPaths-Bapitwvd.mjs";
3
+ import { a as MetricsCollector, c as metricsPlugin, d as ssePlugin, f as CachingOptions, h as cachingPlugin, i as MetricEntry, l as SSEOptions, m as _default$1, n as _default$7, o as MetricsOptions, p as CachingRule, r as versioningPlugin, s as _default$4, t as VersioningOptions, u as _default$6 } from "../versioning-CeUXHfjw.mjs";
4
+ import { i as errorHandlerPlugin, n as ErrorMapper, r as defaultIsDuplicateKeyError, t as ErrorHandlerOptions } from "../errorHandler-2ii4RIYr.mjs";
5
+ import { t as TracingOptions } from "../tracing-xqXzWeaf.mjs";
5
6
  import { FastifyInstance, FastifyPluginAsync } from "fastify";
6
7
  import * as _$node_stream0 from "node:stream";
7
8
 
@@ -34,7 +35,26 @@ interface ArcCore {
34
35
  }
35
36
  declare module "fastify" {
36
37
  interface FastifyInstance {
37
- arc: ArcCore;
38
+ /**
39
+ * Arc core decorator. Optional because:
40
+ *
41
+ * 1. Consumers who import any `@classytic/arc/*` subpath get this module
42
+ * augmentation merged into every `FastifyInstance` they see — even
43
+ * instances on apps that never register {@link arcCorePlugin}. Making
44
+ * it required would force those apps to assert or guard every
45
+ * property access.
46
+ * 2. Hosts that extend `FastifyInstance` to narrow `arc` to their own
47
+ * type (`interface X extends FastifyInstance { arc?: MyArc }`) were
48
+ * previously blocked because non-optional `arc: ArcCore` conflicts
49
+ * with the re-declaration. An optional field lets hosts re-declare
50
+ * with a compatible subtype without fighting TS.
51
+ *
52
+ * Inside Arc's own code, any call site that runs *after* `arcCorePlugin`
53
+ * has registered treats this as non-null — see the call sites in
54
+ * `factory/registerAuth.ts` and `factory/createApp.ts` which assert
55
+ * with `fastify.arc!` or narrow explicitly.
56
+ */
57
+ arc?: ArcCore;
38
58
  }
39
59
  }
40
60
  declare const arcCorePlugin: FastifyPluginAsync<ArcCorePluginOptions>;
@@ -1,15 +1,15 @@
1
1
  import { p as MUTATION_OPERATIONS } from "../constants-BhY1OHoH.mjs";
2
2
  import { o as getOrgId } from "../types-AOD8fxIw.mjs";
3
- import { t as requestContext } from "../requestContext-xHIKedG6.mjs";
3
+ import { t as requestContext } from "../requestContext-C38GskNt.mjs";
4
4
  import { t as hasEvents } from "../typeGuards-Cj5Rgvlg.mjs";
5
- import { t as HookSystem } from "../HookSystem-BNYKnrXF.mjs";
6
- import { t as ResourceRegistry } from "../ResourceRegistry-BPd6NQDm.mjs";
7
- import { n as caching_default, t as cachingPlugin } from "../caching-CBpK_SCM.mjs";
8
- import { n as errorHandlerPlugin, t as defaultIsDuplicateKeyError } from "../errorHandler-Bb49BvPD.mjs";
9
- import { n as metrics_default, t as metricsPlugin } from "../metrics-DuhiSEZI.mjs";
10
- import { t as replyHelpersPlugin } from "../replyHelpers-CXtJDAZ0.mjs";
11
- import { n as sse_default, t as ssePlugin } from "../sse-yBCgOLGu.mjs";
12
- import { n as versioning_default, t as versioningPlugin } from "../versioning-C2U_bLY0.mjs";
5
+ import { t as HookSystem } from "../HookSystem-BjFu7zf1.mjs";
6
+ import { t as ResourceRegistry } from "../ResourceRegistry-CcN2LVrc.mjs";
7
+ import { n as caching_default, t as cachingPlugin } from "../caching-3h93rkJM.mjs";
8
+ import { n as errorHandlerPlugin, t as defaultIsDuplicateKeyError } from "../errorHandler-CSxe7KIM.mjs";
9
+ import { n as metrics_default, t as metricsPlugin } from "../metrics-TuOmguhi.mjs";
10
+ import { t as replyHelpersPlugin } from "../replyHelpers-BLojtuvR.mjs";
11
+ import { n as sse_default, t as ssePlugin } from "../sse-D8UeDwis.mjs";
12
+ import { n as versioning_default, t as versioningPlugin } from "../versioning-B6mimogM.mjs";
13
13
  import { randomUUID } from "node:crypto";
14
14
  import fp from "fastify-plugin";
15
15
  //#region src/core/arcCorePlugin.ts
@@ -1,2 +1,2 @@
1
- import { a as traced, i as isTracingAvailable, n as _default, r as createSpan, t as TracingOptions } from "../tracing-65B51Dw3.mjs";
1
+ import { a as traced, i as isTracingAvailable, n as _default, r as createSpan, t as TracingOptions } from "../tracing-xqXzWeaf.mjs";
2
2
  export { type TracingOptions, createSpan, isTracingAvailable, traced, _default as tracingPlugin };
@@ -44,7 +44,7 @@ try {
44
44
  function createTracerProvider(options) {
45
45
  if (!isAvailable) return null;
46
46
  const { serviceName = "@classytic/arc", serviceVersion, exporterUrl = "http://localhost:4318/v1/traces" } = options;
47
- const resolvedVersion = serviceVersion ?? "2.10.3";
47
+ const resolvedVersion = serviceVersion ?? "2.10.8";
48
48
  const exporter = new OTLPTraceExporter({ url: exporterUrl });
49
49
  const provider = new NodeTracerProvider({ resource: { attributes: {
50
50
  "service.name": serviceName,
@@ -1,7 +1,7 @@
1
- import { r as RequestScope } from "../types-BD85MlEK.mjs";
2
- import { c as PermissionCheck } from "../fields-Lo1VUDpt.mjs";
3
- import { ot as PresetResult } from "../index-Cl0uoKd5.mjs";
4
- import { a as StorageReadResult, i as StorageReadRange, n as StorageContext, o as StorageUploadInput, r as StorageFile, t as Storage } from "../storage-CVk_SEn2.mjs";
1
+ import { _t as PresetResult } from "../index-BGbpGVyM.mjs";
2
+ import { r as RequestScope } from "../types-tgR4Pt8F.mjs";
3
+ import { c as PermissionCheck } from "../fields-C8Y0XLAu.mjs";
4
+ import { a as StorageReadResult, i as StorageReadRange, n as StorageContext, o as StorageUploadInput, r as StorageFile, t as Storage } from "../storage-BwGQXUpd.mjs";
5
5
 
6
6
  //#region src/presets/filesUpload.d.ts
7
7
  interface FilesUploadPresetRoutes {