@classytic/arc 2.20.0 → 2.21.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (111) hide show
  1. package/dist/{BaseController-D-MHZ27_.mjs → BaseController-BnLYgE9A.mjs} +2 -2
  2. package/dist/{EventTransport-IEn7Tn-Q.d.mts → EventTransport-QmY7A258.d.mts} +0 -1
  3. package/dist/{QueryCache-TRfXau3W.d.mts → QueryCache-Z1B38koh.d.mts} +0 -1
  4. package/dist/{actionPermissions-C9RMiIpc.mjs → actionPermissions-ze70xXJi.mjs} +1 -1
  5. package/dist/audit/index.d.mts +9 -5
  6. package/dist/auth/audit.d.mts +7 -4
  7. package/dist/auth/audit.mjs +5 -0
  8. package/dist/auth/index.d.mts +7 -14
  9. package/dist/auth/index.mjs +1 -1
  10. package/dist/auth/redis-session.d.mts +1 -2
  11. package/dist/cache/index.d.mts +2 -3
  12. package/dist/cli/commands/describe.d.mts +1 -2
  13. package/dist/cli/commands/docs.mjs +1 -1
  14. package/dist/cli/commands/init.mjs +1 -1
  15. package/dist/cli/index.mjs +1 -1
  16. package/dist/context/index.d.mts +2 -2
  17. package/dist/core/index.d.mts +3 -3
  18. package/dist/core/index.mjs +4 -4
  19. package/dist/{core-CWhyGkiM.mjs → core-DZ6Xe1jR.mjs} +65 -10
  20. package/dist/{createActionRouter-HlQso0jO.mjs → createActionRouter-BWMDW-dL.mjs} +2 -2
  21. package/dist/{createAggregationRouter-5LzPzgw1.mjs → createAggregationRouter-l5mNdYrZ.mjs} +1 -1
  22. package/dist/{createApp-D6uwzCKu.mjs → createApp-Bi61XxqU.mjs} +149 -137
  23. package/dist/discovery/index.d.mts +0 -1
  24. package/dist/docs/index.d.mts +1 -2
  25. package/dist/docs/index.mjs +1 -1
  26. package/dist/{elevation-xGUBq6p_.d.mts → elevation-C9s5hFP_.d.mts} +0 -1
  27. package/dist/encryption/index.d.mts +2 -144
  28. package/dist/{errorHandler-BtUUDPEa.d.mts → errorHandler-B0e-bq-O.d.mts} +0 -1
  29. package/dist/{errors-DOHkjQlD.d.mts → errors-DHcHVAgk.d.mts} +0 -1
  30. package/dist/{eventPlugin-DbBFd3x_.d.mts → eventPlugin-A6EbthXR.d.mts} +10 -6
  31. package/dist/events/index.d.mts +9 -6
  32. package/dist/events/transports/redis-stream-entry.d.mts +1 -1
  33. package/dist/events/transports/redis.d.mts +1 -2
  34. package/dist/factory/index.d.mts +4 -4
  35. package/dist/factory/index.mjs +2 -2
  36. package/dist/{fastify-augmentation-CCQJEDgh.d.mts → fastify-augmentation-DafigGQp.d.mts} +2 -3
  37. package/dist/{fields-C7ahdGYf.d.mts → fields-BGqrAa_u.d.mts} +1 -2
  38. package/dist/hooks/index.d.mts +1 -1
  39. package/dist/idempotency/index.d.mts +4 -3
  40. package/dist/idempotency/redis.d.mts +1 -1
  41. package/dist/{index-DUa8WHz3.d.mts → index-B5N-NaHs.d.mts} +88 -7
  42. package/dist/{index-CdFkIMEd.d.mts → index-B5PoNbfu.d.mts} +36 -7
  43. package/dist/{index-_--GyzcO.d.mts → index-Dtrj6XZk.d.mts} +62 -28
  44. package/dist/index.d.mts +7 -7
  45. package/dist/index.mjs +6 -6
  46. package/dist/{init-YH_nslQR.mjs → init-0YhHkXGk.mjs} +154 -137
  47. package/dist/integrations/event-gateway.d.mts +2 -3
  48. package/dist/integrations/index.d.mts +2 -2
  49. package/dist/integrations/jobs.d.mts +0 -1
  50. package/dist/integrations/mcp/index.d.mts +6 -7
  51. package/dist/integrations/mcp/index.mjs +1 -1
  52. package/dist/integrations/mcp/testing.d.mts +1 -2
  53. package/dist/integrations/mcp/testing.mjs +1 -1
  54. package/dist/integrations/streamline.d.mts +2 -2
  55. package/dist/integrations/webhooks.d.mts +0 -1
  56. package/dist/integrations/websocket-pushref-redis.d.mts +1 -2
  57. package/dist/integrations/websocket-redis.d.mts +1 -2
  58. package/dist/integrations/websocket.d.mts +2 -2
  59. package/dist/{loadResources-B8UmpITt.mjs → loadResources-DpU8pfjV.mjs} +4 -3
  60. package/dist/{mcpPlugin-CuW6L_uD.mjs → mcpPlugin-B9XjjNVG.mjs} +3 -3
  61. package/dist/middleware/index.d.mts +1 -2
  62. package/dist/{module-JYH9V0I8.d.mts → module-WeuU5jfd.d.mts} +46 -1
  63. package/dist/{openapi-Dq6RbEGK.mjs → openapi-Kyod_di6.mjs} +2 -2
  64. package/dist/permissions/index.d.mts +3 -3
  65. package/dist/permissions/index.mjs +2 -2
  66. package/dist/{permissions-CgbOLJZG.mjs → permissions-BJMuKMl7.mjs} +33 -1
  67. package/dist/pipeline/index.d.mts +1 -2
  68. package/dist/plugins/index.d.mts +79 -7
  69. package/dist/plugins/index.mjs +88 -1
  70. package/dist/plugins/response-cache.d.mts +5 -3
  71. package/dist/plugins/tracing-entry.d.mts +1 -1
  72. package/dist/plugins/tracing-entry.mjs +1 -1
  73. package/dist/presets/filesUpload.d.mts +4 -5
  74. package/dist/presets/filesUpload.mjs +1 -1
  75. package/dist/presets/index.d.mts +1 -2
  76. package/dist/presets/index.mjs +1 -1
  77. package/dist/presets/multiTenant.d.mts +1 -2
  78. package/dist/presets/search.d.mts +2 -3
  79. package/dist/presets/search.mjs +1 -1
  80. package/dist/{presets-DWsYQdbV.mjs → presets-gw0ciIUD.mjs} +1 -1
  81. package/dist/{pushref-registry-DnCqL3aa.d.mts → pushref-registry-BbcnpNTm.d.mts} +4 -2
  82. package/dist/{queryCachePlugin-xzFyKAjT.d.mts → queryCachePlugin-CfYWq-Ak.d.mts} +1 -2
  83. package/dist/{redis-C3W0qbz8.d.mts → redis-UDtLaNj6.d.mts} +0 -1
  84. package/dist/{redis-stream-DsP1vqZB.d.mts → redis-stream-iVR2l7aS.d.mts} +1 -2
  85. package/dist/{registerRoute-DGSREwPw.mjs → registerRoute-oGAl0oA8.mjs} +1 -1
  86. package/dist/registry/index.d.mts +2 -2
  87. package/dist/schemas/index.d.mts +0 -1
  88. package/dist/scim/index.d.mts +0 -1
  89. package/dist/scope/index.d.mts +2 -3
  90. package/dist/{sessionManager-BXG-HGwG.d.mts → sessionManager-BHOM3N_0.d.mts} +10 -6
  91. package/dist/{storage-Co_PQpeQ.d.mts → storage-DLUZ04kK.d.mts} +8 -4
  92. package/dist/testing/index.d.mts +2 -3
  93. package/dist/testing/index.mjs +5 -2
  94. package/dist/testing/storageContract.d.mts +1 -2
  95. package/dist/{tracing-D8jlGXP7.d.mts → tracing-CsGKQJGg.d.mts} +0 -1
  96. package/dist/types/index.d.mts +4 -4
  97. package/dist/types/storage.d.mts +1 -1
  98. package/dist/types-Cc91nXuA.d.mts +132 -0
  99. package/dist/{types-LNebCoJx.d.mts → types-DH0GupI7.d.mts} +8 -4
  100. package/dist/{types-C9b2HR5W.d.mts → types-DRj-Ut4n.d.mts} +1 -2
  101. package/dist/{types-BHMKlMBU.d.mts → types-DpxoNX5v.d.mts} +61 -21
  102. package/dist/utils/index.d.mts +182 -128
  103. package/dist/utils/index.mjs +2 -2
  104. package/dist/{utils-ChjYQpjn.mjs → utils-CO8a3B_1.mjs} +70 -26
  105. package/dist/{versioning-D_eBCfNr.d.mts → versioning-DQ4mCvg0.d.mts} +1 -2
  106. package/dist/{websocket-MlYlrYq0.d.mts → websocket-uuWqM6UY.d.mts} +5 -4
  107. package/package.json +7 -7
  108. package/skills/arc-module-publishing/SKILL.md +242 -0
  109. package/skills/arc-module-publishing/references/authoring-modules.md +272 -0
  110. package/skills/arc-module-publishing/references/package-manifest.md +155 -0
  111. package/skills/arc-module-publishing/references/publishing-workflow.md +182 -0
@@ -98,14 +98,18 @@ interface StorageReadRange {
98
98
  type StorageReadResult = {
99
99
  kind: "stream";
100
100
  stream: NodeJS.ReadableStream;
101
- contentType: string; /** Total size of the full object (NOT the ranged slice). Required for `Content-Range`. */
102
- bytes?: number; /** Actual byte range returned when the caller passed `range`. */
101
+ contentType: string;
102
+ /** Total size of the full object (NOT the ranged slice). Required for `Content-Range`. */
103
+ bytes?: number;
104
+ /** Actual byte range returned when the caller passed `range`. */
103
105
  range?: StorageReadRange;
104
106
  } | {
105
107
  kind: "buffer";
106
108
  buffer: Buffer;
107
- contentType: string; /** Total size of the full object. Used for `Content-Range` on partial reads. */
108
- totalBytes?: number; /** Actual byte range returned when the caller passed `range`. */
109
+ contentType: string;
110
+ /** Total size of the full object. Used for `Content-Range` on partial reads. */
111
+ totalBytes?: number;
112
+ /** Actual byte range returned when the caller passed `range`. */
109
113
  range?: StorageReadRange;
110
114
  };
111
115
  /**
@@ -1,10 +1,9 @@
1
- import { V as ResourceDefinition, qt as AnyRecord } from "../index-_--GyzcO.mjs";
2
- import { d as preloadResourcesAsync, r as CreateAppOptions, u as preloadResources } from "../types-BHMKlMBU.mjs";
1
+ import { V as ResourceDefinition, qt as AnyRecord } from "../index-Dtrj6XZk.mjs";
2
+ import { d as preloadResourcesAsync, r as CreateAppOptions, u as preloadResources } from "../types-DpxoNX5v.mjs";
3
3
  import { StorageContractSetup, StorageContractSetupResult, runStorageContract } from "./storageContract.mjs";
4
4
  import { FastifyInstance, FastifyServerOptions } from "fastify";
5
5
  import { Mock } from "vitest";
6
6
  import { StandardRepo } from "@classytic/repo-core/repository";
7
-
8
7
  //#region src/testing/assertions.d.ts
9
8
  /**
10
9
  * expectArc — Arc-specific response assertions
@@ -210,7 +210,10 @@ function createJwtAuthProvider(app, opts = {}) {
210
210
  if (!config.user) throw new Error(`[jwt] role '${role}' has neither 'user' nor 'token'`);
211
211
  const jwt = app.jwt;
212
212
  if (!jwt?.sign) throw new Error(`[jwt] app.jwt.sign() is unavailable — register @fastify/jwt before calling createJwtAuthProvider.`);
213
- return jwt.sign(config.user);
213
+ return jwt.sign({
214
+ type: "access",
215
+ ...config.user
216
+ });
214
217
  }
215
218
  });
216
219
  }
@@ -1046,7 +1049,7 @@ function pickDefaultAuth(authMode, callerAuth) {
1046
1049
  };
1047
1050
  }
1048
1051
  async function createTestApp(options = {}) {
1049
- const { createApp } = await import("../createApp-D6uwzCKu.mjs").then((n) => n.r);
1052
+ const { createApp } = await import("../createApp-Bi61XxqU.mjs").then((n) => n.r);
1050
1053
  const { resources = [], db = "in-memory", connectMongoose = false, authMode = "jwt", defaultOrgId, plugins, auth: callerAuth, ...appOptions } = options;
1051
1054
  let dbHandle;
1052
1055
  let dbUri;
@@ -1,5 +1,4 @@
1
- import { t as Storage } from "../storage-Co_PQpeQ.mjs";
2
-
1
+ import { t as Storage } from "../storage-DLUZ04kK.mjs";
3
2
  //#region src/testing/storageContract.d.ts
4
3
  interface StorageContractSetupResult {
5
4
  storage: Storage;
@@ -1,6 +1,5 @@
1
1
  import { FastifyInstance, FastifyRequest } from "fastify";
2
2
  import { Span, Tracer } from "@opentelemetry/api";
3
-
4
3
  //#region src/plugins/tracing.d.ts
5
4
  interface TracingOptions {
6
5
  /**
@@ -1,5 +1,5 @@
1
- import { $ as OnTenantDeleteConfig, $t as UserOrganization, A as RequestIdOptions, C as RequestContext, D as HealthCheck, E as GracefulShutdownOptions, F as FastifyWithDecorators, Fn as BaseControllerOptions, G as ActionsMap, Gt as JwtContext, H as ActionDefinition, Ht as AuthPluginOptions, I as MiddlewareHandler, J as CrudRouteKey, Jt as ApiResponse, K as ArcFieldRule, Kt as TokenPair, L as RequestWithExtras, M as EventsDecorator, N as FastifyRequestExtras, O as HealthOptions, P as FastifyWithAuth, Q as MiddlewareConfig, Qt as UserLike, S as QueryParserInterface, St as RouteHandler, T as CrudRouterOptions, U as ActionEntry, Ut as Authenticator, Vt as AuthHelpers, W as ActionHandlerFn, Wt as AuthenticatorContext, X as EventDefinition, Xt as JWTPayload, Y as CrudSchemas, Yt as ArcRequest, Z as FieldRule, Zt as ObjectId, _ as ControllerQueryOptions, _t as ControllerLike, a as InferAdapterDoc, at as ResolvedTenantPurge, b as ParsedQuery, bt as IControllerResponse, c as TypedController, ct as ResourceExtensions, d as PaginationResult, dt as ResourcePermissions, et as OpenApiSchemas, f as IntrospectionData, ft as RouteDefinition, g as ArcInternalMetadata, gt as ControllerHandler, h as ResourceMetadata, ht as RouteSchemaOptions, i as ValidationResult, it as RateLimitConfig, j as ArcDecorator, k as IntrospectionPluginOptions, l as TypedRepository, lt as ResourceHookContext, m as RegistryStats, mt as RouteMethod, n as ConfigError, nt as PresetHook, o as InferDocType, ot as ResourceCacheConfig, p as RegistryEntry, pt as RouteMcpConfig, q as CrudController, qt as AnyRecord, r as ValidateOptions, rt as PresetResult, s as InferResourceDoc, st as ResourceConfig, t as RouteHandlerMethod, tt as PresetFunction, u as TypedResourceConfig, ut as ResourceHooks, v as LookupOption, vt as FastifyHandler, w as ServiceContext, x as PopulateOption, xt as IRequestContext, y as OwnershipCheck, yt as IController } from "../index-_--GyzcO.mjs";
2
- import { i as RequestScope } from "../types-LNebCoJx.mjs";
3
- import { c as PermissionCheck, d as UserBase, l as PermissionContext, u as PermissionResult } from "../fields-C7ahdGYf.mjs";
4
- import { n as ElevationOptions, t as ElevationEvent } from "../elevation-xGUBq6p_.mjs";
1
+ import { $ as OnTenantDeleteConfig, $t as UserOrganization, A as RequestIdOptions, C as RequestContext, D as HealthCheck, E as GracefulShutdownOptions, F as FastifyWithDecorators, Fn as BaseControllerOptions, G as ActionsMap, Gt as JwtContext, H as ActionDefinition, Ht as AuthPluginOptions, I as MiddlewareHandler, J as CrudRouteKey, Jt as ApiResponse, K as ArcFieldRule, Kt as TokenPair, L as RequestWithExtras, M as EventsDecorator, N as FastifyRequestExtras, O as HealthOptions, P as FastifyWithAuth, Q as MiddlewareConfig, Qt as UserLike, S as QueryParserInterface, St as RouteHandler, T as CrudRouterOptions, U as ActionEntry, Ut as Authenticator, Vt as AuthHelpers, W as ActionHandlerFn, Wt as AuthenticatorContext, X as EventDefinition, Xt as JWTPayload, Y as CrudSchemas, Yt as ArcRequest, Z as FieldRule, Zt as ObjectId, _ as ControllerQueryOptions, _t as ControllerLike, a as InferAdapterDoc, at as ResolvedTenantPurge, b as ParsedQuery, bt as IControllerResponse, c as TypedController, ct as ResourceExtensions, d as PaginationResult, dt as ResourcePermissions, et as OpenApiSchemas, f as IntrospectionData, ft as RouteDefinition, g as ArcInternalMetadata, gt as ControllerHandler, h as ResourceMetadata, ht as RouteSchemaOptions, i as ValidationResult, it as RateLimitConfig, j as ArcDecorator, k as IntrospectionPluginOptions, l as TypedRepository, lt as ResourceHookContext, m as RegistryStats, mt as RouteMethod, n as ConfigError, nt as PresetHook, o as InferDocType, ot as ResourceCacheConfig, p as RegistryEntry, pt as RouteMcpConfig, q as CrudController, qt as AnyRecord, r as ValidateOptions, rt as PresetResult, s as InferResourceDoc, st as ResourceConfig, t as RouteHandlerMethod, tt as PresetFunction, u as TypedResourceConfig, ut as ResourceHooks, v as LookupOption, vt as FastifyHandler, w as ServiceContext, x as PopulateOption, xt as IRequestContext, y as OwnershipCheck, yt as IController } from "../index-Dtrj6XZk.mjs";
2
+ import { i as RequestScope } from "../types-DH0GupI7.mjs";
3
+ import { c as PermissionCheck, d as UserBase, l as PermissionContext, u as PermissionResult } from "../fields-BGqrAa_u.mjs";
4
+ import { n as ElevationOptions, t as ElevationEvent } from "../elevation-C9s5hFP_.mjs";
5
5
  export type { ActionDefinition, ActionEntry, ActionHandlerFn, ActionsMap, AnyRecord, ApiResponse, ArcDecorator, ArcFieldRule, ArcInternalMetadata, ArcRequest, AuthHelpers, AuthPluginOptions, Authenticator, AuthenticatorContext, BaseControllerOptions, ConfigError, ControllerHandler, ControllerLike, ControllerQueryOptions, CrudController, CrudRouteKey, CrudRouterOptions, CrudSchemas, ElevationEvent, ElevationOptions, EventDefinition, EventsDecorator, FastifyHandler, FastifyRequestExtras, FastifyWithAuth, FastifyWithDecorators, FieldRule, GracefulShutdownOptions, HealthCheck, HealthOptions, IController, IControllerResponse, IRequestContext, InferAdapterDoc, InferDocType, InferResourceDoc, IntrospectionData, IntrospectionPluginOptions, JWTPayload, JwtContext, LookupOption, MiddlewareConfig, MiddlewareHandler, ObjectId, OnTenantDeleteConfig, OpenApiSchemas, OwnershipCheck, PaginationResult, ParsedQuery, PermissionCheck, PermissionContext, PermissionResult, PopulateOption, PresetFunction, PresetHook, PresetResult, QueryParserInterface, RateLimitConfig, RegistryEntry, RegistryStats, RequestContext, RequestIdOptions, RequestScope, RequestWithExtras, ResolvedTenantPurge, ResourceCacheConfig, ResourceConfig, ResourceExtensions, ResourceHookContext, ResourceHooks, ResourceMetadata, ResourcePermissions, RouteDefinition, RouteHandler, RouteHandlerMethod, RouteMcpConfig, RouteMethod, RouteSchemaOptions, ServiceContext, TokenPair, TypedController, TypedRepository, TypedResourceConfig, UserBase, UserLike, UserOrganization, ValidateOptions, ValidationResult };
@@ -1,2 +1,2 @@
1
- import { a as StorageReadResult, i as StorageReadRange, n as StorageContext, o as StorageUploadInput, r as StorageFile, t as Storage } from "../storage-Co_PQpeQ.mjs";
1
+ import { a as StorageReadResult, i as StorageReadRange, n as StorageContext, o as StorageUploadInput, r as StorageFile, t as Storage } from "../storage-DLUZ04kK.mjs";
2
2
  export { Storage, StorageContext, StorageFile, StorageReadRange, StorageReadResult, StorageUploadInput };
@@ -0,0 +1,132 @@
1
+ import { FastifyRequest } from "fastify";
2
+ //#region src/encryption/types.d.ts
3
+ /** JWE key-management algorithm — the protected-header `alg`. */
4
+ type JweAlg = "RSA-OAEP-256" | "RSA-OAEP-384" | "RSA-OAEP-512" | "ECDH-ES" | "ECDH-ES+A256KW" | "A256GCMKW" | "dir";
5
+ /** JWE content-encryption algorithm — the protected-header `enc`. AEAD only. */
6
+ type JweEnc = "A128GCM" | "A192GCM" | "A256GCM";
7
+ /** Encryption strategy for a route's response. */
8
+ type EncryptionMode = "jwe" | "fields";
9
+ /**
10
+ * Opaque key material. For `jwe` mode this is a `jose` `KeyLike` /
11
+ * `CryptoKey` / `Uint8Array`; for `fields` mode a 32-byte secret
12
+ * (`Buffer` / `Uint8Array`). Kept `unknown` at the contract layer so the
13
+ * `KeyProvider` interface carries no hard `jose` type dependency — hosts
14
+ * without `jose` installed can still implement field-mode providers.
15
+ */
16
+ type KeyMaterial = unknown;
17
+ /** A key paired with its identifier — what encrypt operations consume. */
18
+ interface ActiveKey {
19
+ /** Key id, stamped into the JWE `kid` header / field envelope for rotation. */
20
+ readonly kid: string;
21
+ /** The key material (public key for JWE, 32-byte secret for fields). */
22
+ readonly key: KeyMaterial;
23
+ /** Optional per-key `alg` override (else the plugin default applies). */
24
+ readonly alg?: JweAlg;
25
+ }
26
+ /** Context handed to the key provider so resolution can be request-scoped. */
27
+ interface KeyContext {
28
+ readonly request: FastifyRequest;
29
+ }
30
+ type MaybePromise<T> = T | Promise<T>;
31
+ /**
32
+ * Pluggable key resolution. Arc owns the request-time plumbing — `kid` →
33
+ * key, algorithm allowlist enforcement; the host owns the trust store —
34
+ * which keys are valid and where they live (file / env / AWS KMS / GCP KMS
35
+ * / Vault). Encryption and decryption are deliberately separate operations
36
+ * because they often use DIFFERENT keys (JWE: a public key encrypts the
37
+ * outbound response, a private key by `kid` decrypts the inbound request —
38
+ * exactly Visa's two-key-pair model).
39
+ *
40
+ * Rotation mirrors `@fastify/secure-session`: the active key encrypts; any
41
+ * key resolvable by `kid` can decrypt, so you can roll keys without dropping
42
+ * in-flight traffic.
43
+ */
44
+ interface KeyProvider {
45
+ /** Active key for encrypting OUTBOUND responses. */
46
+ encryptionKey(ctx: KeyContext): MaybePromise<ActiveKey>;
47
+ /** Resolve a DECRYPTION key by the inbound message's `kid`. */
48
+ decryptionKey(kid: string, ctx: KeyContext): MaybePromise<KeyMaterial | undefined>;
49
+ }
50
+ /**
51
+ * Per-resource encryption directive — the typed slice plugins register on
52
+ * `ResourceExtensions`. Declared on a resource via
53
+ * `defineResource({ extensions: { encryption: { … } } })`; arc threads it
54
+ * to request time on `request.routeOptions.config.arcExtensions.encryption`.
55
+ */
56
+ interface EncryptionDirective {
57
+ /** Strategy. Defaults to the plugin-level `mode` (default `'jwe'`). */
58
+ readonly mode?: EncryptionMode;
59
+ /**
60
+ * For `mode: 'fields'` — dot-paths of fields to encrypt, resolved against
61
+ * the serialized response body (e.g. `'cardNumber'`, `'account.iban'`).
62
+ * Ignored for `mode: 'jwe'` (the whole body is encrypted).
63
+ */
64
+ readonly fields?: readonly string[];
65
+ /**
66
+ * Explicit opt-out — set `false` to disable encryption for this resource
67
+ * even when a plugin-level default (`routes`) would otherwise apply.
68
+ */
69
+ readonly enabled?: boolean;
70
+ }
71
+ /**
72
+ * Plugin-level options. `keyProvider` is the only required field; everything
73
+ * else has a secure default.
74
+ */
75
+ interface EncryptionOptions {
76
+ /**
77
+ * Master on/off. Default `true`. Set `false` to register the plugin as a
78
+ * typed no-op (config-gated environments) — same pattern as
79
+ * `idempotencyPlugin`.
80
+ */
81
+ readonly enabled?: boolean;
82
+ /** Key provider — resolves `kid` → key for encrypt/decrypt. Required. */
83
+ readonly keyProvider: KeyProvider;
84
+ /** Default mode when a route opts in without naming one. Default `'jwe'`. */
85
+ readonly mode?: EncryptionMode;
86
+ /** JWE key-management algorithm. Default `'RSA-OAEP-256'`. */
87
+ readonly alg?: JweAlg;
88
+ /** JWE content-encryption algorithm. Default `'A256GCM'`. */
89
+ readonly enc?: JweEnc;
90
+ /**
91
+ * Inbound-decryption algorithm allowlists — block algorithm-substitution
92
+ * downgrade attacks. Default `[alg]` / `[enc]`. Set explicitly only when a
93
+ * client legitimately uses more than one algorithm.
94
+ */
95
+ readonly allowedAlgs?: readonly JweAlg[];
96
+ readonly allowedEncs?: readonly JweEnc[];
97
+ /**
98
+ * Fallback opt-in for routes that don't declare
99
+ * `extensions.encryption`. Return a directive (or `true` for the default
100
+ * mode) to encrypt, `false`/`undefined` to skip. The per-resource
101
+ * `extensions.encryption` ALWAYS wins when present. Use this to scope ALE
102
+ * to sensitive prefixes without touching every resource.
103
+ *
104
+ * @example confine ALE to `/payments` and `/accounts`
105
+ * ```ts
106
+ * routes: (req) => /^\/(payments|accounts)\b/.test(req.url)
107
+ * ```
108
+ */
109
+ readonly routes?: (request: FastifyRequest) => EncryptionDirective | boolean | undefined;
110
+ /** Decrypt inbound `application/jose` request bodies. Default `true`. */
111
+ readonly decryptRequests?: boolean;
112
+ /** Media type that signals an encrypted REQUEST body. Default `'application/jose'`. */
113
+ readonly contentType?: string;
114
+ /** Content-Type set on full-body JWE RESPONSES. Default `'application/jose'`. */
115
+ readonly responseContentType?: string;
116
+ /**
117
+ * Response header advertising that the body is encrypted, so generic
118
+ * client SDKs know to decrypt. Default `'x-encrypted'`; set `false` to omit.
119
+ */
120
+ readonly flagHeader?: string | false;
121
+ }
122
+ /** Request decorations added by the plugin. */
123
+ declare module "fastify" {
124
+ interface FastifyRequest {
125
+ /** `true` when the inbound body was decrypted from a JWE by this plugin. */
126
+ requestDecrypted?: boolean;
127
+ /** `true` when the outbound body was encrypted by this plugin. */
128
+ responseEncrypted?: boolean;
129
+ }
130
+ }
131
+ //#endregion
132
+ export { JweAlg as a, KeyMaterial as c, EncryptionOptions as i, KeyProvider as l, EncryptionDirective as n, JweEnc as o, EncryptionMode as r, KeyContext as s, ActiveKey as t };
@@ -168,8 +168,10 @@ type RequestScope = {
168
168
  kind: "service";
169
169
  clientId: string;
170
170
  organizationId: string;
171
- scopes?: readonly string[]; /** App-defined scope dimensions — see `member.context` for details. */
172
- context?: Readonly<Record<string, string>>; /** Parent organizations — see `member.ancestorOrgIds` for details. */
171
+ scopes?: readonly string[];
172
+ /** App-defined scope dimensions — see `member.context` for details. */
173
+ context?: Readonly<Record<string, string>>;
174
+ /** Parent organizations — see `member.ancestorOrgIds` for details. */
173
175
  ancestorOrgIds?: readonly string[];
174
176
  /**
175
177
  * Capability mandate — narrows what the caller may do beyond OAuth `scopes`.
@@ -207,8 +209,10 @@ type RequestScope = {
207
209
  kind: "elevated";
208
210
  userId?: string;
209
211
  organizationId?: string;
210
- elevatedBy: string; /** App-defined scope dimensions — see `member.context` for details. */
211
- context?: Readonly<Record<string, string>>; /** Parent organizations — see `member.ancestorOrgIds` for details. */
212
+ elevatedBy: string;
213
+ /** App-defined scope dimensions — see `member.context` for details. */
214
+ context?: Readonly<Record<string, string>>;
215
+ /** Parent organizations — see `member.ancestorOrgIds` for details. */
212
216
  ancestorOrgIds?: readonly string[];
213
217
  };
214
218
  /** Check if scope is `member` kind */
@@ -1,6 +1,5 @@
1
- import { V as ResourceDefinition } from "./index-_--GyzcO.mjs";
1
+ import { V as ResourceDefinition } from "./index-Dtrj6XZk.mjs";
2
2
  import { z } from "zod";
3
-
4
3
  //#region src/integrations/mcp/types.d.ts
5
4
  /** Behavioral hints for MCP clients (tool annotations per MCP spec) */
6
5
  interface ToolAnnotations {
@@ -1,16 +1,15 @@
1
- import { Ut as Authenticator } from "./index-_--GyzcO.mjs";
1
+ import { Ut as Authenticator } from "./index-Dtrj6XZk.mjs";
2
2
  import { r as CacheStore } from "./interface-C1_WLTMK.mjs";
3
- import { n as ElevationOptions } from "./elevation-xGUBq6p_.mjs";
4
- import { a as EventTransport } from "./EventTransport-IEn7Tn-Q.mjs";
3
+ import { n as ElevationOptions } from "./elevation-C9s5hFP_.mjs";
4
+ import { a as EventTransport } from "./EventTransport-QmY7A258.mjs";
5
5
  import { t as ExternalOpenApiPaths } from "./externalPaths-BE6wFpYv.mjs";
6
- import { r as QueryCachePluginOptions } from "./queryCachePlugin-xzFyKAjT.mjs";
7
- import { l as ResourceLike, n as ArcModuleInput } from "./module-JYH9V0I8.mjs";
8
- import { t as EventPluginOptions } from "./eventPlugin-DbBFd3x_.mjs";
9
- import { _ as HealthOptions, f as CachingOptions, l as SSEOptions, o as MetricsOptions, t as VersioningOptions } from "./versioning-D_eBCfNr.mjs";
10
- import { t as ErrorHandlerOptions } from "./errorHandler-BtUUDPEa.mjs";
6
+ import { r as QueryCachePluginOptions } from "./queryCachePlugin-CfYWq-Ak.mjs";
7
+ import { t as ErrorHandlerOptions } from "./errorHandler-B0e-bq-O.mjs";
8
+ import { l as ResourceLike, n as ArcModuleInput } from "./module-WeuU5jfd.mjs";
9
+ import { t as EventPluginOptions } from "./eventPlugin-A6EbthXR.mjs";
10
+ import { _ as HealthOptions, f as CachingOptions, l as SSEOptions, o as MetricsOptions, t as VersioningOptions } from "./versioning-DQ4mCvg0.mjs";
11
11
  import { r as IdempotencyStore } from "./interface-Uk8ONJv7.mjs";
12
12
  import { FastifyInstance, FastifyPluginAsync, FastifyReply, FastifyRequest, FastifyServerOptions } from "fastify";
13
-
14
13
  //#region src/testing/preloadResources.d.ts
15
14
  /** Eager glob result: `{ '/path/to/file.ts': resourceModule }` */
16
15
  type EagerGlobResult = Record<string, unknown>;
@@ -95,11 +94,17 @@ interface JwtAuthOption {
95
94
  * If provided, jwt utilities are available in authenticator context
96
95
  */
97
96
  jwt?: {
98
- /** JWT secret (required for JWT features) */secret: string; /** Access token expiry (default: '15m') */
99
- expiresIn?: string; /** Refresh token secret (defaults to main secret) */
100
- refreshSecret?: string; /** Refresh token expiry (default: '7d') */
101
- refreshExpiresIn?: string; /** Additional @fastify/jwt sign options */
102
- sign?: Record<string, unknown>; /** Additional @fastify/jwt verify options */
97
+ /** JWT secret (required for JWT features) */
98
+ secret: string;
99
+ /** Access token expiry (default: '15m') */
100
+ expiresIn?: string;
101
+ /** Refresh token secret (defaults to main secret) */
102
+ refreshSecret?: string;
103
+ /** Refresh token expiry (default: '7d') */
104
+ refreshExpiresIn?: string;
105
+ /** Additional @fastify/jwt sign options */
106
+ sign?: Record<string, unknown>;
107
+ /** Additional @fastify/jwt verify options */
103
108
  verify?: Record<string, unknown>;
104
109
  };
105
110
  /**
@@ -289,9 +294,13 @@ interface CreateAppOptions {
289
294
  * not memory-backed. Provide Redis or other durable adapters.
290
295
  */
291
296
  stores?: {
292
- /** Event transport (e.g., RedisEventTransport) */events?: EventTransport; /** Cache store (e.g., RedisCacheStore) */
293
- cache?: CacheStore; /** Idempotency store (e.g., RedisIdempotencyStore) */
294
- idempotency?: IdempotencyStore; /** QueryCache store (e.g., RedisCacheStore). Default: MemoryCacheStore. */
297
+ /** Event transport (e.g., RedisEventTransport) */
298
+ events?: EventTransport;
299
+ /** Cache store (e.g., RedisCacheStore) */
300
+ cache?: CacheStore;
301
+ /** Idempotency store (e.g., RedisIdempotencyStore) */
302
+ idempotency?: IdempotencyStore;
303
+ /** QueryCache store (e.g., RedisCacheStore). Default: MemoryCacheStore. */
295
304
  queryCache?: CacheStore;
296
305
  };
297
306
  /** Fastify logger configuration */
@@ -442,7 +451,8 @@ interface CreateAppOptions {
442
451
  rawBody?: RawBodyOptions | false;
443
452
  /** Enable Arc plugins (requestId, health, gracefulShutdown, events, caching, sse) */
444
453
  arcPlugins?: {
445
- /** Request ID tracking (default: true) */requestId?: boolean;
454
+ /** Request ID tracking (default: true) */
455
+ requestId?: boolean;
446
456
  /**
447
457
  * Health endpoints (default: true).
448
458
  *
@@ -469,8 +479,10 @@ interface CreateAppOptions {
469
479
  * }
470
480
  * ```
471
481
  */
472
- health?: boolean | HealthOptions; /** Graceful shutdown handling (default: true) */
473
- gracefulShutdown?: boolean; /** Emit events for CRUD operations (default: true) */
482
+ health?: boolean | HealthOptions;
483
+ /** Graceful shutdown handling (default: true) */
484
+ gracefulShutdown?: boolean;
485
+ /** Emit events for CRUD operations (default: true) */
474
486
  emitEvents?: boolean;
475
487
  /**
476
488
  * Event plugin configuration. Default: true (enabled with MemoryEventTransport).
@@ -851,6 +863,32 @@ interface CreateAppOptions {
851
863
  * @default false
852
864
  */
853
865
  strictResources?: boolean;
866
+ /**
867
+ * Pre-boot hook — awaited BEFORE arc does anything else: before the
868
+ * Fastify instance exists, before module thunks resolve, before resource
869
+ * discovery imports a single host file.
870
+ *
871
+ * The canonical slot for the DB connection and anything that
872
+ * module-EVAL-time code depends on. Engines that register Mongoose models
873
+ * at import time (top-level `createXEngine(...)`) trigger eager
874
+ * `createIndex()` calls from schema plugins — if the connection isn't
875
+ * open yet those buffer and die with `buffering timed out`. Hosts used to
876
+ * hand-orchestrate this with `await connectDatabase()` + dynamic
877
+ * `await import(...)` tricks before calling `createApp`; with `beforeBoot`
878
+ * the ordering is arc's contract instead:
879
+ *
880
+ * ```ts
881
+ * const app = await createApp({
882
+ * beforeBoot: async () => { await connectDatabase(); },
883
+ * modules: [() => import('#modules/accounting.js')], // thunks resolve AFTER beforeBoot
884
+ * resources: async () => [...],
885
+ * });
886
+ * ```
887
+ *
888
+ * Runs after option validation (config bugs fail fast without touching
889
+ * the DB). Cleanup stays host-owned — pair with `onClose`.
890
+ */
891
+ beforeBoot?: () => void | Promise<void>;
854
892
  /**
855
893
  * Custom plugin registration — runs after Arc core (security, auth, events)
856
894
  * but before `bootstrap` and `resources`.
@@ -907,7 +945,9 @@ interface UnderPressureOptions {
907
945
  }
908
946
  interface MultipartOptions {
909
947
  limits?: {
910
- /** Max file size in bytes (default: Fastify default ~1MB) */fileSize?: number; /** Max number of files per request */
948
+ /** Max file size in bytes (default: Fastify default ~1MB) */
949
+ fileSize?: number;
950
+ /** Max number of files per request */
911
951
  files?: number;
912
952
  };
913
953
  }