@classytic/arc 2.11.3 → 2.13.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 +27 -18
- package/dist/{BaseController-swXruJ2_.mjs → BaseController-DX_T-bDB.mjs} +388 -423
- package/dist/EventTransport-CT_52aWU.d.mts +34 -0
- package/dist/EventTransport-DLWoUMHy.mjs +103 -0
- package/dist/{QueryCache-DOBNHBE0.d.mts → QueryCache-D41bfdBB.d.mts} +1 -1
- package/dist/{ResourceRegistry-DkAeAuTX.mjs → ResourceRegistry-CTERg_2x.mjs} +139 -66
- package/dist/audit/index.d.mts +2 -2
- package/dist/audit/index.mjs +1 -1
- package/dist/auth/audit.d.mts +199 -0
- package/dist/auth/audit.mjs +288 -0
- package/dist/auth/index.d.mts +5 -5
- package/dist/auth/index.mjs +117 -191
- package/dist/auth/redis-session.d.mts +1 -1
- package/dist/{betterAuthOpenApi-DwxtK3uG.mjs → betterAuthOpenApi--M_i87dQ.mjs} +1 -1
- package/dist/buildHandler-olo-gt94.mjs +610 -0
- package/dist/cache/index.d.mts +3 -3
- package/dist/cache/index.mjs +3 -3
- package/dist/cli/commands/describe.d.mts +89 -13
- package/dist/cli/commands/describe.mjs +56 -2
- package/dist/cli/commands/docs.mjs +2 -2
- package/dist/cli/commands/generate.mjs +147 -48
- package/dist/cli/commands/init.d.mts +13 -0
- package/dist/cli/commands/init.mjs +237 -112
- package/dist/cli/commands/introspect.mjs +8 -1
- package/dist/context/index.mjs +1 -1
- package/dist/core/index.d.mts +3 -3
- package/dist/core/index.mjs +5 -5
- package/dist/core-D72ia0EH.mjs +1399 -0
- package/dist/{createActionRouter-u3ql2EDo.mjs → createActionRouter-CEvzKcy8.mjs} +7 -20
- package/dist/createAggregationRouter-CyecOxnO.mjs +114 -0
- package/dist/{createApp-BFxtdKy6.mjs → createApp-XX2-N0Yd.mjs} +31 -27
- package/dist/defineEvent-D5h7EvAx.mjs +188 -0
- package/dist/docs/index.d.mts +2 -2
- package/dist/docs/index.mjs +2 -2
- package/dist/{elevation-DOFoxoDs.mjs → elevation-DgoeTyfX.mjs} +1 -1
- package/dist/errorHandler-Bk-AGhkU.mjs +174 -0
- package/dist/errorHandler-DFr45ZG4.d.mts +45 -0
- package/dist/errors-j4aJm1Wg.mjs +184 -0
- package/dist/{eventPlugin-KrFIQ097.mjs → eventPlugin-CaKTYkYM.mjs} +35 -137
- package/dist/{eventPlugin-CUNjYYRY.d.mts → eventPlugin-qXpqTebY.d.mts} +57 -7
- package/dist/events/index.d.mts +164 -5
- package/dist/events/index.mjs +133 -209
- package/dist/events/transports/redis-stream-entry.d.mts +1 -1
- package/dist/events/transports/redis-stream-entry.mjs +204 -31
- package/dist/events/transports/redis.d.mts +1 -1
- package/dist/factory/index.d.mts +2 -2
- package/dist/factory/index.mjs +2 -2
- package/dist/{fields-C8Y0XLAu.d.mts → fields-COhcH3fk.d.mts} +23 -2
- 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/index.mjs +1 -20
- package/dist/idempotency/redis.d.mts +1 -1
- package/dist/idempotency/redis.mjs +1 -1
- package/dist/{index-BYCqHCVu.d.mts → index-BTqLEvhu.d.mts} +164 -4
- package/dist/{index-6u4_Gg6G.d.mts → index-BtW7qYwa.d.mts} +661 -281
- package/dist/{index-BdXnTPRj.d.mts → index-Ds61mrJE.d.mts} +50 -4
- package/dist/{index-DdQ3O9Pg.d.mts → index-Dz5IKsrE.d.mts} +360 -219
- package/dist/index.d.mts +6 -7
- package/dist/index.mjs +9 -10
- package/dist/integrations/event-gateway.d.mts +2 -2
- package/dist/integrations/event-gateway.mjs +1 -1
- package/dist/integrations/index.d.mts +2 -2
- 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/integrations/streamline.d.mts +60 -11
- package/dist/integrations/streamline.mjs +75 -85
- package/dist/integrations/websocket-redis.d.mts +1 -1
- package/dist/integrations/websocket.d.mts +1 -1
- package/dist/integrations/websocket.mjs +2 -8
- package/dist/middleware/index.d.mts +1 -1
- package/dist/middleware/index.mjs +2 -2
- package/dist/migrations/index.d.mts +23 -3
- package/dist/migrations/index.mjs +0 -7
- package/dist/{multipartBody-CvTR1Un6.mjs → multipartBody-BOvVSVCD.mjs} +11 -8
- package/dist/{openapi-BGUn7Ki1.mjs → openapi-CiOMVW1p.mjs} +143 -13
- package/dist/org/index.d.mts +2 -2
- package/dist/org/index.mjs +1 -1
- package/dist/permissions/index.d.mts +3 -3
- package/dist/permissions/index.mjs +3 -3
- package/dist/{permissions-gd_aUWrR.mjs → permissions-ohQyv50e.mjs} +404 -176
- package/dist/{pipe-DVoIheVC.mjs → pipe-Zr0KXjQe.mjs} +1 -1
- package/dist/pipeline/index.d.mts +1 -1
- package/dist/pipeline/index.mjs +1 -1
- package/dist/plugins/index.d.mts +18 -33
- package/dist/plugins/index.mjs +33 -13
- 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/presets/filesUpload.d.mts +5 -5
- package/dist/presets/filesUpload.mjs +6 -9
- package/dist/presets/index.d.mts +1 -1
- package/dist/presets/index.mjs +1 -1
- package/dist/presets/multiTenant.d.mts +1 -1
- package/dist/presets/multiTenant.mjs +2 -2
- package/dist/presets/search.d.mts +2 -2
- package/dist/presets/search.mjs +6 -8
- package/dist/{presets-Z7P5w4gF.mjs → presets-BbkjdPeH.mjs} +6 -28
- package/dist/{queryCachePlugin-BUXBSm4F.d.mts → queryCachePlugin-CqMdLI2-.d.mts} +2 -2
- package/dist/{queryCachePlugin-Bq6bO6vc.mjs → queryCachePlugin-m1XsgAIJ.mjs} +3 -3
- package/dist/{redis-Cm1gnRDf.d.mts → redis-DiMkdHEl.d.mts} +1 -1
- package/dist/redis-stream-D6HzR1Z_.d.mts +232 -0
- package/dist/registry/index.d.mts +1 -1
- package/dist/registry/index.mjs +2 -2
- package/dist/{replyHelpers-ByllIXXV.mjs → replyHelpers-CK-FNO8E.mjs} +3 -21
- package/dist/{resourceToTools-ByZpgjeH.mjs → resourceToTools-C5coh64w.mjs} +224 -71
- package/dist/{routerShared-BqLRb5l7.mjs → routerShared-D6_fEGHh.mjs} +40 -36
- package/dist/{schemaIR-BlG9bY7v.mjs → schemaIR-7Vl611Qs.mjs} +1 -1
- package/dist/schemas/index.d.mts +100 -30
- package/dist/schemas/index.mjs +86 -29
- package/dist/scim/index.d.mts +264 -0
- package/dist/scim/index.mjs +963 -0
- package/dist/scope/index.d.mts +3 -3
- package/dist/scope/index.mjs +4 -4
- package/dist/{sse-V7aXc3bW.mjs → sse-Bz-5ZeTt.mjs} +1 -1
- package/dist/{store-helpers-BhrzxvyQ.mjs → store-helpers-BkIN9-vu.mjs} +1 -1
- package/dist/testing/index.d.mts +2 -8
- package/dist/testing/index.mjs +16 -24
- package/dist/testing/storageContract.d.mts +1 -1
- package/dist/types/index.d.mts +4 -4
- package/dist/types/storage.d.mts +1 -1
- package/dist/{types-BH7dEGvU.d.mts → types-BvqwCCSx.d.mts} +77 -29
- package/dist/{types-tgR4Pt8F.d.mts → types-CTYvcwHe.d.mts} +195 -1
- package/dist/{types-AOD8fxIw.mjs → types-C_s5moIu.mjs} +117 -1
- package/dist/{types-9beEMe25.d.mts → types-DQHFc8PM.d.mts} +1 -1
- package/dist/utils/index.d.mts +2 -2
- package/dist/utils/index.mjs +5 -5
- package/dist/{utils-CcYTj09l.mjs → utils-_h9B3c57.mjs} +1269 -1334
- package/dist/{versioning-M9lNLhO8.d.mts → versioning-DTTvc80y.d.mts} +1 -1
- package/package.json +24 -34
- package/skills/arc/SKILL.md +521 -785
- package/skills/arc/references/agent-auth.md +238 -0
- package/skills/arc/references/api-reference.md +187 -0
- package/skills/arc/references/auth.md +354 -7
- package/skills/arc/references/enterprise-auth.md +94 -0
- package/skills/arc/references/events.md +8 -6
- package/skills/arc/references/mcp.md +2 -2
- package/skills/arc/references/multi-tenancy.md +11 -2
- package/skills/arc/references/production.md +10 -9
- package/skills/arc/references/scim.md +247 -0
- package/skills/arc/references/testing.md +1 -1
- package/skills/arc-code-review/SKILL.md +141 -0
- package/skills/arc-code-review/references/anti-patterns.md +911 -0
- package/skills/arc-code-review/references/arc-cheatsheet.md +380 -0
- package/skills/arc-code-review/references/migration-recipes.md +700 -0
- package/skills/arc-code-review/references/mongokit-migration.md +386 -0
- package/skills/arc-code-review/references/scaffolding.md +230 -0
- package/skills/arc-code-review/references/severity.md +127 -0
- package/dist/EventTransport-CfVEGaEl.d.mts +0 -293
- package/dist/adapters/index.d.mts +0 -3
- package/dist/adapters/index.mjs +0 -2
- package/dist/adapters-D0tT2Tyo.mjs +0 -949
- package/dist/auth/mongoose.d.mts +0 -191
- package/dist/auth/mongoose.mjs +0 -73
- package/dist/core-DnUsRpuX.mjs +0 -1049
- package/dist/errorHandler-BQm8ZxTK.mjs +0 -173
- package/dist/errorHandler-Co3lnVmJ.d.mts +0 -114
- package/dist/errors-D5c-5BJL.mjs +0 -232
- package/dist/index-BbMrcvGp.d.mts +0 -362
- package/dist/redis-stream-CM8TXTix.d.mts +0 -110
- /package/dist/{HookSystem-CGsMd6oK.mjs → HookSystem-Iiebom92.mjs} +0 -0
- /package/dist/{actionPermissions-sUUKDhtP.mjs → actionPermissions-CyUkQu6O.mjs} +0 -0
- /package/dist/{caching-CheW3m-S.mjs → caching-SM8gghN6.mjs} +0 -0
- /package/dist/{constants-BhY1OHoH.mjs → constants-Cxde4rpC.mjs} +0 -0
- /package/dist/{elevation-s5ykdNHr.d.mts → elevation-BXOWoGCF.d.mts} +0 -0
- /package/dist/{externalPaths-Bapitwvd.d.mts → externalPaths-BD5nw6St.d.mts} +0 -0
- /package/dist/{interface-CkkWm5uR.d.mts → interface-DfLGcus7.d.mts} +0 -0
- /package/dist/{interface-Da0r7Lna.d.mts → interface-beEtJyWM.d.mts} +0 -0
- /package/dist/{keys-CARyUjiR.mjs → keys-CGcCbNyu.mjs} +0 -0
- /package/dist/{loadResources-CPpkyKfM.mjs → loadResources-DBMQg_Aj.mjs} +0 -0
- /package/dist/{memory-DikHSvWa.mjs → memory-UBydS5ku.mjs} +0 -0
- /package/dist/{metrics-Csh4nsvv.mjs → metrics-Qnvwc-LQ.mjs} +0 -0
- /package/dist/{pluralize-BneOJkpi.mjs → pluralize-DQgqgifU.mjs} +0 -0
- /package/dist/{registry-D63ee7fl.mjs → registry-I-ogLgL9.mjs} +0 -0
- /package/dist/{requestContext-C5XeK3VA.mjs → requestContext-SSaaTgW8.mjs} +0 -0
- /package/dist/{schemaConverter-B0oKLuqI.mjs → schemaConverter-De34B1ZG.mjs} +0 -0
- /package/dist/{sessionManager-D-oNWHz3.d.mts → sessionManager-C4Le_UB3.d.mts} +0 -0
- /package/dist/{storage-BwGQXUpd.d.mts → storage-Dfzt4VTl.d.mts} +0 -0
- /package/dist/{tracing-DokiEsuz.d.mts → tracing-QJVprktp.d.mts} +0 -0
- /package/dist/{typeGuards-CcFZXgU7.mjs → typeGuards-BzkXkvVv.mjs} +0 -0
- /package/dist/{types-DV9WDfeg.mjs → types-D57iXYb8.mjs} +0 -0
- /package/dist/{versioning-CGPjkqAg.mjs → versioning-BUrT5aP4.mjs} +0 -0
- /package/dist/{websocket-CyJ1VIFI.d.mts → websocket-ChC2rqe1.d.mts} +0 -0
package/dist/plugins/index.d.mts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { t as ExternalOpenApiPaths } from "../externalPaths-
|
|
3
|
-
import { a as MetricsCollector, c as metricsPlugin, d as ssePlugin, f as CachingOptions, h as cachingPlugin, i as MetricEntry, l as SSEOptions, m as _default$1, n as _default$7, o as MetricsOptions, p as CachingRule, r as versioningPlugin, s as _default$4, t as VersioningOptions, u as _default$6 } from "../versioning-
|
|
4
|
-
import { i as errorHandlerPlugin, n as ErrorMapper, r as defaultIsDuplicateKeyError, t as ErrorHandlerOptions } from "../errorHandler-
|
|
5
|
-
import { t as TracingOptions } from "../tracing-
|
|
1
|
+
import { En as HookSystem, Q as MiddlewareConfig, Wt as AnyRecord, ft as RouteSchemaOptions, lt as RouteDefinition, tt as PresetHook, z as ResourceRegistry } from "../index-BtW7qYwa.mjs";
|
|
2
|
+
import { t as ExternalOpenApiPaths } from "../externalPaths-BD5nw6St.mjs";
|
|
3
|
+
import { a as MetricsCollector, c as metricsPlugin, d as ssePlugin, f as CachingOptions, h as cachingPlugin, i as MetricEntry, l as SSEOptions, m as _default$1, n as _default$7, o as MetricsOptions, p as CachingRule, r as versioningPlugin, s as _default$4, t as VersioningOptions, u as _default$6 } from "../versioning-DTTvc80y.mjs";
|
|
4
|
+
import { i as errorHandlerPlugin, n as ErrorMapper, r as defaultIsDuplicateKeyError, t as ErrorHandlerOptions } from "../errorHandler-DFr45ZG4.mjs";
|
|
5
|
+
import { t as TracingOptions } from "../tracing-QJVprktp.mjs";
|
|
6
|
+
import { PaginatedResult } from "@classytic/repo-core/pagination";
|
|
6
7
|
import { FastifyInstance, FastifyPluginAsync } from "fastify";
|
|
7
8
|
import * as _$node_stream0 from "node:stream";
|
|
8
9
|
|
|
@@ -172,38 +173,22 @@ declare const _default$3: FastifyPluginAsync<HealthOptions>;
|
|
|
172
173
|
//#region src/plugins/replyHelpers.d.ts
|
|
173
174
|
declare module "fastify" {
|
|
174
175
|
interface FastifyReply {
|
|
175
|
-
/**
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
}): FastifyReply;
|
|
176
|
+
/**
|
|
177
|
+
* Send a list response, normalised to the canonical wire shape.
|
|
178
|
+
*
|
|
179
|
+
* Accepts either a bare array (endpoints that don't paginate) or any
|
|
180
|
+
* kit-shaped pagination result (`OffsetPaginationResult`,
|
|
181
|
+
* `KeysetPaginationResult`, `AggregatePaginationResult`). Routes
|
|
182
|
+
* through `toCanonicalList` from `@classytic/repo-core/pagination`
|
|
183
|
+
* so server and typed-client (`@classytic/arc-next`) share one
|
|
184
|
+
* declaration — the `method` discriminant cannot drift between them.
|
|
185
|
+
*/
|
|
186
|
+
sendList<T>(input: T[] | readonly T[] | PaginatedResult<T>): FastifyReply;
|
|
187
187
|
/**
|
|
188
188
|
* Stream a readable source as a file download or raw stream.
|
|
189
189
|
*
|
|
190
190
|
* @example
|
|
191
|
-
*
|
|
192
|
-
* // CSV export
|
|
193
|
-
* return reply.stream(csvReadableStream, {
|
|
194
|
-
* contentType: 'text/csv',
|
|
195
|
-
* filename: 'export.csv',
|
|
196
|
-
* });
|
|
197
|
-
*
|
|
198
|
-
* // PDF download
|
|
199
|
-
* return reply.stream(pdfBuffer, {
|
|
200
|
-
* contentType: 'application/pdf',
|
|
201
|
-
* filename: 'report.pdf',
|
|
202
|
-
* });
|
|
203
|
-
*
|
|
204
|
-
* // Raw stream (no Content-Disposition)
|
|
205
|
-
* return reply.stream(dataStream, { contentType: 'application/octet-stream' });
|
|
206
|
-
* ```
|
|
191
|
+
* return reply.stream(csvReadable, { contentType: 'text/csv', filename: 'export.csv' });
|
|
207
192
|
*/
|
|
208
193
|
stream(source: _$node_stream0.Readable | Buffer | AsyncIterable<unknown>, options: {
|
|
209
194
|
contentType: string;
|
package/dist/plugins/index.mjs
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import { p as MUTATION_OPERATIONS } from "../constants-
|
|
2
|
-
import {
|
|
3
|
-
import { t as requestContext } from "../requestContext-
|
|
4
|
-
import { t as hasEvents } from "../typeGuards-
|
|
5
|
-
import { t as HookSystem } from "../HookSystem-
|
|
6
|
-
import { t as ResourceRegistry } from "../ResourceRegistry-
|
|
7
|
-
import { n as caching_default, t as cachingPlugin } from "../caching-
|
|
8
|
-
import { n as errorHandlerPlugin, t as defaultIsDuplicateKeyError } from "../errorHandler-
|
|
9
|
-
import { n as metrics_default, t as metricsPlugin } from "../metrics-
|
|
10
|
-
import { t as replyHelpersPlugin } from "../replyHelpers-
|
|
11
|
-
import { n as sse_default, t as ssePlugin } from "../sse-
|
|
12
|
-
import { n as versioning_default, t as versioningPlugin } from "../versioning-
|
|
1
|
+
import { p as MUTATION_OPERATIONS } from "../constants-Cxde4rpC.mjs";
|
|
2
|
+
import { c as getOrgId } from "../types-C_s5moIu.mjs";
|
|
3
|
+
import { t as requestContext } from "../requestContext-SSaaTgW8.mjs";
|
|
4
|
+
import { t as hasEvents } from "../typeGuards-BzkXkvVv.mjs";
|
|
5
|
+
import { t as HookSystem } from "../HookSystem-Iiebom92.mjs";
|
|
6
|
+
import { t as ResourceRegistry } from "../ResourceRegistry-CTERg_2x.mjs";
|
|
7
|
+
import { n as caching_default, t as cachingPlugin } from "../caching-SM8gghN6.mjs";
|
|
8
|
+
import { n as errorHandlerPlugin, t as defaultIsDuplicateKeyError } from "../errorHandler-Bk-AGhkU.mjs";
|
|
9
|
+
import { n as metrics_default, t as metricsPlugin } from "../metrics-Qnvwc-LQ.mjs";
|
|
10
|
+
import { t as replyHelpersPlugin } from "../replyHelpers-CK-FNO8E.mjs";
|
|
11
|
+
import { n as sse_default, t as ssePlugin } from "../sse-Bz-5ZeTt.mjs";
|
|
12
|
+
import { n as versioning_default, t as versioningPlugin } from "../versioning-BUrT5aP4.mjs";
|
|
13
13
|
import { randomUUID } from "node:crypto";
|
|
14
14
|
import fp from "fastify-plugin";
|
|
15
15
|
//#region src/core/arcCorePlugin.ts
|
|
@@ -198,6 +198,26 @@ function createHttpMetrics() {
|
|
|
198
198
|
const healthPlugin = async (fastify, opts = {}) => {
|
|
199
199
|
const { prefix = "/_health", checks = [], metrics = false, metricsCollector, version, collectHttpMetrics = metrics } = opts;
|
|
200
200
|
const httpMetrics = createHttpMetrics();
|
|
201
|
+
fastify.get(prefix, { schema: {
|
|
202
|
+
tags: ["Health"],
|
|
203
|
+
summary: "Liveness probe (alias for /live)",
|
|
204
|
+
description: "Returns 200 if the process is alive",
|
|
205
|
+
response: { 200: {
|
|
206
|
+
type: "object",
|
|
207
|
+
properties: {
|
|
208
|
+
status: {
|
|
209
|
+
type: "string",
|
|
210
|
+
enum: ["ok"]
|
|
211
|
+
},
|
|
212
|
+
timestamp: { type: "string" },
|
|
213
|
+
version: { type: "string" }
|
|
214
|
+
}
|
|
215
|
+
} }
|
|
216
|
+
} }, async () => ({
|
|
217
|
+
status: "ok",
|
|
218
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
219
|
+
...version ? { version } : {}
|
|
220
|
+
}));
|
|
201
221
|
fastify.get(`${prefix}/live`, { schema: {
|
|
202
222
|
tags: ["Health"],
|
|
203
223
|
summary: "Liveness probe",
|
|
@@ -331,7 +351,7 @@ const healthPlugin = async (fastify, opts = {}) => {
|
|
|
331
351
|
httpMetrics._ringIndex = httpMetrics._ringIndex + 1;
|
|
332
352
|
});
|
|
333
353
|
}
|
|
334
|
-
fastify.log?.debug?.(`Health plugin registered at ${prefix}`);
|
|
354
|
+
fastify.log?.debug?.(`Health plugin registered at ${prefix} (alias), ${prefix}/live, ${prefix}/ready${metrics ? `, ${prefix}/metrics` : ""}`);
|
|
335
355
|
};
|
|
336
356
|
/**
|
|
337
357
|
* Run all health checks with timeout
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as traced, i as isTracingAvailable, n as _default, r as createSpan, t as TracingOptions } from "../tracing-
|
|
1
|
+
import { a as traced, i as isTracingAvailable, n as _default, r as createSpan, t as TracingOptions } from "../tracing-QJVprktp.mjs";
|
|
2
2
|
export { type TracingOptions, createSpan, isTracingAvailable, traced, _default as tracingPlugin };
|
|
@@ -58,7 +58,7 @@ try {
|
|
|
58
58
|
function createTracerProvider(options) {
|
|
59
59
|
if (!isAvailable || !NodeTracerProvider || !BatchSpanProcessor || !OTLPTraceExporter) return null;
|
|
60
60
|
const { serviceName = "@classytic/arc", serviceVersion, exporterUrl = "http://localhost:4318/v1/traces" } = options;
|
|
61
|
-
const resolvedVersion = serviceVersion ?? "2.
|
|
61
|
+
const resolvedVersion = serviceVersion ?? "2.13.1";
|
|
62
62
|
const exporter = new OTLPTraceExporter({ url: exporterUrl });
|
|
63
63
|
const provider = new NodeTracerProvider({ resource: { attributes: {
|
|
64
64
|
"service.name": serviceName,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { nt as PresetResult } from "../index-
|
|
2
|
-
import {
|
|
3
|
-
import { c as PermissionCheck } from "../fields-
|
|
4
|
-
import { a as StorageReadResult, i as StorageReadRange, n as StorageContext, o as StorageUploadInput, r as StorageFile, t as Storage } from "../storage-
|
|
1
|
+
import { nt as PresetResult } from "../index-BtW7qYwa.mjs";
|
|
2
|
+
import { i as RequestScope } from "../types-CTYvcwHe.mjs";
|
|
3
|
+
import { c as PermissionCheck } from "../fields-COhcH3fk.mjs";
|
|
4
|
+
import { a as StorageReadResult, i as StorageReadRange, n as StorageContext, o as StorageUploadInput, r as StorageFile, t as Storage } from "../storage-Dfzt4VTl.mjs";
|
|
5
5
|
|
|
6
6
|
//#region src/presets/filesUpload.d.ts
|
|
7
7
|
interface FilesUploadPresetRoutes {
|
|
@@ -27,7 +27,7 @@ interface FilesUploadPresetPermissions {
|
|
|
27
27
|
* - function: custom policy. Return a string to *transform* the filename,
|
|
28
28
|
* `false` to reject (triggers `ValidationError`), or `true`/`void` to accept.
|
|
29
29
|
*/
|
|
30
|
-
type FilenamePolicy = boolean | "*" | ((filename: string) => string | boolean |
|
|
30
|
+
type FilenamePolicy = boolean | "*" | ((filename: string) => string | boolean | undefined);
|
|
31
31
|
interface FilesUploadPresetOptions {
|
|
32
32
|
/** Any implementation of the `Storage` interface. App owns it. */
|
|
33
33
|
storage: Storage;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { t as multipartBody } from "../multipartBody-
|
|
1
|
+
import { i as NotFoundError, u as ValidationError } from "../errors-j4aJm1Wg.mjs";
|
|
2
|
+
import { c as getOrgId, h as getUserId } from "../types-C_s5moIu.mjs";
|
|
3
|
+
import { C as allowPublic, D as requireAuth } from "../permissions-ohQyv50e.mjs";
|
|
4
|
+
import { t as multipartBody } from "../multipartBody-BOvVSVCD.mjs";
|
|
5
5
|
//#region src/presets/filesUpload.ts
|
|
6
6
|
const DEFAULT_FIELD_NAME = "file";
|
|
7
7
|
const DEFAULT_MAX_FILE_SIZE = 10 * 1024 * 1024;
|
|
@@ -29,7 +29,7 @@ function buildStorageContext(request, contextFrom) {
|
|
|
29
29
|
* to the full-object response (per RFC 7233 §4.1 a server MAY ignore ranges).
|
|
30
30
|
*/
|
|
31
31
|
function parseRangeHeader(header, totalSize) {
|
|
32
|
-
if (!header
|
|
32
|
+
if (!header?.startsWith("bytes=")) return void 0;
|
|
33
33
|
const spec = header.slice(6).split(",")[0]?.trim();
|
|
34
34
|
if (!spec) return void 0;
|
|
35
35
|
const dashIndex = spec.indexOf("-");
|
|
@@ -102,10 +102,7 @@ function makeUploadHandler(deps) {
|
|
|
102
102
|
mimeType: file.mimetype,
|
|
103
103
|
size: file.size
|
|
104
104
|
}, ctx);
|
|
105
|
-
return reply.code(201).send(
|
|
106
|
-
success: true,
|
|
107
|
-
data: toResponseFile(result)
|
|
108
|
-
});
|
|
105
|
+
return reply.code(201).send(toResponseFile(result));
|
|
109
106
|
};
|
|
110
107
|
}
|
|
111
108
|
function toResponseFile(file) {
|
package/dist/presets/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Wt as AnyRecord, _t as IControllerResponse, at as ResourceConfig, d as PaginationResult, nt as PresetResult, vt as IRequestContext } from "../index-BtW7qYwa.mjs";
|
|
2
2
|
import { FilesUploadPresetOptions, FilesUploadPresetPermissions, FilesUploadPresetRoutes, filesUploadPreset } from "./filesUpload.mjs";
|
|
3
3
|
import { MultiTenantOptions, TenantFieldSpec, multiTenantPreset } from "./multiTenant.mjs";
|
|
4
4
|
import { SearchHandler, SearchPresetOptions, SearchRouteConfig, searchPreset } from "./search.mjs";
|
package/dist/presets/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { multiTenantPreset } from "./multiTenant.mjs";
|
|
2
|
-
import { a as registerPreset, c as auditedPreset, d as ownedByUserPreset, i as getPreset, l as softDeletePreset, n as flexibleMultiTenantPreset, o as treePreset, r as getAvailablePresets, s as bulkPreset, t as applyPresets, u as slugLookupPreset } from "../presets-
|
|
2
|
+
import { a as registerPreset, c as auditedPreset, d as ownedByUserPreset, i as getPreset, l as softDeletePreset, n as flexibleMultiTenantPreset, o as treePreset, r as getAvailablePresets, s as bulkPreset, t as applyPresets, u as slugLookupPreset } from "../presets-BbkjdPeH.mjs";
|
|
3
3
|
import { filesUploadPreset } from "./filesUpload.mjs";
|
|
4
4
|
import { searchPreset } from "./search.mjs";
|
|
5
5
|
export { applyPresets, auditedPreset, bulkPreset, filesUploadPreset, flexibleMultiTenantPreset, getAvailablePresets, getPreset, multiTenantPreset, ownedByUserPreset, registerPreset, searchPreset, slugLookupPreset, softDeletePreset, treePreset };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import "../constants-
|
|
2
|
-
import { _ as
|
|
1
|
+
import "../constants-Cxde4rpC.mjs";
|
|
2
|
+
import { _ as hasOrgAccess, c as getOrgId, d as getScopeContext, m as getTeamId, u as getRequestScope, y as isElevated } from "../types-C_s5moIu.mjs";
|
|
3
3
|
//#region src/presets/multiTenant.ts
|
|
4
4
|
/**
|
|
5
5
|
* Resolve a single TenantFieldSpec against the current scope.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { lt as RouteDefinition, nt as PresetResult, pt as ControllerHandler, ut as RouteMcpConfig } from "../index-
|
|
2
|
-
import { c as PermissionCheck } from "../fields-
|
|
1
|
+
import { lt as RouteDefinition, nt as PresetResult, pt as ControllerHandler, ut as RouteMcpConfig } from "../index-BtW7qYwa.mjs";
|
|
2
|
+
import { c as PermissionCheck } from "../fields-COhcH3fk.mjs";
|
|
3
3
|
|
|
4
4
|
//#region src/presets/search.d.ts
|
|
5
5
|
/**
|
package/dist/presets/search.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { C as
|
|
1
|
+
import { C as allowPublic, D as requireAuth } from "../permissions-ohQyv50e.mjs";
|
|
2
2
|
//#region src/presets/search.ts
|
|
3
3
|
const BUILTINS = [
|
|
4
4
|
{
|
|
@@ -28,17 +28,15 @@ const BUILTINS = [
|
|
|
28
28
|
];
|
|
29
29
|
/**
|
|
30
30
|
* Wrap the user handler to normalise the return shape into arc's envelope.
|
|
31
|
-
* If the handler already returns `
|
|
32
|
-
* otherwise we wrap the raw return
|
|
31
|
+
* If the handler already returns an `IControllerResponse` envelope (carrying
|
|
32
|
+
* a `data` slot), arc passes it through; otherwise we wrap the raw return
|
|
33
|
+
* value so callers don't have to.
|
|
33
34
|
*/
|
|
34
35
|
function wrapEnvelope(handler) {
|
|
35
36
|
return async (req) => {
|
|
36
37
|
const out = await handler(req);
|
|
37
|
-
if (out !== null && typeof out === "object" && "
|
|
38
|
-
return {
|
|
39
|
-
success: true,
|
|
40
|
-
data: out
|
|
41
|
-
};
|
|
38
|
+
if (out !== null && typeof out === "object" && "data" in out) return out;
|
|
39
|
+
return { data: out };
|
|
42
40
|
};
|
|
43
41
|
}
|
|
44
42
|
/**
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { C as
|
|
1
|
+
import { n as PUBLIC_SCOPE, y as isElevated } from "./types-C_s5moIu.mjs";
|
|
2
|
+
import { C as allowPublic, D as requireAuth, k as requireRoles } from "./permissions-ohQyv50e.mjs";
|
|
3
3
|
import { multiTenantPreset } from "./presets/multiTenant.mjs";
|
|
4
4
|
//#region src/presets/ownedByUser.ts
|
|
5
5
|
/**
|
|
@@ -169,17 +169,7 @@ function bulkPreset(opts) {
|
|
|
169
169
|
} },
|
|
170
170
|
required: ["items"]
|
|
171
171
|
},
|
|
172
|
-
response: { 201: {
|
|
173
|
-
type: "object",
|
|
174
|
-
properties: {
|
|
175
|
-
success: { type: "boolean" },
|
|
176
|
-
data: { type: "array" },
|
|
177
|
-
meta: {
|
|
178
|
-
type: "object",
|
|
179
|
-
properties: { count: { type: "number" } }
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
} }
|
|
172
|
+
response: { 201: { type: "array" } }
|
|
183
173
|
}
|
|
184
174
|
});
|
|
185
175
|
if (operations.includes("updateMany")) routes.push({
|
|
@@ -201,14 +191,8 @@ function bulkPreset(opts) {
|
|
|
201
191
|
response: { 200: {
|
|
202
192
|
type: "object",
|
|
203
193
|
properties: {
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
type: "object",
|
|
207
|
-
properties: {
|
|
208
|
-
matchedCount: { type: "number" },
|
|
209
|
-
modifiedCount: { type: "number" }
|
|
210
|
-
}
|
|
211
|
-
}
|
|
194
|
+
matchedCount: { type: "number" },
|
|
195
|
+
modifiedCount: { type: "number" }
|
|
212
196
|
}
|
|
213
197
|
} }
|
|
214
198
|
}
|
|
@@ -228,13 +212,7 @@ function bulkPreset(opts) {
|
|
|
228
212
|
},
|
|
229
213
|
response: { 200: {
|
|
230
214
|
type: "object",
|
|
231
|
-
properties: {
|
|
232
|
-
success: { type: "boolean" },
|
|
233
|
-
data: {
|
|
234
|
-
type: "object",
|
|
235
|
-
properties: { deletedCount: { type: "number" } }
|
|
236
|
-
}
|
|
237
|
-
}
|
|
215
|
+
properties: { deletedCount: { type: "number" } }
|
|
238
216
|
} }
|
|
239
217
|
}
|
|
240
218
|
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { r as CacheStore } from "./interface-
|
|
2
|
-
import { i as QueryCache } from "./QueryCache-
|
|
1
|
+
import { r as CacheStore } from "./interface-beEtJyWM.mjs";
|
|
2
|
+
import { i as QueryCache } from "./QueryCache-D41bfdBB.mjs";
|
|
3
3
|
import { FastifyPluginAsync } from "fastify";
|
|
4
4
|
|
|
5
5
|
//#region src/cache/queryCachePlugin.d.ts
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { t as __exportAll } from "./chunk-BpYLSNr0.mjs";
|
|
2
|
-
import {
|
|
3
|
-
import { t as
|
|
4
|
-
import {
|
|
2
|
+
import { t as MemoryCacheStore } from "./memory-UBydS5ku.mjs";
|
|
3
|
+
import { t as hasEvents } from "./typeGuards-BzkXkvVv.mjs";
|
|
4
|
+
import { i as versionKey, r as tagVersionKey } from "./keys-CGcCbNyu.mjs";
|
|
5
5
|
import fp from "fastify-plugin";
|
|
6
6
|
//#region src/cache/QueryCache.ts
|
|
7
7
|
var QueryCache = class {
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
import { a as EventTransport, i as EventLogger, n as DomainEvent, r as EventHandler } from "./EventTransport-CT_52aWU.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/events/transports/redis-stream.d.ts
|
|
4
|
+
interface RedisStreamLike {
|
|
5
|
+
xadd(key: string, id: string, ...fieldValues: string[]): Promise<string | null>;
|
|
6
|
+
xreadgroup(command: "GROUP", group: string, consumer: string, ...args: (string | number)[]): Promise<Array<[string, Array<[string, string[]]>]> | null>;
|
|
7
|
+
xack(key: string, group: string, ...ids: string[]): Promise<number>;
|
|
8
|
+
xgroup(command: string, key: string, group: string, ...args: string[]): Promise<unknown>;
|
|
9
|
+
xpending(key: string, group: string, ...args: (string | number)[]): Promise<Array<[string, string, number, number]>>;
|
|
10
|
+
xclaim(key: string, group: string, consumer: string, minIdleTime: number, ...ids: string[]): Promise<Array<[string, string[]]>>;
|
|
11
|
+
xlen(key: string): Promise<number>;
|
|
12
|
+
/**
|
|
13
|
+
* Read a range of entries by id. When present, the DLQ writer uses this
|
|
14
|
+
* to fetch the original message payload so dead-lettered events are
|
|
15
|
+
* **fully replayable** (a re-publish of `envelope.event` is sufficient).
|
|
16
|
+
*
|
|
17
|
+
* Optional to preserve back-compat with custom Redis wrappers that
|
|
18
|
+
* satisfied the pre-2.11.3 shape. When missing, the DLQ envelope still
|
|
19
|
+
* carries the **error reason + attempt accounting** (operator-grade
|
|
20
|
+
* triage info survives), but `envelope.event.payload` is `null` and
|
|
21
|
+
* `envelope.event.type` is `<unknown>` — replay is NOT possible without
|
|
22
|
+
* upgrading the client. A one-shot warning fires per process so this
|
|
23
|
+
* isn't silent.
|
|
24
|
+
*/
|
|
25
|
+
xrange?(key: string, start: string, end: string): Promise<Array<[string, string[]]>>;
|
|
26
|
+
/** Graceful close — flushes queued commands then closes. ioredis-style. */
|
|
27
|
+
quit(): Promise<unknown>;
|
|
28
|
+
/**
|
|
29
|
+
* Force-disconnect — closes the socket immediately, abandoning any
|
|
30
|
+
* pending command (including a live `XREADGROUP BLOCK`). Optional because
|
|
31
|
+
* non-ioredis clients may not expose a force path; `close()` falls back
|
|
32
|
+
* to `quit()` when this is missing, accepting a longer shutdown wait.
|
|
33
|
+
*/
|
|
34
|
+
disconnect?(): void;
|
|
35
|
+
}
|
|
36
|
+
interface RedisStreamTransportOptions {
|
|
37
|
+
/**
|
|
38
|
+
* Redis stream key name.
|
|
39
|
+
* @default 'arc:events'
|
|
40
|
+
*/
|
|
41
|
+
stream?: string;
|
|
42
|
+
/**
|
|
43
|
+
* Consumer group name. Each group receives every event independently.
|
|
44
|
+
* Multiple instances of the same service should share a group name.
|
|
45
|
+
* @default 'default'
|
|
46
|
+
*/
|
|
47
|
+
group?: string;
|
|
48
|
+
/**
|
|
49
|
+
* Consumer name within the group. Must be unique per instance.
|
|
50
|
+
* @default 'consumer-<random>'
|
|
51
|
+
*/
|
|
52
|
+
consumer?: string;
|
|
53
|
+
/**
|
|
54
|
+
* Block time in ms when waiting for new events.
|
|
55
|
+
* @default 5000
|
|
56
|
+
*/
|
|
57
|
+
blockTimeMs?: number;
|
|
58
|
+
/**
|
|
59
|
+
* Max events to read per batch.
|
|
60
|
+
* @default 10
|
|
61
|
+
*/
|
|
62
|
+
batchSize?: number;
|
|
63
|
+
/**
|
|
64
|
+
* Max delivery attempts before moving to dead letter stream.
|
|
65
|
+
* @default 5
|
|
66
|
+
*/
|
|
67
|
+
maxRetries?: number;
|
|
68
|
+
/**
|
|
69
|
+
* Idle time in ms before pending entries are claimed by this consumer.
|
|
70
|
+
* Handles crash recovery — if a consumer dies mid-processing, another
|
|
71
|
+
* consumer will claim its pending entries after this timeout.
|
|
72
|
+
* @default 30000
|
|
73
|
+
*/
|
|
74
|
+
claimTimeoutMs?: number;
|
|
75
|
+
/**
|
|
76
|
+
* Dead letter stream name. Failed events are moved here after maxRetries.
|
|
77
|
+
* Set to `false` to disable DLQ (failed events are acked and dropped).
|
|
78
|
+
* @default 'arc:events:dlq'
|
|
79
|
+
*/
|
|
80
|
+
deadLetterStream?: string | false;
|
|
81
|
+
/**
|
|
82
|
+
* Max stream length (approximate). Uses XADD MAXLEN ~ to trim old entries.
|
|
83
|
+
* Set to 0 to disable trimming.
|
|
84
|
+
* @default 10000
|
|
85
|
+
*/
|
|
86
|
+
maxLen?: number;
|
|
87
|
+
/**
|
|
88
|
+
* Max event payload size in bytes. Publish rejects events exceeding this limit
|
|
89
|
+
* to prevent Redis memory exhaustion from oversized payloads.
|
|
90
|
+
* @default 1_000_000 (1 MB)
|
|
91
|
+
*/
|
|
92
|
+
maxPayloadBytes?: number;
|
|
93
|
+
/**
|
|
94
|
+
* If `true`, `close()` does NOT call `redis.quit()` — useful when the host
|
|
95
|
+
* manages the Redis connection lifecycle externally (shared client across
|
|
96
|
+
* multiple transports / cache stores). Without this, every transport
|
|
97
|
+
* `close()` would tear down a shared client and break siblings.
|
|
98
|
+
*
|
|
99
|
+
* Mirror of `RedisEventTransportOptions.externalLifecycle`.
|
|
100
|
+
* @default false
|
|
101
|
+
*/
|
|
102
|
+
externalLifecycle?: boolean;
|
|
103
|
+
/**
|
|
104
|
+
* Hard cap on how long `close()` waits for the in-flight `XREADGROUP BLOCK`
|
|
105
|
+
* iteration to drain. Tests and serverless shutdowns would otherwise hang
|
|
106
|
+
* up to `blockTimeMs` (default 5s) per close.
|
|
107
|
+
*
|
|
108
|
+
* Behaviour after timeout:
|
|
109
|
+
* - `externalLifecycle: false` (default) — `redis.disconnect()` (or
|
|
110
|
+
* `quit()` if the client lacks `disconnect`) breaks the BLOCK
|
|
111
|
+
* immediately. Strict bounded close.
|
|
112
|
+
* - `externalLifecycle: true` — arc CANNOT touch the host's connection,
|
|
113
|
+
* so the poll loop is left to drain in the background when its
|
|
114
|
+
* XREADGROUP returns. `close()` returns within `closeTimeoutMs` but
|
|
115
|
+
* the loop's eventual completion is silently absorbed (no log spam,
|
|
116
|
+
* no unhandled rejection). The contract here is "bounded return,
|
|
117
|
+
* background drain" — set `blockTimeMs` low (e.g. 500ms) under
|
|
118
|
+
* externalLifecycle to keep the drain window short.
|
|
119
|
+
*
|
|
120
|
+
* @default 1000
|
|
121
|
+
*/
|
|
122
|
+
closeTimeoutMs?: number;
|
|
123
|
+
/**
|
|
124
|
+
* Logger for error messages (default: console).
|
|
125
|
+
* Pass `fastify.log` to integrate with your application logger.
|
|
126
|
+
*/
|
|
127
|
+
logger?: EventLogger;
|
|
128
|
+
}
|
|
129
|
+
declare class RedisStreamTransport implements EventTransport {
|
|
130
|
+
readonly name = "redis-stream";
|
|
131
|
+
private redis;
|
|
132
|
+
private stream;
|
|
133
|
+
private group;
|
|
134
|
+
private consumer;
|
|
135
|
+
private blockTimeMs;
|
|
136
|
+
private batchSize;
|
|
137
|
+
private maxRetries;
|
|
138
|
+
private claimTimeoutMs;
|
|
139
|
+
private deadLetterStream;
|
|
140
|
+
private maxLen;
|
|
141
|
+
private maxPayloadBytes;
|
|
142
|
+
private logger;
|
|
143
|
+
/** Tracks the lifecycle policy — set in constructor, read in close(). */
|
|
144
|
+
private externalLifecycle;
|
|
145
|
+
private closeTimeoutMs;
|
|
146
|
+
private handlers;
|
|
147
|
+
private running;
|
|
148
|
+
private pollPromise;
|
|
149
|
+
/**
|
|
150
|
+
* Monotonic counter bumped every time the poll loop should stop —
|
|
151
|
+
* `unsubscribe` (last handler removed) and `close()` increment it. Each
|
|
152
|
+
* `pollLoop` instance captures its generation at start and exits when
|
|
153
|
+
* `this.generation` no longer matches. Prevents the
|
|
154
|
+
* subscribe → unsubscribe → fast-resubscribe race where the old loop
|
|
155
|
+
* would still be in `XREADGROUP BLOCK` while a new loop started, leading
|
|
156
|
+
* to two concurrent poll loops on the same consumer name.
|
|
157
|
+
*/
|
|
158
|
+
private generation;
|
|
159
|
+
private groupCreated;
|
|
160
|
+
/**
|
|
161
|
+
* Last-seen failure context per message id, populated when an in-process
|
|
162
|
+
* handler throws in {@link processEntry}. Consumed (and cleared) by
|
|
163
|
+
* {@link moveToDlq} so the dead-letter envelope carries the actual error
|
|
164
|
+
* message instead of opaque "reclaimed without context". Bounded by
|
|
165
|
+
* `maxRetries × consumer-throughput` — entries are deleted on ack and
|
|
166
|
+
* on DLQ write, so the map naturally drains.
|
|
167
|
+
*/
|
|
168
|
+
private failureContext;
|
|
169
|
+
/** One-shot guard so the "client lacks xrange" warning fires once per process. */
|
|
170
|
+
private xrangeWarningEmitted;
|
|
171
|
+
constructor(redis: RedisStreamLike, options?: RedisStreamTransportOptions);
|
|
172
|
+
publish(event: DomainEvent): Promise<void>;
|
|
173
|
+
subscribe(pattern: string, handler: EventHandler): Promise<() => void>;
|
|
174
|
+
/**
|
|
175
|
+
* Stop polling and release transport state.
|
|
176
|
+
*
|
|
177
|
+
* **Two close contracts** — pick the one that matches your deployment:
|
|
178
|
+
*
|
|
179
|
+
* 1. **Default (`externalLifecycle: false`) — strict bounded close.**
|
|
180
|
+
* `close()` waits up to `closeTimeoutMs` for the in-flight
|
|
181
|
+
* `XREADGROUP BLOCK` to drain. On timeout it calls `redis.disconnect()`
|
|
182
|
+
* (or `quit()` if the client lacks `disconnect`) to break the BLOCK
|
|
183
|
+
* immediately, then awaits the loop's exit. After `close()` returns
|
|
184
|
+
* the transport is fully closed and the connection is released.
|
|
185
|
+
*
|
|
186
|
+
* 2. **`externalLifecycle: true` — bounded RETURN, background drain.**
|
|
187
|
+
* Arc must NOT touch a connection it doesn't own. `close()` returns
|
|
188
|
+
* within `closeTimeoutMs`, but the poll loop is left to drain on its
|
|
189
|
+
* own when its outstanding `XREADGROUP BLOCK` returns (up to
|
|
190
|
+
* `blockTimeMs`). Arc silently absorbs the loop's eventual completion
|
|
191
|
+
* so the host doesn't see unhandled rejections / log spam against a
|
|
192
|
+
* transport it considers closed. The host's own `redis.quit()` /
|
|
193
|
+
* process exit is what ultimately tears the connection down.
|
|
194
|
+
*
|
|
195
|
+
* Practical implication: under `externalLifecycle: true`, set
|
|
196
|
+
* `blockTimeMs` low (e.g. 500ms) so the background drain window is
|
|
197
|
+
* short. The transport is "closed enough" to stop dispatching to
|
|
198
|
+
* handlers (handlers map is cleared and generation is bumped) but is
|
|
199
|
+
* not "fully closed" in the connection-lifecycle sense until the host
|
|
200
|
+
* closes the underlying client.
|
|
201
|
+
*
|
|
202
|
+
* In both modes the generation counter is bumped, so a follow-up
|
|
203
|
+
* `subscribe()` spawns a fresh poll loop with a new generation — the
|
|
204
|
+
* stale loop exits on its next iteration and never overlaps the new one.
|
|
205
|
+
*/
|
|
206
|
+
close(): Promise<void>;
|
|
207
|
+
private ensureGroup;
|
|
208
|
+
private pollLoop;
|
|
209
|
+
private readNewMessages;
|
|
210
|
+
private claimPending;
|
|
211
|
+
private processEntry;
|
|
212
|
+
private getMatchingHandlers;
|
|
213
|
+
private matchesPattern;
|
|
214
|
+
private moveToDlq;
|
|
215
|
+
/**
|
|
216
|
+
* Reconstruct a `DeadLetteredEvent` for a message id. Reads the original
|
|
217
|
+
* entry via `xrange` (when the client supports it) and merges in any
|
|
218
|
+
* in-process failure context. Returns `null` only when BOTH sources are
|
|
219
|
+
* missing — callers ack-and-drop rather than re-queuing a ghost.
|
|
220
|
+
*
|
|
221
|
+
* Graceful degradation paths:
|
|
222
|
+
* - Client lacks `xrange` (older custom wrappers) → log once, build the
|
|
223
|
+
* envelope from `failureContext` alone. Payload is absent but the
|
|
224
|
+
* error reason + attempt accounting still survive.
|
|
225
|
+
* - `xrange` throws (network blip, ACL) → same fallback.
|
|
226
|
+
* - Source entry trimmed before DLQ write → same fallback.
|
|
227
|
+
*/
|
|
228
|
+
private buildDlqEnvelope;
|
|
229
|
+
private sleep;
|
|
230
|
+
}
|
|
231
|
+
//#endregion
|
|
232
|
+
export { RedisStreamTransport as n, RedisStreamTransportOptions as r, RedisStreamLike as t };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { R as RegisterOptions, k as IntrospectionPluginOptions, z as ResourceRegistry } from "../index-
|
|
1
|
+
import { R as RegisterOptions, k as IntrospectionPluginOptions, z as ResourceRegistry } from "../index-BtW7qYwa.mjs";
|
|
2
2
|
import { FastifyPluginAsync } from "fastify";
|
|
3
3
|
|
|
4
4
|
//#region src/registry/introspectionPlugin.d.ts
|
package/dist/registry/index.mjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { n as introspectionPlugin_default, t as introspectionPlugin } from "../registry-
|
|
2
|
-
import { t as ResourceRegistry } from "../ResourceRegistry-
|
|
1
|
+
import { n as introspectionPlugin_default, t as introspectionPlugin } from "../registry-I-ogLgL9.mjs";
|
|
2
|
+
import { t as ResourceRegistry } from "../ResourceRegistry-CTERg_2x.mjs";
|
|
3
3
|
export { ResourceRegistry, introspectionPlugin_default as introspectionPlugin, introspectionPlugin as introspectionPluginFn };
|
|
@@ -1,29 +1,11 @@
|
|
|
1
1
|
import { t as __exportAll } from "./chunk-BpYLSNr0.mjs";
|
|
2
|
+
import { toCanonicalList } from "@classytic/repo-core/pagination";
|
|
2
3
|
import fp from "fastify-plugin";
|
|
3
4
|
//#region src/plugins/replyHelpers.ts
|
|
4
5
|
var replyHelpers_exports = /* @__PURE__ */ __exportAll({ replyHelpersPlugin: () => replyHelpersPlugin });
|
|
5
6
|
async function replyHelpersPluginFn(fastify) {
|
|
6
|
-
fastify.decorateReply("
|
|
7
|
-
return this.code(
|
|
8
|
-
success: true,
|
|
9
|
-
data
|
|
10
|
-
});
|
|
11
|
-
});
|
|
12
|
-
fastify.decorateReply("fail", function(error, statusCode = 400) {
|
|
13
|
-
if (Array.isArray(error)) return this.code(statusCode).send({
|
|
14
|
-
success: false,
|
|
15
|
-
errors: error
|
|
16
|
-
});
|
|
17
|
-
return this.code(statusCode).send({
|
|
18
|
-
success: false,
|
|
19
|
-
error
|
|
20
|
-
});
|
|
21
|
-
});
|
|
22
|
-
fastify.decorateReply("paginated", function(result) {
|
|
23
|
-
return this.code(200).send({
|
|
24
|
-
success: true,
|
|
25
|
-
...result
|
|
26
|
-
});
|
|
7
|
+
fastify.decorateReply("sendList", function(input) {
|
|
8
|
+
return this.code(200).send(toCanonicalList(input));
|
|
27
9
|
});
|
|
28
10
|
fastify.decorateReply("stream", function(source, options) {
|
|
29
11
|
this.code(options.statusCode ?? 200);
|