@classytic/arc 2.11.1 → 2.11.3

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 (70) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +143 -673
  3. package/bin/arc.js +2 -2
  4. package/dist/{BaseController-JNV08qOT.mjs → BaseController-swXruJ2_.mjs} +2 -2
  5. package/dist/{actionPermissions-C8YYU92K.mjs → actionPermissions-sUUKDhtP.mjs} +4 -2
  6. package/dist/adapters/index.d.mts +2 -2
  7. package/dist/audit/index.d.mts +1 -1
  8. package/dist/auth/index.d.mts +1 -1
  9. package/dist/auth/index.mjs +1 -1
  10. package/dist/cli/commands/docs.mjs +1 -1
  11. package/dist/cli/commands/generate.d.mts +0 -2
  12. package/dist/cli/commands/generate.mjs +15 -15
  13. package/dist/cli/commands/init.mjs +24 -22
  14. package/dist/context/index.mjs +1 -1
  15. package/dist/core/index.d.mts +2 -2
  16. package/dist/core/index.mjs +3 -3
  17. package/dist/{core-DXdSSFW-.mjs → core-DnUsRpuX.mjs} +20 -8
  18. package/dist/{createActionRouter-BwaSM0No.mjs → createActionRouter-u3ql2EDo.mjs} +73 -13
  19. package/dist/{createApp-P1d6rjPy.mjs → createApp-BFxtdKy6.mjs} +1 -1
  20. package/dist/docs/index.d.mts +1 -1
  21. package/dist/docs/index.mjs +1 -1
  22. package/dist/{eventPlugin--5HIkdPU.mjs → eventPlugin-KrFIQ097.mjs} +1 -1
  23. package/dist/events/index.d.mts +1 -1
  24. package/dist/events/index.mjs +11 -3
  25. package/dist/factory/index.d.mts +1 -1
  26. package/dist/factory/index.mjs +1 -1
  27. package/dist/hooks/index.d.mts +1 -1
  28. package/dist/idempotency/index.d.mts +1 -1
  29. package/dist/{index-C_bgx9o4.d.mts → index-6u4_Gg6G.d.mts} +34 -0
  30. package/dist/{index-CvM1e09j.d.mts → index-BbMrcvGp.d.mts} +1 -1
  31. package/dist/{index-pUczGjO0.d.mts → index-BdXnTPRj.d.mts} +1 -1
  32. package/dist/{index-smCAoA5W.d.mts → index-DdQ3O9Pg.d.mts} +1 -1
  33. package/dist/index.d.mts +4 -4
  34. package/dist/index.mjs +6 -6
  35. package/dist/integrations/index.d.mts +1 -1
  36. package/dist/integrations/mcp/index.d.mts +2 -2
  37. package/dist/integrations/mcp/index.mjs +1 -1
  38. package/dist/integrations/mcp/testing.d.mts +1 -1
  39. package/dist/integrations/mcp/testing.mjs +1 -1
  40. package/dist/middleware/index.d.mts +1 -1
  41. package/dist/{openapi-C0L9ar7m.mjs → openapi-BGUn7Ki1.mjs} +2 -2
  42. package/dist/org/index.d.mts +1 -1
  43. package/dist/permissions/index.mjs +1 -1
  44. package/dist/{permissions-B4vU9L0Q.mjs → permissions-gd_aUWrR.mjs} +42 -0
  45. package/dist/pipeline/index.d.mts +1 -1
  46. package/dist/plugins/index.d.mts +1 -1
  47. package/dist/plugins/index.mjs +1 -1
  48. package/dist/plugins/tracing-entry.mjs +1 -1
  49. package/dist/presets/filesUpload.d.mts +1 -1
  50. package/dist/presets/filesUpload.mjs +1 -1
  51. package/dist/presets/index.d.mts +1 -1
  52. package/dist/presets/index.mjs +1 -1
  53. package/dist/presets/multiTenant.d.mts +1 -1
  54. package/dist/presets/search.d.mts +1 -1
  55. package/dist/presets/search.mjs +1 -1
  56. package/dist/{presets-k604Lj99.mjs → presets-Z7P5w4gF.mjs} +1 -1
  57. package/dist/registry/index.d.mts +1 -1
  58. package/dist/{requestContext-CfRkaxwf.mjs → requestContext-C5XeK3VA.mjs} +15 -0
  59. package/dist/{resourceToTools--okX6QBr.mjs → resourceToTools-ByZpgjeH.mjs} +5 -4
  60. package/dist/{routerShared-DeESFp4a.mjs → routerShared-BqLRb5l7.mjs} +60 -3
  61. package/dist/testing/index.d.mts +2 -2
  62. package/dist/testing/index.mjs +1 -1
  63. package/dist/types/index.d.mts +1 -1
  64. package/dist/{types-Bh_gEJBi.d.mts → types-9beEMe25.d.mts} +1 -1
  65. package/dist/{types-BdA4uMBV.d.mts → types-BH7dEGvU.d.mts} +1 -1
  66. package/dist/utils/index.d.mts +1 -1
  67. package/dist/utils/index.mjs +1 -1
  68. package/dist/{utils-D3Yxnrwr.mjs → utils-CcYTj09l.mjs} +1 -1
  69. package/package.json +5 -1
  70. package/skills/arc/references/events.md +489 -489
package/bin/arc.js CHANGED
@@ -334,7 +334,7 @@ GLOBAL OPTIONS
334
334
 
335
335
  INIT OPTIONS
336
336
  --mongokit Use MongoKit adapter (default, recommended)
337
- --custom Use custom adapter (empty template)
337
+ --custom Use custom / Drizzle-ready adapter template
338
338
  --better-auth Use Better Auth (default, recommended)
339
339
  --jwt Use Arc built-in JWT auth
340
340
  --multi-tenant, --multi Multi-tenant mode (adds org scoping)
@@ -346,7 +346,7 @@ INIT OPTIONS
346
346
  --skip-install Skip npm install after scaffolding
347
347
 
348
348
  GENERATE SUBCOMMANDS
349
- resource, r Generate full resource (model, repo, controller, schemas, resource)
349
+ resource, r Generate resource-first scaffold (model, repo, resource, test)
350
350
  controller, c Generate controller only
351
351
  model, m Generate model only
352
352
  repository, repo Generate repository only
@@ -1,9 +1,9 @@
1
1
  import { h as SYSTEM_FIELDS, o as DEFAULT_TENANT_FIELD } from "./constants-BhY1OHoH.mjs";
2
2
  import { arcLog } from "./logger/index.mjs";
3
3
  import { _ as isElevated, n as PUBLIC_SCOPE, o as getOrgId, v as isMember } from "./types-AOD8fxIw.mjs";
4
- import { M as simpleEqualityMatcher, j as getUserId, k as ArcQueryParser } from "./utils-D3Yxnrwr.mjs";
4
+ import { M as simpleEqualityMatcher, j as getUserId, k as ArcQueryParser } from "./utils-CcYTj09l.mjs";
5
5
  import { t as buildQueryKey } from "./keys-CARyUjiR.mjs";
6
- import { M as applyFieldWritePermissions, P as resolveEffectiveRoles } from "./permissions-B4vU9L0Q.mjs";
6
+ import { M as applyFieldWritePermissions, P as resolveEffectiveRoles } from "./permissions-gd_aUWrR.mjs";
7
7
  import { t as getUserRoles } from "./types-DV9WDfeg.mjs";
8
8
  import { r as ForbiddenError } from "./errors-D5c-5BJL.mjs";
9
9
  //#region src/core/AccessControl.ts
@@ -5,8 +5,10 @@
5
5
  *
6
6
  * Callers decide what "no gate" means:
7
7
  * - HTTP: boot-time throw in `normalizeActionsToRouterConfig`.
8
- * - MCP: treated as allow (legacy) — but the HTTP fallback now fills the
9
- * gap when `permissions.update` is set, so the MCP hole closes too.
8
+ * - MCP: tool-generation throw in `resourceToTools` (mirrors HTTP the
9
+ * two surfaces fail closed identically so MCP can't expose an
10
+ * unauthenticated mutating tool when the HTTP plugin lifecycle hasn't
11
+ * run).
10
12
  * - OpenAPI: docs advertise the endpoint as unauthenticated.
11
13
  */
12
14
  function resolveActionPermission(input) {
@@ -1,3 +1,3 @@
1
- import { An as RelationMetadata, En as AdapterFactory, Mn as SchemaMetadata, Nn as ValidationResult, On as DataAdapter, jn as RepositoryLike, kn as FieldMetadata } from "../index-C_bgx9o4.mjs";
2
- import { a as PrismaQueryParserOptions, c as MongooseAdapterOptions, d as DrizzleAdapterOptions, f as createDrizzleAdapter, i as PrismaQueryParser, l as createMongooseAdapter, n as PrismaAdapterOptions, o as createPrismaAdapter, r as PrismaQueryOptions, s as MongooseAdapter, t as PrismaAdapter, u as DrizzleAdapter } from "../index-CvM1e09j.mjs";
1
+ import { An as RelationMetadata, En as AdapterFactory, Mn as SchemaMetadata, Nn as ValidationResult, On as DataAdapter, jn as RepositoryLike, kn as FieldMetadata } from "../index-6u4_Gg6G.mjs";
2
+ import { a as PrismaQueryParserOptions, c as MongooseAdapterOptions, d as DrizzleAdapterOptions, f as createDrizzleAdapter, i as PrismaQueryParser, l as createMongooseAdapter, n as PrismaAdapterOptions, o as createPrismaAdapter, r as PrismaQueryOptions, s as MongooseAdapter, t as PrismaAdapter, u as DrizzleAdapter } from "../index-BbMrcvGp.mjs";
3
3
  export { AdapterFactory, DataAdapter, DrizzleAdapter, DrizzleAdapterOptions, FieldMetadata, MongooseAdapter, MongooseAdapterOptions, PrismaAdapter, PrismaAdapterOptions, PrismaQueryOptions, PrismaQueryParser, PrismaQueryParserOptions, RelationMetadata, RepositoryLike, SchemaMetadata, ValidationResult, createDrizzleAdapter, createMongooseAdapter, createPrismaAdapter };
@@ -1,4 +1,4 @@
1
- import { jn as RepositoryLike } from "../index-C_bgx9o4.mjs";
1
+ import { jn as RepositoryLike } from "../index-6u4_Gg6G.mjs";
2
2
  import { d as UserBase } from "../fields-C8Y0XLAu.mjs";
3
3
  import { FastifyPluginAsync } from "fastify";
4
4
 
@@ -1,4 +1,4 @@
1
- import { Ot as AuthHelpers, kt as AuthPluginOptions } from "../index-C_bgx9o4.mjs";
1
+ import { Ot as AuthHelpers, kt as AuthPluginOptions } from "../index-6u4_Gg6G.mjs";
2
2
  import { c as PermissionCheck } from "../fields-C8Y0XLAu.mjs";
3
3
  import { t as ExternalOpenApiPaths } from "../externalPaths-Bapitwvd.mjs";
4
4
  import { a as SessionManagerOptions, c as createSessionManager, i as SessionData, n as MemorySessionStoreOptions, o as SessionManagerResult, r as SessionCookieOptions, s as SessionStore, t as MemorySessionStore } from "../sessionManager-D-oNWHz3.mjs";
@@ -1,4 +1,4 @@
1
- import { _ as requireTeamMembership, m as requireOrgRole, p as requireOrgMembership } from "../permissions-B4vU9L0Q.mjs";
1
+ import { _ as requireTeamMembership, m as requireOrgRole, p as requireOrgMembership } from "../permissions-gd_aUWrR.mjs";
2
2
  import { n as normalizeRoles, t as getUserRoles } from "../types-DV9WDfeg.mjs";
3
3
  import { t as ArcError } from "../errors-D5c-5BJL.mjs";
4
4
  import { n as extractBetterAuthOpenApi } from "../betterAuthOpenApi-DwxtK3uG.mjs";
@@ -1,5 +1,5 @@
1
1
  import { t as ResourceRegistry } from "../../ResourceRegistry-DkAeAuTX.mjs";
2
- import { t as buildOpenApiSpec } from "../../openapi-C0L9ar7m.mjs";
2
+ import { t as buildOpenApiSpec } from "../../openapi-BGUn7Ki1.mjs";
3
3
  import { dirname, resolve } from "node:path";
4
4
  import { pathToFileURL } from "node:url";
5
5
  import { mkdirSync, writeFileSync } from "node:fs";
@@ -6,8 +6,6 @@
6
6
  * - src/resources/product/product.model.ts
7
7
  * - src/resources/product/product.repository.ts
8
8
  * - src/resources/product/product.resource.ts
9
- * - src/resources/product/product.controller.ts
10
- * - src/resources/product/product.schemas.ts
11
9
  *
12
10
  * Handles kebab-case names: `arc g r org-profile` generates:
13
11
  * - Class names: OrgProfile, OrgProfileRepository
@@ -9,8 +9,6 @@ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
9
9
  * - src/resources/product/product.model.ts
10
10
  * - src/resources/product/product.repository.ts
11
11
  * - src/resources/product/product.resource.ts
12
- * - src/resources/product/product.controller.ts
13
- * - src/resources/product/product.schemas.ts
14
12
  *
15
13
  * Handles kebab-case names: `arc g r org-profile` generates:
16
14
  * - Class names: OrgProfile, OrgProfileRepository
@@ -58,7 +56,7 @@ ${ts ? `
58
56
  export interface I${name} {
59
57
  name: string;
60
58
  description?: string;
61
- isActive: boolean;
59
+ ${isMultiTenant ? "organizationId: string;\n " : ""}isActive: boolean;
62
60
  }
63
61
 
64
62
  export type ${name}Document = HydratedDocument<I${name}>;
@@ -67,14 +65,14 @@ const ${camel}Schema = new Schema${ts ? `<I${name}>` : ""}(
67
65
  {
68
66
  name: { type: String, required: true, trim: true },
69
67
  description: { type: String, trim: true },
70
- isActive: { type: Boolean, default: true },
68
+ ${isMultiTenant ? "organizationId: { type: String, required: true, index: true },\n " : ""}isActive: { type: Boolean, default: true },
71
69
  },
72
70
  { timestamps: true }
73
71
  );
74
72
 
75
73
  // Indexes
76
74
  ${camel}Schema.index({ name: 1 });
77
- ${camel}Schema.index({ isActive: 1 });
75
+ ${isMultiTenant ? `${camel}Schema.index({ organizationId: 1, isActive: 1 });\n` : ""}${camel}Schema.index({ isActive: 1 });
78
76
 
79
77
  const ${name} = mongoose.models.${name} || mongoose.model('${name}', ${camel}Schema);
80
78
  export default ${name};
@@ -193,20 +191,21 @@ export default crudSchemas;
193
191
  */
194
192
 
195
193
  import { defineResource, createMongooseAdapter } from '@classytic/arc';
196
- import { requireAuth, requireRoles } from '@classytic/arc/permissions';
194
+ import { allOf, requireOrgMembership, requireRoles } from '@classytic/arc/permissions';
195
+ import { multiTenantPreset } from '@classytic/arc/presets';
197
196
  import ${name}${ts ? `, { type I${name} }` : ""} from './${fileName}.model.js';
198
197
  import ${camel}Repository from './${fileName}.repository.js';${queryParserImport}
199
198
 
200
199
  const ${camel}Resource = defineResource${ts ? `<I${name}>` : ""}({
201
200
  name: '${fileName}',
202
201
  adapter: createMongooseAdapter({ model: ${name}, repository: ${camel}Repository }),${queryParserConfig}
203
- presets: ['softDelete'],
202
+ presets: ['softDelete', multiTenantPreset({ tenantField: 'organizationId' })],
204
203
  permissions: {
205
- list: requireAuth(),
206
- get: requireAuth(),
207
- create: requireRoles(['admin']),
208
- update: requireRoles(['admin']),
209
- delete: requireRoles(['admin']),
204
+ list: requireOrgMembership(),
205
+ get: requireOrgMembership(),
206
+ create: allOf(requireOrgMembership(), requireRoles(['admin'])),
207
+ update: allOf(requireOrgMembership(), requireRoles(['admin'])),
208
+ delete: allOf(requireOrgMembership(), requireRoles(['admin'])),
210
209
  },
211
210
  });
212
211
 
@@ -367,7 +366,7 @@ async function generate(type, args) {
367
366
  }
368
367
  }
369
368
  /**
370
- * Generate a full resource
369
+ * Generate a resource-first scaffold
371
370
  */
372
371
  async function generateResource(name, lowerName, resourcePath, templates, ext, includeMcp = false) {
373
372
  console.log(`\nGenerating resource: ${name}...\n`);
@@ -417,8 +416,9 @@ Next steps:
417
416
  src/resources/${lowerName}/${lowerName}.model.${ext}
418
417
 
419
418
  3. Adjust permissions in ${lowerName}.resource.${ext}:
420
- ${isMultiTenant ? ` - requireAuth() any authenticated user
421
- - requireRoles(['admin']) specific platform roles` : ` - requireAuth() → any authenticated user
419
+ ${isMultiTenant ? ` - requireOrgMembership() member of the current organization
420
+ - multiTenantPreset() injects and filters organizationId
421
+ - requireRoles(['admin']) → admin writes inside the org scope` : ` - requireAuth() → any authenticated user
422
422
  - requireRoles(['admin']) → specific platform roles`}
423
423
 
424
424
  4. Run tests:
@@ -26,7 +26,7 @@ async function init(options = {}) {
26
26
  `);
27
27
  const config = await gatherConfig(options);
28
28
  console.log(`\nCreating project: ${config.name}`);
29
- console.log(` Adapter: ${config.adapter === "mongokit" ? "MongoKit (MongoDB)" : "Custom"}`);
29
+ console.log(` Adapter: ${config.adapter === "mongokit" ? "MongoKit (MongoDB)" : "Custom / Drizzle-ready"}`);
30
30
  console.log(` Auth: ${config.auth === "better-auth" ? "Better Auth (recommended)" : "Arc JWT"}`);
31
31
  console.log(` Tenant: ${config.tenant === "multi" ? "Multi-tenant" : "Single-tenant"}`);
32
32
  console.log(` Language: ${config.typescript ? "TypeScript" : "JavaScript"}`);
@@ -156,7 +156,7 @@ async function gatherConfig(options) {
156
156
  try {
157
157
  const name = options.name || await question("Project name: ") || "my-arc-app";
158
158
  let adapter = options.adapter || "mongokit";
159
- if (!options.adapter && !nonInteractive) adapter = await question("Database adapter [1=MongoKit (recommended), 2=Custom]: ") === "2" ? "custom" : "mongokit";
159
+ if (!options.adapter && !nonInteractive) adapter = await question("Database adapter [1=MongoKit (recommended), 2=Custom / Drizzle-ready]: ") === "2" ? "custom" : "mongokit";
160
160
  let auth = options.auth || "better-auth";
161
161
  if (!options.auth && !nonInteractive) auth = await question("Auth strategy [1=Better Auth (recommended), 2=Arc JWT]: ") === "2" ? "jwt" : "better-auth";
162
162
  let tenant = options.tenant || "single";
@@ -171,12 +171,12 @@ async function gatherConfig(options) {
171
171
  console.log(" MongoDB Atlas works with the raw driver (mongodb 6.15+ with nodejs_compat_v2),");
172
172
  console.log(" but MongoKit depends on Mongoose. Options:");
173
173
  console.log(" 1. Use AWS Lambda / Vercel Serverless (Node.js) — Mongoose works normally");
174
- console.log(" 2. Use Cloudflare Hyperdrive + PostgreSQL (switch to Prisma/Drizzle adapter)");
174
+ console.log(" 2. Use Cloudflare Hyperdrive + PostgreSQL (wire sqlitekit/Drizzle via custom adapter)");
175
175
  console.log(" 3. Continue with MongoKit — works on Lambda/Vercel, NOT on Cloudflare Workers");
176
176
  console.log("");
177
177
  if ((await question("Continue with MongoKit? [y/N]: ")).toLowerCase() !== "y") {
178
178
  adapter = "custom";
179
- console.log(" Switched to custom adapter. You can wire Drizzle, Prisma, or the raw MongoDB driver.");
179
+ console.log(" Switched to custom adapter. Wire sqlitekit/Drizzle here; Prisma remains experimental.");
180
180
  }
181
181
  }
182
182
  return {
@@ -465,7 +465,7 @@ src/
465
465
  │ ├── env.${ext} # Env loader (import first!)
466
466
  │ └── index.${ext} # App config
467
467
  ├── shared/ # Shared utilities
468
- │ ├── adapter.${ext} # ${config.adapter === "mongokit" ? "MongoKit adapter factory" : "Custom adapter"}
468
+ │ ├── adapter.${ext} # ${config.adapter === "mongokit" ? "MongoKit adapter factory" : "Custom / Drizzle-ready adapter"}
469
469
  │ ├── permissions.${ext} # Permission helpers
470
470
  │ └── presets/ # ${config.tenant === "multi" ? "Multi-tenant presets" : "Standard presets"}
471
471
  ├── plugins/ # App-specific plugins
@@ -995,29 +995,31 @@ function customAdapterTemplate(config) {
995
995
  return `/**
996
996
  * Custom Adapter Factory
997
997
  *
998
- * Implement your own database adapter here.
998
+ * Use this for sqlitekit/Drizzle, Prisma experiments, or any repository
999
+ * that satisfies Arc's RepositoryLike contract.
999
1000
  */
1000
1001
 
1001
- import { createMongooseAdapter } from '@classytic/arc';
1002
- ${ts ? "import type { Model } from 'mongoose';" : ""}
1002
+ ${ts ? "import type { DataAdapter, RepositoryLike } from '@classytic/arc/adapters';" : ""}
1003
1003
 
1004
1004
  /**
1005
- * Create a custom adapter for a resource
1005
+ * Create a custom adapter for a resource.
1006
1006
  *
1007
- * Implement this based on your database choice:
1008
- * - Prisma: Use @classytic/prismakit (coming soon)
1009
- * - Drizzle: Create custom adapter
1010
- * - Raw SQL: Create custom adapter
1011
- */
1012
- export function createAdapter${ts ? "<TDoc>" : ""}(
1013
- model${ts ? ": Model<TDoc>" : ""},
1014
- repository${ts ? ": any" : ""}
1015
- )${ts ? ": ReturnType<typeof createMongooseAdapter>" : ""} {
1016
- // SCAFFOLD: Replace with your custom adapter implementation
1017
- return createMongooseAdapter({
1018
- model,
1007
+ * Recommended SQL path:
1008
+ * - sqlitekit repository + Arc's createDrizzleAdapter for Drizzle tables
1009
+ *
1010
+ * Experimental path:
1011
+ * - Prisma can be wired with createPrismaAdapter, but keep it opt-in until
1012
+ * your app has integration coverage.
1013
+ */
1014
+ export function createAdapter${ts ? "<TDoc = unknown>" : ""}(
1015
+ _source${ts ? ": unknown" : ""},
1016
+ repository${ts ? ": RepositoryLike<TDoc>" : ""}
1017
+ )${ts ? ": DataAdapter<TDoc>" : ""} {
1018
+ return {
1019
+ type: 'custom',
1020
+ name: 'custom-repository',
1019
1021
  repository,
1020
- });
1022
+ };
1021
1023
  }
1022
1024
  `;
1023
1025
  }
@@ -1,2 +1,2 @@
1
- import { t as requestContext } from "../requestContext-CfRkaxwf.mjs";
1
+ import { t as requestContext } from "../requestContext-C5XeK3VA.mjs";
2
2
  export { requestContext };
@@ -1,3 +1,3 @@
1
- import { B as ResourceDefinition, Gt as TreeMixin, Ht as SoftDeleteExt, Jt as BulkExt, Kt as SlugExt, Ut as SoftDeleteMixin, V as defineResource, Vt as BaseController, Wt as TreeExt, Yt as BulkMixin, an as QueryResolverConfig, cn as AccessControl, in as QueryResolver, ln as AccessControlConfig, nn as BaseCrudController, on as BodySanitizer, qt as SlugMixin, rn as ListResult, sn as BodySanitizerConfig, tn as BaseControllerOptions } from "../index-C_bgx9o4.mjs";
2
- 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, c as createCrudRouter, d as CrudOperation, f as DEFAULT_ID_FIELD, g as DEFAULT_TENANT_FIELD, h as DEFAULT_SORT, i as getControllerContext, l as createPermissionMiddleware, m as DEFAULT_MAX_LIMIT, n as createFastifyHandler, o as sendControllerResponse, p as DEFAULT_LIMIT, r as createRequestContext, s as defineResourceVariants, t as createCrudHandlers, u as CRUD_OPERATIONS, v as HOOK_OPERATIONS, w as MAX_SEARCH_LENGTH, x as HookPhase, y as HOOK_PHASES } from "../index-pUczGjO0.mjs";
1
+ import { B as ResourceDefinition, Gt as TreeMixin, Ht as SoftDeleteExt, Jt as BulkExt, Kt as SlugExt, Ut as SoftDeleteMixin, V as defineResource, Vt as BaseController, Wt as TreeExt, Yt as BulkMixin, an as QueryResolverConfig, cn as AccessControl, in as QueryResolver, ln as AccessControlConfig, nn as BaseCrudController, on as BodySanitizer, qt as SlugMixin, rn as ListResult, sn as BodySanitizerConfig, tn as BaseControllerOptions } from "../index-6u4_Gg6G.mjs";
2
+ 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, c as createCrudRouter, d as CrudOperation, f as DEFAULT_ID_FIELD, g as DEFAULT_TENANT_FIELD, h as DEFAULT_SORT, i as getControllerContext, l as createPermissionMiddleware, m as DEFAULT_MAX_LIMIT, n as createFastifyHandler, o as sendControllerResponse, p as DEFAULT_LIMIT, r as createRequestContext, s as defineResourceVariants, t as createCrudHandlers, u as CRUD_OPERATIONS, v as HOOK_OPERATIONS, w as MAX_SEARCH_LENGTH, x as HookPhase, y as HOOK_PHASES } from "../index-BdXnTPRj.mjs";
3
3
  export { AccessControl, AccessControlConfig, BaseController, BaseControllerOptions, BaseCrudController, BodySanitizer, BodySanitizerConfig, BulkExt, BulkMixin, CRUD_OPERATIONS, CrudOperation, DEFAULT_ID_FIELD, DEFAULT_LIMIT, DEFAULT_MAX_LIMIT, DEFAULT_SORT, DEFAULT_TENANT_FIELD, DEFAULT_UPDATE_METHOD, HOOK_OPERATIONS, HOOK_PHASES, HookOperation, HookPhase, ListResult, MAX_FILTER_DEPTH, MAX_REGEX_LENGTH, MAX_SEARCH_LENGTH, MUTATION_OPERATIONS, MutationOperation, QueryResolver, QueryResolverConfig, RESERVED_QUERY_PARAMS, ResourceDefinition, SYSTEM_FIELDS, SlugExt, SlugMixin, SoftDeleteExt, SoftDeleteMixin, TreeExt, TreeMixin, createCrudHandlers, createCrudRouter, createFastifyHandler, createPermissionMiddleware, createRequestContext, defineResource, defineResourceVariants, getControllerContext, getControllerScope, sendControllerResponse };
@@ -1,5 +1,5 @@
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-BhY1OHoH.mjs";
2
- import { a as BulkMixin, c as BodySanitizer, i as SlugMixin, l as AccessControl, n as TreeMixin, o as BaseCrudController, r as SoftDeleteMixin, s as QueryResolver, t as BaseController } from "../BaseController-JNV08qOT.mjs";
3
- import { _ as getControllerScope, g as getControllerContext, h as createRequestContext, m as createFastifyHandler, p as createCrudHandlers, v as sendControllerResponse } from "../routerShared-DeESFp4a.mjs";
4
- import { a as createPermissionMiddleware, i as createCrudRouter, n as ResourceDefinition, r as defineResource, t as defineResourceVariants } from "../core-DXdSSFW-.mjs";
2
+ import { a as BulkMixin, c as BodySanitizer, i as SlugMixin, l as AccessControl, n as TreeMixin, o as BaseCrudController, r as SoftDeleteMixin, s as QueryResolver, t as BaseController } from "../BaseController-swXruJ2_.mjs";
3
+ import { _ as getControllerContext, g as createRequestContext, h as createFastifyHandler, m as createCrudHandlers, v as getControllerScope, y as sendControllerResponse } from "../routerShared-BqLRb5l7.mjs";
4
+ import { a as createPermissionMiddleware, i as createCrudRouter, n as ResourceDefinition, r as defineResource, t as defineResourceVariants } from "../core-DnUsRpuX.mjs";
5
5
  export { AccessControl, BaseController, BaseCrudController, BodySanitizer, BulkMixin, CRUD_OPERATIONS, DEFAULT_ID_FIELD, DEFAULT_LIMIT, DEFAULT_MAX_LIMIT, DEFAULT_SORT, DEFAULT_TENANT_FIELD, DEFAULT_UPDATE_METHOD, HOOK_OPERATIONS, HOOK_PHASES, MAX_FILTER_DEPTH, MAX_REGEX_LENGTH, MAX_SEARCH_LENGTH, MUTATION_OPERATIONS, QueryResolver, RESERVED_QUERY_PARAMS, ResourceDefinition, SYSTEM_FIELDS, SlugMixin, SoftDeleteMixin, TreeMixin, createCrudHandlers, createCrudRouter, createFastifyHandler, createPermissionMiddleware, createRequestContext, defineResource, defineResourceVariants, getControllerContext, getControllerScope, sendControllerResponse };
@@ -1,12 +1,12 @@
1
1
  import { s as DEFAULT_UPDATE_METHOD, t as CRUD_OPERATIONS } from "./constants-BhY1OHoH.mjs";
2
2
  import { arcLog } from "./logger/index.mjs";
3
- import { m as assertValidConfig, y as getDefaultCrudSchemas } from "./utils-D3Yxnrwr.mjs";
4
- import { t as BaseController } from "./BaseController-JNV08qOT.mjs";
3
+ import { m as assertValidConfig, y as getDefaultCrudSchemas } from "./utils-CcYTj09l.mjs";
4
+ import { t as BaseController } from "./BaseController-swXruJ2_.mjs";
5
5
  import { n as convertRouteSchema, t as convertOpenApiSchemas } from "./schemaConverter-B0oKLuqI.mjs";
6
- import { c as buildPreHandlerChain, d as resolveRouterPluginMw, f as selectPluginMw, i as buildAuthMiddleware, l as buildRateLimitConfig, m as createFastifyHandler, o as buildCrudPermissionMw, p as createCrudHandlers, r as buildArcDecorator, s as buildPipelineHandler, u as resolvePipelineSteps, y as buildRequestScopeProjection } from "./routerShared-DeESFp4a.mjs";
7
- import { t as applyPresets } from "./presets-k604Lj99.mjs";
6
+ import { b as buildRequestScopeProjection, c as buildPreHandlerChain, d as resolveRoutePreHandlers, f as resolveRouterPluginMw, h as createFastifyHandler, i as buildAuthMiddleware, l as buildRateLimitConfig, m as createCrudHandlers, o as buildCrudPermissionMw, p as selectPluginMw, r as buildArcDecorator, s as buildPipelineHandler, u as resolvePipelineSteps } from "./routerShared-BqLRb5l7.mjs";
7
+ import { t as applyPresets } from "./presets-Z7P5w4gF.mjs";
8
8
  import { t as hasEvents } from "./typeGuards-CcFZXgU7.mjs";
9
- import { t as resolveActionPermission } from "./actionPermissions-C8YYU92K.mjs";
9
+ import { t as resolveActionPermission } from "./actionPermissions-sUUKDhtP.mjs";
10
10
  //#region src/core/createCrudRouter.ts
11
11
  /**
12
12
  * Mount custom routes (from presets or user-defined `routes`) on Fastify.
@@ -39,7 +39,7 @@ function createCustomRoutes(fastify, routes, controller, options) {
39
39
  ...route.description ? { description: route.description } : {},
40
40
  ...convertedSchema ?? {}
41
41
  };
42
- const customPreHandlers = typeof route.preHandler === "function" ? route.preHandler(fastify) : route.preHandler ?? [];
42
+ const customPreHandlers = resolveRoutePreHandlers(route.preHandler, fastify, `${route.method} ${route.path}`);
43
43
  const preHandler = buildPreHandlerChain({
44
44
  preAuth: route.preAuth ?? [],
45
45
  arcDecorator,
@@ -469,7 +469,19 @@ function resolveOrAutoCreateController(resolvedConfig, adapter, repository, hasC
469
469
  if (typeof ctrl.setQueryParser === "function") ctrl.setQueryParser(resolvedConfig.queryParser);
470
470
  else arcLog("defineResource").warn(`Resource "${resolvedConfig.name}" declares a custom \`queryParser\` but its controller does not expose \`setQueryParser(qp)\`. The parser will NOT be threaded into the controller's query resolution — operator filters (\`[contains]\`, \`[like]\`, etc.) may fall back to the controller's internal default. Extend \`BaseController\` / \`BaseCrudController\` (both implement \`setQueryParser\`) OR add the method to your custom controller to honor the resource-level parser.`);
471
471
  }
472
- if (controller || !hasCrudRoutes || !repository) return controller;
472
+ if (controller) {
473
+ const droppedOptions = [];
474
+ if (resolvedConfig.tenantField !== void 0) droppedOptions.push("tenantField");
475
+ if (resolvedConfig.schemaOptions !== void 0 && Object.keys(resolvedConfig.schemaOptions).length > 0) droppedOptions.push("schemaOptions");
476
+ if (resolvedConfig.idField !== void 0) droppedOptions.push("idField");
477
+ if (resolvedConfig.defaultSort !== void 0) droppedOptions.push("defaultSort");
478
+ if (resolvedConfig.cache !== void 0) droppedOptions.push("cache");
479
+ if (resolvedConfig.onFieldWriteDenied !== void 0) droppedOptions.push("onFieldWriteDenied");
480
+ if (resolvedConfig._controllerOptions !== void 0) droppedOptions.push("preset-injected fields (slug/softDelete/parent)");
481
+ if (droppedOptions.length > 0) arcLog("defineResource").warn(`Resource "${resolvedConfig.name}" declares a custom controller AND resource-level option(s) [${droppedOptions.join(", ")}]. Arc only threads these when it auto-builds the controller — when you pass your own, they are dropped silently and the controller falls back to its own defaults (e.g. tenantField → 'organizationId'). Forward them to your controller's \`super(repo, { ... })\` call. Same root cause as the \`queryParser\` warn above.`);
482
+ return controller;
483
+ }
484
+ if (!hasCrudRoutes || !repository) return controller;
473
485
  const qp = resolvedConfig.queryParser;
474
486
  let maxLimitFromParser;
475
487
  if (qp?.getQuerySchema) {
@@ -869,7 +881,7 @@ var ResourceDefinition = class {
869
881
  fields: self.fields
870
882
  });
871
883
  if (self.actions && Object.keys(self.actions).length > 0) {
872
- const { createActionRouter } = await import("./createActionRouter-BwaSM0No.mjs").then((n) => n.n);
884
+ const { createActionRouter } = await import("./createActionRouter-u3ql2EDo.mjs").then((n) => n.n);
873
885
  createActionRouter(typedInstance, {
874
886
  ...normalizeActionsToRouterConfig(self.actions, self.actionPermissions, self.tag, self.permissions, self.name, typedInstance.log),
875
887
  resourceName: self.name,
@@ -1,5 +1,5 @@
1
1
  import { t as __exportAll } from "./chunk-BpYLSNr0.mjs";
2
- import { a as buildAuthMiddlewareForPermissions, c as buildPreHandlerChain, d as resolveRouterPluginMw, f as selectPluginMw, l as buildRateLimitConfig, n as buildActionPipelineHandler, r as buildArcDecorator, t as buildActionPermissionMw, u as resolvePipelineSteps, v as sendControllerResponse } from "./routerShared-DeESFp4a.mjs";
2
+ import { a as buildAuthMiddlewareForPermissions, c as buildPreHandlerChain, f as resolveRouterPluginMw, l as buildRateLimitConfig, n as buildActionPipelineHandler, p as selectPluginMw, r as buildArcDecorator, t as buildActionPermissionMw, u as resolvePipelineSteps, y as sendControllerResponse } from "./routerShared-BqLRb5l7.mjs";
3
3
  import { n as schemaIRToJsonSchemaBranch, t as normalizeSchemaIR } from "./schemaIR-BlG9bY7v.mjs";
4
4
  //#region src/core/createActionRouter.ts
5
5
  var createActionRouter_exports = /* @__PURE__ */ __exportAll({
@@ -118,34 +118,94 @@ function createActionRouter(fastify, config) {
118
118
  * {
119
119
  * "type": "object",
120
120
  * "required": ["action"],
121
+ * "properties": {
122
+ * "action": { "type": "string", "enum": ["dispatch", "approve"] },
123
+ * "carrier": { "type": "string" }
124
+ * },
121
125
  * "oneOf": [
122
- * { "properties": { "action": { "const": "dispatch" }, "carrier": {...} }, "required": ["action", "carrier"] },
123
- * { "properties": { "action": { "const": "approve" } }, "required": ["action"] }
126
+ * {
127
+ * "properties": {
128
+ * "action": { "const": "dispatch" },
129
+ * "carrier": { "type": "string" } // ← every branch lists the union
130
+ * },
131
+ * "required": ["action", "carrier"]
132
+ * },
133
+ * {
134
+ * "properties": {
135
+ * "action": { "const": "approve" },
136
+ * "carrier": { "type": "string" } // ← even though approve doesn't use it
137
+ * },
138
+ * "required": ["action"]
139
+ * }
124
140
  * ]
125
141
  * }
126
142
  * ```
127
143
  *
128
- * AJV validates this natively, so an action call missing required fields is
129
- * rejected with HTTP 400 before the handler ever runs.
144
+ * **Why every branch carries the full property union.** AJV's
145
+ * `removeAdditional: 'all'` (Fastify's framework default) interacts badly
146
+ * with `oneOf`: when a branch's `properties` lacks a field, AJV strips it
147
+ * from the body during that branch's evaluation — *even if a different
148
+ * branch would have allowed it*. The strip mutates the body before
149
+ * `oneOf` finishes discriminating, so by the time the matching branch
150
+ * wins, the body has already lost fields. Concretely: `actions: { verify:
151
+ * {}, hold: { schema: z.object({ amount, reason }.optional()) } }` +
152
+ * `POST { action: 'hold', amount: 1, reason }` lands at the handler as
153
+ * `{ action: 'hold' }`. Empirically reproduced and locked at
154
+ * [tests/core/action-discriminator-strip.test.ts](../../tests/core/action-discriminator-strip.test.ts).
155
+ *
156
+ * Listing every action's properties on every branch makes per-branch
157
+ * removeAdditional walks see every caller field as "in this branch's
158
+ * properties," so nothing gets stripped during oneOf evaluation. The
159
+ * `required` array stays per-action, so the handler still gets called
160
+ * only when the matching branch's required-field contract is satisfied.
161
+ * Per-branch `additionalProperties: false` (Zod v4 default) carries
162
+ * through but, under host removeAdditional: 'all', it can no longer
163
+ * reject sibling-action fields — those become silently stripped at top
164
+ * level instead. That's the host's opt-in to stripping; arc's job is to
165
+ * stop accidentally losing the action's *own* declared fields.
166
+ *
167
+ * Under arc's own `createApp` (`removeAdditional: false`), strict-mode
168
+ * rejection still functions normally — see
169
+ * [tests/core/action-strict-schema-parity.test.ts](../../tests/core/action-strict-schema-parity.test.ts).
130
170
  *
131
171
  * Exported so OpenAPI generation and MCP tool generation can reuse the same
132
172
  * schema shape (single source of truth).
133
173
  */
134
174
  function buildActionBodySchema(actionEnum, actionSchemas = {}) {
135
- const branches = [];
175
+ const unionProperties = {};
176
+ const irs = [];
136
177
  for (const actionName of actionEnum) {
137
178
  const ir = normalizeSchemaIR(actionSchemas[actionName]);
138
- branches.push(schemaIRToJsonSchemaBranch(ir, {
139
- properties: { action: {
140
- type: "string",
141
- const: actionName
142
- } },
143
- required: ["action"]
144
- }));
179
+ irs.push({
180
+ name: actionName,
181
+ ir
182
+ });
183
+ for (const [key, val] of Object.entries(ir.properties)) unionProperties[key] = val;
145
184
  }
185
+ const branches = [];
186
+ for (const { name, ir } of irs) branches.push(schemaIRToJsonSchemaBranch({
187
+ ...ir,
188
+ properties: {
189
+ ...unionProperties,
190
+ ...ir.properties
191
+ }
192
+ }, {
193
+ properties: { action: {
194
+ type: "string",
195
+ const: name
196
+ } },
197
+ required: ["action"]
198
+ }));
146
199
  return {
147
200
  type: "object",
148
201
  required: ["action"],
202
+ properties: {
203
+ action: {
204
+ type: "string",
205
+ enum: [...actionEnum]
206
+ },
207
+ ...unionProperties
208
+ },
149
209
  oneOf: branches
150
210
  };
151
211
  }
@@ -204,7 +204,7 @@ async function registerArcCore(fastify, config, trackPlugin) {
204
204
  await fastify.register(arcCorePlugin, { emitEvents: config.arcPlugins?.emitEvents !== false });
205
205
  trackPlugin("arc-core");
206
206
  if (config.arcPlugins?.events !== false) {
207
- const { default: eventPlugin } = await import("./eventPlugin--5HIkdPU.mjs").then((n) => n.n);
207
+ const { default: eventPlugin } = await import("./eventPlugin-KrFIQ097.mjs").then((n) => n.n);
208
208
  const eventOpts = typeof config.arcPlugins?.events === "object" ? config.arcPlugins.events : {};
209
209
  await fastify.register(eventPlugin, {
210
210
  ...eventOpts,
@@ -1,4 +1,4 @@
1
- import { p as RegistryEntry } from "../index-C_bgx9o4.mjs";
1
+ import { p as RegistryEntry } from "../index-6u4_Gg6G.mjs";
2
2
  import { t as ExternalOpenApiPaths } from "../externalPaths-Bapitwvd.mjs";
3
3
  import { FastifyPluginAsync } from "fastify";
4
4
 
@@ -1,5 +1,5 @@
1
1
  import { t as getUserRoles } from "../types-DV9WDfeg.mjs";
2
- import { n as openApiPlugin, r as openapi_default, t as buildOpenApiSpec } from "../openapi-C0L9ar7m.mjs";
2
+ import { n as openApiPlugin, r as openapi_default, t as buildOpenApiSpec } from "../openapi-BGUn7Ki1.mjs";
3
3
  import fp from "fastify-plugin";
4
4
  //#region src/docs/scalar.ts
5
5
  const scalarPlugin = async (fastify, opts = {}) => {
@@ -1,5 +1,5 @@
1
1
  import { t as __exportAll } from "./chunk-BpYLSNr0.mjs";
2
- import { t as requestContext } from "./requestContext-CfRkaxwf.mjs";
2
+ import { t as requestContext } from "./requestContext-C5XeK3VA.mjs";
3
3
  import fp from "fastify-plugin";
4
4
  //#region src/events/EventTransport.ts
5
5
  /**
@@ -1,4 +1,4 @@
1
- import { jn as RepositoryLike } from "../index-C_bgx9o4.mjs";
1
+ import { jn as RepositoryLike } from "../index-6u4_Gg6G.mjs";
2
2
  import { a as EventMeta, c as MemoryEventTransportOptions, d as createEvent, i as EventLogger, l as PublishManyResult, n as DomainEvent, o as EventTransport, r as EventHandler, s as MemoryEventTransport, t as DeadLetteredEvent, u as createChildEvent } from "../EventTransport-CfVEGaEl.mjs";
3
3
  import { a as withRetry, c as EventDefinitionOutput, d as EventSchema, f as ValidationResult, i as createDeadLetterPublisher, l as EventRegistry, m as defineEvent, n as eventPlugin, o as CustomValidator, p as createEventRegistry, r as RetryOptions, s as EventDefinitionInput, t as EventPluginOptions, u as EventRegistryOptions } from "../eventPlugin-CUNjYYRY.mjs";
4
4
  import { RedisEventTransportOptions, RedisLike } from "./transports/redis.mjs";
@@ -1,4 +1,4 @@
1
- import { a as MemoryEventTransport, i as withRetry, o as createChildEvent, r as createDeadLetterPublisher, s as createEvent, t as eventPlugin } from "../eventPlugin--5HIkdPU.mjs";
1
+ import { a as MemoryEventTransport, i as withRetry, o as createChildEvent, r as createDeadLetterPublisher, s as createEvent, t as eventPlugin } from "../eventPlugin-KrFIQ097.mjs";
2
2
  import { n as createSafeGetOne, t as createIsDuplicateKeyError } from "../store-helpers-BhrzxvyQ.mjs";
3
3
  import { and, anyOf, eq, lte, ne, or } from "@classytic/repo-core/filter";
4
4
  import { update } from "@classytic/repo-core/update";
@@ -217,12 +217,16 @@ function crudEventType(resource, suffix) {
217
217
  }
218
218
  /** Arc framework lifecycle events — emitted automatically by the framework */
219
219
  const ARC_LIFECYCLE_EVENTS = Object.freeze({
220
+ /** Emitted when a resource plugin is registered */
220
221
  RESOURCE_REGISTERED: "arc.resource.registered",
222
+ /** Emitted when Arc is fully ready (all resources registered, onReady fired) */
221
223
  READY: "arc.ready"
222
224
  });
223
225
  /** Cache-specific event types for observability and external triggers */
224
226
  const CACHE_EVENTS = Object.freeze({
227
+ /** Emitted when a resource's cache version is bumped */
225
228
  VERSION_BUMPED: "arc.cache.version.bumped",
229
+ /** Emitted when a tag version is bumped */
226
230
  TAG_VERSION_BUMPED: "arc.cache.tag.bumped"
227
231
  });
228
232
  //#endregion
@@ -489,7 +493,7 @@ function repositoryAsOutboxStore(repository) {
489
493
  code: error.code
490
494
  } : { message: error.message };
491
495
  const firstFailedAt = current.firstFailedAt ?? now;
492
- await r.findOneAndUpdate(filter, update({ set: {
496
+ if (await r.findOneAndUpdate(filter, update({ set: {
493
497
  status: targetStatus,
494
498
  visibleAt,
495
499
  leaseOwner: null,
@@ -497,7 +501,11 @@ function repositoryAsOutboxStore(repository) {
497
501
  lastFailedAt: now,
498
502
  lastError: errorInfo,
499
503
  firstFailedAt
500
- } }), { returnDocument: "after" });
504
+ } }), { returnDocument: "after" })) return;
505
+ if (options?.consumerId) {
506
+ const after = await safeGetOne(baseFilter);
507
+ if (after && after.leaseOwner !== options.consumerId) throw new OutboxOwnershipError(eventId, options.consumerId, after.leaseOwner);
508
+ }
501
509
  },
502
510
  async getDeadLettered(limit) {
503
511
  return unwrapDocs(await r.getAll({
@@ -1,4 +1,4 @@
1
- import { a as CustomPluginAuthOption, c as RawBodyOptions, d as ResourceLike, f as ResourceModule, i as CustomAuthenticatorOption, l as UnderPressureOptions, n as BetterAuthOption, o as JwtAuthOption, p as loadResources, r as CreateAppOptions, s as MultipartOptions, t as AuthOption, u as LoadResourcesOptions } from "../types-BdA4uMBV.mjs";
1
+ import { a as CustomPluginAuthOption, c as RawBodyOptions, d as ResourceLike, f as ResourceModule, i as CustomAuthenticatorOption, l as UnderPressureOptions, n as BetterAuthOption, o as JwtAuthOption, p as loadResources, r as CreateAppOptions, s as MultipartOptions, t as AuthOption, u as LoadResourcesOptions } from "../types-BH7dEGvU.mjs";
2
2
  import { FastifyInstance } from "fastify";
3
3
 
4
4
  //#region src/factory/createApp.d.ts
@@ -1,4 +1,4 @@
1
- import { a as edgePreset, c as testingPreset, i as developmentPreset, n as createApp, o as getPreset, s as productionPreset, t as ArcFactory } from "../createApp-P1d6rjPy.mjs";
1
+ import { a as edgePreset, c as testingPreset, i as developmentPreset, n as createApp, o as getPreset, s as productionPreset, t as ArcFactory } from "../createApp-BFxtdKy6.mjs";
2
2
  import { t as loadResources } from "../loadResources-CPpkyKfM.mjs";
3
3
  //#region src/factory/edge.ts
4
4
  /**
@@ -1,2 +1,2 @@
1
- import { Cn as beforeUpdate, Sn as beforeDelete, Tn as defineHook, _n as HookSystemOptions, bn as afterUpdate, dn as HookContext, fn as HookHandler, gn as HookSystem, hn as HookRegistration, mn as HookPhase, pn as HookOperation, un as DefineHookOptions, vn as afterCreate, wn as createHookSystem, xn as beforeCreate, yn as afterDelete } from "../index-C_bgx9o4.mjs";
1
+ import { Cn as beforeUpdate, Sn as beforeDelete, Tn as defineHook, _n as HookSystemOptions, bn as afterUpdate, dn as HookContext, fn as HookHandler, gn as HookSystem, hn as HookRegistration, mn as HookPhase, pn as HookOperation, un as DefineHookOptions, vn as afterCreate, wn as createHookSystem, xn as beforeCreate, yn as afterDelete } from "../index-6u4_Gg6G.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 };
@@ -1,4 +1,4 @@
1
- import { jn as RepositoryLike } from "../index-C_bgx9o4.mjs";
1
+ import { jn as RepositoryLike } from "../index-6u4_Gg6G.mjs";
2
2
  import { i as createIdempotencyResult, n as IdempotencyResult, r as IdempotencyStore, t as IdempotencyLock } from "../interface-CkkWm5uR.mjs";
3
3
  import { i as RedisIdempotencyStoreOptions, n as RedisClient } from "../redis-Cm1gnRDf.mjs";
4
4
  import { FastifyPluginAsync } from "fastify";