@classytic/arc 2.30.0 → 2.32.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/LICENSE +1 -1
- package/README.md +7 -0
- package/TRADEMARK.md +22 -0
- package/dist/{BaseController-B5DwufbB.mjs → BaseController-Dk34dxhI.mjs} +21 -19
- package/dist/{EventTransport-QmY7A258.d.mts → EventTransport-2uVV34WU.d.mts} +1 -0
- package/dist/{EventTransport-C6YA8xY9.mjs → EventTransport-BV10D0oG.mjs} +1 -0
- package/dist/{HookSystem-WkIougo6.mjs → HookSystem-vimw5D7Z.mjs} +2 -1
- package/dist/{QueryCache-DOMT_iq7.d.mts → QueryCache-DFA-QrU9.d.mts} +2 -1
- package/dist/{ResourceRegistry-y9Hnypus.mjs → ResourceRegistry-BVr7PgA0.mjs} +18 -15
- package/dist/{actionPermissions-CAphcmUG.mjs → actionPermissions-Dti7ebyv.mjs} +1 -0
- package/dist/audit/index.d.mts +3 -2
- package/dist/audit/index.mjs +2 -1
- package/dist/auth/audit.d.mts +1 -0
- package/dist/auth/audit.mjs +1 -0
- package/dist/auth/index.d.mts +5 -4
- package/dist/auth/index.mjs +11 -9
- package/dist/auth/redis-session.d.mts +2 -1
- package/dist/auth/redis-session.mjs +1 -0
- package/dist/{applyPermissionResult-Cf6zUCvb.mjs → authorizationDecision-__T3EJDA.mjs} +19 -10
- package/dist/{buildHandler-BYS3Vkfz.mjs → buildHandler-Dn7rzUJo.mjs} +6 -4
- package/dist/cache/index.d.mts +4 -3
- package/dist/cache/index.mjs +4 -3
- package/dist/{caching-_NJeDd1_.mjs → caching-DFJqHyFs.mjs} +2 -1
- package/dist/cleanup/index.d.mts +39 -16
- package/dist/cleanup/index.mjs +50 -38
- package/dist/cli/commands/describe.d.mts +2 -1
- package/dist/cli/commands/describe.mjs +4 -5
- package/dist/cli/commands/docs.d.mts +1 -0
- package/dist/cli/commands/docs.mjs +3 -2
- package/dist/cli/commands/doctor.d.mts +1 -0
- package/dist/cli/commands/doctor.mjs +1 -0
- package/dist/cli/commands/generate.d.mts +2 -1
- package/dist/cli/commands/generate.mjs +2 -1
- package/dist/cli/commands/init.d.mts +2 -1
- package/dist/cli/commands/init.mjs +2 -1
- package/dist/cli/commands/introspect.d.mts +1 -0
- package/dist/cli/commands/introspect.mjs +2 -1
- package/dist/cli/index.d.mts +3 -2
- package/dist/cli/index.mjs +3 -2
- package/dist/{constants-DNre0wRg.mjs → constants-J99LGTJI.mjs} +1 -0
- package/dist/context/index.d.mts +1 -0
- package/dist/context/index.mjs +3 -2
- package/dist/core/index.d.mts +3 -2
- package/dist/core/index.mjs +7 -6
- package/dist/{core-poalJLvp.mjs → core-BwwmNSp7.mjs} +3 -2
- package/dist/{createActionRouter-BxuywVRB.mjs → createActionRouter-DkJZWo0m.mjs} +14 -10
- package/dist/{createAggregationRouter-BiY-lGdY.mjs → createAggregationRouter-B1exOVD8.mjs} +10 -7
- package/dist/{createApp-CXrKFciH.mjs → createApp-Bv0m-Q6_.mjs} +625 -229
- package/dist/{defineAggregation-ufWjUwml.mjs → defineAggregation-gX4No1gt.mjs} +1 -0
- package/dist/{defineResource-CxWqDCAy.mjs → defineResource-XFPPUu2c.mjs} +84 -50
- package/dist/discovery/index.d.mts +1 -0
- package/dist/discovery/index.mjs +1 -0
- package/dist/docs/index.d.mts +3 -2
- package/dist/docs/index.mjs +3 -2
- package/dist/{elevation-C9s5hFP_.d.mts → elevation-BXCfVcNG.d.mts} +1 -0
- package/dist/{elevation-CIz1GjGm.mjs → elevation-DNXXxgjl.mjs} +4 -3
- package/dist/encryption/index.d.mts +2 -1
- package/dist/encryption/index.mjs +5 -3
- package/dist/{errorHandler-Bq2OeEQL.mjs → errorHandler-B2AZUJUj.mjs} +3 -2
- package/dist/{errorHandler-C6yv4ZTW.d.mts → errorHandler-CpYUJmPA.d.mts} +1 -0
- package/dist/{errors-DHcHVAgk.d.mts → errors-BGdVwP25.d.mts} +1 -0
- package/dist/{errors-DkO8Nk6-.mjs → errors-Bh1KK5ps.mjs} +1 -0
- package/dist/{eventPlugin-D2NNR4py.mjs → eventPlugin-Dk_TyXeE.mjs} +8 -6
- package/dist/{eventPlugin-Bg3cP2_u.d.mts → eventPlugin-GF5nnBIq.d.mts} +2 -1
- package/dist/events/index.d.mts +112 -44
- package/dist/events/index.mjs +177 -141
- package/dist/events/transports/redis-stream-entry.d.mts +2 -1
- package/dist/events/transports/redis-stream-entry.mjs +14 -9
- package/dist/events/transports/redis.d.mts +2 -1
- package/dist/events/transports/redis.mjs +1 -0
- package/dist/{externalPaths-BE6wFpYv.d.mts → externalPaths-CmGOxOtD.d.mts} +1 -0
- package/dist/factory/index.d.mts +9 -5
- package/dist/factory/index.mjs +131 -7
- package/dist/fastify-augmentation-BppG5bMT.d.mts +179 -0
- package/dist/{fields-CQ_7KQWw.mjs → fields-DEi65pGj.mjs} +6 -10
- package/dist/{fields-D3lhgzhD.d.mts → fields-I_EeRWND.d.mts} +1 -0
- package/dist/{generate-D0wZupBg.mjs → generate-CRSG0jTv.mjs} +2 -1
- package/dist/{generate-BnsL9GBm.d.mts → generate-DCGuEbqI.d.mts} +1 -0
- package/dist/{headers-BvlQSDMB.mjs → headers-BXjQYbeC.mjs} +2 -1
- package/dist/{health-CB_m4S32.mjs → health-5XnTa2uo.mjs} +1 -0
- package/dist/hooks/index.d.mts +2 -1
- package/dist/hooks/index.mjs +2 -1
- package/dist/idempotency/index.d.mts +3 -2
- package/dist/idempotency/index.mjs +8 -5
- package/dist/idempotency/redis.d.mts +2 -1
- package/dist/idempotency/redis.mjs +1 -0
- package/dist/{index-CG4yqMDB.d.mts → index-C-481Zf2.d.mts} +74 -18
- package/dist/{index-Q5gzEIWY.d.mts → index-CpzxqePp.d.mts} +107 -32
- package/dist/{index-Cx7bro4R.d.mts → index-DXlHwvuE.d.mts} +5 -4
- package/dist/index-ZWhLTp_s.d.mts +290 -0
- package/dist/{index-Ch16aAah.d.mts → index-zq6VrjaB.d.mts} +122 -15
- package/dist/index.d.mts +9 -8
- package/dist/index.mjs +11 -10
- package/dist/{init-tlRSt667.mjs → init-BbfP8aky.mjs} +25 -27
- package/dist/{init-BPEu8cs-.d.mts → init-Cscs4lab.d.mts} +1 -0
- package/dist/integrations/event-gateway.d.mts +3 -2
- package/dist/integrations/event-gateway.mjs +2 -1
- package/dist/integrations/index.d.mts +4 -3
- package/dist/integrations/index.mjs +1 -0
- package/dist/integrations/jobs/index.d.mts +2 -1
- package/dist/integrations/jobs/index.mjs +109 -33
- package/dist/integrations/mcp/index.d.mts +6 -6
- package/dist/integrations/mcp/index.mjs +2 -1
- package/dist/integrations/mcp/testing.d.mts +3 -2
- package/dist/integrations/mcp/testing.mjs +2 -2
- package/dist/integrations/streamline.d.mts +1 -0
- package/dist/integrations/streamline.mjs +3 -2
- package/dist/integrations/webhooks.d.mts +1 -0
- package/dist/integrations/webhooks.mjs +1 -0
- package/dist/integrations/websocket-pushref-redis.d.mts +2 -1
- package/dist/integrations/websocket-pushref-redis.mjs +1 -0
- package/dist/integrations/websocket-redis.d.mts +2 -1
- package/dist/integrations/websocket-redis.mjs +1 -0
- package/dist/integrations/websocket.d.mts +3 -2
- package/dist/integrations/websocket.mjs +38 -34
- package/dist/{interface-BGZCzOGL.d.mts → interface-BOk3YnTz.d.mts} +1 -0
- package/dist/{interface-n5hpKg1d.mjs → interface-BP4IJCBO.mjs} +1 -0
- package/dist/{interface-Uk8ONJv7.d.mts → interface-DEWNOMza.d.mts} +1 -0
- package/dist/{jsonBody-BlzAoGCe.mjs → jsonBody-DDSR2HFl.mjs} +2 -1
- package/dist/{keys-Cd316u_y.mjs → keys-B-HBTGXl.mjs} +1 -0
- package/dist/{loadResources-DpU8pfjV.mjs → loadResources-DisEAmkm.mjs} +4 -2
- package/dist/{loadResourcesFromEntry-kvGT6EcO.mjs → loadResourcesFromEntry-D1MJp13f.mjs} +2 -1
- package/dist/logger/index.d.mts +1 -0
- package/dist/logger/index.mjs +1 -0
- package/dist/{mcpPlugin-nRzm5g2s.mjs → mcpPlugin-CpfVpKHE.mjs} +38 -38
- package/dist/{memory-CmnzXE5Z.mjs → memory-DsuWnj4T.mjs} +5 -4
- package/dist/{metrics-fdxI5mn_.mjs → metrics-DdQL8syd.mjs} +2 -1
- package/dist/middleware/index.d.mts +2 -1
- package/dist/middleware/index.mjs +3 -2
- package/dist/migrations/index.d.mts +1 -0
- package/dist/migrations/index.mjs +3 -2
- package/dist/module-Br81am6m.mjs +78 -0
- package/dist/{multipartBody-D0eBvkeq.mjs → multipartBody-BnkBLN7v.mjs} +3 -2
- package/dist/{openapi-B8Vkbxbn.mjs → openapi-DIRzvxC0.mjs} +6 -5
- package/dist/outbox-admin/index.d.mts +85 -0
- package/dist/outbox-admin/index.mjs +115 -0
- package/dist/permissions/index.d.mts +5 -4
- package/dist/permissions/index.mjs +6 -5
- package/dist/{permissions-Bfu_8y1U.mjs → permissions-Dl_m0NCe.mjs} +308 -42
- package/dist/{pipe-BOLmGIxa.mjs → pipe-ELHCP3zj.mjs} +3 -4
- package/dist/pipeline/index.d.mts +2 -1
- package/dist/pipeline/index.mjs +2 -1
- package/dist/{pipeline-BJnpkY9i.mjs → pipeline-CPA-jx0M.mjs} +17 -14
- package/dist/plugins/index.d.mts +8 -7
- package/dist/plugins/index.mjs +16 -15
- package/dist/plugins/response-cache.d.mts +1 -0
- package/dist/plugins/response-cache.mjs +2 -1
- package/dist/plugins/tracing-entry.d.mts +2 -1
- package/dist/plugins/tracing-entry.mjs +2 -1
- package/dist/{pluralize-BhrgwZb9.mjs → pluralize-C2ZkKbsn.mjs} +1 -0
- package/dist/{preloadResources-DSY5HGpS.mjs → preloadResources-CDs87fTw.mjs} +1 -0
- package/dist/{preloadResources-DCfa2egz.d.mts → preloadResources-T1hmlTEZ.d.mts} +117 -12
- package/dist/presets/filesUpload.d.mts +6 -5
- package/dist/presets/filesUpload.mjs +10 -12
- package/dist/presets/index.d.mts +3 -2
- package/dist/presets/index.mjs +2 -1
- package/dist/presets/multiTenant.d.mts +2 -1
- package/dist/presets/multiTenant.mjs +3 -2
- package/dist/presets/search.d.mts +3 -2
- package/dist/presets/search.mjs +2 -1
- package/dist/{presets-CJOEXLuk.mjs → presets-Dntd_pUO.mjs} +6 -4
- package/dist/{projection-UBDgfMwu.mjs → projection-CjHhM5W1.mjs} +2 -1
- package/dist/{pushref-registry-BbcnpNTm.d.mts → pushref-registry-Dov9l4qE.d.mts} +1 -0
- package/dist/{queryCachePlugin-br4otiqF.d.mts → queryCachePlugin-BzqxconG.d.mts} +3 -2
- package/dist/{queryCachePlugin-DSGuSVLW.mjs → queryCachePlugin-Dhps-Ldt.mjs} +6 -5
- package/dist/{rateLimit-DrED-C4v.mjs → rateLimit-C7mmAGs3.mjs} +7 -3
- package/dist/{rateLimitKey-BoWRH3e7.mjs → rateLimitKey-CccEFBfk.mjs} +1 -0
- package/dist/{realtime-B9nmIY5V.mjs → realtime-DVvVZZFz.mjs} +20 -9
- package/dist/{redis-UDtLaNj6.d.mts → redis-CduhKsJi.d.mts} +2 -1
- package/dist/{redis-stream-uIaauNpZ.d.mts → redis-stream-qN6A-RFv.d.mts} +2 -1
- package/dist/{registerRoute-JkxIEBJq.mjs → registerRoute-B_QrjYZS.mjs} +10 -7
- package/dist/registry/index.d.mts +3 -2
- package/dist/registry/index.mjs +3 -2
- package/dist/{registry-BYXUUg21.mjs → registry-DqUmzA9W.mjs} +2 -1
- package/dist/{renewingLease-3cuQH7h8.mjs → renewingLease-BpP9wwj7.mjs} +1 -0
- package/dist/{replyHelpers-67tRawQZ.mjs → replyHelpers-DS-P0b32.mjs} +2 -1
- package/dist/{repositoryFilter-Dz8k3S4P.mjs → repositoryFilter-DotlxG3L.mjs} +1 -0
- package/dist/{requestContext-MrlJwECf.mjs → requestContext-B6vQF-sy.mjs} +1 -0
- package/dist/{rolldown-runtime-8H4AJuhK.mjs → rolldown-runtime-BhflRrBs.mjs} +1 -0
- package/dist/{schedules-CjOd2MG9.mjs → schedules-C2Q3uv2d.mjs} +3 -2
- package/dist/{schemaConverter-DJvodiHj.mjs → schemaConverter-Crjvczi_.mjs} +70 -17
- package/dist/{schemaIR-Ca7ySNPx.mjs → schemaIR-CnyKK_1j.mjs} +2 -1
- package/dist/schemas/index.d.mts +1 -0
- package/dist/schemas/index.mjs +1 -0
- package/dist/scim/index.d.mts +1 -0
- package/dist/scim/index.mjs +2 -1
- package/dist/scope/index.d.mts +3 -2
- package/dist/scope/index.mjs +5 -4
- package/dist/{scope-DfaPntpo.mjs → scope-afz_Ieek.mjs} +4 -3
- package/dist/{sessionManager-BHOM3N_0.d.mts → sessionManager-qimlKV0P.d.mts} +1 -0
- package/dist/{simpleEqualityMatcher-Cg05HPsn.mjs → simpleEqualityMatcher-C4KiMWUa.mjs} +1 -0
- package/dist/{sse-BQ1w0dfl.mjs → sse-B9P4Y-UI.mjs} +7 -5
- package/dist/{sseStream-BQ7Qaynp.mjs → sseStream-B3zb_d1h.mjs} +2 -1
- package/dist/{storage-DLUZ04kK.d.mts → storage-Cx9Sz3Ou.d.mts} +1 -0
- package/dist/{store-helpers-DY6xq4sM.mjs → store-helpers-DmEMHlPQ.mjs} +1 -0
- package/dist/{streaming-BQcW6_Kq.mjs → streaming-DPZdQmDz.mjs} +1 -0
- package/dist/{subscribe-helpers-DfzsivM6.mjs → subscribe-helpers-sp5xTDVA.mjs} +2 -1
- package/dist/sync/changelog.d.mts +1 -0
- package/dist/sync/changelog.mjs +1 -0
- package/dist/testing/cleanupStoreContract.d.mts +2 -1
- package/dist/testing/cleanupStoreContract.mjs +10 -5
- package/dist/testing/index.d.mts +166 -12
- package/dist/testing/index.mjs +315 -43
- package/dist/testing/outboxStoreContract.d.mts +12 -2
- package/dist/testing/outboxStoreContract.mjs +110 -20
- package/dist/testing/storageContract.d.mts +2 -1
- package/dist/testing/storageContract.mjs +11 -5
- package/dist/{tracing-CsGKQJGg.d.mts → tracing-Dro5eH6j.d.mts} +1 -0
- package/dist/{transactionContext-PNdoyLLm.mjs → transactionContext-BvLKvOIL.mjs} +1 -0
- package/dist/{typeGuards-C9KXUly6.mjs → typeGuards-B_5-hKjJ.mjs} +1 -0
- package/dist/types/index.d.mts +6 -5
- package/dist/types/index.mjs +1 -0
- package/dist/types/storage.d.mts +2 -1
- package/dist/types/storage.mjs +1 -0
- package/dist/{types-ChvvVNP8.d.mts → types-B7XeLEgK.d.mts} +34 -2
- package/dist/{types-Cc91nXuA.d.mts → types-ByHn9rEO.d.mts} +1 -0
- package/dist/{types-C_ZZRcD6.d.mts → types-C4QE8qnm.d.mts} +1 -0
- package/dist/{types-D_n8L6VY.d.mts → types-CT5vu6M0.d.mts} +132 -17
- package/dist/{types-DjC-KUCz.d.mts → types-ChuShpCP.d.mts} +1 -0
- package/dist/{types-Bmmn-fO0.d.mts → types-CwcUQ610.d.mts} +2 -6
- package/dist/{types-CSyCxl2V.mjs → types-DXYX7dIR.mjs} +4 -3
- package/dist/usage/index.d.mts +3 -2
- package/dist/usage/index.mjs +0 -0
- package/dist/{userHelpers-Cg_y3fBz.mjs → userHelpers-BNsOXzOd.mjs} +1 -0
- package/dist/utils/index.d.mts +16 -7
- package/dist/utils/index.mjs +10 -9
- package/dist/{utils-taUVD4p3.mjs → utils-BtOha_Sp.mjs} +3 -2
- package/dist/{validate-Bk44F2yT.mjs → validate-PMCPR9El.mjs} +2 -1
- package/dist/{versioning-gKWyryT3.mjs → versioning-CKv2jz_U.mjs} +4 -3
- package/dist/{versioning-DXgY5BUm.d.mts → versioning-D_rhHfZm.d.mts} +5 -2
- package/dist/{websocket-_Pd0CgR0.d.mts → websocket-BOXVggMf.d.mts} +2 -1
- package/package.json +557 -539
- package/skills/arc/SKILL.md +22 -8
- package/skills/arc/references/api-reference.md +4 -0
- package/skills/arc/references/auth.md +3 -0
- package/skills/arc/references/integrations.md +33 -0
- package/skills/arc/references/mcp.md +6 -7
- package/skills/arc/references/production.md +24 -25
- package/skills/arc-code-review/references/anti-patterns.md +3 -3
- package/dist/fastify-augmentation-0WhPnUH7.d.mts +0 -76
- package/dist/index-CCzVR-N3.d.mts +0 -107
- package/dist/module-_-M7C5ES.mjs +0 -29
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
|
|
2
|
+
import { hn as HookSystem, z as ResourceRegistry } from "./index-CpzxqePp.mjs";
|
|
3
|
+
import { t as ExternalOpenApiPaths } from "./externalPaths-CmGOxOtD.mjs";
|
|
4
|
+
import { _ as HealthCheck, f as ScheduleDefinition, r as ArcModuleRegistry, t as ArcModule } from "./types-CT5vu6M0.mjs";
|
|
5
|
+
import { s as ModuleState } from "./index-ZWhLTp_s.mjs";
|
|
6
|
+
import { FastifyPluginAsync } from "fastify";
|
|
7
|
+
//#region src/factory/module/descriptor.d.ts
|
|
8
|
+
/**
|
|
9
|
+
* Resolved module introspection — what a module ACTUALLY composed to.
|
|
10
|
+
*
|
|
11
|
+
* `ArcModule` is the authoring shape: `resources` may be an array or a factory,
|
|
12
|
+
* `owns` may be a list or `"provided"`, and neither tells you what the module
|
|
13
|
+
* ended up mounting. Consumers that needed the resolved answer were reduced to
|
|
14
|
+
* inspecting that shape — a downstream conformance suite had to treat every
|
|
15
|
+
* resource FACTORY as a violation, because it could not distinguish "late-bound
|
|
16
|
+
* and legitimate" from "unresolvable", and so rejected valid modules.
|
|
17
|
+
*
|
|
18
|
+
* A descriptor is the resolved, read-only answer, published after arc has done
|
|
19
|
+
* the work exactly once. It lets tooling assert on the real graph without
|
|
20
|
+
* touching arc internals:
|
|
21
|
+
*
|
|
22
|
+
* - conformance suites verify what a module provides and supersedes;
|
|
23
|
+
* - `doctor` surfaces duplicate resources and unmet dependencies;
|
|
24
|
+
* - tests assert the composed graph instead of re-deriving it;
|
|
25
|
+
* - operators inspect a large installation;
|
|
26
|
+
* - documentation generators read one stable contract.
|
|
27
|
+
*
|
|
28
|
+
* Deliberately DATA — no functions, no live handles. It survives
|
|
29
|
+
* `structuredClone`, so it can cross a worker boundary or be written to a file
|
|
30
|
+
* as-is, and holding one cannot keep a closed app alive.
|
|
31
|
+
*/
|
|
32
|
+
/** One resource as arc resolved it. */
|
|
33
|
+
interface ResolvedResourceDescriptor {
|
|
34
|
+
/** Resource name; absent for an anonymous resource (participates in no dedup). */
|
|
35
|
+
readonly name?: string;
|
|
36
|
+
/** Route prefix, when the resource declared one. */
|
|
37
|
+
readonly prefix?: string;
|
|
38
|
+
/** Whether the resource opted out of the app-wide `resourcePrefix`. */
|
|
39
|
+
readonly skipGlobalPrefix: boolean;
|
|
40
|
+
}
|
|
41
|
+
/** Lifecycle surface a module ended up with — counts, not handles. */
|
|
42
|
+
interface ResolvedModuleLifecycle {
|
|
43
|
+
/** Does the module tear anything down? */
|
|
44
|
+
readonly hasClose: boolean;
|
|
45
|
+
/** Event-handler subscriptions arc owns for this module. */
|
|
46
|
+
readonly subscriptions: number;
|
|
47
|
+
/** Recurring schedules contributed. */
|
|
48
|
+
readonly scheduledJobs: number;
|
|
49
|
+
/** Readiness checks contributed. */
|
|
50
|
+
readonly healthChecks: number;
|
|
51
|
+
/** Whether the module contributed a public export at `arc.modules[name]`. */
|
|
52
|
+
readonly exports: boolean;
|
|
53
|
+
}
|
|
54
|
+
/** The resolved, read-only description of one composed module. */
|
|
55
|
+
interface ResolvedModuleDescriptor {
|
|
56
|
+
readonly name: string;
|
|
57
|
+
/** Declared composition edges, in the order the module listed them. */
|
|
58
|
+
readonly dependsOn: readonly string[];
|
|
59
|
+
/** Resources this module actually mounted, in registration order. */
|
|
60
|
+
readonly resources: readonly ResolvedResourceDescriptor[];
|
|
61
|
+
/**
|
|
62
|
+
* The EFFECTIVE supersession list — already derived when the module declared
|
|
63
|
+
* `owns: "provided"`, so callers never re-implement that resolution.
|
|
64
|
+
*/
|
|
65
|
+
readonly owns: readonly string[];
|
|
66
|
+
readonly lifecycle: ResolvedModuleLifecycle;
|
|
67
|
+
}
|
|
68
|
+
/** Minimal resource shape the descriptor reads. Structural — matches `ResourceLike`. */
|
|
69
|
+
interface DescribableResource {
|
|
70
|
+
readonly name?: string | undefined;
|
|
71
|
+
readonly prefix?: string | undefined;
|
|
72
|
+
readonly skipGlobalPrefix?: boolean | undefined;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Build a descriptor. Called by `registerResources` once per module, after
|
|
76
|
+
* resources are resolved and `owns` is effective.
|
|
77
|
+
*
|
|
78
|
+
* Frozen at every level: a descriptor is a snapshot of a completed decision,
|
|
79
|
+
* and a consumer mutating it would silently disagree with the running app.
|
|
80
|
+
*/
|
|
81
|
+
declare function describeResolvedModule(input: {
|
|
82
|
+
readonly name: string;
|
|
83
|
+
readonly dependsOn?: readonly string[] | undefined;
|
|
84
|
+
readonly resources: readonly DescribableResource[];
|
|
85
|
+
readonly owns: readonly string[];
|
|
86
|
+
readonly lifecycle: ResolvedModuleLifecycle;
|
|
87
|
+
}): ResolvedModuleDescriptor;
|
|
88
|
+
//#endregion
|
|
89
|
+
//#region src/core/arcCorePlugin.d.ts
|
|
90
|
+
interface ArcCorePluginOptions {
|
|
91
|
+
/** Enable event emission for CRUD operations (requires eventPlugin) */
|
|
92
|
+
emitEvents?: boolean;
|
|
93
|
+
/** Hook system instance (for testing/custom setup) */
|
|
94
|
+
hookSystem?: HookSystem;
|
|
95
|
+
/** Resource registry instance (for testing/custom setup) */
|
|
96
|
+
registry?: ResourceRegistry;
|
|
97
|
+
}
|
|
98
|
+
interface PluginMeta {
|
|
99
|
+
name: string;
|
|
100
|
+
version?: string;
|
|
101
|
+
options?: Record<string, unknown>;
|
|
102
|
+
registeredAt: string;
|
|
103
|
+
}
|
|
104
|
+
interface ArcCore {
|
|
105
|
+
/** Instance-scoped hook system */
|
|
106
|
+
hooks: HookSystem;
|
|
107
|
+
/** Instance-scoped resource registry */
|
|
108
|
+
registry: ResourceRegistry;
|
|
109
|
+
/** Whether event emission is enabled */
|
|
110
|
+
emitEvents: boolean;
|
|
111
|
+
/** External OpenAPI paths contributed by auth adapters or third-party integrations */
|
|
112
|
+
externalOpenApiPaths: ExternalOpenApiPaths[];
|
|
113
|
+
/** Registered plugins for introspection */
|
|
114
|
+
plugins: Map<string, PluginMeta>;
|
|
115
|
+
/**
|
|
116
|
+
* Module public exports — `bootstrap()` return values keyed by module name
|
|
117
|
+
* (see `src/factory/module.ts`). Read via `getModuleExports(fastify, name)`:
|
|
118
|
+
* augment `ArcModuleRegistry` once and the name infers the export type;
|
|
119
|
+
* otherwise pass it inline. `Partial<ArcModuleRegistry>` gives augmented
|
|
120
|
+
* apps typed direct access (`fastify.arc.modules.order`), while the
|
|
121
|
+
* `Record<string, unknown>` intersection keeps un-augmented reads open.
|
|
122
|
+
* Populated lazily by `registerResources` — absent until a module exports.
|
|
123
|
+
*/
|
|
124
|
+
modules?: Partial<ArcModuleRegistry> & Record<string, unknown>;
|
|
125
|
+
/**
|
|
126
|
+
* Lifecycle state per composed module (null-proto map, populated by
|
|
127
|
+
* `registerResources` the moment the graph is validated — so it answers
|
|
128
|
+
* "is this module composed?" even for resource-only modules that never
|
|
129
|
+
* record an export). Read via `hasModule(fastify, name)` /
|
|
130
|
+
* `getModuleState(fastify, name)`; the map itself is internal.
|
|
131
|
+
*/
|
|
132
|
+
moduleStates?: Record<string, ModuleState>;
|
|
133
|
+
/**
|
|
134
|
+
* Module-contributed readiness checks, collected in dependency order and
|
|
135
|
+
* frozen by `createApp`. The API role merges these into its `healthPlugin`;
|
|
136
|
+
* `createWorker` reads this to give its probe listener the identical union
|
|
137
|
+
* (the worker preset disables the main health plugin, so this is how module
|
|
138
|
+
* checks reach the probe without a double registration). Empty until
|
|
139
|
+
* `createApp` populates it.
|
|
140
|
+
*/
|
|
141
|
+
healthChecks?: readonly HealthCheck[];
|
|
142
|
+
/**
|
|
143
|
+
* The resolved, dependency-ordered module definitions (frozen by createApp).
|
|
144
|
+
* Integrations that collect a module arm at their OWN init time — e.g. the
|
|
145
|
+
* streamline integration calling `collectModuleWorkflows(fastify, defs)` after
|
|
146
|
+
* it has created + decorated its container — read the list from here. Empty
|
|
147
|
+
* until createApp populates it.
|
|
148
|
+
*/
|
|
149
|
+
moduleDefinitions?: readonly ArcModule[];
|
|
150
|
+
/**
|
|
151
|
+
* RESOLVED module descriptors — what each module actually composed to
|
|
152
|
+
* (resources mounted, effective `owns`, lifecycle counts), published once
|
|
153
|
+
* boot has settled them.
|
|
154
|
+
*
|
|
155
|
+
* Read this rather than `moduleDefinitions` for anything that needs the real
|
|
156
|
+
* graph: a definition's `resources` may still be an unresolved factory and
|
|
157
|
+
* its `owns` may be `"provided"`, so the authoring shape cannot answer "what
|
|
158
|
+
* did this module actually mount?". Frozen, plain data — safe to clone, log,
|
|
159
|
+
* or hand to tooling.
|
|
160
|
+
*/
|
|
161
|
+
moduleDescriptors?: readonly ResolvedModuleDescriptor[];
|
|
162
|
+
/**
|
|
163
|
+
* Module-contributed recurring schedules, resolved once in dependency order
|
|
164
|
+
* and frozen after bootstraps. The same definitions are executed by Arc's
|
|
165
|
+
* schedules plugin and exposed here for introspection. Empty until collection.
|
|
166
|
+
*/
|
|
167
|
+
scheduledJobs?: readonly Readonly<ScheduleDefinition>[];
|
|
168
|
+
}
|
|
169
|
+
declare const arcCorePlugin: FastifyPluginAsync<ArcCorePluginOptions>;
|
|
170
|
+
declare const _default: FastifyPluginAsync<ArcCorePluginOptions>;
|
|
171
|
+
//#endregion
|
|
172
|
+
//#region src/types/fastify-augmentation.d.ts
|
|
173
|
+
declare module "fastify" {
|
|
174
|
+
interface FastifyInstance {
|
|
175
|
+
arc?: ArcCore;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
//#endregion
|
|
179
|
+
export { arcCorePlugin as a, ResolvedResourceDescriptor as c, _default as i, describeResolvedModule as l, ArcCorePluginOptions as n, ResolvedModuleDescriptor as o, PluginMeta as r, ResolvedModuleLifecycle as s, ArcCore as t };
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/*! @classytic/arc v2.32.0 | MIT | https://classytic.com */
|
|
1
2
|
//#region src/permissions/fields.ts
|
|
2
3
|
/**
|
|
3
4
|
* Field-Level Permissions
|
|
@@ -110,10 +111,7 @@ function applyFieldReadPermissions(data, fieldPermissions, userRoles) {
|
|
|
110
111
|
case "visibleTo":
|
|
111
112
|
if (!perm.roles?.some((r) => userRoles.includes(r))) delete result[field];
|
|
112
113
|
break;
|
|
113
|
-
case "redactFor":
|
|
114
|
-
if (perm.roles?.some((r) => userRoles.includes(r))) result[field] = perm.redactValue ?? "***";
|
|
115
|
-
break;
|
|
116
|
-
case "writableBy": break;
|
|
114
|
+
case "redactFor": if (perm.roles?.some((r) => userRoles.includes(r))) result[field] = perm.redactValue ?? "***";
|
|
117
115
|
}
|
|
118
116
|
return result;
|
|
119
117
|
}
|
|
@@ -139,12 +137,10 @@ function applyFieldWritePermissions(body, fieldPermissions, userRoles) {
|
|
|
139
137
|
delete result[field];
|
|
140
138
|
}
|
|
141
139
|
break;
|
|
142
|
-
case "writableBy":
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
}
|
|
147
|
-
break;
|
|
140
|
+
case "writableBy": if (field in result && !perm.roles?.some((r) => userRoles.includes(r))) {
|
|
141
|
+
deniedFields.push(field);
|
|
142
|
+
delete result[field];
|
|
143
|
+
}
|
|
148
144
|
}
|
|
149
145
|
return {
|
|
150
146
|
body: result,
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
|
|
1
|
+
/*! @classytic/arc v2.32.0 | MIT | https://classytic.com */
|
|
2
|
+
import { t as pluralize } from "./pluralize-C2ZkKbsn.mjs";
|
|
2
3
|
import { join } from "node:path";
|
|
3
4
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
4
5
|
//#region src/cli/commands/generate/name-helpers.ts
|
package/dist/hooks/index.d.mts
CHANGED
|
@@ -1,2 +1,3 @@
|
|
|
1
|
-
|
|
1
|
+
|
|
2
|
+
import { Cn as createHookSystem, Sn as beforeUpdate, _n as afterCreate, bn as beforeCreate, dn as HookHandler, fn as HookOperation, gn as HookSystemOptions, hn as HookSystem, ln as DefineHookOptions, mn as HookRegistration, pn as HookPhase, un as HookContext, vn as afterDelete, wn as defineHook, xn as beforeDelete, yn as afterUpdate } from "../index-CpzxqePp.mjs";
|
|
2
3
|
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/hooks/index.mjs
CHANGED
|
@@ -1,2 +1,3 @@
|
|
|
1
|
-
|
|
1
|
+
/*! @classytic/arc v2.32.0 | MIT | https://classytic.com */
|
|
2
|
+
import { a as beforeCreate, c as createHookSystem, i as afterUpdate, l as defineHook, n as afterCreate, o as beforeDelete, r as afterDelete, s as beforeUpdate, t as HookSystem } from "../HookSystem-vimw5D7Z.mjs";
|
|
2
3
|
export { HookSystem, afterCreate, afterDelete, afterUpdate, beforeCreate, beforeDelete, beforeUpdate, createHookSystem, defineHook };
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
import { i as
|
|
1
|
+
|
|
2
|
+
import { i as createIdempotencyResult, n as IdempotencyResult, r as IdempotencyStore, t as IdempotencyLock } from "../interface-DEWNOMza.mjs";
|
|
3
|
+
import { i as RedisIdempotencyStoreOptions, n as RedisClient } from "../redis-CduhKsJi.mjs";
|
|
3
4
|
import { FastifyPluginAsync } from "fastify";
|
|
4
5
|
import { RepositoryLike } from "@classytic/repo-core/adapter";
|
|
5
6
|
//#region src/idempotency/idempotencyPlugin.d.ts
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
import { n as
|
|
3
|
-
import { t as
|
|
1
|
+
/*! @classytic/arc v2.32.0 | MIT | https://classytic.com */
|
|
2
|
+
import { n as requireSingleHeaderValue } from "../headers-BXjQYbeC.mjs";
|
|
3
|
+
import { n as createSafeGetOne, t as createIsDuplicateKeyError } from "../store-helpers-DmEMHlPQ.mjs";
|
|
4
|
+
import { t as createIdempotencyResult } from "../interface-BP4IJCBO.mjs";
|
|
4
5
|
import { and, eq, exists, gt, lt, or, startsWith } from "@classytic/repo-core/filter";
|
|
5
6
|
import { createHash } from "node:crypto";
|
|
6
7
|
import fp from "fastify-plugin";
|
|
@@ -137,8 +138,10 @@ var MemoryIdempotencyStore = class {
|
|
|
137
138
|
}
|
|
138
139
|
async tryLock(key, requestId, ttlMs) {
|
|
139
140
|
const existing = this.locks.get(key);
|
|
140
|
-
if (existing)
|
|
141
|
-
|
|
141
|
+
if (existing) {
|
|
142
|
+
if (/* @__PURE__ */ new Date() > existing.expiresAt) this.locks.delete(key);
|
|
143
|
+
else return false;
|
|
144
|
+
}
|
|
142
145
|
this.locks.set(key, {
|
|
143
146
|
key,
|
|
144
147
|
requestId,
|
|
@@ -1,2 +1,3 @@
|
|
|
1
|
-
|
|
1
|
+
|
|
2
|
+
import { a as UpstashRedisLike, i as RedisIdempotencyStoreOptions, n as RedisClient, o as ioredisAsIdempotencyClient, r as RedisIdempotencyStore, s as upstashAsIdempotencyClient, t as IoredisLike } from "../redis-CduhKsJi.mjs";
|
|
2
3
|
export { type IoredisLike, type RedisClient, RedisIdempotencyStore, type RedisIdempotencyStoreOptions, type UpstashRedisLike, ioredisAsIdempotencyClient, upstashAsIdempotencyClient };
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
|
|
2
|
+
import { r as PermissionCheck } from "./types-B7XeLEgK.mjs";
|
|
1
3
|
import { FastifyPluginAsync } from "fastify";
|
|
2
4
|
//#region src/integrations/jobs/execution.d.ts
|
|
3
5
|
/**
|
|
@@ -43,18 +45,6 @@ interface ExecuteTimedHandlerOptions<T> {
|
|
|
43
45
|
declare function executeTimedHandler<T>(options: ExecuteTimedHandlerOptions<T>): Promise<T>;
|
|
44
46
|
//#endregion
|
|
45
47
|
//#region src/integrations/jobs/types.d.ts
|
|
46
|
-
/**
|
|
47
|
-
* Job queue integration — public contract (definitions, meta, dispatcher).
|
|
48
|
-
*
|
|
49
|
-
* Directory map (mechanical split of the former single file):
|
|
50
|
-
* types.ts — this contract + `defineJob`
|
|
51
|
-
* execution.ts — `executeTimedHandler` (timeout / cancellation / bulkhead)
|
|
52
|
-
* repeat.ts — repeatable-schedule reconciliation (boot hygiene)
|
|
53
|
-
* plugin.ts — BullMQ wiring (queues, workers, DLQ, routes, shutdown)
|
|
54
|
-
* index.ts — public barrel; `src/integrations/jobs.ts` re-exports it
|
|
55
|
-
* so the package subpath is unchanged
|
|
56
|
-
*/
|
|
57
|
-
/** Repeat schedule — cron pattern or fixed interval. Explicit timezone is required. */
|
|
58
48
|
interface JobRepeatOptions {
|
|
59
49
|
/** Cron pattern (e.g. '0 9 * * *' = every day 09:00). Mutually exclusive with `every`. */
|
|
60
50
|
pattern?: string;
|
|
@@ -177,6 +167,61 @@ interface JobsPluginOptions {
|
|
|
177
167
|
jobs: JobDefinition[];
|
|
178
168
|
/** URL prefix for job management endpoints (default: '/jobs') */
|
|
179
169
|
prefix?: string;
|
|
170
|
+
/**
|
|
171
|
+
* Job management HTTP endpoints (`GET <prefix>/stats`,
|
|
172
|
+
* `GET <prefix>/:queue/:id/status`).
|
|
173
|
+
*
|
|
174
|
+
* **Disabled by default.** A job status carries `returnValue` and
|
|
175
|
+
* `failedReason` — the handler's own output and error text, which routinely
|
|
176
|
+
* hold export URLs, billing results, model output, recipient addresses, or
|
|
177
|
+
* internal stack detail. Serving that unauthenticated turns a job id into a
|
|
178
|
+
* read primitive over other tenants' work.
|
|
179
|
+
*
|
|
180
|
+
* Enable it deliberately, with a permission check:
|
|
181
|
+
*
|
|
182
|
+
* ```ts
|
|
183
|
+
* managementRoutes: { operatorPermission: requireRoles(["platform-ops"]) }
|
|
184
|
+
* ```
|
|
185
|
+
*
|
|
186
|
+
* Queue-level counts are also available through the metrics/health
|
|
187
|
+
* integration, which does not expose individual jobs.
|
|
188
|
+
*/
|
|
189
|
+
managementRoutes?: false | {
|
|
190
|
+
/**
|
|
191
|
+
* REQUIRED — arc will not mount an unguarded management surface.
|
|
192
|
+
*
|
|
193
|
+
* **This is an OPERATOR surface, not a tenant-facing one.** A BullMQ job
|
|
194
|
+
* carries no framework-level tenant identity, and `getStatus` fetches
|
|
195
|
+
* straight by queue + id, so a row-level `policy` on the decision has
|
|
196
|
+
* nothing to filter: `requireOrgRole("manager")` would let a manager in
|
|
197
|
+
* org A read a known job handle from org B. `/stats` is inherently
|
|
198
|
+
* global for the same reason.
|
|
199
|
+
*
|
|
200
|
+
* Gate it on an operator role — `requireRoles(["platform-ops"])` — and
|
|
201
|
+
* keep tenant-facing job status in a resource that owns its own row
|
|
202
|
+
* policy. Arc REFUSES a request whose decision carries a `policy`
|
|
203
|
+
* rather than silently ignoring it.
|
|
204
|
+
*/
|
|
205
|
+
operatorPermission: PermissionCheck;
|
|
206
|
+
/**
|
|
207
|
+
* Accept an `operatorPermission` that arc cannot prove is platform-only.
|
|
208
|
+
*
|
|
209
|
+
* By default the gate must carry `_platformOnly` (i.e. come from
|
|
210
|
+
* `requirePlatformRole`), because that property is unprovable from
|
|
211
|
+
* outside: `requireOrgRole("manager")` and the default
|
|
212
|
+
* `requireRoles(["ops"])` both return a bare allow with no policy, so a
|
|
213
|
+
* manager in org A passes and reads a known handle from org B. Boot fails
|
|
214
|
+
* rather than serving a surface whose guard reads as tenant-scoped.
|
|
215
|
+
*
|
|
216
|
+
* Set this only for a custom check you have verified consults platform
|
|
217
|
+
* identity alone.
|
|
218
|
+
*/
|
|
219
|
+
allowUnverifiedOperatorPermission?: boolean;
|
|
220
|
+
/** Include the handler's return value in a status response. Default `false`. */
|
|
221
|
+
exposeResult?: boolean;
|
|
222
|
+
/** Include `failedReason` in a status response. Default `false`. */
|
|
223
|
+
exposeFailureReason?: boolean;
|
|
224
|
+
};
|
|
180
225
|
/** Bridge job events to Arc's event bus (default: true) */
|
|
181
226
|
bridgeEvents?: boolean;
|
|
182
227
|
/** Default job options applied to all jobs */
|
|
@@ -192,19 +237,30 @@ interface JobsPluginOptions {
|
|
|
192
237
|
};
|
|
193
238
|
}
|
|
194
239
|
interface JobDispatcher {
|
|
195
|
-
dispatch<TData = unknown>(name: string, data: TData, options?: JobDispatchOptions): Promise<
|
|
196
|
-
jobId: string;
|
|
197
|
-
}>;
|
|
240
|
+
dispatch<TData = unknown>(name: string, data: TData, options?: JobDispatchOptions): Promise<JobHandle>;
|
|
198
241
|
getQueue(name: string): unknown | null;
|
|
199
242
|
getStats(): Promise<Record<string, QueueStats>>;
|
|
200
243
|
/**
|
|
201
244
|
* Fetch a point-in-time status snapshot for a job by its ID.
|
|
202
|
-
*
|
|
203
|
-
*
|
|
245
|
+
* QUEUE-QUALIFIED: BullMQ job ids are local to their queue, so an id alone
|
|
246
|
+
* cannot identify a job. `dispatch()` returns the queue name alongside the id
|
|
247
|
+
* for exactly this reason.
|
|
248
|
+
*
|
|
249
|
+
* Returns `null` if the queue is not registered, or the job doesn't exist /
|
|
250
|
+
* has been removed by retention policy.
|
|
204
251
|
*/
|
|
205
|
-
getStatus(jobId: string): Promise<JobStatus | null>;
|
|
252
|
+
getStatus(queue: string, jobId: string): Promise<JobStatus | null>;
|
|
206
253
|
close(): Promise<void>;
|
|
207
254
|
}
|
|
255
|
+
/**
|
|
256
|
+
* A dispatched job's address. The queue is part of the identity because BullMQ
|
|
257
|
+
* ids are queue-local — two queues can both hold `"123"`.
|
|
258
|
+
*/
|
|
259
|
+
interface JobHandle {
|
|
260
|
+
/** Registered job name (= queue name). */
|
|
261
|
+
queue: string;
|
|
262
|
+
jobId: string;
|
|
263
|
+
}
|
|
208
264
|
interface QueueStats {
|
|
209
265
|
waiting: number;
|
|
210
266
|
active: number;
|