@classytic/arc 2.19.0 → 2.21.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/bin/arc.js +37 -0
- package/dist/{BaseController-Dy6EQHjM.mjs → BaseController-BnLYgE9A.mjs} +4 -4
- package/dist/{EventTransport-IEn7Tn-Q.d.mts → EventTransport-QmY7A258.d.mts} +0 -1
- package/dist/{QueryCache-TRfXau3W.d.mts → QueryCache-Z1B38koh.d.mts} +0 -1
- package/dist/{ResourceRegistry-5fKZwhK_.mjs → ResourceRegistry-7RnrEWNP.mjs} +1 -1
- package/dist/{actionPermissions-D7NGwcAR.mjs → actionPermissions-ze70xXJi.mjs} +1 -1
- package/dist/audit/index.d.mts +9 -5
- package/dist/audit/index.mjs +1 -1
- package/dist/auth/audit.d.mts +7 -4
- package/dist/auth/audit.mjs +5 -0
- package/dist/auth/index.d.mts +7 -14
- package/dist/auth/index.mjs +7 -5
- package/dist/auth/redis-session.d.mts +1 -2
- package/dist/{buildHandler-B0qvAguf.mjs → buildHandler-D_2ULWxZ.mjs} +3 -3
- package/dist/cache/index.d.mts +2 -3
- package/dist/cache/index.mjs +2 -2
- package/dist/cli/commands/describe.d.mts +1 -2
- package/dist/cli/commands/describe.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 +1 -1
- package/dist/cli/commands/introspect.mjs +4 -13
- package/dist/cli/index.mjs +2 -2
- package/dist/{constants-gaEeMlz-.mjs → constants-DNre0wRg.mjs} +1 -1
- package/dist/context/index.d.mts +2 -2
- package/dist/core/index.d.mts +3 -3
- package/dist/core/index.mjs +5 -5
- package/dist/{core-Ba-6Sue6.mjs → core-DZ6Xe1jR.mjs} +182 -55
- package/dist/{createActionRouter-B_WzBFyf.mjs → createActionRouter-BWMDW-dL.mjs} +4 -4
- package/dist/{createAggregationRouter-B_G_nIjm.mjs → createAggregationRouter-l5mNdYrZ.mjs} +5 -4
- package/dist/{createApp--703hQE1.mjs → createApp-Bi61XxqU.mjs} +229 -24
- package/dist/discovery/index.d.mts +0 -1
- package/dist/docs/index.d.mts +1 -2
- package/dist/docs/index.mjs +1 -1
- package/dist/{elevation-xGUBq6p_.d.mts → elevation-C9s5hFP_.d.mts} +0 -1
- package/dist/encryption/index.d.mts +2 -144
- package/dist/{errorHandler-BtUUDPEa.d.mts → errorHandler-B0e-bq-O.d.mts} +0 -1
- package/dist/{errors-DOHkjQlD.d.mts → errors-DHcHVAgk.d.mts} +0 -1
- package/dist/{eventPlugin-DbBFd3x_.d.mts → eventPlugin-A6EbthXR.d.mts} +10 -6
- package/dist/events/index.d.mts +9 -6
- package/dist/events/index.mjs +9 -6
- package/dist/events/transports/redis-stream-entry.d.mts +1 -1
- package/dist/events/transports/redis.d.mts +1 -2
- package/dist/factory/index.d.mts +5 -4
- package/dist/factory/index.mjs +3 -3
- package/dist/{fastify-augmentation-D-5_yQJi.d.mts → fastify-augmentation-DafigGQp.d.mts} +12 -2
- package/dist/{fields-C7ahdGYf.d.mts → fields-BGqrAa_u.d.mts} +1 -2
- package/dist/{generate-Brans3fW.mjs → generate-usRSdQmP.mjs} +4 -3
- package/dist/hooks/index.d.mts +1 -1
- package/dist/idempotency/index.d.mts +4 -3
- package/dist/idempotency/index.mjs +1 -1
- package/dist/idempotency/redis.d.mts +1 -1
- package/dist/{index-CP6A1Ffj.d.mts → index-B5N-NaHs.d.mts} +88 -7
- package/dist/{index-CRKiiP5o.d.mts → index-B5PoNbfu.d.mts} +41 -7
- package/dist/{index-CUTG2Cuo.d.mts → index-Dtrj6XZk.d.mts} +90 -29
- package/dist/index.d.mts +7 -7
- package/dist/index.mjs +7 -7
- package/dist/{init-Bqpt1Hxf.mjs → init-0YhHkXGk.mjs} +239 -140
- package/dist/integrations/event-gateway.d.mts +2 -3
- package/dist/integrations/index.d.mts +2 -2
- package/dist/integrations/jobs.d.mts +0 -1
- package/dist/integrations/mcp/index.d.mts +6 -7
- package/dist/integrations/mcp/index.mjs +1 -1
- package/dist/integrations/mcp/testing.d.mts +1 -2
- package/dist/integrations/mcp/testing.mjs +1 -1
- package/dist/integrations/streamline.d.mts +19 -7
- package/dist/integrations/streamline.mjs +9 -5
- package/dist/integrations/webhooks.d.mts +0 -1
- package/dist/integrations/websocket-pushref-redis.d.mts +1 -2
- package/dist/integrations/websocket-redis.d.mts +1 -2
- package/dist/integrations/websocket.d.mts +2 -2
- package/dist/{loadResources-B8UmpITt.mjs → loadResources-DpU8pfjV.mjs} +4 -3
- package/dist/{loadResourcesFromEntry-BTlFEx05.mjs → loadResourcesFromEntry-OMCvIEE7.mjs} +1 -1
- package/dist/{mcpPlugin-C088Nd-G.mjs → mcpPlugin-B9XjjNVG.mjs} +148 -49
- package/dist/middleware/index.d.mts +1 -2
- package/dist/middleware/index.mjs +1 -1
- package/dist/module-WeuU5jfd.d.mts +429 -0
- package/dist/{openapi-DZ-5a5Op.mjs → openapi-Kyod_di6.mjs} +3 -3
- package/dist/permissions/index.d.mts +3 -3
- package/dist/permissions/index.mjs +2 -2
- package/dist/{permissions-BPB1xqGf.mjs → permissions-BJMuKMl7.mjs} +43 -3
- package/dist/pipeline/index.d.mts +1 -2
- package/dist/plugins/index.d.mts +87 -10
- package/dist/plugins/index.mjs +91 -4
- package/dist/plugins/response-cache.d.mts +5 -3
- package/dist/plugins/tracing-entry.d.mts +1 -1
- package/dist/plugins/tracing-entry.mjs +1 -1
- package/dist/{pluralize-DccFV9R7.mjs → pluralize-BhrgwZb9.mjs} +3 -3
- package/dist/presets/filesUpload.d.mts +4 -5
- package/dist/presets/filesUpload.mjs +1 -1
- package/dist/presets/index.d.mts +16 -3
- package/dist/presets/index.mjs +1 -1
- package/dist/presets/multiTenant.d.mts +1 -2
- package/dist/presets/multiTenant.mjs +1 -1
- package/dist/presets/search.d.mts +2 -3
- package/dist/presets/search.mjs +3 -2
- package/dist/{presets-BtyFwTO4.mjs → presets-gw0ciIUD.mjs} +1 -1
- package/dist/{pushref-registry-DnCqL3aa.d.mts → pushref-registry-BbcnpNTm.d.mts} +4 -2
- package/dist/{queryCachePlugin-xzFyKAjT.d.mts → queryCachePlugin-CfYWq-Ak.d.mts} +1 -2
- package/dist/{queryCachePlugin-emHb0CuX.mjs → queryCachePlugin-DzqLN904.mjs} +2 -2
- package/dist/{redis-C3W0qbz8.d.mts → redis-UDtLaNj6.d.mts} +0 -1
- package/dist/{redis-stream-DsP1vqZB.d.mts → redis-stream-iVR2l7aS.d.mts} +1 -2
- package/dist/{registerRoute-BdV8DDwU.mjs → registerRoute-oGAl0oA8.mjs} +1 -1
- package/dist/registry/index.d.mts +2 -2
- package/dist/registry/index.mjs +2 -2
- package/dist/{registry-Bm9LjWKs.mjs → registry-vcOCtPij.mjs} +1 -1
- package/dist/{schemaIR-D1MJwqmp.mjs → schemaIR-ajetw3Fv.mjs} +1 -42
- package/dist/schemas/index.d.mts +0 -1
- package/dist/scim/index.d.mts +0 -1
- package/dist/scim/index.mjs +2 -2
- package/dist/scope/index.d.mts +2 -3
- package/dist/{sessionManager-BXG-HGwG.d.mts → sessionManager-BHOM3N_0.d.mts} +10 -6
- package/dist/{storage-Co_PQpeQ.d.mts → storage-DLUZ04kK.d.mts} +8 -4
- package/dist/sync/changelog.d.mts +2 -0
- package/dist/sync/changelog.mjs +2 -0
- package/dist/testing/index.d.mts +2 -3
- package/dist/testing/index.mjs +6 -3
- package/dist/testing/storageContract.d.mts +1 -2
- package/dist/{tracing-D8jlGXP7.d.mts → tracing-CsGKQJGg.d.mts} +0 -1
- package/dist/types/index.d.mts +4 -4
- package/dist/types/storage.d.mts +1 -1
- package/dist/types-Cc91nXuA.d.mts +132 -0
- package/dist/{types-LNebCoJx.d.mts → types-DH0GupI7.d.mts} +8 -4
- package/dist/{types-DpvSF5Hh.d.mts → types-DRj-Ut4n.d.mts} +1 -2
- package/dist/{types-9_wtNPsI.d.mts → types-DpxoNX5v.d.mts} +112 -214
- package/dist/utils/index.d.mts +182 -128
- package/dist/utils/index.mjs +2 -2
- package/dist/{utils-C6QQ9-hd.mjs → utils-CO8a3B_1.mjs} +1435 -1391
- package/dist/{validate-CRcaWzp2.mjs → validate-C2mGgSXg.mjs} +3 -3
- package/dist/{versioning-D_eBCfNr.d.mts → versioning-DQ4mCvg0.d.mts} +1 -2
- package/dist/{websocket-MlYlrYq0.d.mts → websocket-uuWqM6UY.d.mts} +5 -4
- package/package.json +18 -13
- package/skills/arc/SKILL.md +10 -0
- package/skills/arc/references/mcp.md +2 -0
- package/skills/arc-module-publishing/SKILL.md +242 -0
- package/skills/arc-module-publishing/references/authoring-modules.md +272 -0
- package/skills/arc-module-publishing/references/package-manifest.md +155 -0
- package/skills/arc-module-publishing/references/publishing-workflow.md +182 -0
|
@@ -1,208 +1,15 @@
|
|
|
1
|
-
import { Ut as Authenticator } from "./index-
|
|
1
|
+
import { Ut as Authenticator } from "./index-Dtrj6XZk.mjs";
|
|
2
2
|
import { r as CacheStore } from "./interface-C1_WLTMK.mjs";
|
|
3
|
-
import { n as ElevationOptions } from "./elevation-
|
|
4
|
-
import { a as EventTransport } from "./EventTransport-
|
|
3
|
+
import { n as ElevationOptions } from "./elevation-C9s5hFP_.mjs";
|
|
4
|
+
import { a as EventTransport } from "./EventTransport-QmY7A258.mjs";
|
|
5
5
|
import { t as ExternalOpenApiPaths } from "./externalPaths-BE6wFpYv.mjs";
|
|
6
|
-
import { r as QueryCachePluginOptions } from "./queryCachePlugin-
|
|
7
|
-
import { t as
|
|
8
|
-
import {
|
|
9
|
-
import { t as
|
|
6
|
+
import { r as QueryCachePluginOptions } from "./queryCachePlugin-CfYWq-Ak.mjs";
|
|
7
|
+
import { t as ErrorHandlerOptions } from "./errorHandler-B0e-bq-O.mjs";
|
|
8
|
+
import { l as ResourceLike, n as ArcModuleInput } from "./module-WeuU5jfd.mjs";
|
|
9
|
+
import { t as EventPluginOptions } from "./eventPlugin-A6EbthXR.mjs";
|
|
10
|
+
import { _ as HealthOptions, f as CachingOptions, l as SSEOptions, o as MetricsOptions, t as VersioningOptions } from "./versioning-DQ4mCvg0.mjs";
|
|
10
11
|
import { r as IdempotencyStore } from "./interface-Uk8ONJv7.mjs";
|
|
11
12
|
import { FastifyInstance, FastifyPluginAsync, FastifyReply, FastifyRequest, FastifyServerOptions } from "fastify";
|
|
12
|
-
|
|
13
|
-
//#region src/factory/loadResources.d.ts
|
|
14
|
-
/**
|
|
15
|
-
* loadResources — Auto-discover resource files from a directory.
|
|
16
|
-
*
|
|
17
|
-
* Scans for `*.resource.{ts,js,mts,mjs}` files, imports each,
|
|
18
|
-
* and collects their default exports. No barrel file needed.
|
|
19
|
-
*
|
|
20
|
-
* @example
|
|
21
|
-
* ```ts
|
|
22
|
-
* import { createApp, loadResources } from '@classytic/arc/factory';
|
|
23
|
-
*
|
|
24
|
-
* // Recommended: import.meta.url — works in both src/ (dev) and dist/ (prod)
|
|
25
|
-
* const app = await createApp({
|
|
26
|
-
* resources: await loadResources(import.meta.url),
|
|
27
|
-
* auth: { type: 'jwt', jwt: { secret: process.env.JWT_SECRET } },
|
|
28
|
-
* });
|
|
29
|
-
*
|
|
30
|
-
* // Or explicit path (must match runtime layout)
|
|
31
|
-
* const app2 = await createApp({
|
|
32
|
-
* resources: await loadResources('./src/resources'),
|
|
33
|
-
* });
|
|
34
|
-
* ```
|
|
35
|
-
*
|
|
36
|
-
* File convention:
|
|
37
|
-
* ```
|
|
38
|
-
* src/resources/
|
|
39
|
-
* product/product.resource.ts → export default defineResource({ name: 'product', ... })
|
|
40
|
-
* order/order.resource.ts → export default defineResource({ name: 'order', ... })
|
|
41
|
-
* ```
|
|
42
|
-
*/
|
|
43
|
-
/**
|
|
44
|
-
* Resource interface — the contract between `loadResources`/`createApp` and resource definitions.
|
|
45
|
-
*
|
|
46
|
-
* Matches the shape of `ResourceDefinition` from `defineResource()` without requiring
|
|
47
|
-
* the import. All properties except `toPlugin` are optional so plain objects work too:
|
|
48
|
-
*
|
|
49
|
-
* ```typescript
|
|
50
|
-
* // Full resource (from defineResource)
|
|
51
|
-
* const product = defineResource({ name: 'product', ... }); // satisfies ResourceLike
|
|
52
|
-
*
|
|
53
|
-
* // Minimal resource (plain object)
|
|
54
|
-
* const simple: ResourceLike = { name: 'ping', toPlugin: () => () => {} };
|
|
55
|
-
* ```
|
|
56
|
-
*
|
|
57
|
-
* **DO NOT add an index signature** (`[key: string]: unknown`) to this interface.
|
|
58
|
-
* Class instances (like `ResourceDefinition`) don't implicitly carry index signatures,
|
|
59
|
-
* so adding one here makes `ResourceDefinition` *unassignable* to `ResourceLike` —
|
|
60
|
-
* the exact opposite of the intent. TypeScript's structural typing already allows
|
|
61
|
-
* classes with extra properties to satisfy this interface without an index signature.
|
|
62
|
-
*/
|
|
63
|
-
interface ResourceLike {
|
|
64
|
-
/** Plugin factory — called by createApp to register routes */
|
|
65
|
-
toPlugin: () => unknown;
|
|
66
|
-
/** Resource name (used for route generation, logging, duplicate detection) */
|
|
67
|
-
name?: string;
|
|
68
|
-
/** Route prefix (default: `/${name}s`) */
|
|
69
|
-
prefix?: string;
|
|
70
|
-
/** Skip the global `resourcePrefix` from createApp — register at root */
|
|
71
|
-
skipGlobalPrefix?: boolean;
|
|
72
|
-
/** Display name for docs/OpenAPI */
|
|
73
|
-
displayName?: string;
|
|
74
|
-
/** Applied preset names */
|
|
75
|
-
_appliedPresets?: string[];
|
|
76
|
-
}
|
|
77
|
-
/**
|
|
78
|
-
* Resource module — what a `.resource.ts` file's default (or named) export
|
|
79
|
-
* may resolve to.
|
|
80
|
-
*
|
|
81
|
-
* Two shapes accepted:
|
|
82
|
-
* 1. **Plain `ResourceLike`** — the result of `defineResource({...})`.
|
|
83
|
-
* Used as-is; no engine wiring needed.
|
|
84
|
-
* 2. **Factory `(ctx: TContext) => ResourceLike | Promise<ResourceLike>`**
|
|
85
|
-
* — a function arc calls with the `context` from `LoadResourcesOptions`.
|
|
86
|
-
* Eliminates the parallel `createXResource(engine)` factory files +
|
|
87
|
-
* `exclude: [...]` bookkeeping that engine-bound resources used to need.
|
|
88
|
-
*
|
|
89
|
-
* Detection is by `typeof === 'function'`: `ResourceDefinition` instances
|
|
90
|
-
* (returned by `defineResource()`) are class instances (`typeof === 'object'`),
|
|
91
|
-
* so the two shapes are unambiguous in practice.
|
|
92
|
-
*/
|
|
93
|
-
type ResourceModule<TContext = unknown> = ResourceLike | ((ctx: TContext) => ResourceLike | Promise<ResourceLike>);
|
|
94
|
-
interface LoadResourcesOptions<TContext = unknown> {
|
|
95
|
-
/** File pattern suffix (default: '.resource'). Matches `*.resource.{ts,js,mts,mjs}`. */
|
|
96
|
-
suffix?: string;
|
|
97
|
-
/** Recurse into subdirectories (default: true) */
|
|
98
|
-
recursive?: boolean;
|
|
99
|
-
/**
|
|
100
|
-
* Context passed to factory-style default exports. Resources whose default
|
|
101
|
-
* export is a function `(ctx) => ResourceLike` are called with this value;
|
|
102
|
-
* plain `ResourceLike` exports are returned unchanged.
|
|
103
|
-
*
|
|
104
|
-
* Use this to thread engine handles into engine-bound resources without
|
|
105
|
-
* creating parallel factory files outside `loadResources`'s sweep:
|
|
106
|
-
*
|
|
107
|
-
* ```ts
|
|
108
|
-
* // category.resource.ts
|
|
109
|
-
* import type { AppContext } from '#core/app/context.js';
|
|
110
|
-
* export default (ctx: AppContext) =>
|
|
111
|
-
* defineResource({
|
|
112
|
-
* name: 'category',
|
|
113
|
-
* adapter: createMongooseAdapter(
|
|
114
|
-
* ctx.catalog.models.Category,
|
|
115
|
-
* ctx.catalog.repositories.category,
|
|
116
|
-
* ),
|
|
117
|
-
* });
|
|
118
|
-
*
|
|
119
|
-
* // create-arc-app-options.ts
|
|
120
|
-
* resources: async () => {
|
|
121
|
-
* const [catalog, flow] = await Promise.all([
|
|
122
|
-
* ensureCatalogEngine(),
|
|
123
|
-
* ensureFlowEngine(),
|
|
124
|
-
* ]);
|
|
125
|
-
* return loadResources(import.meta.url, { context: { catalog, flow } });
|
|
126
|
-
* }
|
|
127
|
-
* ```
|
|
128
|
-
*
|
|
129
|
-
* Backwards compatible — pre-2.11.1 callers omit `context`, plain exports
|
|
130
|
-
* keep working unchanged. Factories that need a context but receive
|
|
131
|
-
* `undefined` should narrow defensively.
|
|
132
|
-
*/
|
|
133
|
-
context?: TContext;
|
|
134
|
-
/**
|
|
135
|
-
* Resource names to exclude. Matched against the resource's `.name` property
|
|
136
|
-
* after import, so you use the resource name (not the filename).
|
|
137
|
-
*
|
|
138
|
-
* @example
|
|
139
|
-
* ```ts
|
|
140
|
-
* await loadResources('./src/resources', { exclude: ['debug', 'legacy-report'] })
|
|
141
|
-
* ```
|
|
142
|
-
*/
|
|
143
|
-
exclude?: string[];
|
|
144
|
-
/**
|
|
145
|
-
* Resource names to include. When set, only matching resources are returned.
|
|
146
|
-
* Takes priority over `exclude`.
|
|
147
|
-
*
|
|
148
|
-
* @example
|
|
149
|
-
* ```ts
|
|
150
|
-
* // Only load these two resources (useful for testing or microservice splits)
|
|
151
|
-
* await loadResources('./src/resources', { include: ['product', 'order'] })
|
|
152
|
-
* ```
|
|
153
|
-
*/
|
|
154
|
-
include?: string[];
|
|
155
|
-
/**
|
|
156
|
-
* Optional logger override for diagnostics. When omitted, warnings flow
|
|
157
|
-
* through arc's standard logger (`arcLog('loadResources')`) — same path
|
|
158
|
-
* as every other arc-internal warning, controlled by `ARC_SUPPRESS_WARNINGS=1`
|
|
159
|
-
* and routable via `configureArcLogger({ writer })`.
|
|
160
|
-
*
|
|
161
|
-
* Pass any object with `warn(msg)` to override (e.g. `fastify.log` —
|
|
162
|
-
* which is what `registerResources` passes automatically when arc's
|
|
163
|
-
* factory triggers auto-discovery via `resourceDir`).
|
|
164
|
-
*
|
|
165
|
-
* Pre-2.11.1 had a `silent: boolean` flag and "silent by default" semantics;
|
|
166
|
-
* both removed. Migration:
|
|
167
|
-
*
|
|
168
|
-
* ```ts
|
|
169
|
-
* // Pre-2.11.1 // 2.11.1+
|
|
170
|
-
* loadResources(url, { silent: true }); // ARC_SUPPRESS_WARNINGS=1 (env)
|
|
171
|
-
* // OR configureArcLogger({ writer })
|
|
172
|
-
* loadResources(url, { silent: !isDev }); // ARC_SUPPRESS_WARNINGS=1 in prod
|
|
173
|
-
* loadResources(url, { logger: pinoAdapter }); // unchanged — still works
|
|
174
|
-
* ```
|
|
175
|
-
*/
|
|
176
|
-
logger?: {
|
|
177
|
-
warn: (msg: string) => void;
|
|
178
|
-
};
|
|
179
|
-
}
|
|
180
|
-
/**
|
|
181
|
-
* Scan a directory for resource files and import their default exports.
|
|
182
|
-
*
|
|
183
|
-
* Accepts a directory path OR `import.meta.url` (file:// URL).
|
|
184
|
-
* When given a URL, resolves to the directory containing that file —
|
|
185
|
-
* so `loadResources(import.meta.url)` works in both dev (`src/`) and
|
|
186
|
-
* production (`dist/`) without path gymnastics.
|
|
187
|
-
*
|
|
188
|
-
* @param dir - Directory path, or `import.meta.url` (file:// URL resolved to its dirname)
|
|
189
|
-
* @param options - Pattern and recursion options
|
|
190
|
-
* @returns Array of resource definitions (anything with `.toPlugin()`)
|
|
191
|
-
*
|
|
192
|
-
* @example
|
|
193
|
-
* ```ts
|
|
194
|
-
* // Works from both src/ and dist/ — resolves relative to the calling file
|
|
195
|
-
* await loadResources(import.meta.url);
|
|
196
|
-
*
|
|
197
|
-
* // Subdirectory relative to the calling file
|
|
198
|
-
* await loadResources(import.meta.url, { suffix: '.resource' });
|
|
199
|
-
*
|
|
200
|
-
* // Explicit path (must match runtime layout)
|
|
201
|
-
* await loadResources('./src/resources');
|
|
202
|
-
* ```
|
|
203
|
-
*/
|
|
204
|
-
declare function loadResources<TContext = unknown>(dir: string, options?: LoadResourcesOptions<TContext>): Promise<ResourceLike[]>;
|
|
205
|
-
//#endregion
|
|
206
13
|
//#region src/testing/preloadResources.d.ts
|
|
207
14
|
/** Eager glob result: `{ '/path/to/file.ts': resourceModule }` */
|
|
208
15
|
type EagerGlobResult = Record<string, unknown>;
|
|
@@ -287,11 +94,17 @@ interface JwtAuthOption {
|
|
|
287
94
|
* If provided, jwt utilities are available in authenticator context
|
|
288
95
|
*/
|
|
289
96
|
jwt?: {
|
|
290
|
-
/** JWT secret (required for JWT features) */
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
97
|
+
/** JWT secret (required for JWT features) */
|
|
98
|
+
secret: string;
|
|
99
|
+
/** Access token expiry (default: '15m') */
|
|
100
|
+
expiresIn?: string;
|
|
101
|
+
/** Refresh token secret (defaults to main secret) */
|
|
102
|
+
refreshSecret?: string;
|
|
103
|
+
/** Refresh token expiry (default: '7d') */
|
|
104
|
+
refreshExpiresIn?: string;
|
|
105
|
+
/** Additional @fastify/jwt sign options */
|
|
106
|
+
sign?: Record<string, unknown>;
|
|
107
|
+
/** Additional @fastify/jwt verify options */
|
|
295
108
|
verify?: Record<string, unknown>;
|
|
296
109
|
};
|
|
297
110
|
/**
|
|
@@ -481,9 +294,13 @@ interface CreateAppOptions {
|
|
|
481
294
|
* not memory-backed. Provide Redis or other durable adapters.
|
|
482
295
|
*/
|
|
483
296
|
stores?: {
|
|
484
|
-
/** Event transport (e.g., RedisEventTransport) */
|
|
485
|
-
|
|
486
|
-
|
|
297
|
+
/** Event transport (e.g., RedisEventTransport) */
|
|
298
|
+
events?: EventTransport;
|
|
299
|
+
/** Cache store (e.g., RedisCacheStore) */
|
|
300
|
+
cache?: CacheStore;
|
|
301
|
+
/** Idempotency store (e.g., RedisIdempotencyStore) */
|
|
302
|
+
idempotency?: IdempotencyStore;
|
|
303
|
+
/** QueryCache store (e.g., RedisCacheStore). Default: MemoryCacheStore. */
|
|
487
304
|
queryCache?: CacheStore;
|
|
488
305
|
};
|
|
489
306
|
/** Fastify logger configuration */
|
|
@@ -634,7 +451,8 @@ interface CreateAppOptions {
|
|
|
634
451
|
rawBody?: RawBodyOptions | false;
|
|
635
452
|
/** Enable Arc plugins (requestId, health, gracefulShutdown, events, caching, sse) */
|
|
636
453
|
arcPlugins?: {
|
|
637
|
-
/** Request ID tracking (default: true) */
|
|
454
|
+
/** Request ID tracking (default: true) */
|
|
455
|
+
requestId?: boolean;
|
|
638
456
|
/**
|
|
639
457
|
* Health endpoints (default: true).
|
|
640
458
|
*
|
|
@@ -661,8 +479,10 @@ interface CreateAppOptions {
|
|
|
661
479
|
* }
|
|
662
480
|
* ```
|
|
663
481
|
*/
|
|
664
|
-
health?: boolean | HealthOptions;
|
|
665
|
-
|
|
482
|
+
health?: boolean | HealthOptions;
|
|
483
|
+
/** Graceful shutdown handling (default: true) */
|
|
484
|
+
gracefulShutdown?: boolean;
|
|
485
|
+
/** Emit events for CRUD operations (default: true) */
|
|
666
486
|
emitEvents?: boolean;
|
|
667
487
|
/**
|
|
668
488
|
* Event plugin configuration. Default: true (enabled with MemoryEventTransport).
|
|
@@ -843,6 +663,56 @@ interface CreateAppOptions {
|
|
|
843
663
|
* ```
|
|
844
664
|
*/
|
|
845
665
|
serializeBigInt?: boolean | "number" | "string";
|
|
666
|
+
/**
|
|
667
|
+
* Domain modules — compose whole domains into the app, one entry each.
|
|
668
|
+
*
|
|
669
|
+
* Where a `resources` entry is a single route group, a module is a self-
|
|
670
|
+
* contained domain package's full contribution (engine init + resources +
|
|
671
|
+
* post-wiring) bundled as one `ArcModule`. A package exports
|
|
672
|
+
* `createXModule(deps): ArcModule`; the host lists it here instead of hand-
|
|
673
|
+
* threading the package's pieces across `bootstrap` / `resources` /
|
|
674
|
+
* `afterResources`.
|
|
675
|
+
*
|
|
676
|
+
* Modules are pure sugar over the existing lifecycle — each expands into the
|
|
677
|
+
* SAME phases, in `dependsOn` order, running BEFORE the app-level entry in
|
|
678
|
+
* every phase:
|
|
679
|
+
* ```
|
|
680
|
+
* app plugins() → modules[].plugins (infra registration)
|
|
681
|
+
* modules[].bootstrap → options.bootstrap
|
|
682
|
+
* modules[].resources → options.resources / resourceDir (see note ↓)
|
|
683
|
+
* modules[].afterResources → options.afterResources
|
|
684
|
+
* modules[].onClose (REVERSE order) → options.onClose (one hook; see below)
|
|
685
|
+
* ```
|
|
686
|
+
* RESOURCES — two orderings, both intentional: app `resources`/`resourceDir`
|
|
687
|
+
* RESOLVE first (semantics untouched), but module resources REGISTER first
|
|
688
|
+
* (prepended, so their routes mount ahead of app resources). Teardown runs
|
|
689
|
+
* module `onClose` (reverse composition order) then app `onClose` in a single
|
|
690
|
+
* close hook, so module teardown (flush outboxes, drain queues, close a
|
|
691
|
+
* module-owned connection) sees live shared infra — the app/plugin
|
|
692
|
+
* connections close last. Module resources flow through arc's normal
|
|
693
|
+
* registration (prefix, dedup, docs, audit) — they are not special-cased.
|
|
694
|
+
*
|
|
695
|
+
* Entries may be eager modules, promises, or **thunks of dynamic imports**
|
|
696
|
+
* (the `next/dynamic` idea, backend-shaped) — thunks resolve once at boot,
|
|
697
|
+
* so region/tier-gated packs are only imported when selected:
|
|
698
|
+
*
|
|
699
|
+
* @example
|
|
700
|
+
* ```ts
|
|
701
|
+
* const taxPack = region === 'BD'
|
|
702
|
+
* ? () => import('@classytic/bd-tax/module').then((m) => m.createBdTaxModule(deps))
|
|
703
|
+
* : () => import('@classytic/us-tax/module').then((m) => m.createUsTaxModule(deps));
|
|
704
|
+
*
|
|
705
|
+
* const app = await createApp({
|
|
706
|
+
* resourcePrefix: '/api/v1',
|
|
707
|
+
* modules: [accountingModule({ permissions }), taxPack],
|
|
708
|
+
* resources: [healthResource], // app-local resources still compose alongside
|
|
709
|
+
* });
|
|
710
|
+
* ```
|
|
711
|
+
*
|
|
712
|
+
* See `wiki/modules.md` for the full design (authoring convention, events/
|
|
713
|
+
* outbox integration, microservices path).
|
|
714
|
+
*/
|
|
715
|
+
modules?: ReadonlyArray<ArcModuleInput>;
|
|
846
716
|
/**
|
|
847
717
|
* Resources to register automatically. Accepts two shapes:
|
|
848
718
|
*
|
|
@@ -993,6 +863,32 @@ interface CreateAppOptions {
|
|
|
993
863
|
* @default false
|
|
994
864
|
*/
|
|
995
865
|
strictResources?: boolean;
|
|
866
|
+
/**
|
|
867
|
+
* Pre-boot hook — awaited BEFORE arc does anything else: before the
|
|
868
|
+
* Fastify instance exists, before module thunks resolve, before resource
|
|
869
|
+
* discovery imports a single host file.
|
|
870
|
+
*
|
|
871
|
+
* The canonical slot for the DB connection and anything that
|
|
872
|
+
* module-EVAL-time code depends on. Engines that register Mongoose models
|
|
873
|
+
* at import time (top-level `createXEngine(...)`) trigger eager
|
|
874
|
+
* `createIndex()` calls from schema plugins — if the connection isn't
|
|
875
|
+
* open yet those buffer and die with `buffering timed out`. Hosts used to
|
|
876
|
+
* hand-orchestrate this with `await connectDatabase()` + dynamic
|
|
877
|
+
* `await import(...)` tricks before calling `createApp`; with `beforeBoot`
|
|
878
|
+
* the ordering is arc's contract instead:
|
|
879
|
+
*
|
|
880
|
+
* ```ts
|
|
881
|
+
* const app = await createApp({
|
|
882
|
+
* beforeBoot: async () => { await connectDatabase(); },
|
|
883
|
+
* modules: [() => import('#modules/accounting.js')], // thunks resolve AFTER beforeBoot
|
|
884
|
+
* resources: async () => [...],
|
|
885
|
+
* });
|
|
886
|
+
* ```
|
|
887
|
+
*
|
|
888
|
+
* Runs after option validation (config bugs fail fast without touching
|
|
889
|
+
* the DB). Cleanup stays host-owned — pair with `onClose`.
|
|
890
|
+
*/
|
|
891
|
+
beforeBoot?: () => void | Promise<void>;
|
|
996
892
|
/**
|
|
997
893
|
* Custom plugin registration — runs after Arc core (security, auth, events)
|
|
998
894
|
* but before `bootstrap` and `resources`.
|
|
@@ -1049,7 +945,9 @@ interface UnderPressureOptions {
|
|
|
1049
945
|
}
|
|
1050
946
|
interface MultipartOptions {
|
|
1051
947
|
limits?: {
|
|
1052
|
-
/** Max file size in bytes (default: Fastify default ~1MB) */
|
|
948
|
+
/** Max file size in bytes (default: Fastify default ~1MB) */
|
|
949
|
+
fileSize?: number;
|
|
950
|
+
/** Max number of files per request */
|
|
1053
951
|
files?: number;
|
|
1054
952
|
};
|
|
1055
953
|
}
|
|
@@ -1064,4 +962,4 @@ interface RawBodyOptions {
|
|
|
1064
962
|
runFirst?: boolean;
|
|
1065
963
|
}
|
|
1066
964
|
//#endregion
|
|
1067
|
-
export { CustomPluginAuthOption as a, RawBodyOptions as c, preloadResourcesAsync as d,
|
|
965
|
+
export { CustomPluginAuthOption as a, RawBodyOptions as c, preloadResourcesAsync as d, CustomAuthenticatorOption as i, UnderPressureOptions as l, BetterAuthOption as n, JwtAuthOption as o, CreateAppOptions as r, MultipartOptions as s, AuthOption as t, preloadResources as u };
|