@classytic/arc 2.6.3 → 2.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +84 -1
- package/dist/{BaseController-DzRtluEF.mjs → BaseController-CpMfCXdn.mjs} +134 -16
- package/dist/adapters/index.d.mts +2 -2
- package/dist/adapters/index.mjs +1 -1
- package/dist/{adapters-gM-WYjNe.mjs → adapters-BxGgSHjj.mjs} +1 -9
- package/dist/applyPermissionResult-D6GPMsvh.mjs +37 -0
- package/dist/audit/index.d.mts +1 -1
- package/dist/audit/index.mjs +1 -1
- package/dist/audit/mongodb.d.mts +1 -1
- package/dist/audit/mongodb.mjs +1 -1
- package/dist/auth/index.d.mts +4 -4
- package/dist/auth/index.mjs +7 -6
- package/dist/auth/mongoose.d.mts +191 -0
- package/dist/auth/mongoose.mjs +73 -0
- package/dist/auth/redis-session.d.mts +1 -1
- package/dist/{betterAuthOpenApi-lz0IRbXJ.mjs → betterAuthOpenApi-CCw3YX0g.mjs} +1 -1
- package/dist/cache/index.d.mts +2 -2
- package/dist/cache/index.mjs +2 -2
- package/dist/cli/commands/docs.mjs +2 -2
- package/dist/cli/commands/generate.mjs +1 -1
- package/dist/cli/commands/init.mjs +7 -5
- package/dist/cli/commands/introspect.mjs +1 -1
- package/dist/core/index.d.mts +3 -3
- package/dist/core/index.mjs +4 -4
- package/dist/{core-C1XCMtqM.mjs → core-BWekSEju.mjs} +41 -13
- package/dist/{createApp-D2w0LdYJ.mjs → createApp-B_nvKNAQ.mjs} +11 -11
- package/dist/{defineResource-wWMBB4GP.mjs → defineResource-DZzyl4a4.mjs} +42 -37
- package/dist/docs/index.d.mts +2 -2
- package/dist/docs/index.mjs +1 -1
- package/dist/dynamic/index.d.mts +2 -2
- package/dist/dynamic/index.mjs +2 -2
- package/dist/{elevation-BEdACOLB.mjs → elevation-By_p2lnn.mjs} +1 -1
- package/dist/elevation-Dm-HTBCt.d.mts +23 -0
- package/dist/{errorHandler-Do4vVQ1f.d.mts → errorHandler-COa51ho_.d.mts} +1 -1
- package/dist/{errorHandler-r2595m8T.mjs → errorHandler-DXUttWEO.mjs} +1 -1
- package/dist/{eventPlugin-DW45v4V5.d.mts → eventPlugin-BgLxJkIB.d.mts} +1 -1
- package/dist/{eventPlugin-Ba00swHF.mjs → eventPlugin-DsaNNXzZ.mjs} +1 -1
- package/dist/events/index.d.mts +3 -3
- package/dist/events/index.mjs +1 -1
- package/dist/events/transports/redis-stream-entry.d.mts +1 -1
- package/dist/events/transports/redis.d.mts +1 -1
- package/dist/factory/index.d.mts +1 -1
- package/dist/factory/index.mjs +1 -1
- package/dist/hooks/index.d.mts +1 -1
- package/dist/hooks/index.mjs +1 -1
- package/dist/idempotency/index.d.mts +3 -3
- package/dist/idempotency/mongodb.d.mts +1 -1
- package/dist/idempotency/redis.d.mts +1 -1
- package/dist/index-BYpRGXif.d.mts +640 -0
- package/dist/{index-gz6iuzCp.d.mts → index-KXM8_JmQ.d.mts} +47 -4
- package/dist/{index-CHeJa4Zd.d.mts → index-StgFaQKD.d.mts} +1 -1
- package/dist/index.d.mts +8 -8
- package/dist/index.mjs +10 -9
- package/dist/integrations/event-gateway.d.mts +1 -1
- package/dist/integrations/event-gateway.mjs +1 -1
- package/dist/integrations/index.d.mts +1 -1
- package/dist/integrations/mcp/index.d.mts +2 -2
- package/dist/integrations/mcp/index.mjs +1 -1
- package/dist/integrations/mcp/testing.d.mts +1 -1
- package/dist/integrations/mcp/testing.mjs +1 -1
- package/dist/{interface-DYH8AXGe.d.mts → interface-Dwzqt4mn.d.mts} +150 -14
- package/dist/{mongodb-pMvOlR5_.d.mts → mongodb-Bq90j-Uj.d.mts} +1 -1
- package/dist/{mongodb-kltrBPa1.d.mts → mongodb-DdyYlIXg.d.mts} +1 -1
- package/dist/{openapi-CBmZ6EQN.mjs → openapi-C5UhIeWu.mjs} +1 -1
- package/dist/org/index.d.mts +2 -2
- package/dist/org/index.mjs +1 -1
- package/dist/permissions/index.d.mts +4 -4
- package/dist/permissions/index.mjs +3 -2
- package/dist/{permissions-C8ImI8gC.mjs → permissions-CH4cNwJi.mjs} +358 -64
- package/dist/plugins/index.d.mts +4 -4
- package/dist/plugins/index.mjs +10 -10
- package/dist/plugins/response-cache.mjs +1 -1
- package/dist/plugins/tracing-entry.d.mts +1 -1
- package/dist/plugins/tracing-entry.mjs +1 -1
- package/dist/policies/index.d.mts +1 -1
- package/dist/presets/index.d.mts +3 -3
- package/dist/presets/index.mjs +1 -1
- package/dist/presets/multiTenant.d.mts +53 -3
- package/dist/presets/multiTenant.mjs +89 -47
- package/dist/{presets-BMfdy34e.mjs → presets-BFrGvvjL.mjs} +2 -2
- package/dist/{queryCachePlugin-DcmETvcB.d.mts → queryCachePlugin-Bw8XyJpX.d.mts} +1 -1
- package/dist/{queryCachePlugin-XtFplYO9.mjs → queryCachePlugin-CwTpR04-.mjs} +2 -2
- package/dist/{redis-D0Qc-9EW.d.mts → redis-CyCntzTO.d.mts} +1 -1
- package/dist/{redis-stream-BW9UKLZM.d.mts → redis-stream-We_Ucl9-.d.mts} +1 -1
- package/dist/registry/index.d.mts +1 -1
- package/dist/registry/index.mjs +2 -2
- package/dist/{resourceToTools-nCJWnG1r.mjs → resourceToTools-CkVSSzKg.mjs} +64 -21
- package/dist/rpc/index.d.mts +1 -1
- package/dist/rpc/index.mjs +1 -1
- package/dist/scope/index.d.mts +3 -2
- package/dist/scope/index.mjs +4 -3
- package/dist/{sse-BF7GR7IB.mjs → sse-Bp3dabF1.mjs} +2 -2
- package/dist/testing/index.d.mts +2 -2
- package/dist/testing/index.mjs +1 -1
- package/dist/types/index.d.mts +4 -3
- package/dist/types/index.mjs +1 -1
- package/dist/types-AOD8fxIw.mjs +229 -0
- package/dist/types-CNEbix8T.d.mts +286 -0
- package/dist/{types-B4_TDdPe.d.mts → types-ClmkMDK1.d.mts} +1 -1
- package/dist/{types-By-5mIfn.d.mts → types-D0qf0Mf4.d.mts} +9 -9
- package/dist/types-DPsC0taJ.d.mts +178 -0
- package/dist/utils/index.d.mts +3 -3
- package/dist/utils/index.mjs +5 -5
- package/package.json +17 -5
- package/skills/arc/SKILL.md +253 -6
- package/skills/arc/references/multi-tenancy.md +208 -0
- package/dist/elevation-C_taLQrM.d.mts +0 -147
- package/dist/index-NGZksqM5.d.mts +0 -398
- package/dist/types-BNUccdcf.d.mts +0 -101
- package/dist/types-BhtYdxZU.mjs +0 -91
- /package/dist/{EventTransport-wc5hSLik.d.mts → EventTransport-CUpRK_Lg.d.mts} +0 -0
- /package/dist/{HookSystem-COkyWztM.mjs → HookSystem-D7lfx--K.mjs} +0 -0
- /package/dist/{ResourceRegistry-C6ngvOnn.mjs → ResourceRegistry-DsHiG9cL.mjs} +0 -0
- /package/dist/{caching-BSXB-Xr7.mjs → caching-5DtLwIqb.mjs} +0 -0
- /package/dist/{circuitBreaker-JP2GdJ4b.d.mts → circuitBreaker-DwxrljLB.d.mts} +0 -0
- /package/dist/{circuitBreaker-BOBOpN2w.mjs → circuitBreaker-l18oRgL5.mjs} +0 -0
- /package/dist/{errors-CcVbl1-T.d.mts → errors-CCSsMpXE.d.mts} +0 -0
- /package/dist/{errors-NoQKsbAT.mjs → errors-Cg58SLNi.mjs} +0 -0
- /package/dist/{externalPaths-DpO-s7r8.d.mts → externalPaths-Dg7OLsKo.d.mts} +0 -0
- /package/dist/{fields-DFwdaWCq.d.mts → fields-CYuLMJPD.d.mts} +0 -0
- /package/dist/{interface-gr-7qo9j.d.mts → interface-B9rHWPxD.d.mts} +0 -0
- /package/dist/{interface-D_BWALyZ.d.mts → interface-CnluRL4_.d.mts} +0 -0
- /package/dist/{logger-Dz3j1ItV.mjs → logger-DLg8-Ueg.mjs} +0 -0
- /package/dist/{memory-BFAYkf8H.mjs → memory-Cp7_cAko.mjs} +0 -0
- /package/dist/{metrics-Csh4nsvv.mjs → metrics-Qnvwc-LQ.mjs} +0 -0
- /package/dist/{mongodb-BuQ7fNTg.mjs → mongodb-mlgxkYI3.mjs} +0 -0
- /package/dist/{pluralize-CcT6qF0a.mjs → pluralize-COpOVar8.mjs} +0 -0
- /package/dist/{registry-I-ogLgL9.mjs → registry-B3lRFBWo.mjs} +0 -0
- /package/dist/{requestContext-DYtmNpm5.mjs → requestContext-xHIKedG6.mjs} +0 -0
- /package/dist/{schemaConverter-DjzHpFam.mjs → schemaConverter-0TyONAwM.mjs} +0 -0
- /package/dist/{sessionManager-wbkYj2HL.d.mts → sessionManager-IW4sbIea.d.mts} +0 -0
- /package/dist/{tracing-bz_U4EM1.d.mts → tracing-65B51Dw3.d.mts} +0 -0
- /package/dist/{typeGuards-Cj5Rgvlg.mjs → typeGuards-CcFZXgU7.mjs} +0 -0
- /package/dist/{utils-Dc0WhlIl.mjs → utils-B-l6410F.mjs} +0 -0
- /package/dist/{versioning-BzfeHmhj.mjs → versioning-aUUVziBY.mjs} +0 -0
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
//#region src/auth/mongoose.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Better Auth × Mongoose Bridge
|
|
4
|
+
*
|
|
5
|
+
* Optional helper that registers stub Mongoose models for the collections
|
|
6
|
+
* that Better Auth's MongoDB adapter writes to. This is a one-way *read*
|
|
7
|
+
* bridge: Better Auth still writes via its own native `mongodb` driver
|
|
8
|
+
* (through `@better-auth/mongo-adapter`), but stub models let arc resources
|
|
9
|
+
* built on Mongoose use `.populate()` against BA-owned collections.
|
|
10
|
+
*
|
|
11
|
+
* **Why this is needed**: Mongoose's `populate()` looks up the target model
|
|
12
|
+
* by name. BA never registers anything with Mongoose, so a schema like
|
|
13
|
+
* `new Schema({ userId: { ref: 'user' } })` throws `MissingSchemaError`
|
|
14
|
+
* the first time you call `.populate('userId')`. This helper registers an
|
|
15
|
+
* empty `strict: false` schema for each BA collection, so populate works
|
|
16
|
+
* without interfering with BA's writes.
|
|
17
|
+
*
|
|
18
|
+
* **DB-agnostic by design**: this file lives at the dedicated subpath
|
|
19
|
+
* `@classytic/arc/auth/mongoose`. Users on Prisma/Drizzle/Kysely never
|
|
20
|
+
* import it and never get Mongoose pulled into their bundle. Mongoose is
|
|
21
|
+
* passed in as a parameter so this module has zero runtime imports of it.
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* ```ts
|
|
25
|
+
* import mongoose from 'mongoose';
|
|
26
|
+
* import { betterAuth } from 'better-auth';
|
|
27
|
+
* import { mongodbAdapter } from '@better-auth/mongo-adapter';
|
|
28
|
+
* import { organization } from 'better-auth/plugins';
|
|
29
|
+
* import { registerBetterAuthMongooseModels } from '@classytic/arc/auth/mongoose';
|
|
30
|
+
*
|
|
31
|
+
* const auth = betterAuth({
|
|
32
|
+
* database: mongodbAdapter(mongoose.connection.getClient().db()),
|
|
33
|
+
* plugins: [organization({ teams: { enabled: true } })],
|
|
34
|
+
* // ...
|
|
35
|
+
* });
|
|
36
|
+
*
|
|
37
|
+
* // Register stub models AFTER betterAuth() so collections are known.
|
|
38
|
+
* // For plugins shipped as separate @better-auth/* packages (passkey, sso,
|
|
39
|
+
* // api-key, oauth-provider, etc.), add their collection names via
|
|
40
|
+
* // `extraCollections` — see the JSDoc on that option for known names.
|
|
41
|
+
* registerBetterAuthMongooseModels(mongoose, {
|
|
42
|
+
* plugins: ['organization', 'organization-teams', 'mcp'],
|
|
43
|
+
* extraCollections: ['passkey', 'ssoProvider'], // @better-auth/passkey, @better-auth/sso
|
|
44
|
+
* });
|
|
45
|
+
*
|
|
46
|
+
* // Now an arc resource can populate BA-owned references:
|
|
47
|
+
* const PostSchema = new mongoose.Schema({
|
|
48
|
+
* title: String,
|
|
49
|
+
* authorId: { type: String, ref: 'user' },
|
|
50
|
+
* });
|
|
51
|
+
* const Post = mongoose.model('Post', PostSchema);
|
|
52
|
+
* await Post.findOne().populate('authorId'); // resolves against BA's user collection
|
|
53
|
+
* ```
|
|
54
|
+
*/
|
|
55
|
+
/**
|
|
56
|
+
* Minimal structural type for the subset of Mongoose we touch.
|
|
57
|
+
* Declared structurally so this file has zero `import` of mongoose —
|
|
58
|
+
* mongoose stays a peer dep and is never bundled with arc.
|
|
59
|
+
*/
|
|
60
|
+
interface MongooseLike {
|
|
61
|
+
models: Record<string, unknown>;
|
|
62
|
+
Schema: new (definition: Record<string, unknown>, options?: {
|
|
63
|
+
strict?: boolean;
|
|
64
|
+
collection?: string;
|
|
65
|
+
_id?: boolean;
|
|
66
|
+
}) => unknown;
|
|
67
|
+
model: (name: string, schema?: unknown) => unknown;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Plugin keys that map to Better Auth collection sets.
|
|
71
|
+
*
|
|
72
|
+
* Only plugins that ship inside the **core `better-auth` package** are listed
|
|
73
|
+
* here. Plugins distributed as separate `@better-auth/*` packages
|
|
74
|
+
* (api-key, passkey, sso, oauth-provider, etc.) evolve independently and
|
|
75
|
+
* should be handled via `extraCollections` — see the JSDoc on that option.
|
|
76
|
+
*
|
|
77
|
+
* Plugins that only add *fields* to existing tables (admin, username,
|
|
78
|
+
* phoneNumber, magicLink, emailOtp, anonymous, bearer, multiSession, siwe,
|
|
79
|
+
* lastLoginMethod, genericOAuth, etc.) don't need an entry here — the stub
|
|
80
|
+
* schemas are registered with `strict: false`, so extra fields round-trip
|
|
81
|
+
* automatically.
|
|
82
|
+
*
|
|
83
|
+
* - `core` — always included; covers `user`, `session`, `account`, `verification`.
|
|
84
|
+
* - `organization` — adds `organization`, `member`, `invitation`.
|
|
85
|
+
* - `organization-teams` — adds `team`, `teamMember` (only when `teams.enabled`).
|
|
86
|
+
* - `twoFactor` — adds `twoFactor`.
|
|
87
|
+
* - `jwt` — adds `jwks`.
|
|
88
|
+
* - `oidcProvider` — adds `oauthApplication`, `oauthAccessToken`, `oauthConsent`.
|
|
89
|
+
* - `oauthProvider` — alias of `oidcProvider` (same schema). Use this key if
|
|
90
|
+
* you've migrated to `@better-auth/oauth-provider` per BA 1.6 release notes
|
|
91
|
+
* — the collections are identical.
|
|
92
|
+
* - `mcp` — MCP plugin **reuses the oidcProvider schema** (docs: "The MCP
|
|
93
|
+
* plugin uses the same schema as the OIDC Provider plugin"). Selecting this
|
|
94
|
+
* registers the oauth* collections.
|
|
95
|
+
* - `deviceAuthorization` — adds `deviceCode` (RFC 8628 device authorization).
|
|
96
|
+
*/
|
|
97
|
+
type BetterAuthPluginKey = "core" | "organization" | "organization-teams" | "twoFactor" | "jwt" | "oidcProvider" | "oauthProvider" | "mcp" | "deviceAuthorization";
|
|
98
|
+
interface RegisterBetterAuthMongooseModelsOptions {
|
|
99
|
+
/**
|
|
100
|
+
* Which Better Auth plugin collection sets to register stubs for.
|
|
101
|
+
* `'core'` is always included implicitly (covers `user`, `session`,
|
|
102
|
+
* `account`, `verification`).
|
|
103
|
+
*
|
|
104
|
+
* **Default is `[]` (core only) on purpose** — the helper should never
|
|
105
|
+
* register stubs for plugins you haven't enabled. Opt in explicitly to
|
|
106
|
+
* each plugin you've added to your `betterAuth({ plugins: [...] })` config.
|
|
107
|
+
*
|
|
108
|
+
* @default []
|
|
109
|
+
* @example
|
|
110
|
+
* ```ts
|
|
111
|
+
* // Just core BA (email/password, sessions)
|
|
112
|
+
* registerBetterAuthMongooseModels(mongoose);
|
|
113
|
+
*
|
|
114
|
+
* // Core + organization plugin
|
|
115
|
+
* registerBetterAuthMongooseModels(mongoose, { plugins: ['organization'] });
|
|
116
|
+
*
|
|
117
|
+
* // Core + organization with teams + MCP server
|
|
118
|
+
* registerBetterAuthMongooseModels(mongoose, {
|
|
119
|
+
* plugins: ['organization', 'organization-teams', 'mcp'],
|
|
120
|
+
* });
|
|
121
|
+
* ```
|
|
122
|
+
*/
|
|
123
|
+
plugins?: BetterAuthPluginKey[];
|
|
124
|
+
/**
|
|
125
|
+
* Whether Better Auth's mongo adapter was configured with `usePlural: true`.
|
|
126
|
+
* When true, model names and collection names are pluralized
|
|
127
|
+
* (`user` → `users`, `organization` → `organizations`, etc).
|
|
128
|
+
*
|
|
129
|
+
* **Must match** the `usePlural` value passed to `mongodbAdapter()`.
|
|
130
|
+
*
|
|
131
|
+
* @default false
|
|
132
|
+
*/
|
|
133
|
+
usePlural?: boolean;
|
|
134
|
+
/**
|
|
135
|
+
* Override the model name for specific Better Auth collections.
|
|
136
|
+
* Use this when you've passed `user: { modelName: 'profiles' }` (or similar)
|
|
137
|
+
* to `betterAuth()` — pass the same map here so populate names line up.
|
|
138
|
+
*
|
|
139
|
+
* Keys are the canonical BA names (`user`, `session`, etc.); values are
|
|
140
|
+
* the model name to register with Mongoose. The collection name is also
|
|
141
|
+
* set to the override value.
|
|
142
|
+
*
|
|
143
|
+
* @example
|
|
144
|
+
* ```ts
|
|
145
|
+
* registerBetterAuthMongooseModels(mongoose, {
|
|
146
|
+
* modelOverrides: { user: 'profile', member: 'orgMember' },
|
|
147
|
+
* });
|
|
148
|
+
* ```
|
|
149
|
+
*/
|
|
150
|
+
modelOverrides?: Partial<Record<string, string>>;
|
|
151
|
+
/**
|
|
152
|
+
* Additional collection names to register beyond the built-in plugin set.
|
|
153
|
+
*
|
|
154
|
+
* **Use this for plugins that ship as separate `@better-auth/*` packages**
|
|
155
|
+
* (they're intentionally not hardcoded in `BetterAuthPluginKey` because
|
|
156
|
+
* their collection names live in their own packages and can evolve
|
|
157
|
+
* independently of the core `better-auth` release cycle).
|
|
158
|
+
*
|
|
159
|
+
* Known collection names for official separate-package plugins:
|
|
160
|
+
* - `@better-auth/passkey` → `'passkey'`
|
|
161
|
+
* - `@better-auth/sso` → `'ssoProvider'`
|
|
162
|
+
* - `@better-auth/oauth-provider` → already covered by `plugins: ['oauthProvider']`
|
|
163
|
+
* (same schema as the in-core `oidcProvider`)
|
|
164
|
+
* - `@better-auth/api-key` → consult the plugin's docs for the current
|
|
165
|
+
* model name; it's one collection
|
|
166
|
+
*
|
|
167
|
+
* For your own custom Better Auth plugins, pass whatever collection names
|
|
168
|
+
* they write to.
|
|
169
|
+
*
|
|
170
|
+
* @default []
|
|
171
|
+
* @example
|
|
172
|
+
* ```ts
|
|
173
|
+
* registerBetterAuthMongooseModels(mongoose, {
|
|
174
|
+
* plugins: ['organization'],
|
|
175
|
+
* extraCollections: ['passkey', 'ssoProvider'],
|
|
176
|
+
* });
|
|
177
|
+
* ```
|
|
178
|
+
*/
|
|
179
|
+
extraCollections?: string[];
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Register stub Mongoose models for Better Auth's collections so that
|
|
183
|
+
* Mongoose-based arc resources can `.populate()` references to BA-owned
|
|
184
|
+
* documents. Idempotent — safe to call multiple times.
|
|
185
|
+
*
|
|
186
|
+
* Returns the list of model names that were newly registered (excluding
|
|
187
|
+
* any that already existed on `mongoose.models`).
|
|
188
|
+
*/
|
|
189
|
+
declare function registerBetterAuthMongooseModels(mongoose: MongooseLike, options?: RegisterBetterAuthMongooseModelsOptions): string[];
|
|
190
|
+
//#endregion
|
|
191
|
+
export { BetterAuthPluginKey, MongooseLike, RegisterBetterAuthMongooseModelsOptions, registerBetterAuthMongooseModels };
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
//#region src/auth/mongoose.ts
|
|
2
|
+
const COLLECTIONS_BY_PLUGIN = {
|
|
3
|
+
core: [
|
|
4
|
+
"user",
|
|
5
|
+
"session",
|
|
6
|
+
"account",
|
|
7
|
+
"verification"
|
|
8
|
+
],
|
|
9
|
+
organization: [
|
|
10
|
+
"organization",
|
|
11
|
+
"member",
|
|
12
|
+
"invitation"
|
|
13
|
+
],
|
|
14
|
+
"organization-teams": ["team", "teamMember"],
|
|
15
|
+
twoFactor: ["twoFactor"],
|
|
16
|
+
jwt: ["jwks"],
|
|
17
|
+
oidcProvider: [
|
|
18
|
+
"oauthApplication",
|
|
19
|
+
"oauthAccessToken",
|
|
20
|
+
"oauthConsent"
|
|
21
|
+
],
|
|
22
|
+
oauthProvider: [
|
|
23
|
+
"oauthApplication",
|
|
24
|
+
"oauthAccessToken",
|
|
25
|
+
"oauthConsent"
|
|
26
|
+
],
|
|
27
|
+
mcp: [
|
|
28
|
+
"oauthApplication",
|
|
29
|
+
"oauthAccessToken",
|
|
30
|
+
"oauthConsent"
|
|
31
|
+
],
|
|
32
|
+
deviceAuthorization: ["deviceCode"]
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* Naive English pluralization that matches Better Auth's `usePlural` behavior.
|
|
36
|
+
* BA's mongo adapter just appends `s` (it doesn't handle irregular nouns —
|
|
37
|
+
* none of its collection names are irregular). We mirror that exactly.
|
|
38
|
+
*/
|
|
39
|
+
function pluralize(name) {
|
|
40
|
+
return name.endsWith("s") ? name : `${name}s`;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Register stub Mongoose models for Better Auth's collections so that
|
|
44
|
+
* Mongoose-based arc resources can `.populate()` references to BA-owned
|
|
45
|
+
* documents. Idempotent — safe to call multiple times.
|
|
46
|
+
*
|
|
47
|
+
* Returns the list of model names that were newly registered (excluding
|
|
48
|
+
* any that already existed on `mongoose.models`).
|
|
49
|
+
*/
|
|
50
|
+
function registerBetterAuthMongooseModels(mongoose, options = {}) {
|
|
51
|
+
const { plugins = [], usePlural = false, modelOverrides = {}, extraCollections = [] } = options;
|
|
52
|
+
const pluginSet = new Set(["core", ...plugins]);
|
|
53
|
+
const collected = [];
|
|
54
|
+
for (const key of pluginSet) for (const name of COLLECTIONS_BY_PLUGIN[key]) collected.push(name);
|
|
55
|
+
for (const name of extraCollections) collected.push(name);
|
|
56
|
+
const seen = /* @__PURE__ */ new Set();
|
|
57
|
+
const unique = collected.filter((n) => seen.has(n) ? false : (seen.add(n), true));
|
|
58
|
+
const registered = [];
|
|
59
|
+
for (const canonical of unique) {
|
|
60
|
+
const finalName = modelOverrides[canonical] ?? (usePlural ? pluralize(canonical) : canonical);
|
|
61
|
+
if (mongoose.models[finalName]) continue;
|
|
62
|
+
const schema = new mongoose.Schema({}, {
|
|
63
|
+
strict: false,
|
|
64
|
+
collection: finalName,
|
|
65
|
+
_id: false
|
|
66
|
+
});
|
|
67
|
+
mongoose.model(finalName, schema);
|
|
68
|
+
registered.push(finalName);
|
|
69
|
+
}
|
|
70
|
+
return registered;
|
|
71
|
+
}
|
|
72
|
+
//#endregion
|
|
73
|
+
export { registerBetterAuthMongooseModels };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { i as SessionData, s as SessionStore } from "../sessionManager-
|
|
1
|
+
import { i as SessionData, s as SessionStore } from "../sessionManager-IW4sbIea.mjs";
|
|
2
2
|
|
|
3
3
|
//#region src/auth/redis-session.d.ts
|
|
4
4
|
/** Minimal Redis client interface — compatible with ioredis */
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as __exportAll } from "./chunk-BpYLSNr0.mjs";
|
|
2
|
-
import { a as toJsonSchema } from "./schemaConverter-
|
|
2
|
+
import { a as toJsonSchema } from "./schemaConverter-0TyONAwM.mjs";
|
|
3
3
|
//#region src/auth/betterAuthOpenApi.ts
|
|
4
4
|
var betterAuthOpenApi_exports = /* @__PURE__ */ __exportAll({ extractBetterAuthOpenApi: () => extractBetterAuthOpenApi });
|
|
5
5
|
/**
|
package/dist/cache/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { i as CacheStore, n as CacheSetOptions, r as CacheStats, t as CacheLogger } from "../interface-
|
|
2
|
-
import { a as CacheEnvelope, c as QueryCache, i as queryCachePlugin, l as QueryCacheConfig, n as QueryCacheDefaults, o as CacheResult, r as QueryCachePluginOptions, s as CacheStatus, t as CrossResourceRule } from "../queryCachePlugin-
|
|
1
|
+
import { i as CacheStore, n as CacheSetOptions, r as CacheStats, t as CacheLogger } from "../interface-CnluRL4_.mjs";
|
|
2
|
+
import { a as CacheEnvelope, c as QueryCache, i as queryCachePlugin, l as QueryCacheConfig, n as QueryCacheDefaults, o as CacheResult, r as QueryCachePluginOptions, s as CacheStatus, t as CrossResourceRule } from "../queryCachePlugin-Bw8XyJpX.mjs";
|
|
3
3
|
|
|
4
4
|
//#region src/cache/keys.d.ts
|
|
5
5
|
/**
|
package/dist/cache/index.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { i as versionKey, n as hashParams, r as tagVersionKey, t as buildQueryKey } from "../keys-qcD-TVJl.mjs";
|
|
2
|
-
import { t as MemoryCacheStore } from "../memory-
|
|
3
|
-
import { r as QueryCache, t as queryCachePlugin } from "../queryCachePlugin-
|
|
2
|
+
import { t as MemoryCacheStore } from "../memory-Cp7_cAko.mjs";
|
|
3
|
+
import { r as QueryCache, t as queryCachePlugin } from "../queryCachePlugin-CwTpR04-.mjs";
|
|
4
4
|
//#region src/cache/redis.ts
|
|
5
5
|
/**
|
|
6
6
|
* Redis-backed cache store.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { t as ResourceRegistry } from "../../ResourceRegistry-
|
|
2
|
-
import { t as buildOpenApiSpec } from "../../openapi-
|
|
1
|
+
import { t as ResourceRegistry } from "../../ResourceRegistry-DsHiG9cL.mjs";
|
|
2
|
+
import { t as buildOpenApiSpec } from "../../openapi-C5UhIeWu.mjs";
|
|
3
3
|
import { dirname, resolve } from "node:path";
|
|
4
4
|
import { pathToFileURL } from "node:url";
|
|
5
5
|
import { mkdirSync, writeFileSync } from "node:fs";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as pluralize } from "../../pluralize-
|
|
1
|
+
import { t as pluralize } from "../../pluralize-COpOVar8.mjs";
|
|
2
2
|
import { join } from "node:path";
|
|
3
3
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
4
4
|
//#region src/cli/commands/generate.ts
|
|
@@ -100,9 +100,9 @@ async function installDependencies(projectPath, config, pm) {
|
|
|
100
100
|
"@fastify/under-pressure@latest",
|
|
101
101
|
"dotenv@latest"
|
|
102
102
|
];
|
|
103
|
-
if (config.auth === "better-auth") deps.push("better-auth
|
|
103
|
+
if (config.auth === "better-auth") deps.push("better-auth@^1.6.0", "mongodb@latest");
|
|
104
104
|
else deps.push("@fastify/jwt@latest", "bcryptjs@latest");
|
|
105
|
-
if (config.adapter === "mongokit") deps.push("@classytic/mongokit
|
|
105
|
+
if (config.adapter === "mongokit") deps.push("@classytic/mongokit@^3.5.5", "mongoose@^9.4.1");
|
|
106
106
|
const devDeps = ["vitest@latest", "pino-pretty@latest"];
|
|
107
107
|
if (config.typescript) devDeps.push("typescript@latest", "@types/node@latest", "tsx@latest");
|
|
108
108
|
const installCmd = getInstallCommand(pm, deps, false);
|
|
@@ -1323,13 +1323,15 @@ export const requireSuperadmin = ()${returnType} =>
|
|
|
1323
1323
|
/**
|
|
1324
1324
|
* Organization-level guards (per-org member.role):
|
|
1325
1325
|
*
|
|
1326
|
-
* -
|
|
1326
|
+
* - requireRoles('admin') — checks BOTH user.role AND org member.role (recommended)
|
|
1327
1327
|
* - requireOrgRole(['admin','owner']) — checks member.role in active org ONLY
|
|
1328
1328
|
* - requireOrgMembership() — just checks if user is in the org (any role)
|
|
1329
1329
|
* - requireTeamMembership() — checks if user is in the active team
|
|
1330
1330
|
*
|
|
1331
|
-
* RECOMMENDED: Use
|
|
1332
|
-
*
|
|
1331
|
+
* RECOMMENDED: Use requireRoles() for most cases. Since Arc 2.7.1 it defaults to
|
|
1332
|
+
* checking both platform AND org roles, so a single call covers BA org plugin users
|
|
1333
|
+
* with platform-admin overrides. Use requireOrgRole() when you ONLY want org-level
|
|
1334
|
+
* checks (and want to explicitly exclude platform admins).
|
|
1333
1335
|
*
|
|
1334
1336
|
* Platform superadmin automatically bypasses all org role checks.
|
|
1335
1337
|
*
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as ResourceRegistry } from "../../ResourceRegistry-
|
|
1
|
+
import { t as ResourceRegistry } from "../../ResourceRegistry-DsHiG9cL.mjs";
|
|
2
2
|
import { resolve } from "node:path";
|
|
3
3
|
import { pathToFileURL } from "node:url";
|
|
4
4
|
//#region src/cli/commands/introspect.ts
|
package/dist/core/index.d.mts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { At as AccessControl, Dt as QueryResolverConfig, Et as QueryResolver, Ht as defineResource, Ot as BodySanitizer, Tt as BaseControllerOptions, Vt as ResourceDefinition, jt as AccessControlConfig, kt as BodySanitizerConfig, wt as BaseController } from "../interface-
|
|
2
|
-
import { A as
|
|
3
|
-
export { AccessControl, AccessControlConfig, ActionHandler, ActionRouterConfig, BaseController, BaseControllerOptions, BodySanitizer, 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, IdempotencyService, MAX_FILTER_DEPTH, MAX_REGEX_LENGTH, MAX_SEARCH_LENGTH, MUTATION_OPERATIONS, MutationOperation, QueryResolver, QueryResolverConfig, RESERVED_QUERY_PARAMS, ResourceDefinition, SYSTEM_FIELDS, createActionRouter, createCrudHandlers, createCrudRouter, createFastifyHandler, createPermissionMiddleware, createRequestContext, defineResource, getControllerContext, getControllerScope, sendControllerResponse };
|
|
1
|
+
import { At as AccessControl, Dt as QueryResolverConfig, Et as QueryResolver, Ht as defineResource, Ot as BodySanitizer, Tt as BaseControllerOptions, Vt as ResourceDefinition, jt as AccessControlConfig, kt as BodySanitizerConfig, wt as BaseController } from "../interface-Dwzqt4mn.mjs";
|
|
2
|
+
import { A as MutationOperation, C as HOOK_PHASES, D as MAX_REGEX_LENGTH, E as MAX_FILTER_DEPTH, M as SYSTEM_FIELDS, O as MAX_SEARCH_LENGTH, S as HOOK_OPERATIONS, T as HookPhase, _ as DEFAULT_LIMIT, a as getControllerScope, b as DEFAULT_TENANT_FIELD, c as createCrudRouter, d as ActionRouterConfig, f as IdempotencyService, g as DEFAULT_ID_FIELD, h as CrudOperation, i as getControllerContext, j as RESERVED_QUERY_PARAMS, k as MUTATION_OPERATIONS, l as createPermissionMiddleware, m as CRUD_OPERATIONS, n as createFastifyHandler, o as sendControllerResponse, p as createActionRouter, r as createRequestContext, s as defineResourceVariants, t as createCrudHandlers, u as ActionHandler, v as DEFAULT_MAX_LIMIT, w as HookOperation, x as DEFAULT_UPDATE_METHOD, y as DEFAULT_SORT } from "../index-KXM8_JmQ.mjs";
|
|
3
|
+
export { AccessControl, AccessControlConfig, ActionHandler, ActionRouterConfig, BaseController, BaseControllerOptions, BodySanitizer, 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, IdempotencyService, MAX_FILTER_DEPTH, MAX_REGEX_LENGTH, MAX_SEARCH_LENGTH, MUTATION_OPERATIONS, MutationOperation, QueryResolver, QueryResolverConfig, RESERVED_QUERY_PARAMS, ResourceDefinition, SYSTEM_FIELDS, createActionRouter, createCrudHandlers, createCrudRouter, createFastifyHandler, createPermissionMiddleware, createRequestContext, defineResource, defineResourceVariants, getControllerContext, getControllerScope, sendControllerResponse };
|
package/dist/core/index.mjs
CHANGED
|
@@ -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-Cxde4rpC.mjs";
|
|
2
|
-
import { i as AccessControl, n as QueryResolver, r as BodySanitizer, t as BaseController } from "../BaseController-
|
|
3
|
-
import {
|
|
4
|
-
import { c as createCrudHandlers, d as getControllerContext, f as getControllerScope, l as createFastifyHandler, n as defineResource, o as createCrudRouter, p as sendControllerResponse, s as createPermissionMiddleware, t as ResourceDefinition, u as createRequestContext } from "../defineResource-
|
|
5
|
-
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 };
|
|
2
|
+
import { i as AccessControl, n as QueryResolver, r as BodySanitizer, t as BaseController } from "../BaseController-CpMfCXdn.mjs";
|
|
3
|
+
import { n as createActionRouter, t as defineResourceVariants } from "../core-BWekSEju.mjs";
|
|
4
|
+
import { c as createCrudHandlers, d as getControllerContext, f as getControllerScope, l as createFastifyHandler, n as defineResource, o as createCrudRouter, p as sendControllerResponse, s as createPermissionMiddleware, t as ResourceDefinition, u as createRequestContext } from "../defineResource-DZzyl4a4.mjs";
|
|
5
|
+
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, defineResourceVariants, getControllerContext, getControllerScope, sendControllerResponse };
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { n as normalizePermissionResult, t as applyPermissionResult } from "./applyPermissionResult-D6GPMsvh.mjs";
|
|
2
|
+
import { n as defineResource } from "./defineResource-DZzyl4a4.mjs";
|
|
1
3
|
//#region src/core/createActionRouter.ts
|
|
2
4
|
/**
|
|
3
5
|
* Create action-based state transition endpoint
|
|
@@ -103,18 +105,12 @@ function createActionRouter(fastify, config) {
|
|
|
103
105
|
error: "Permission denied"
|
|
104
106
|
});
|
|
105
107
|
}
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
const permResult = result;
|
|
113
|
-
if (!permResult.granted) return reply.code(context.user ? 403 : 401).send({
|
|
114
|
-
success: false,
|
|
115
|
-
error: permResult.reason ?? (context.user ? `Permission denied for '${action}'` : "Authentication required")
|
|
116
|
-
});
|
|
117
|
-
}
|
|
108
|
+
const permResult = normalizePermissionResult(result);
|
|
109
|
+
if (!permResult.granted) return reply.code(context.user ? 403 : 401).send({
|
|
110
|
+
success: false,
|
|
111
|
+
error: permResult.reason ?? (context.user ? `Permission denied for '${action}'` : "Authentication required")
|
|
112
|
+
});
|
|
113
|
+
applyPermissionResult(permResult, req);
|
|
118
114
|
}
|
|
119
115
|
try {
|
|
120
116
|
if (idempotencyKey && idempotencyService) {
|
|
@@ -182,4 +178,36 @@ function buildActionDescription(actions, actionPermissions) {
|
|
|
182
178
|
return lines.join("\n");
|
|
183
179
|
}
|
|
184
180
|
//#endregion
|
|
185
|
-
|
|
181
|
+
//#region src/core/defineResourceVariants.ts
|
|
182
|
+
/**
|
|
183
|
+
* Define multiple resources from a shared base config and per-variant overrides.
|
|
184
|
+
*
|
|
185
|
+
* Each variant is independently passed through `defineResource()` — the
|
|
186
|
+
* returned `ResourceDefinition`s are real, fully-registered resources.
|
|
187
|
+
* Register each one's plugin in your app:
|
|
188
|
+
*
|
|
189
|
+
* ```typescript
|
|
190
|
+
* await app.register(articlePublic.toPlugin());
|
|
191
|
+
* await app.register(articleAdmin.toPlugin());
|
|
192
|
+
* ```
|
|
193
|
+
*
|
|
194
|
+
* @param base Shared config — adapter, queryParser, schemaOptions, hooks, etc.
|
|
195
|
+
* Must NOT include `name` or `prefix` (those are per-variant).
|
|
196
|
+
* @param variants Map of variant key → override. Each variant must declare
|
|
197
|
+
* its own `name` and `prefix`. Other fields override the base.
|
|
198
|
+
* @returns A record where each key from `variants` maps to a real
|
|
199
|
+
* `ResourceDefinition` ready for `.toPlugin()` registration.
|
|
200
|
+
*/
|
|
201
|
+
function defineResourceVariants(base, variants) {
|
|
202
|
+
const out = {};
|
|
203
|
+
for (const key of Object.keys(variants)) {
|
|
204
|
+
const override = variants[key];
|
|
205
|
+
out[key] = defineResource({
|
|
206
|
+
...base,
|
|
207
|
+
...override
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
return out;
|
|
211
|
+
}
|
|
212
|
+
//#endregion
|
|
213
|
+
export { createActionRouter as n, defineResourceVariants as t };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as __exportAll } from "./chunk-BpYLSNr0.mjs";
|
|
2
|
-
import { n as PUBLIC_SCOPE } from "./types-
|
|
2
|
+
import { n as PUBLIC_SCOPE } from "./types-AOD8fxIw.mjs";
|
|
3
3
|
import Fastify from "fastify";
|
|
4
4
|
import qs from "qs";
|
|
5
5
|
//#region src/factory/presets.ts
|
|
@@ -208,7 +208,7 @@ async function registerArcCore(fastify, config, trackPlugin) {
|
|
|
208
208
|
await fastify.register(arcCorePlugin, { emitEvents: config.arcPlugins?.emitEvents !== false });
|
|
209
209
|
trackPlugin("arc-core");
|
|
210
210
|
if (config.arcPlugins?.events !== false) {
|
|
211
|
-
const { default: eventPlugin } = await import("./eventPlugin-
|
|
211
|
+
const { default: eventPlugin } = await import("./eventPlugin-DsaNNXzZ.mjs").then((n) => n.n);
|
|
212
212
|
const eventOpts = typeof config.arcPlugins?.events === "object" ? config.arcPlugins.events : {};
|
|
213
213
|
await fastify.register(eventPlugin, {
|
|
214
214
|
...eventOpts,
|
|
@@ -244,15 +244,15 @@ async function registerArcPlugins(fastify, config, trackPlugin, modules) {
|
|
|
244
244
|
trackPlugin("arc-graceful-shutdown");
|
|
245
245
|
}
|
|
246
246
|
if (config.arcPlugins?.caching) {
|
|
247
|
-
const { default: cachingPlugin } = await import("./caching-
|
|
247
|
+
const { default: cachingPlugin } = await import("./caching-5DtLwIqb.mjs").then((n) => n.r);
|
|
248
248
|
const opts = config.arcPlugins.caching === true ? {} : config.arcPlugins.caching;
|
|
249
249
|
await fastify.register(cachingPlugin, opts);
|
|
250
250
|
trackPlugin("arc-caching", opts);
|
|
251
251
|
}
|
|
252
252
|
if (config.arcPlugins?.queryCache) {
|
|
253
|
-
const { queryCachePlugin } = await import("./queryCachePlugin-
|
|
253
|
+
const { queryCachePlugin } = await import("./queryCachePlugin-CwTpR04-.mjs").then((n) => n.n);
|
|
254
254
|
const opts = config.arcPlugins.queryCache === true ? {} : config.arcPlugins.queryCache;
|
|
255
|
-
const store = config.stores?.queryCache ?? new (await (import("./memory-
|
|
255
|
+
const store = config.stores?.queryCache ?? new (await (import("./memory-Cp7_cAko.mjs").then((n) => n.n))).MemoryCacheStore();
|
|
256
256
|
await fastify.register(queryCachePlugin, {
|
|
257
257
|
store,
|
|
258
258
|
...opts
|
|
@@ -261,19 +261,19 @@ async function registerArcPlugins(fastify, config, trackPlugin, modules) {
|
|
|
261
261
|
}
|
|
262
262
|
if (config.arcPlugins?.sse) if (config.arcPlugins?.events === false) fastify.log.warn("SSE plugin requires events plugin (arcPlugins.events). SSE disabled.");
|
|
263
263
|
else {
|
|
264
|
-
const { default: ssePlugin } = await import("./sse-
|
|
264
|
+
const { default: ssePlugin } = await import("./sse-Bp3dabF1.mjs").then((n) => n.r);
|
|
265
265
|
const opts = config.arcPlugins.sse === true ? {} : config.arcPlugins.sse;
|
|
266
266
|
await fastify.register(ssePlugin, opts);
|
|
267
267
|
trackPlugin("arc-sse", opts);
|
|
268
268
|
}
|
|
269
269
|
if (config.arcPlugins?.metrics) {
|
|
270
|
-
const { default: metricsPlugin } = await import("./metrics-
|
|
270
|
+
const { default: metricsPlugin } = await import("./metrics-Qnvwc-LQ.mjs").then((n) => n.r);
|
|
271
271
|
const opts = config.arcPlugins.metrics === true ? {} : config.arcPlugins.metrics;
|
|
272
272
|
await fastify.register(metricsPlugin, opts);
|
|
273
273
|
trackPlugin("arc-metrics", opts);
|
|
274
274
|
}
|
|
275
275
|
if (config.arcPlugins?.versioning) {
|
|
276
|
-
const { default: versioningPlugin } = await import("./versioning-
|
|
276
|
+
const { default: versioningPlugin } = await import("./versioning-aUUVziBY.mjs").then((n) => n.r);
|
|
277
277
|
await fastify.register(versioningPlugin, config.arcPlugins.versioning);
|
|
278
278
|
trackPlugin("arc-versioning", config.arcPlugins.versioning);
|
|
279
279
|
}
|
|
@@ -341,7 +341,7 @@ async function registerAuth(fastify, config, trackPlugin) {
|
|
|
341
341
|
*/
|
|
342
342
|
async function registerElevation(fastify, config, trackPlugin) {
|
|
343
343
|
if (!config.elevation) return;
|
|
344
|
-
const { elevationPlugin } = await import("./elevation-
|
|
344
|
+
const { elevationPlugin } = await import("./elevation-By_p2lnn.mjs").then((n) => n.r);
|
|
345
345
|
await fastify.register(elevationPlugin, config.elevation);
|
|
346
346
|
trackPlugin("arc-elevation", config.elevation);
|
|
347
347
|
fastify.log.debug("Elevation plugin enabled");
|
|
@@ -351,7 +351,7 @@ async function registerElevation(fastify, config, trackPlugin) {
|
|
|
351
351
|
*/
|
|
352
352
|
async function registerErrorHandler(fastify, config, trackPlugin) {
|
|
353
353
|
if (config.errorHandler === false) return;
|
|
354
|
-
const { errorHandlerPlugin } = await import("./errorHandler-
|
|
354
|
+
const { errorHandlerPlugin } = await import("./errorHandler-DXUttWEO.mjs").then((n) => n.n);
|
|
355
355
|
const errorOpts = typeof config.errorHandler === "object" ? config.errorHandler : { includeStack: config.preset !== "production" };
|
|
356
356
|
await fastify.register(errorHandlerPlugin, errorOpts);
|
|
357
357
|
trackPlugin("arc-error-handler", errorOpts);
|
|
@@ -668,7 +668,7 @@ function validateDistributedRuntime(options) {
|
|
|
668
668
|
*/
|
|
669
669
|
async function createApp(options) {
|
|
670
670
|
if (options.debug !== void 0 && options.debug !== false) {
|
|
671
|
-
const { configureArcLogger } = await import("./logger-
|
|
671
|
+
const { configureArcLogger } = await import("./logger-DLg8-Ueg.mjs").then((n) => n.r);
|
|
672
672
|
configureArcLogger({ debug: options.debug });
|
|
673
673
|
}
|
|
674
674
|
validateAuthOptions(options);
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
import { s as DEFAULT_UPDATE_METHOD, t as CRUD_OPERATIONS } from "./constants-Cxde4rpC.mjs";
|
|
2
|
-
import {
|
|
3
|
-
import { t as BaseController } from "./BaseController-
|
|
2
|
+
import { _ as isElevated, n as PUBLIC_SCOPE, v as isMember } from "./types-AOD8fxIw.mjs";
|
|
3
|
+
import { t as BaseController } from "./BaseController-CpMfCXdn.mjs";
|
|
4
4
|
import { i as resolveEffectiveRoles, t as applyFieldReadPermissions } from "./fields-ipsbIRPK.mjs";
|
|
5
5
|
import { t as getUserRoles } from "./types-ZUu_h0jp.mjs";
|
|
6
|
-
import { t as
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import { t as
|
|
11
|
-
import {
|
|
6
|
+
import { n as normalizePermissionResult, t as applyPermissionResult } from "./applyPermissionResult-D6GPMsvh.mjs";
|
|
7
|
+
import { t as requestContext } from "./requestContext-xHIKedG6.mjs";
|
|
8
|
+
import { i as getDefaultCrudSchemas } from "./utils-B-l6410F.mjs";
|
|
9
|
+
import { r as ForbiddenError } from "./errors-Cg58SLNi.mjs";
|
|
10
|
+
import { n as convertRouteSchema, t as convertOpenApiSchemas } from "./schemaConverter-0TyONAwM.mjs";
|
|
11
|
+
import { t as hasEvents } from "./typeGuards-CcFZXgU7.mjs";
|
|
12
|
+
import { r as getAvailablePresets, t as applyPresets } from "./presets-BFrGvvjL.mjs";
|
|
12
13
|
//#region src/pipeline/pipe.ts
|
|
13
14
|
/**
|
|
14
15
|
* Compose pipeline steps into an ordered array.
|
|
@@ -372,17 +373,7 @@ function buildPermissionMiddleware(permissionCheck, resourceName, action) {
|
|
|
372
373
|
});
|
|
373
374
|
return;
|
|
374
375
|
}
|
|
375
|
-
|
|
376
|
-
if (!result) {
|
|
377
|
-
reply.code(context.user ? 403 : 401).send({
|
|
378
|
-
success: false,
|
|
379
|
-
error: context.user ? "Permission denied" : "Authentication required"
|
|
380
|
-
});
|
|
381
|
-
return;
|
|
382
|
-
}
|
|
383
|
-
return;
|
|
384
|
-
}
|
|
385
|
-
const permResult = result;
|
|
376
|
+
const permResult = normalizePermissionResult(result);
|
|
386
377
|
if (!permResult.granted) {
|
|
387
378
|
const defaultMsg = context.user ? "Permission denied" : "Authentication required";
|
|
388
379
|
const reason = permResult.reason && permResult.reason.length <= 100 ? permResult.reason : defaultMsg;
|
|
@@ -392,10 +383,7 @@ function buildPermissionMiddleware(permissionCheck, resourceName, action) {
|
|
|
392
383
|
});
|
|
393
384
|
return;
|
|
394
385
|
}
|
|
395
|
-
|
|
396
|
-
...reqWithExtras._policyFilters ?? {},
|
|
397
|
-
...permResult.filters
|
|
398
|
-
};
|
|
386
|
+
applyPermissionResult(permResult, request);
|
|
399
387
|
};
|
|
400
388
|
}
|
|
401
389
|
/**
|
|
@@ -907,6 +895,13 @@ function defineResource(config) {
|
|
|
907
895
|
}
|
|
908
896
|
}
|
|
909
897
|
const repository = config.adapter?.repository;
|
|
898
|
+
if (config.idField === void 0 && repository) {
|
|
899
|
+
const repoIdField = repository.idField;
|
|
900
|
+
if (typeof repoIdField === "string" && repoIdField !== "_id") config = {
|
|
901
|
+
...config,
|
|
902
|
+
idField: repoIdField
|
|
903
|
+
};
|
|
904
|
+
}
|
|
910
905
|
const crudRoutes = CRUD_OPERATIONS;
|
|
911
906
|
const disabledRoutes = new Set(config.disabledRoutes ?? []);
|
|
912
907
|
const hasCrudRoutes = !config.disableDefaultRoutes && crudRoutes.some((route) => !disabledRoutes.has(route));
|
|
@@ -1218,22 +1213,32 @@ var ResourceDefinition = class {
|
|
|
1218
1213
|
}
|
|
1219
1214
|
const listQuerySchema = self._registryMeta?.openApiSchemas?.listQuery;
|
|
1220
1215
|
if (listQuerySchema) {
|
|
1221
|
-
const
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1216
|
+
const NORMALIZED_PROPS = {
|
|
1217
|
+
page: {
|
|
1218
|
+
type: "integer",
|
|
1219
|
+
minimum: 1
|
|
1220
|
+
},
|
|
1221
|
+
limit: {
|
|
1222
|
+
type: "integer",
|
|
1223
|
+
minimum: 1
|
|
1224
|
+
},
|
|
1225
|
+
sort: {},
|
|
1226
|
+
search: {},
|
|
1227
|
+
select: {},
|
|
1228
|
+
after: {},
|
|
1229
|
+
populate: {},
|
|
1230
|
+
lookup: {},
|
|
1231
|
+
aggregate: {}
|
|
1232
|
+
};
|
|
1232
1233
|
const props = listQuerySchema.properties;
|
|
1233
1234
|
const normalizedProps = props ? { ...props } : void 0;
|
|
1234
|
-
if (normalizedProps)
|
|
1235
|
-
|
|
1236
|
-
|
|
1235
|
+
if (normalizedProps) {
|
|
1236
|
+
const originalLimit = normalizedProps.limit;
|
|
1237
|
+
if (originalLimit?.maximum) NORMALIZED_PROPS.limit = {
|
|
1238
|
+
...NORMALIZED_PROPS.limit,
|
|
1239
|
+
maximum: originalLimit.maximum
|
|
1240
|
+
};
|
|
1241
|
+
for (const key of Object.keys(normalizedProps)) normalizedProps[key] = NORMALIZED_PROPS[key] ?? {};
|
|
1237
1242
|
}
|
|
1238
1243
|
const normalizedSchema = {
|
|
1239
1244
|
...listQuerySchema,
|