@classytic/arc 2.1.3 → 2.1.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -326,11 +326,12 @@ import { tracingPlugin } from '@classytic/arc/plugins/tracing';
326
326
  ## CLI
327
327
 
328
328
  ```bash
329
- arc init my-api --mongokit --better-auth --ts # Scaffold project
330
- arc generate resource product # Generate resource files
331
- arc docs ./openapi.json --entry ./dist/index.js # Export OpenAPI
332
- arc introspect --entry ./dist/index.js # Show resources
333
- arc doctor # Health check
329
+ npx @classytic/arc init my-api --mongokit --better-auth --ts # Scaffold project
330
+ npx @classytic/arc generate resource product # Generate resource files
331
+ npx @classytic/arc describe ./dist/index.js # Resource metadata (JSON)
332
+ npx @classytic/arc docs ./openapi.json --entry ./dist/index.js # Export OpenAPI
333
+ npx @classytic/arc introspect --entry ./dist/index.js # Show resources
334
+ npx @classytic/arc doctor # Health check
334
335
  ```
335
336
 
336
337
  ## Subpath Imports
package/bin/arc.js CHANGED
@@ -221,6 +221,7 @@ function parseInitOptions(rawArgs) {
221
221
  const opts = {
222
222
  name: undefined,
223
223
  adapter: undefined,
224
+ auth: undefined,
224
225
  tenant: undefined,
225
226
  typescript: undefined,
226
227
  edge: undefined,
@@ -1,5 +1,5 @@
1
1
  import "../elevation-DGo5shaX.mjs";
2
- import { a as RepositoryLike, i as RelationMetadata, n as DataAdapter, o as SchemaMetadata, r as FieldMetadata, s as ValidationResult, t as AdapterFactory } from "../interface-e9XfSsUV.mjs";
2
+ import { a as RepositoryLike, i as RelationMetadata, n as DataAdapter, o as SchemaMetadata, r as FieldMetadata, s as ValidationResult, t as AdapterFactory } from "../interface-Cb2klgid.mjs";
3
3
  import "../types-RLkFVgaw.mjs";
4
- import { a as PrismaQueryParserOptions, c as MongooseAdapterOptions, i as PrismaQueryParser, l as createMongooseAdapter, n as PrismaAdapterOptions, o as createPrismaAdapter, r as PrismaQueryOptions, s as MongooseAdapter, t as PrismaAdapter } from "../prisma-C3iornoK.mjs";
4
+ import { a as PrismaQueryParserOptions, c as MongooseAdapterOptions, i as PrismaQueryParser, l as createMongooseAdapter, n as PrismaAdapterOptions, o as createPrismaAdapter, r as PrismaQueryOptions, s as MongooseAdapter, t as PrismaAdapter } from "../prisma-DQBSSHAB.mjs";
5
5
  export { type AdapterFactory, type DataAdapter, type FieldMetadata, MongooseAdapter, type MongooseAdapterOptions, PrismaAdapter, type PrismaAdapterOptions, type PrismaQueryOptions, PrismaQueryParser, type PrismaQueryParserOptions, type RelationMetadata, type RepositoryLike, type SchemaMetadata, type ValidationResult, createMongooseAdapter, createPrismaAdapter };
@@ -1,5 +1,5 @@
1
1
  import "../elevation-DGo5shaX.mjs";
2
- import "../interface-e9XfSsUV.mjs";
2
+ import "../interface-Cb2klgid.mjs";
3
3
  import "../types-RLkFVgaw.mjs";
4
4
  import { a as AuditContext, c as AuditStore, i as AuditAction, l as AuditStoreOptions, n as MongoAuditStoreOptions, o as AuditEntry, r as MongoConnection, s as AuditQueryOptions, u as createAuditEntry } from "../mongodb-ClykrfGo.mjs";
5
5
  import { FastifyPluginAsync } from "fastify";
@@ -1,5 +1,5 @@
1
1
  import "../elevation-DGo5shaX.mjs";
2
- import "../interface-e9XfSsUV.mjs";
2
+ import "../interface-Cb2klgid.mjs";
3
3
  import "../types-RLkFVgaw.mjs";
4
4
  import { n as MongoAuditStoreOptions, t as MongoAuditStore } from "../mongodb-ClykrfGo.mjs";
5
5
  export { MongoAuditStore, type MongoAuditStoreOptions };
@@ -1,5 +1,5 @@
1
1
  import "../elevation-DGo5shaX.mjs";
2
- import "../interface-e9XfSsUV.mjs";
2
+ import "../interface-Cb2klgid.mjs";
3
3
  import { t as PermissionCheck } from "../types-RLkFVgaw.mjs";
4
4
  import { AuthHelpers, AuthPluginOptions } from "../types/index.mjs";
5
5
  import { t as ExternalOpenApiPaths } from "../externalPaths-SyPF2tgK.mjs";
@@ -8,6 +8,11 @@
8
8
  * - src/resources/product/product.resource.ts
9
9
  * - src/resources/product/product.controller.ts
10
10
  * - src/resources/product/product.schemas.ts
11
+ *
12
+ * Handles kebab-case names: `arc g r org-profile` generates:
13
+ * - Class names: OrgProfile, OrgProfileRepository
14
+ * - Variable names: orgProfileSchema, orgProfileRepository
15
+ * - File names: org-profile.model.ts, org-profile.repository.ts
11
16
  */
12
17
  /**
13
18
  * Generate command handler
@@ -12,6 +12,11 @@ import { join } from "node:path";
12
12
  * - src/resources/product/product.resource.ts
13
13
  * - src/resources/product/product.controller.ts
14
14
  * - src/resources/product/product.schemas.ts
15
+ *
16
+ * Handles kebab-case names: `arc g r org-profile` generates:
17
+ * - Class names: OrgProfile, OrgProfileRepository
18
+ * - Variable names: orgProfileSchema, orgProfileRepository
19
+ * - File names: org-profile.model.ts, org-profile.repository.ts
15
20
  */
16
21
  function readProjectConfig() {
17
22
  try {
@@ -24,10 +29,25 @@ function readProjectConfig() {
24
29
  function isTypeScriptProject() {
25
30
  return existsSync(join(process.cwd(), "tsconfig.json"));
26
31
  }
32
+ /** Convert kebab-case to PascalCase: org-profile → OrgProfile */
33
+ function toPascalCase(name) {
34
+ return name.split("-").map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join("");
35
+ }
36
+ /** Convert PascalCase to camelCase: OrgProfile → orgProfile */
37
+ function toCamelCase(pascalName) {
38
+ return pascalName.charAt(0).toLowerCase() + pascalName.slice(1);
39
+ }
40
+ /**
41
+ * Template functions accept:
42
+ * - name: PascalCase class name (e.g., OrgProfile)
43
+ * - fileName: kebab-case for file paths (e.g., org-profile)
44
+ */
27
45
  function getTemplates(ts, config = {}) {
28
46
  const isMultiTenant = config.tenant === "multi";
29
47
  return {
30
- model: (name) => `/**
48
+ model: (name, fileName) => {
49
+ const camel = toCamelCase(name);
50
+ return `/**
31
51
  * ${name} Model
32
52
  * Generated by Arc CLI
33
53
  */
@@ -44,7 +64,7 @@ export interface I${name} {
44
64
 
45
65
  export type ${name}Document = HydratedDocument<I${name}>;
46
66
  ` : ""}
47
- const ${name.toLowerCase()}Schema = new Schema${ts ? `<I${name}>` : ""}(
67
+ const ${camel}Schema = new Schema${ts ? `<I${name}>` : ""}(
48
68
  {
49
69
  name: { type: String, required: true, trim: true },
50
70
  description: { type: String, trim: true },
@@ -54,13 +74,16 @@ const ${name.toLowerCase()}Schema = new Schema${ts ? `<I${name}>` : ""}(
54
74
  );
55
75
 
56
76
  // Indexes
57
- ${name.toLowerCase()}Schema.index({ name: 1 });
58
- ${name.toLowerCase()}Schema.index({ isActive: 1 });
77
+ ${camel}Schema.index({ name: 1 });
78
+ ${camel}Schema.index({ isActive: 1 });
59
79
 
60
- const ${name} = mongoose.models.${name} || mongoose.model('${name}', ${name.toLowerCase()}Schema);
80
+ const ${name} = mongoose.models.${name} || mongoose.model('${name}', ${camel}Schema);
61
81
  export default ${name};
62
- `,
63
- repository: (name) => `/**
82
+ `;
83
+ },
84
+ repository: (name, fileName) => {
85
+ const camel = toCamelCase(name);
86
+ return `/**
64
87
  * ${name} Repository
65
88
  * Generated by Arc CLI
66
89
  */
@@ -71,7 +94,7 @@ import {
71
94
  softDeletePlugin,
72
95
  mongoOperationsPlugin,
73
96
  } from '@classytic/mongokit';
74
- import ${name} from './${name.toLowerCase()}.model.js';
97
+ import ${name} from './${fileName}.model.js';
75
98
 
76
99
  class ${name}Repository extends Repository {
77
100
  constructor() {
@@ -90,11 +113,14 @@ class ${name}Repository extends Repository {
90
113
  }
91
114
  }
92
115
 
93
- const ${name.toLowerCase()}Repository = new ${name}Repository();
94
- export default ${name.toLowerCase()}Repository;
116
+ const ${camel}Repository = new ${name}Repository();
117
+ export default ${camel}Repository;
95
118
  export { ${name}Repository };
96
- `,
97
- controller: (name) => `/**
119
+ `;
120
+ },
121
+ controller: (name, fileName) => {
122
+ const camel = toCamelCase(name);
123
+ return `/**
98
124
  * ${name} Controller
99
125
  * Generated by Arc CLI
100
126
  *
@@ -103,27 +129,28 @@ export { ${name}Repository };
103
129
  */
104
130
 
105
131
  import { BaseController } from '@classytic/arc';
106
- import ${name.toLowerCase()}Repository from './${name.toLowerCase()}.repository.js';
132
+ import ${camel}Repository from './${fileName}.repository.js';
107
133
 
108
134
  class ${name}Controller extends BaseController {
109
135
  constructor() {
110
- super(${name.toLowerCase()}Repository, {
111
- resourceName: '${name.toLowerCase()}',
136
+ super(${camel}Repository, {
137
+ resourceName: '${fileName}',
112
138
  });
113
139
  }
114
140
 
115
141
  // Add custom controller methods here
116
142
  }
117
143
 
118
- const ${name.toLowerCase()}Controller = new ${name}Controller();
119
- export default ${name.toLowerCase()}Controller;
120
- `,
121
- schemas: (name) => `/**
144
+ const ${camel}Controller = new ${name}Controller();
145
+ export default ${camel}Controller;
146
+ `;
147
+ },
148
+ schemas: (name, fileName) => `/**
122
149
  * ${name} Schemas
123
150
  * Generated by Arc CLI
124
151
  */
125
152
 
126
- import ${name} from './${name.toLowerCase()}.model.js';
153
+ import ${name} from './${fileName}.model.js';
127
154
  import { buildCrudSchemasFromModel } from '@classytic/mongokit/utils';
128
155
 
129
156
  /**
@@ -145,7 +172,8 @@ const crudSchemas = buildCrudSchemasFromModel(${name}, {
145
172
 
146
173
  export default crudSchemas;
147
174
  `,
148
- resource: (name) => {
175
+ resource: (name, fileName) => {
176
+ const camel = toCamelCase(name);
149
177
  const useMongoKit = config.adapter === "mongokit" || !config.adapter;
150
178
  const queryParserImport = useMongoKit ? `\nimport { QueryParser } from '@classytic/mongokit';\n\nconst queryParser = new QueryParser();\n` : "";
151
179
  const queryParserConfig = useMongoKit ? `\n queryParser,` : "";
@@ -155,24 +183,24 @@ export default crudSchemas;
155
183
  */
156
184
 
157
185
  import { defineResource, createMongooseAdapter } from '@classytic/arc';
158
- import { requireOrgMembership, requireOrgRole } from '@classytic/arc/permissions';
159
- import ${name}${ts ? `, { type I${name} }` : ""} from './${name.toLowerCase()}.model.js';
160
- import ${name.toLowerCase()}Repository from './${name.toLowerCase()}.repository.js';${queryParserImport}
186
+ import { requireAuth, requireRoles } from '@classytic/arc/permissions';
187
+ import ${name}${ts ? `, { type I${name} }` : ""} from './${fileName}.model.js';
188
+ import ${camel}Repository from './${fileName}.repository.js';${queryParserImport}
161
189
 
162
- const ${name.toLowerCase()}Resource = defineResource${ts ? `<I${name}>` : ""}({
163
- name: '${name.toLowerCase()}',
164
- adapter: createMongooseAdapter(${name}, ${name.toLowerCase()}Repository),${queryParserConfig}
190
+ const ${camel}Resource = defineResource${ts ? `<I${name}>` : ""}({
191
+ name: '${fileName}',
192
+ adapter: createMongooseAdapter(${name}, ${camel}Repository),${queryParserConfig}
165
193
  presets: ['softDelete'],
166
194
  permissions: {
167
- list: requireOrgMembership(),
168
- get: requireOrgMembership(),
169
- create: requireOrgRole('admin'),
170
- update: requireOrgRole('admin'),
171
- delete: requireOrgRole('admin'),
195
+ list: requireAuth(),
196
+ get: requireAuth(),
197
+ create: requireRoles(['admin']),
198
+ update: requireRoles(['admin']),
199
+ delete: requireRoles(['admin']),
172
200
  },
173
201
  });
174
202
 
175
- export default ${name.toLowerCase()}Resource;
203
+ export default ${camel}Resource;
176
204
  ` : `/**
177
205
  * ${name} Resource
178
206
  * Generated by Arc CLI
@@ -180,12 +208,12 @@ export default ${name.toLowerCase()}Resource;
180
208
 
181
209
  import { defineResource, createMongooseAdapter } from '@classytic/arc';
182
210
  import { requireAuth, requireRoles } from '@classytic/arc/permissions';
183
- import ${name}${ts ? `, { type I${name} }` : ""} from './${name.toLowerCase()}.model.js';
184
- import ${name.toLowerCase()}Repository from './${name.toLowerCase()}.repository.js';${queryParserImport}
211
+ import ${name}${ts ? `, { type I${name} }` : ""} from './${fileName}.model.js';
212
+ import ${camel}Repository from './${fileName}.repository.js';${queryParserImport}
185
213
 
186
- const ${name.toLowerCase()}Resource = defineResource${ts ? `<I${name}>` : ""}({
187
- name: '${name.toLowerCase()}',
188
- adapter: createMongooseAdapter(${name}, ${name.toLowerCase()}Repository),${queryParserConfig}
214
+ const ${camel}Resource = defineResource${ts ? `<I${name}>` : ""}({
215
+ name: '${fileName}',
216
+ adapter: createMongooseAdapter(${name}, ${camel}Repository),${queryParserConfig}
189
217
  presets: ['softDelete'],
190
218
  permissions: {
191
219
  list: requireAuth(),
@@ -196,10 +224,12 @@ const ${name.toLowerCase()}Resource = defineResource${ts ? `<I${name}>` : ""}({
196
224
  },
197
225
  });
198
226
 
199
- export default ${name.toLowerCase()}Resource;
227
+ export default ${camel}Resource;
200
228
  `;
201
229
  },
202
- test: (name) => `/**
230
+ test: (name, fileName) => {
231
+ const camel = toCamelCase(name);
232
+ return `/**
203
233
  * ${name} Tests
204
234
  * Generated by Arc CLI
205
235
  */
@@ -207,7 +237,7 @@ export default ${name.toLowerCase()}Resource;
207
237
  import { describe, it, expect, beforeAll, afterAll } from 'vitest';
208
238
  import mongoose from 'mongoose';
209
239
  import { createMinimalTestApp } from '@classytic/arc/testing';
210
- ${ts ? "import type { FastifyInstance } from 'fastify';\n" : ""}import ${name.toLowerCase()}Resource from '../src/resources/${name.toLowerCase()}/${name.toLowerCase()}.resource.js';
240
+ ${ts ? "import type { FastifyInstance } from 'fastify';\n" : ""}import ${camel}Resource from '../src/resources/${fileName}/${fileName}.resource.js';
211
241
 
212
242
  describe('${name} Resource', () => {
213
243
  let app${ts ? ": FastifyInstance" : ""};
@@ -217,7 +247,7 @@ describe('${name} Resource', () => {
217
247
  await mongoose.connect(testDbUri);
218
248
 
219
249
  app = createMinimalTestApp();
220
- await app.register(${name.toLowerCase()}Resource.toPlugin());
250
+ await app.register(${camel}Resource.toPlugin());
221
251
  await app.ready();
222
252
  });
223
253
 
@@ -226,11 +256,11 @@ describe('${name} Resource', () => {
226
256
  await mongoose.connection.close();
227
257
  });
228
258
 
229
- describe('GET /${pluralize(name.toLowerCase())}', () => {
259
+ describe('GET /${pluralize(fileName)}', () => {
230
260
  it('should return a list', async () => {
231
261
  const response = await app.inject({
232
262
  method: 'GET',
233
- url: '/${pluralize(name.toLowerCase())}',
263
+ url: '/${pluralize(fileName)}',
234
264
  });
235
265
 
236
266
  expect(response.statusCode).toBe(200);
@@ -239,7 +269,8 @@ describe('${name} Resource', () => {
239
269
  });
240
270
  });
241
271
  });
242
- `
272
+ `;
273
+ }
243
274
  };
244
275
  }
245
276
  /**
@@ -249,7 +280,7 @@ async function generate(type, args) {
249
280
  if (!type) throw new Error("Missing type argument\nUsage: arc generate <resource|controller|model|repository|schemas> <name>");
250
281
  const [name] = args;
251
282
  if (!name) throw new Error("Missing name argument\nUsage: arc generate <type> <name>\nExample: arc generate resource product");
252
- const capitalizedName = name.charAt(0).toUpperCase() + name.slice(1);
283
+ const capitalizedName = toPascalCase(name);
253
284
  const lowerName = name.toLowerCase();
254
285
  const projectConfig = readProjectConfig();
255
286
  const ts = projectConfig.typescript ?? isTypeScriptProject();
@@ -290,9 +321,9 @@ async function generateResource(name, lowerName, resourcePath, templates, ext) {
290
321
  console.log(` + Created: src/resources/${lowerName}/`);
291
322
  }
292
323
  const files = {
293
- [`${lowerName}.model.${ext}`]: templates.model(name),
294
- [`${lowerName}.repository.${ext}`]: templates.repository(name),
295
- [`${lowerName}.resource.${ext}`]: templates.resource(name)
324
+ [`${lowerName}.model.${ext}`]: templates.model(name, lowerName),
325
+ [`${lowerName}.repository.${ext}`]: templates.repository(name, lowerName),
326
+ [`${lowerName}.resource.${ext}`]: templates.resource(name, lowerName)
296
327
  };
297
328
  for (const [filename, content] of Object.entries(files)) {
298
329
  const filepath = join(resourcePath, filename);
@@ -306,9 +337,10 @@ async function generateResource(name, lowerName, resourcePath, templates, ext) {
306
337
  if (!existsSync(testsDir)) mkdirSync(testsDir, { recursive: true });
307
338
  const testPath = join(testsDir, `${lowerName}.test.${ext}`);
308
339
  if (!existsSync(testPath)) {
309
- writeFileSync(testPath, templates.test(name));
340
+ writeFileSync(testPath, templates.test(name, lowerName));
310
341
  console.log(` + Created: tests/${lowerName}.test.${ext}`);
311
342
  }
343
+ const camel = toCamelCase(name);
312
344
  const isMultiTenant = readProjectConfig().tenant === "multi";
313
345
  console.log(`
314
346
  ╔═══════════════════════════════════════════════════════════════╗
@@ -318,19 +350,19 @@ async function generateResource(name, lowerName, resourcePath, templates, ext) {
318
350
  Next steps:
319
351
 
320
352
  1. Register in src/resources/index.${ext}:
321
- import ${lowerName}Resource from './${lowerName}/${lowerName}.resource.js';
353
+ import ${camel}Resource from './${lowerName}/${lowerName}.resource.js';
322
354
 
323
355
  export const resources = [
324
356
  // ... existing resources
325
- ${lowerName}Resource,
357
+ ${camel}Resource,
326
358
  ];
327
359
 
328
360
  2. Customize the model schema in:
329
361
  src/resources/${lowerName}/${lowerName}.model.${ext}
330
362
 
331
363
  3. Adjust permissions in ${lowerName}.resource.${ext}:
332
- ${isMultiTenant ? ` - requireOrgMembership() → any org member
333
- - requireOrgRole('admin') → specific org roles` : ` - requireAuth() → any authenticated user
364
+ ${isMultiTenant ? ` - requireAuth() → any authenticated user
365
+ - requireRoles(['admin']) → specific platform roles` : ` - requireAuth() → any authenticated user
334
366
  - requireRoles(['admin']) → specific platform roles`}
335
367
 
336
368
  4. Run tests:
@@ -349,7 +381,7 @@ async function generateFile(name, lowerName, resourcePath, fileType, template, e
349
381
  const filename = `${lowerName}.${fileType}.${ext}`;
350
382
  const filepath = join(resourcePath, filename);
351
383
  if (existsSync(filepath)) throw new Error(`${filename} already exists. Remove it first or use a different name.`);
352
- writeFileSync(filepath, template(name));
384
+ writeFileSync(filepath, template(name, lowerName));
353
385
  console.log(` + Created: ${filename}`);
354
386
  }
355
387
 
@@ -260,23 +260,20 @@ function packageJsonTemplate(config) {
260
260
  test: "vitest run",
261
261
  "test:watch": "vitest"
262
262
  };
263
- const imports = config.typescript ? {
264
- "#config/*": "./dist/config/*",
265
- "#shared/*": "./dist/shared/*",
266
- "#resources/*": "./dist/resources/*",
267
- "#plugins/*": "./dist/plugins/*"
268
- } : {
269
- "#config/*": "./src/config/*",
270
- "#shared/*": "./src/shared/*",
271
- "#resources/*": "./src/resources/*",
272
- "#plugins/*": "./src/plugins/*"
273
- };
274
263
  return JSON.stringify({
275
264
  name: config.name,
276
265
  version: "1.0.0",
277
266
  type: "module",
278
267
  main: config.typescript ? "dist/index.js" : "src/index.js",
279
- imports,
268
+ imports: {
269
+ "#config/*": "./src/config/*",
270
+ "#shared/*": "./src/shared/*",
271
+ "#resources/*": "./src/resources/*",
272
+ "#plugins/*": "./src/plugins/*",
273
+ "#services/*": "./src/services/*",
274
+ "#lib/*": "./src/lib/*",
275
+ "#utils/*": "./src/utils/*"
276
+ },
280
277
  scripts,
281
278
  engines: { node: ">=20" }
282
279
  }, null, 2);
@@ -1,5 +1,5 @@
1
1
  import "../elevation-DGo5shaX.mjs";
2
- import { E as defineResource, T as ResourceDefinition, c as BaseController, d as QueryResolverConfig, f as BodySanitizer, h as AccessControlConfig, l as BaseControllerOptions, m as AccessControl, p as BodySanitizerConfig, u as QueryResolver } from "../interface-e9XfSsUV.mjs";
2
+ import { E as defineResource, T as ResourceDefinition, c as BaseController, d as QueryResolverConfig, f as BodySanitizer, h as AccessControlConfig, l as BaseControllerOptions, m as AccessControl, p as BodySanitizerConfig, u as QueryResolver } from "../interface-Cb2klgid.mjs";
3
3
  import "../types-RLkFVgaw.mjs";
4
- import { A as createCrudRouter, C as MutationOperation, D as ActionRouterConfig, E as ActionHandler, O as IdempotencyService, S as MUTATION_OPERATIONS, T as SYSTEM_FIELDS, _ as HookOperation, a as getControllerScope, b as MAX_REGEX_LENGTH, c as CrudOperation, d as DEFAULT_MAX_LIMIT, f as DEFAULT_SORT, g as HOOK_PHASES, h as HOOK_OPERATIONS, i as getControllerContext, j as createPermissionMiddleware, k as createActionRouter, l as DEFAULT_ID_FIELD, m as DEFAULT_UPDATE_METHOD, n as createFastifyHandler, o as sendControllerResponse, p as DEFAULT_TENANT_FIELD, r as createRequestContext, s as CRUD_OPERATIONS, t as createCrudHandlers, u as DEFAULT_LIMIT, v as HookPhase, w as RESERVED_QUERY_PARAMS, x as MAX_SEARCH_LENGTH, y as MAX_FILTER_DEPTH } from "../fastifyAdapter-C8DlE0YH.mjs";
4
+ import { A as createCrudRouter, C as MutationOperation, D as ActionRouterConfig, E as ActionHandler, O as IdempotencyService, S as MUTATION_OPERATIONS, T as SYSTEM_FIELDS, _ as HookOperation, a as getControllerScope, b as MAX_REGEX_LENGTH, c as CrudOperation, d as DEFAULT_MAX_LIMIT, f as DEFAULT_SORT, g as HOOK_PHASES, h as HOOK_OPERATIONS, i as getControllerContext, j as createPermissionMiddleware, k as createActionRouter, l as DEFAULT_ID_FIELD, m as DEFAULT_UPDATE_METHOD, n as createFastifyHandler, o as sendControllerResponse, p as DEFAULT_TENANT_FIELD, r as createRequestContext, s as CRUD_OPERATIONS, t as createCrudHandlers, u as DEFAULT_LIMIT, v as HookPhase, w as RESERVED_QUERY_PARAMS, x as MAX_SEARCH_LENGTH, y as MAX_FILTER_DEPTH } from "../fastifyAdapter-sGkvUvf5.mjs";
5
5
  export { AccessControl, type AccessControlConfig, type ActionHandler, type ActionRouterConfig, BaseController, type BaseControllerOptions, BodySanitizer, type BodySanitizerConfig, 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, type IdempotencyService, MAX_FILTER_DEPTH, MAX_REGEX_LENGTH, MAX_SEARCH_LENGTH, MUTATION_OPERATIONS, MutationOperation, QueryResolver, type QueryResolverConfig, RESERVED_QUERY_PARAMS, ResourceDefinition, SYSTEM_FIELDS, createActionRouter, createCrudHandlers, createCrudRouter, createFastifyHandler, createPermissionMiddleware, createRequestContext, defineResource, getControllerContext, getControllerScope, sendControllerResponse };
@@ -1,4 +1,4 @@
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-DdXFXQtN.mjs";
2
- import { _ as QueryResolver, c as createPermissionMiddleware, d as createFastifyHandler, f as createRequestContext, g as BaseController, h as sendControllerResponse, m as getControllerScope, n as defineResource, o as createActionRouter, p as getControllerContext, s as createCrudRouter, t as ResourceDefinition, u as createCrudHandlers, v as BodySanitizer, y as AccessControl } from "../defineResource-PXzSJ15_.mjs";
2
+ import { _ as QueryResolver, c as createPermissionMiddleware, d as createFastifyHandler, f as createRequestContext, g as BaseController, h as sendControllerResponse, m as getControllerScope, n as defineResource, o as createActionRouter, p as getControllerContext, s as createCrudRouter, t as ResourceDefinition, u as createCrudHandlers, v as BodySanitizer, y as AccessControl } from "../defineResource-DZVbwsFb.mjs";
3
3
 
4
4
  export { AccessControl, BaseController, BodySanitizer, 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, createActionRouter, createCrudHandlers, createCrudRouter, createFastifyHandler, createPermissionMiddleware, createRequestContext, defineResource, getControllerContext, getControllerScope, sendControllerResponse };
@@ -41,7 +41,7 @@ var AccessControl = class AccessControl {
41
41
  if (policyFilters) Object.assign(filter, policyFilters);
42
42
  const scope = arcContext?._scope;
43
43
  const orgId = scope ? getOrgId(scope) : void 0;
44
- if (orgId && !policyFilters?.[this.tenantField]) filter[this.tenantField] = orgId;
44
+ if (this.tenantField && orgId && !policyFilters?.[this.tenantField]) filter[this.tenantField] = orgId;
45
45
  return filter;
46
46
  }
47
47
  /**
@@ -65,6 +65,7 @@ var AccessControl = class AccessControl {
65
65
  * unscoped records from leaking across tenants.
66
66
  */
67
67
  checkOrgScope(item, arcContext) {
68
+ if (!this.tenantField) return true;
68
69
  const scope = arcContext?._scope;
69
70
  const orgId = scope ? getOrgId(scope) : void 0;
70
71
  if (!item || !orgId) return true;
@@ -259,7 +260,7 @@ var QueryResolver = class {
259
260
  this.defaultLimit = config.defaultLimit ?? DEFAULT_LIMIT;
260
261
  this.defaultSort = config.defaultSort ?? DEFAULT_SORT;
261
262
  this.schemaOptions = config.schemaOptions ?? {};
262
- this.tenantField = config.tenantField ?? DEFAULT_TENANT_FIELD;
263
+ this.tenantField = config.tenantField !== void 0 ? config.tenantField : DEFAULT_TENANT_FIELD;
263
264
  }
264
265
  /**
265
266
  * Resolve a request into parsed query options -- ONE parse per request.
@@ -278,7 +279,7 @@ var QueryResolver = class {
278
279
  if (policyFilters) Object.assign(filters, policyFilters);
279
280
  const scope = arcContext?._scope;
280
281
  const orgId = scope ? getOrgId(scope) : void 0;
281
- if (orgId && !policyFilters?.[this.tenantField]) filters[this.tenantField] = orgId;
282
+ if (this.tenantField && orgId && !policyFilters?.[this.tenantField]) filters[this.tenantField] = orgId;
282
283
  return {
283
284
  page,
284
285
  limit,
@@ -371,7 +372,7 @@ var BaseController = class {
371
372
  this.defaultLimit = options.defaultLimit ?? DEFAULT_LIMIT;
372
373
  this.defaultSort = options.defaultSort ?? DEFAULT_SORT;
373
374
  this.resourceName = options.resourceName;
374
- this.tenantField = options.tenantField ?? DEFAULT_TENANT_FIELD;
375
+ this.tenantField = options.tenantField !== void 0 ? options.tenantField : DEFAULT_TENANT_FIELD;
375
376
  this.idField = options.idField ?? DEFAULT_ID_FIELD;
376
377
  this._matchesFilter = options.matchesFilter;
377
378
  if (options.cache) this._cacheConfig = options.cache;
@@ -570,7 +571,7 @@ var BaseController = class {
570
571
  const data = this.bodySanitizer.sanitize(req.body ?? {}, "create", req, arcContext);
571
572
  const scope = arcContext?._scope;
572
573
  const createOrgId = scope ? getOrgId(scope) : void 0;
573
- if (createOrgId) data[this.tenantField] = createOrgId;
574
+ if (this.tenantField && createOrgId) data[this.tenantField] = createOrgId;
574
575
  const userId = getUserId(req.user);
575
576
  if (userId) data.createdBy = userId;
576
577
  const hooks = this.getHooks(req);
@@ -1571,29 +1572,6 @@ function createActionRouter(fastify, config) {
1571
1572
  type: "object",
1572
1573
  properties: bodyProperties,
1573
1574
  required: ["action"]
1574
- },
1575
- response: {
1576
- 200: {
1577
- type: "object",
1578
- properties: {
1579
- success: { type: "boolean" },
1580
- data: { type: "object" }
1581
- }
1582
- },
1583
- 400: {
1584
- type: "object",
1585
- properties: {
1586
- success: { type: "boolean" },
1587
- error: { type: "string" }
1588
- }
1589
- },
1590
- 403: {
1591
- type: "object",
1592
- properties: {
1593
- success: { type: "boolean" },
1594
- error: { type: "string" }
1595
- }
1596
- }
1597
1575
  }
1598
1576
  };
1599
1577
  const preHandler = [];
@@ -1,5 +1,5 @@
1
1
  import "../elevation-DGo5shaX.mjs";
2
- import "../interface-e9XfSsUV.mjs";
2
+ import "../interface-Cb2klgid.mjs";
3
3
  import "../types-RLkFVgaw.mjs";
4
4
  import { RegistryEntry } from "../types/index.mjs";
5
5
  import { t as ExternalOpenApiPaths } from "../externalPaths-SyPF2tgK.mjs";
@@ -1,5 +1,5 @@
1
1
  import "../elevation-DGo5shaX.mjs";
2
- import "../interface-e9XfSsUV.mjs";
2
+ import "../interface-Cb2klgid.mjs";
3
3
  import "../types-RLkFVgaw.mjs";
4
4
  import "../queryCachePlugin-Q6SYuHZ6.mjs";
5
5
  import "../eventPlugin-H6wDDjGO.mjs";
@@ -1,5 +1,5 @@
1
1
  import { s as RequestScope } from "./elevation-DGo5shaX.mjs";
2
- import { b as IControllerResponse, x as IRequestContext, y as IController } from "./interface-e9XfSsUV.mjs";
2
+ import { b as IControllerResponse, x as IRequestContext, y as IController } from "./interface-Cb2klgid.mjs";
3
3
  import { t as PermissionCheck } from "./types-RLkFVgaw.mjs";
4
4
  import { CrudController, CrudRouterOptions, FastifyWithDecorators, RequestContext, RequestWithExtras } from "./types/index.mjs";
5
5
  import { FastifyInstance, FastifyReply, FastifyRequest, RouteHandlerMethod } from "fastify";
@@ -1,4 +1,4 @@
1
1
  import "../elevation-DGo5shaX.mjs";
2
- import { $ as beforeUpdate, B as DefineHookOptions, G as HookRegistration, H as HookHandler, J as afterCreate, K as HookSystem, Q as beforeDelete, U as HookOperation, V as HookContext, W as HookPhase, X as afterUpdate, Y as afterDelete, Z as beforeCreate, et as createHookSystem, q as HookSystemOptions, tt as defineHook } from "../interface-e9XfSsUV.mjs";
2
+ import { $ as beforeUpdate, B as DefineHookOptions, G as HookRegistration, H as HookHandler, J as afterCreate, K as HookSystem, Q as beforeDelete, U as HookOperation, V as HookContext, W as HookPhase, X as afterUpdate, Y as afterDelete, Z as beforeCreate, et as createHookSystem, q as HookSystemOptions, tt as defineHook } from "../interface-Cb2klgid.mjs";
3
3
  import "../types-RLkFVgaw.mjs";
4
4
  export { type DefineHookOptions, type HookContext, type HookHandler, type HookOperation, type HookPhase, type HookRegistration, HookSystem, type HookSystemOptions, afterCreate, afterDelete, afterUpdate, beforeCreate, beforeDelete, beforeUpdate, createHookSystem, defineHook };
package/dist/index.d.mts CHANGED
@@ -1,11 +1,11 @@
1
1
  import "./elevation-DGo5shaX.mjs";
2
- import { D as CrudRepository, E as defineResource, F as OperationFilter, I as PipelineConfig, L as PipelineContext, M as Guard, N as Interceptor, P as NextFunction, R as PipelineStep, S as RouteHandler, T as ResourceDefinition, _ as ControllerLike, a as RepositoryLike, b as IControllerResponse, c as BaseController, i as RelationMetadata, j as QueryOptions, k as PaginatedResult, l as BaseControllerOptions, n as DataAdapter, o as SchemaMetadata, r as FieldMetadata, s as ValidationResult, x as IRequestContext, y as IController, z as Transform } from "./interface-e9XfSsUV.mjs";
2
+ import { D as CrudRepository, E as defineResource, F as OperationFilter, I as PipelineConfig, L as PipelineContext, M as Guard, N as Interceptor, P as NextFunction, R as PipelineStep, S as RouteHandler, T as ResourceDefinition, _ as ControllerLike, a as RepositoryLike, b as IControllerResponse, c as BaseController, i as RelationMetadata, j as QueryOptions, k as PaginatedResult, l as BaseControllerOptions, n as DataAdapter, o as SchemaMetadata, r as FieldMetadata, s as ValidationResult, x as IRequestContext, y as IController, z as Transform } from "./interface-Cb2klgid.mjs";
3
3
  import { a as applyFieldWritePermissions, i as applyFieldReadPermissions, n as FieldPermissionMap, o as fields, t as FieldPermission } from "./fields-Bi_AVKSo.mjs";
4
4
  import { i as UserBase, n as PermissionContext, r as PermissionResult, t as PermissionCheck } from "./types-RLkFVgaw.mjs";
5
5
  import { AdditionalRoute, AnyRecord, ApiResponse, ArcInternalMetadata, AuthPluginOptions, ConfigError, CrudController, CrudRouteKey, CrudRouterOptions, CrudSchemas, EventDefinition, FastifyRequestExtras, FastifyWithAuth, FastifyWithDecorators, FieldRule, GracefulShutdownOptions, HealthCheck, HealthOptions, InferAdapterDoc, InferDocType, InferResourceDoc, IntrospectionData, IntrospectionPluginOptions, JWTPayload, MiddlewareConfig, MiddlewareHandler, OwnershipCheck, PresetFunction, PresetResult, RateLimitConfig, RegistryEntry, RegistryStats, RequestContext, RequestIdOptions, RequestWithExtras, ResourceConfig, ResourceMetadata, RouteHandlerMethod, RouteSchemaOptions, ServiceContext, TypedController, TypedRepository, TypedResourceConfig, UserOrganization, ValidateOptions, ValidationResult as ValidationResult$1 } from "./types/index.mjs";
6
- import { c as MongooseAdapterOptions, l as createMongooseAdapter, n as PrismaAdapterOptions, o as createPrismaAdapter, s as MongooseAdapter, t as PrismaAdapter } from "./prisma-C3iornoK.mjs";
6
+ import { c as MongooseAdapterOptions, l as createMongooseAdapter, n as PrismaAdapterOptions, o as createPrismaAdapter, s as MongooseAdapter, t as PrismaAdapter } from "./prisma-DQBSSHAB.mjs";
7
7
  import "./adapters/index.mjs";
8
- import { C as MutationOperation, S as MUTATION_OPERATIONS, T as SYSTEM_FIELDS, _ as HookOperation, a as getControllerScope, b as MAX_REGEX_LENGTH, c as CrudOperation, d as DEFAULT_MAX_LIMIT, f as DEFAULT_SORT, g as HOOK_PHASES, h as HOOK_OPERATIONS, l as DEFAULT_ID_FIELD, m as DEFAULT_UPDATE_METHOD, p as DEFAULT_TENANT_FIELD, s as CRUD_OPERATIONS, u as DEFAULT_LIMIT, v as HookPhase, w as RESERVED_QUERY_PARAMS, x as MAX_SEARCH_LENGTH, y as MAX_FILTER_DEPTH } from "./fastifyAdapter-C8DlE0YH.mjs";
8
+ import { C as MutationOperation, S as MUTATION_OPERATIONS, T as SYSTEM_FIELDS, _ as HookOperation, a as getControllerScope, b as MAX_REGEX_LENGTH, c as CrudOperation, d as DEFAULT_MAX_LIMIT, f as DEFAULT_SORT, g as HOOK_PHASES, h as HOOK_OPERATIONS, l as DEFAULT_ID_FIELD, m as DEFAULT_UPDATE_METHOD, p as DEFAULT_TENANT_FIELD, s as CRUD_OPERATIONS, u as DEFAULT_LIMIT, v as HookPhase, w as RESERVED_QUERY_PARAMS, x as MAX_SEARCH_LENGTH, y as MAX_FILTER_DEPTH } from "./fastifyAdapter-sGkvUvf5.mjs";
9
9
  import "./core/index.mjs";
10
10
  import { a as NotFoundError, d as ValidationError, i as ForbiddenError, t as ArcError, u as UnauthorizedError } from "./errors-DAWRdiYP.mjs";
11
11
  import { a as presets_d_exports, c as readOnly, i as ownerWithAdminBypass, n as authenticated, o as publicRead, r as fullPublic, s as publicReadAdminWrite, t as adminOnly } from "./presets-BTeYbw7h.mjs";
package/dist/index.mjs CHANGED
@@ -1,6 +1,6 @@
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-DdXFXQtN.mjs";
2
2
  import { a as createMongooseAdapter, i as MongooseAdapter, r as createPrismaAdapter, t as PrismaAdapter } from "./prisma-DJbMt3yf.mjs";
3
- import { a as validateResourceConfig, g as BaseController, i as formatValidationErrors, l as pipe, m as getControllerScope, n as defineResource, r as assertValidConfig, t as ResourceDefinition } from "./defineResource-PXzSJ15_.mjs";
3
+ import { a as validateResourceConfig, g as BaseController, i as formatValidationErrors, l as pipe, m as getControllerScope, n as defineResource, r as assertValidConfig, t as ResourceDefinition } from "./defineResource-DZVbwsFb.mjs";
4
4
  import { n as applyFieldWritePermissions, r as fields, t as applyFieldReadPermissions } from "./fields-CTd_CrKr.mjs";
5
5
  import { i as NotFoundError, l as UnauthorizedError, r as ForbiddenError, t as ArcError, u as ValidationError } from "./errors-DBANPbGr.mjs";
6
6
  import { t as requestContext } from "./requestContext-xi6OKBL-.mjs";
@@ -759,8 +759,8 @@ interface ControllerLike {
759
759
  //#endregion
760
760
  //#region src/core/AccessControl.d.ts
761
761
  interface AccessControlConfig {
762
- /** Field name used for multi-tenant scoping (default: 'organizationId') */
763
- tenantField: string;
762
+ /** Field name used for multi-tenant scoping (default: 'organizationId'). Set to `false` to disable org filtering. */
763
+ tenantField: string | false;
764
764
  /** Primary key field name (default: '_id') */
765
765
  idField: string;
766
766
  /**
@@ -876,8 +876,8 @@ interface QueryResolverConfig {
876
876
  defaultSort?: string;
877
877
  /** Schema options for field sanitization */
878
878
  schemaOptions?: RouteSchemaOptions;
879
- /** Field name used for multi-tenant scoping (default: 'organizationId') */
880
- tenantField?: string;
879
+ /** Field name used for multi-tenant scoping (default: 'organizationId'). Set to `false` to disable. */
880
+ tenantField?: string | false;
881
881
  }
882
882
  declare class QueryResolver {
883
883
  private queryParser;
@@ -926,8 +926,9 @@ interface BaseControllerOptions {
926
926
  /**
927
927
  * Field name used for multi-tenant scoping (default: 'organizationId').
928
928
  * Override to match your schema: 'workspaceId', 'tenantId', 'teamId', etc.
929
+ * Set to `false` to disable org filtering for platform-universal resources.
929
930
  */
930
- tenantField?: string;
931
+ tenantField?: string | false;
931
932
  /**
932
933
  * Primary key field name (default: '_id').
933
934
  * Override for non-MongoDB adapters (e.g., 'id' for SQL databases).
@@ -965,7 +966,7 @@ declare class BaseController<TDoc = AnyRecord, TRepository extends RepositoryLik
965
966
  protected defaultLimit: number;
966
967
  protected defaultSort: string;
967
968
  protected resourceName?: string;
968
- protected tenantField: string;
969
+ protected tenantField: string | false;
969
970
  protected idField: string;
970
971
  /** Composable access control (ID filtering, policy checks, org scope, ownership) */
971
972
  readonly accessControl: AccessControl;
@@ -1,5 +1,5 @@
1
1
  import "../elevation-DGo5shaX.mjs";
2
- import { S as RouteHandler } from "../interface-e9XfSsUV.mjs";
2
+ import { S as RouteHandler } from "../interface-Cb2klgid.mjs";
3
3
  import { i as UserBase } from "../types-RLkFVgaw.mjs";
4
4
  import "../types/index.mjs";
5
5
  import { InvitationAdapter, InvitationDoc, MemberDoc, OrgAdapter, OrgDoc, OrgPermissionStatement, OrgRole, OrganizationPluginOptions } from "./types.mjs";
@@ -1,5 +1,5 @@
1
1
  import "../elevation-DGo5shaX.mjs";
2
- import { K as HookSystem, w as ResourceRegistry } from "../interface-e9XfSsUV.mjs";
2
+ import { K as HookSystem, w as ResourceRegistry } from "../interface-Cb2klgid.mjs";
3
3
  import "../types-RLkFVgaw.mjs";
4
4
  import { AdditionalRoute, AnyRecord, MiddlewareConfig, PresetHook, RouteSchemaOptions } from "../types/index.mjs";
5
5
  import { t as ExternalOpenApiPaths } from "../externalPaths-SyPF2tgK.mjs";
@@ -1,5 +1,5 @@
1
1
  import "../elevation-DGo5shaX.mjs";
2
- import { b as IControllerResponse, k as PaginatedResult, x as IRequestContext } from "../interface-e9XfSsUV.mjs";
2
+ import { b as IControllerResponse, k as PaginatedResult, x as IRequestContext } from "../interface-Cb2klgid.mjs";
3
3
  import "../types-RLkFVgaw.mjs";
4
4
  import { AnyRecord, PresetResult, ResourceConfig } from "../types/index.mjs";
5
5
  import multiTenantPreset, { MultiTenantOptions } from "./multiTenant.mjs";
@@ -1,5 +1,5 @@
1
1
  import "../elevation-DGo5shaX.mjs";
2
- import "../interface-e9XfSsUV.mjs";
2
+ import "../interface-Cb2klgid.mjs";
3
3
  import "../types-RLkFVgaw.mjs";
4
4
  import { CrudRouteKey, PresetResult } from "../types/index.mjs";
5
5
 
@@ -1,4 +1,4 @@
1
- import { D as CrudRepository, a as RepositoryLike, n as DataAdapter, o as SchemaMetadata, s as ValidationResult } from "./interface-e9XfSsUV.mjs";
1
+ import { D as CrudRepository, a as RepositoryLike, n as DataAdapter, o as SchemaMetadata, s as ValidationResult } from "./interface-Cb2klgid.mjs";
2
2
  import { OpenApiSchemas, ParsedQuery, QueryParserInterface, RouteSchemaOptions } from "./types/index.mjs";
3
3
  import { Model } from "mongoose";
4
4
 
@@ -1,5 +1,5 @@
1
1
  import "../elevation-DGo5shaX.mjs";
2
- import { C as RegisterOptions, w as ResourceRegistry } from "../interface-e9XfSsUV.mjs";
2
+ import { C as RegisterOptions, w as ResourceRegistry } from "../interface-Cb2klgid.mjs";
3
3
  import "../types-RLkFVgaw.mjs";
4
4
  import { IntrospectionPluginOptions } from "../types/index.mjs";
5
5
  import { FastifyPluginAsync } from "fastify";
@@ -1,5 +1,5 @@
1
1
  import "../elevation-DGo5shaX.mjs";
2
- import { D as CrudRepository, T as ResourceDefinition } from "../interface-e9XfSsUV.mjs";
2
+ import { D as CrudRepository, T as ResourceDefinition } from "../interface-Cb2klgid.mjs";
3
3
  import "../types-RLkFVgaw.mjs";
4
4
  import { AnyRecord } from "../types/index.mjs";
5
5
  import "../queryCachePlugin-Q6SYuHZ6.mjs";
@@ -1,5 +1,5 @@
1
1
  import { a as AUTHENTICATED_SCOPE, c as getOrgId, d as hasOrgAccess, f as isAuthenticated, l as getOrgRoles, m as isMember, n as ElevationOptions, o as PUBLIC_SCOPE, p as isElevated, s as RequestScope, t as ElevationEvent, u as getTeamId } from "../elevation-DGo5shaX.mjs";
2
- import { A as PaginationParams, D as CrudRepository, I as PipelineConfig, K as HookSystem, O as InferDoc, S as RouteHandler, _ as ControllerLike, b as IControllerResponse, g as ControllerHandler, j as QueryOptions, k as PaginatedResult, l as BaseControllerOptions, n as DataAdapter, v as FastifyHandler, w as ResourceRegistry, x as IRequestContext, y as IController } from "../interface-e9XfSsUV.mjs";
2
+ import { A as PaginationParams, D as CrudRepository, I as PipelineConfig, K as HookSystem, O as InferDoc, S as RouteHandler, _ as ControllerLike, b as IControllerResponse, g as ControllerHandler, j as QueryOptions, k as PaginatedResult, l as BaseControllerOptions, n as DataAdapter, v as FastifyHandler, w as ResourceRegistry, x as IRequestContext, y as IController } from "../interface-Cb2klgid.mjs";
3
3
  import { n as FieldPermissionMap } from "../fields-Bi_AVKSo.mjs";
4
4
  import { i as UserBase, n as PermissionContext, r as PermissionResult, t as PermissionCheck } from "../types-RLkFVgaw.mjs";
5
5
  import { FastifyInstance, FastifyReply, FastifyRequest, RouteHandlerMethod, RouteHandlerMethod as RouteHandlerMethod$1 } from "fastify";
@@ -363,7 +363,7 @@ interface ResourceConfig<TDoc = AnyRecord> {
363
363
  * Override to match your schema: 'workspaceId', 'tenantId', 'teamId', etc.
364
364
  * Takes effect when org context is present (via multiTenant preset).
365
365
  */
366
- tenantField?: string;
366
+ tenantField?: string | false;
367
367
  /**
368
368
  * Primary key field name (default: '_id').
369
369
  * Override for non-MongoDB adapters (e.g., 'id' for SQL databases).
@@ -1,5 +1,5 @@
1
1
  import "../elevation-DGo5shaX.mjs";
2
- import "../interface-e9XfSsUV.mjs";
2
+ import "../interface-Cb2klgid.mjs";
3
3
  import "../types-RLkFVgaw.mjs";
4
4
  import { AnyRecord, OpenApiSchemas, ParsedQuery, QueryParserInterface } from "../types/index.mjs";
5
5
  import { a as NotFoundError, c as RateLimitError, d as ValidationError, f as createError, i as ForbiddenError, l as ServiceUnavailableError, n as ConflictError, o as OrgAccessDeniedError, p as isArcError, r as ErrorDetails, s as OrgRequiredError, t as ArcError, u as UnauthorizedError } from "../errors-DAWRdiYP.mjs";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@classytic/arc",
3
- "version": "2.1.3",
3
+ "version": "2.1.7",
4
4
  "description": "Resource-oriented backend framework for Fastify — clean, minimal, powerful, tree-shakable",
5
5
  "type": "module",
6
6
  "exports": {