@classytic/arc 2.20.0 → 2.22.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/dist/{BaseController-D-MHZ27_.mjs → BaseController-C6FlRWxF.mjs} +2 -2
- 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/{actionPermissions-C9RMiIpc.mjs → actionPermissions-ze70xXJi.mjs} +1 -1
- package/dist/audit/index.d.mts +9 -5
- package/dist/auth/audit.d.mts +7 -4
- package/dist/auth/audit.mjs +5 -0
- package/dist/auth/index.d.mts +35 -14
- package/dist/auth/index.mjs +6 -3
- package/dist/auth/redis-session.d.mts +1 -2
- package/dist/cache/index.d.mts +2 -3
- package/dist/cli/commands/describe.d.mts +1 -2
- package/dist/cli/commands/docs.mjs +1 -1
- package/dist/cli/commands/init.mjs +1 -1
- package/dist/cli/index.mjs +1 -1
- package/dist/context/index.d.mts +2 -2
- package/dist/core/index.d.mts +3 -3
- package/dist/core/index.mjs +4 -4
- package/dist/{core-CWhyGkiM.mjs → core-b6fgFgnd.mjs} +129 -17
- package/dist/{createActionRouter-HlQso0jO.mjs → createActionRouter-h1cEEaEX.mjs} +10 -6
- package/dist/{createAggregationRouter-5LzPzgw1.mjs → createAggregationRouter-B1C0kvTL.mjs} +3 -3
- package/dist/{createApp-D6uwzCKu.mjs → createApp-Ci7yG5gv.mjs} +390 -192
- 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/encryption/index.mjs +9 -5
- package/dist/{errorHandler-Dxf6P_kV.mjs → errorHandler-BTzXSwIg.mjs} +24 -3
- package/dist/{errorHandler-BtUUDPEa.d.mts → errorHandler-C6yv4ZTW.d.mts} +13 -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/transports/redis-stream-entry.d.mts +1 -1
- package/dist/events/transports/redis.d.mts +1 -2
- package/dist/factory/index.d.mts +30 -9
- package/dist/factory/index.mjs +35 -4
- package/dist/{fastify-augmentation-CCQJEDgh.d.mts → fastify-augmentation-9_fuetB4.d.mts} +2 -3
- package/dist/fields-D3lhgzhD.d.mts +121 -0
- package/dist/health-ScyjIVo5.mjs +202 -0
- package/dist/hooks/index.d.mts +1 -1
- package/dist/idempotency/index.d.mts +4 -3
- package/dist/idempotency/index.mjs +2 -0
- package/dist/idempotency/redis.d.mts +1 -1
- package/dist/{types-BHMKlMBU.d.mts → index-BEu4wjbL.d.mts} +241 -80
- package/dist/{index-DUa8WHz3.d.mts → index-D8MKYGDa.d.mts} +88 -7
- package/dist/{index-_--GyzcO.d.mts → index-DbtgCOCj.d.mts} +1324 -1228
- package/dist/{index-CdFkIMEd.d.mts → index-ogIHvOjo.d.mts} +36 -7
- package/dist/index.d.mts +8 -7
- package/dist/index.mjs +6 -6
- package/dist/{init-YH_nslQR.mjs → init-DleK3p9f.mjs} +272 -139
- 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 +2 -2
- package/dist/integrations/webhooks.d.mts +8 -5
- package/dist/integrations/webhooks.mjs +9 -5
- 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/jsonBody-BlzAoGCe.mjs +43 -0
- package/dist/{loadResources-B8UmpITt.mjs → loadResources-DpU8pfjV.mjs} +4 -3
- package/dist/logger/index.d.mts +26 -1
- package/dist/logger/index.mjs +39 -1
- package/dist/{mcpPlugin-CuW6L_uD.mjs → mcpPlugin-ByA2tf6D.mjs} +8 -4
- package/dist/middleware/index.d.mts +1 -2
- package/dist/{module-JYH9V0I8.d.mts → module-B4u10iOJ.d.mts} +71 -1
- package/dist/{openapi-Dq6RbEGK.mjs → openapi-BRpMZD7C.mjs} +3 -3
- package/dist/permissions/index.d.mts +4 -3
- package/dist/permissions/index.mjs +2 -2
- package/dist/{permissions-CgbOLJZG.mjs → permissions-BJMuKMl7.mjs} +33 -1
- package/dist/pipeline/index.d.mts +1 -2
- package/dist/plugins/index.d.mts +96 -7
- package/dist/plugins/index.mjs +86 -268
- package/dist/plugins/response-cache.d.mts +5 -3
- package/dist/plugins/response-cache.mjs +1 -0
- package/dist/plugins/tracing-entry.d.mts +1 -1
- package/dist/plugins/tracing-entry.mjs +7 -4
- package/dist/presets/filesUpload.d.mts +4 -5
- package/dist/presets/filesUpload.mjs +1 -1
- package/dist/presets/index.d.mts +1 -2
- package/dist/presets/index.mjs +1 -1
- package/dist/presets/multiTenant.d.mts +1 -2
- package/dist/presets/search.d.mts +2 -3
- package/dist/presets/search.mjs +1 -1
- package/dist/{presets-DWsYQdbV.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/rateLimitKey-BoWRH3e7.mjs +14 -0
- 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-DGSREwPw.mjs → registerRoute-xHc42fwB.mjs} +38 -18
- package/dist/registry/index.d.mts +2 -2
- package/dist/requestId-5BhTVzBv.mjs +113 -0
- package/dist/schemaConverter-Ds5reSGs.mjs +168 -0
- package/dist/{schemaIR-ajetw3Fv.mjs → schemaIR-B-6SPe7g.mjs} +2 -2
- package/dist/schemas/index.d.mts +0 -1
- package/dist/scim/index.d.mts +0 -1
- package/dist/scim/index.mjs +6 -7
- package/dist/scope/index.d.mts +2 -3
- package/dist/scope/index.mjs +2 -76
- package/dist/scope-k15RXfcq.mjs +64 -0
- 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/testing/index.d.mts +83 -4
- package/dist/testing/index.mjs +74 -4
- 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-C9b2HR5W.d.mts → types-Bc42CUyk.d.mts} +1 -2
- package/dist/types-Cc91nXuA.d.mts +132 -0
- package/dist/{fields-C7ahdGYf.d.mts → types-Csxga7d3.d.mts} +2 -123
- package/dist/{types-LNebCoJx.d.mts → types-DH0GupI7.d.mts} +8 -4
- package/dist/usage/index.d.mts +142 -0
- package/dist/usage/index.mjs +0 -0
- package/dist/utils/index.d.mts +220 -144
- package/dist/utils/index.mjs +3 -3
- package/dist/{utils-ChjYQpjn.mjs → utils-FhJ88TJE.mjs} +129 -39
- package/dist/{versioning-D_eBCfNr.d.mts → versioning-DLwklPlG.d.mts} +1 -7
- package/dist/{websocket-MlYlrYq0.d.mts → websocket-uuWqM6UY.d.mts} +5 -4
- package/llms.txt +39 -0
- package/package.json +453 -447
- package/skills/arc/SKILL.md +14 -8
- package/skills/arc/references/api-reference.md +34 -0
- package/skills/arc/references/auth.md +21 -4
- package/skills/arc/references/mcp.md +1 -1
- package/skills/arc/references/production.md +44 -2
- package/skills/arc-code-review/SKILL.md +1 -1
- package/skills/arc-code-review/references/anti-patterns.md +71 -18
- package/skills/arc-code-review/references/arc-cheatsheet.md +15 -2
- package/skills/arc-code-review/references/migration-recipes.md +7 -7
- package/skills/arc-code-review/references/mongokit-migration.md +4 -3
- package/skills/arc-module-publishing/SKILL.md +243 -0
- package/skills/arc-module-publishing/references/authoring-modules.md +327 -0
- package/skills/arc-module-publishing/references/package-manifest.md +157 -0
- package/skills/arc-module-publishing/references/publishing-workflow.md +182 -0
- package/dist/preloadResources-CHw3_oA_.mjs +0 -45
- package/dist/schemaConverter-U0MnO9vd.mjs +0 -110
package/dist/utils/index.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { a as OrgAccessDeniedError, c as ServiceUnavailableError, d as createDomainError, f as createError, i as NotFoundError, l as UnauthorizedError, n as ConflictError, o as OrgRequiredError, p as isArcError, r as ForbiddenError, s as RateLimitError, t as ArcError, u as ValidationError } from "../errors-DkO8Nk6-.mjs";
|
|
2
|
-
import { A as
|
|
3
|
-
import { a as
|
|
2
|
+
import { A as createCircuitBreaker, C as defineErrorMapper, D as CircuitBreakerError, E as CircuitBreaker, F as simpleEqualityMatcher, M as assertValidConfig, N as formatValidationErrors, O as CircuitBreakerRegistry, P as validateResourceConfig, S as defineGuard, T as withCompensation, _ as ArcQueryParser, a as bareListResponse, b as MONGO_DIALECT, c as errorDetailSchema, d as keysetListResponse, f as listResponse, g as responses, h as queryParams, i as aggregateListResponse, j as createCircuitBreakerRegistry, k as CircuitState, l as getDefaultCrudSchemas, m as paginationSchema, n as createStateMachine, o as deleteResponse, p as offsetListResponse, r as scheduleBackground, s as errorContractSchema, t as getUserId, u as getListQueryParams, v as createQueryParser, w as defineCompensation, x as NEUTRAL_DIALECT, y as handleRaw } from "../utils-FhJ88TJE.mjs";
|
|
3
|
+
import { a as isZodSchema, i as isJsonSchema, n as convertRouteSchema, o as toJsonSchema, t as convertOpenApiSchemas } from "../schemaConverter-Ds5reSGs.mjs";
|
|
4
4
|
import { a as promoteStreamTokenToHeader, i as pipeUIMessageStreamToReply, n as forwardedStreamHeaders, r as isReadableStream, t as UI_MESSAGE_STREAM_HEADERS } from "../streaming-BQcW6_Kq.mjs";
|
|
5
5
|
import { t as hasEvents } from "../typeGuards-C9KXUly6.mjs";
|
|
6
|
-
export { ArcError, ArcQueryParser, CircuitBreaker, CircuitBreakerError, CircuitBreakerRegistry, CircuitState, ConflictError, ForbiddenError, NotFoundError, OrgAccessDeniedError, OrgRequiredError, RateLimitError, ServiceUnavailableError, UI_MESSAGE_STREAM_HEADERS, UnauthorizedError, ValidationError, aggregateListResponse, assertValidConfig, bareListResponse, convertOpenApiSchemas, convertRouteSchema, createCircuitBreaker, createCircuitBreakerRegistry, createDomainError, createError, createQueryParser, createStateMachine, defineCompensation, defineErrorMapper, defineGuard, deleteResponse, errorContractSchema, errorDetailSchema, formatValidationErrors, forwardedStreamHeaders, getDefaultCrudSchemas, getListQueryParams, getUserId, handleRaw, hasEvents, isArcError, isJsonSchema, isReadableStream, isZodSchema, keysetListResponse, listResponse, offsetListResponse, paginationSchema, pipeUIMessageStreamToReply, promoteStreamTokenToHeader, queryParams, responses, scheduleBackground, simpleEqualityMatcher, toJsonSchema, validateResourceConfig, withCompensation };
|
|
6
|
+
export { ArcError, ArcQueryParser, CircuitBreaker, CircuitBreakerError, CircuitBreakerRegistry, CircuitState, ConflictError, ForbiddenError, MONGO_DIALECT, NEUTRAL_DIALECT, NotFoundError, OrgAccessDeniedError, OrgRequiredError, RateLimitError, ServiceUnavailableError, UI_MESSAGE_STREAM_HEADERS, UnauthorizedError, ValidationError, aggregateListResponse, assertValidConfig, bareListResponse, convertOpenApiSchemas, convertRouteSchema, createCircuitBreaker, createCircuitBreakerRegistry, createDomainError, createError, createQueryParser, createStateMachine, defineCompensation, defineErrorMapper, defineGuard, deleteResponse, errorContractSchema, errorDetailSchema, formatValidationErrors, forwardedStreamHeaders, getDefaultCrudSchemas, getListQueryParams, getUserId, handleRaw, hasEvents, isArcError, isJsonSchema, isReadableStream, isZodSchema, keysetListResponse, listResponse, offsetListResponse, paginationSchema, pipeUIMessageStreamToReply, promoteStreamTokenToHeader, queryParams, responses, scheduleBackground, simpleEqualityMatcher, toJsonSchema, validateResourceConfig, withCompensation };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { m as RESERVED_QUERY_PARAMS, t as CRUD_OPERATIONS } from "./constants-DNre0wRg.mjs";
|
|
2
2
|
import { arcLog } from "./logger/index.mjs";
|
|
3
3
|
import { t as ArcError } from "./errors-DkO8Nk6-.mjs";
|
|
4
|
-
import { r as getAvailablePresets } from "./presets-
|
|
4
|
+
import { r as getAvailablePresets } from "./presets-gw0ciIUD.mjs";
|
|
5
5
|
import { errorContractSchema as errorContractSchema$1, errorDetailSchema as errorDetailSchema$1 } from "@classytic/repo-core/errors";
|
|
6
6
|
//#region src/utils/simpleEqualityMatcher.ts
|
|
7
7
|
/**
|
|
@@ -752,6 +752,55 @@ function defineGuard(config) {
|
|
|
752
752
|
};
|
|
753
753
|
}
|
|
754
754
|
//#endregion
|
|
755
|
+
//#region src/utils/filter-dialect.ts
|
|
756
|
+
/**
|
|
757
|
+
* Default dialect — MongoDB / MongoKit operator shape. Emits `$`-prefixed
|
|
758
|
+
* tokens and the `$options: 'i'` case-insensitive sibling. This is what
|
|
759
|
+
* `ArcQueryParser` uses when no dialect is supplied, so behaviour is identical
|
|
760
|
+
* to every prior arc version.
|
|
761
|
+
*/
|
|
762
|
+
const MONGO_DIALECT = {
|
|
763
|
+
operators: {
|
|
764
|
+
eq: "$eq",
|
|
765
|
+
ne: "$ne",
|
|
766
|
+
gt: "$gt",
|
|
767
|
+
gte: "$gte",
|
|
768
|
+
lt: "$lt",
|
|
769
|
+
lte: "$lte",
|
|
770
|
+
in: "$in",
|
|
771
|
+
nin: "$nin",
|
|
772
|
+
like: "$regex",
|
|
773
|
+
contains: "$regex",
|
|
774
|
+
regex: "$regex",
|
|
775
|
+
exists: "$exists"
|
|
776
|
+
},
|
|
777
|
+
caseInsensitiveModifier: () => ({ $options: "i" })
|
|
778
|
+
};
|
|
779
|
+
/**
|
|
780
|
+
* Store-neutral reference dialect — emits UN-prefixed operator tokens as a
|
|
781
|
+
* translation AST (`?price[gte]=40` → `{ price: { gte: 40 } }`, with
|
|
782
|
+
* `{ caseInsensitive: true }` for `like`/`contains`). A non-Mongo adapter can
|
|
783
|
+
* consume this directly instead of writing a full `QueryParserInterface`. Use
|
|
784
|
+
* as a starting point; adjust the token names to your store's vocabulary.
|
|
785
|
+
*/
|
|
786
|
+
const NEUTRAL_DIALECT = {
|
|
787
|
+
operators: {
|
|
788
|
+
eq: "eq",
|
|
789
|
+
ne: "ne",
|
|
790
|
+
gt: "gt",
|
|
791
|
+
gte: "gte",
|
|
792
|
+
lt: "lt",
|
|
793
|
+
lte: "lte",
|
|
794
|
+
in: "in",
|
|
795
|
+
nin: "nin",
|
|
796
|
+
like: "like",
|
|
797
|
+
contains: "contains",
|
|
798
|
+
regex: "regex",
|
|
799
|
+
exists: "exists"
|
|
800
|
+
},
|
|
801
|
+
caseInsensitiveModifier: () => ({ caseInsensitive: true })
|
|
802
|
+
};
|
|
803
|
+
//#endregion
|
|
755
804
|
//#region src/utils/handleRaw.ts
|
|
756
805
|
/**
|
|
757
806
|
* Wrap a raw Fastify handler with Arc's response shape and error handling.
|
|
@@ -868,22 +917,17 @@ var ArcQueryParser = class {
|
|
|
868
917
|
allowedSortFields;
|
|
869
918
|
/** Allowed operators (used by MCP for operator descriptions) */
|
|
870
919
|
allowedOperators;
|
|
871
|
-
/**
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
nin: "$nin",
|
|
881
|
-
like: "$regex",
|
|
882
|
-
contains: "$regex",
|
|
883
|
-
regex: "$regex",
|
|
884
|
-
exists: "$exists"
|
|
885
|
-
};
|
|
920
|
+
/**
|
|
921
|
+
* Datastore dialect — owns the store-specific operator tokens + the
|
|
922
|
+
* case-insensitive modifier. Defaults to Mongo (backward-compatible).
|
|
923
|
+
*/
|
|
924
|
+
dialect;
|
|
925
|
+
/** Supported filter operators (neutral name → emitted token), from the dialect. */
|
|
926
|
+
get operators() {
|
|
927
|
+
return this.dialect.operators;
|
|
928
|
+
}
|
|
886
929
|
constructor(options = {}) {
|
|
930
|
+
this.dialect = options.dialect ?? MONGO_DIALECT;
|
|
887
931
|
this.maxLimit = options.maxLimit ?? 1e3;
|
|
888
932
|
this.defaultLimit = options.defaultLimit ?? 20;
|
|
889
933
|
this.maxRegexLength = options.maxRegexLength ?? 200;
|
|
@@ -1063,17 +1107,17 @@ var ArcQueryParser = class {
|
|
|
1063
1107
|
const allOperators = operatorKeys.every((op) => this.operators[op] && (!this._allowedOperators || this._allowedOperators.has(op)));
|
|
1064
1108
|
const allKnownOperators = operatorKeys.every((op) => this.operators[op]);
|
|
1065
1109
|
if (allOperators && operatorKeys.length > 0) {
|
|
1066
|
-
const
|
|
1110
|
+
const fieldOps = {};
|
|
1067
1111
|
let needsCaseInsensitive = false;
|
|
1068
1112
|
for (const [op, opValue] of Object.entries(operatorObj)) {
|
|
1069
|
-
const
|
|
1070
|
-
if (
|
|
1071
|
-
|
|
1113
|
+
const token = this.operators[op];
|
|
1114
|
+
if (token) {
|
|
1115
|
+
fieldOps[token] = this.parseFilterValue(opValue, op);
|
|
1072
1116
|
if (op === "contains" || op === "like") needsCaseInsensitive = true;
|
|
1073
1117
|
}
|
|
1074
1118
|
}
|
|
1075
|
-
if (needsCaseInsensitive)
|
|
1076
|
-
filters[key] =
|
|
1119
|
+
if (needsCaseInsensitive) Object.assign(fieldOps, this.dialect.caseInsensitiveModifier());
|
|
1120
|
+
filters[key] = fieldOps;
|
|
1077
1121
|
return;
|
|
1078
1122
|
}
|
|
1079
1123
|
if (allKnownOperators && this._allowedOperators) return;
|
|
@@ -1083,12 +1127,12 @@ var ArcQueryParser = class {
|
|
|
1083
1127
|
const [, fieldName, operator] = match;
|
|
1084
1128
|
if (!fieldName) return;
|
|
1085
1129
|
if (operator && this.operators[operator] && (!this._allowedOperators || this._allowedOperators.has(operator))) {
|
|
1086
|
-
const
|
|
1130
|
+
const token = this.operators[operator];
|
|
1087
1131
|
const parsedValue = this.parseFilterValue(value, operator);
|
|
1088
1132
|
if (!filters[fieldName]) filters[fieldName] = {};
|
|
1089
1133
|
const fieldFilter = filters[fieldName];
|
|
1090
|
-
fieldFilter[
|
|
1091
|
-
if (operator === "contains" || operator === "like") fieldFilter
|
|
1134
|
+
fieldFilter[token] = parsedValue;
|
|
1135
|
+
if (operator === "contains" || operator === "like") Object.assign(fieldFilter, this.dialect.caseInsensitiveModifier());
|
|
1092
1136
|
} else if (!operator) filters[fieldName] = this.parseFilterValue(value);
|
|
1093
1137
|
}
|
|
1094
1138
|
parseFilterValue(value, operator) {
|
|
@@ -1251,26 +1295,72 @@ const paginationSchema = {
|
|
|
1251
1295
|
]
|
|
1252
1296
|
};
|
|
1253
1297
|
/**
|
|
1254
|
-
* List response schema —
|
|
1255
|
-
*
|
|
1256
|
-
*
|
|
1298
|
+
* List response schema — accepts every wire shape `toCanonicalList` can
|
|
1299
|
+
* emit. Hosts who know their endpoint only ever produces one variant can
|
|
1300
|
+
* pin to a narrower helper (sharper OpenAPI docs, same serializer speed):
|
|
1257
1301
|
* - `offsetListResponse(item)` — `{ method: 'offset', data, page, limit, total, pages, hasNext, hasPrev }`
|
|
1258
1302
|
* - `keysetListResponse(item)` — `{ method: 'keyset', data, limit, hasMore, next: string|null }`
|
|
1259
1303
|
* - `aggregateListResponse(item)` — `{ method: 'aggregate', ...offset fields }`
|
|
1260
1304
|
* - `bareListResponse(item)` — `{ data }`
|
|
1261
1305
|
*
|
|
1262
|
-
*
|
|
1263
|
-
*
|
|
1264
|
-
*
|
|
1265
|
-
*
|
|
1306
|
+
* SHAPE: one merged permissive object, NOT a `oneOf` union (2.22). The
|
|
1307
|
+
* pre-2.22 union was semantically identical on the wire — every variant is
|
|
1308
|
+
* `additionalProperties: true` and the property definitions never conflict
|
|
1309
|
+
* (`next` only exists on keyset, the offset counters only on offset/
|
|
1310
|
+
* aggregate; fast-json-stringify skips undefined optionals) — but
|
|
1311
|
+
* fast-json-stringify implements top-level `oneOf` by running full AJV
|
|
1312
|
+
* validation PER RESPONSE to pick the branch, on the hottest route of
|
|
1313
|
+
* every arc app. The merge keeps the exact bytes (pinned by
|
|
1314
|
+
* `tests/utils/list-response-serialization.test.ts`) and drops the
|
|
1315
|
+
* per-response branch validation. Only `data` is required — the one field
|
|
1316
|
+
* all four variants share.
|
|
1266
1317
|
*/
|
|
1267
1318
|
function listResponse(itemSchema) {
|
|
1268
|
-
return {
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1319
|
+
return {
|
|
1320
|
+
type: "object",
|
|
1321
|
+
properties: {
|
|
1322
|
+
method: {
|
|
1323
|
+
type: "string",
|
|
1324
|
+
description: "Pagination method discriminant — 'offset' | 'keyset' | 'aggregate'; absent on bare lists.",
|
|
1325
|
+
example: "offset"
|
|
1326
|
+
},
|
|
1327
|
+
data: {
|
|
1328
|
+
type: "array",
|
|
1329
|
+
items: itemSchema
|
|
1330
|
+
},
|
|
1331
|
+
page: {
|
|
1332
|
+
type: "integer",
|
|
1333
|
+
example: 1
|
|
1334
|
+
},
|
|
1335
|
+
limit: {
|
|
1336
|
+
type: "integer",
|
|
1337
|
+
example: 20
|
|
1338
|
+
},
|
|
1339
|
+
total: {
|
|
1340
|
+
type: "integer",
|
|
1341
|
+
example: 100
|
|
1342
|
+
},
|
|
1343
|
+
pages: {
|
|
1344
|
+
type: "integer",
|
|
1345
|
+
example: 5
|
|
1346
|
+
},
|
|
1347
|
+
hasNext: {
|
|
1348
|
+
type: "boolean",
|
|
1349
|
+
example: false
|
|
1350
|
+
},
|
|
1351
|
+
hasPrev: {
|
|
1352
|
+
type: "boolean",
|
|
1353
|
+
example: false
|
|
1354
|
+
},
|
|
1355
|
+
hasMore: { type: "boolean" },
|
|
1356
|
+
next: {
|
|
1357
|
+
type: ["string", "null"],
|
|
1358
|
+
description: "Cursor token for the next page, or null."
|
|
1359
|
+
}
|
|
1360
|
+
},
|
|
1361
|
+
required: ["data"],
|
|
1362
|
+
additionalProperties: true
|
|
1363
|
+
};
|
|
1274
1364
|
}
|
|
1275
1365
|
/** Offset variant — `{ method: 'offset', data, page, limit, total, pages, hasNext, hasPrev }`. */
|
|
1276
1366
|
function offsetListResponse(itemSchema) {
|
|
@@ -1688,4 +1778,4 @@ function getUserId(user) {
|
|
|
1688
1778
|
return id ? String(id) : void 0;
|
|
1689
1779
|
}
|
|
1690
1780
|
//#endregion
|
|
1691
|
-
export {
|
|
1781
|
+
export { createCircuitBreaker as A, defineErrorMapper as C, CircuitBreakerError as D, CircuitBreaker as E, simpleEqualityMatcher as F, assertValidConfig as M, formatValidationErrors as N, CircuitBreakerRegistry as O, validateResourceConfig as P, defineGuard as S, withCompensation as T, ArcQueryParser as _, bareListResponse as a, MONGO_DIALECT as b, errorDetailSchema$1 as c, keysetListResponse as d, listResponse as f, responses as g, queryParams as h, aggregateListResponse as i, createCircuitBreakerRegistry as j, CircuitState as k, getDefaultCrudSchemas as l, paginationSchema as m, createStateMachine as n, deleteResponse as o, offsetListResponse as p, scheduleBackground as r, errorContractSchema$1 as s, getUserId as t, getListQueryParams as u, createQueryParser as v, defineCompensation as w, NEUTRAL_DIALECT as x, handleRaw as y };
|
|
@@ -1,12 +1,6 @@
|
|
|
1
|
-
import { n as DomainEvent } from "./EventTransport-
|
|
1
|
+
import { n as DomainEvent } from "./EventTransport-QmY7A258.mjs";
|
|
2
2
|
import { FastifyPluginAsync, FastifyRequest } from "fastify";
|
|
3
|
-
|
|
4
3
|
//#region src/plugins/health.d.ts
|
|
5
|
-
declare module "fastify" {
|
|
6
|
-
interface FastifyRequest {
|
|
7
|
-
_startTime?: number;
|
|
8
|
-
}
|
|
9
|
-
}
|
|
10
4
|
interface HealthCheck {
|
|
11
5
|
/** Name of the dependency */
|
|
12
6
|
name: string;
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { a as PushRefRegistry, l as EnvelopeWriter, s as PushRefStore } from "./pushref-registry-
|
|
1
|
+
import { a as PushRefRegistry, l as EnvelopeWriter, s as PushRefStore } from "./pushref-registry-BbcnpNTm.mjs";
|
|
2
2
|
import { FastifyBaseLogger, FastifyPluginAsync } from "fastify";
|
|
3
|
-
|
|
4
3
|
//#region src/integrations/websocket/adapter.d.ts
|
|
5
4
|
/**
|
|
6
5
|
* WebSocket cross-instance adapter contract.
|
|
@@ -135,8 +134,10 @@ interface WebSocketClient {
|
|
|
135
134
|
send(data: string): void;
|
|
136
135
|
close(code?: number, reason?: string): void;
|
|
137
136
|
readyState: number;
|
|
138
|
-
bufferedAmount?: number;
|
|
139
|
-
|
|
137
|
+
bufferedAmount?: number;
|
|
138
|
+
/** RFC 6455 §5.5.2 ping control frame. Browsers auto-respond at the protocol layer. */
|
|
139
|
+
ping?(data?: unknown): void;
|
|
140
|
+
/** Immediate socket destroy — no Close frame, no flush. Use for zombies. */
|
|
140
141
|
terminate?(): void;
|
|
141
142
|
};
|
|
142
143
|
subscriptions: Set<string>;
|
package/llms.txt
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# @classytic/arc
|
|
2
|
+
|
|
3
|
+
> Resource-oriented backend framework for Fastify. One `defineResource()` call =
|
|
4
|
+
> REST + validation + auth + permissions + events + caching + OpenAPI + MCP tools.
|
|
5
|
+
> DB-agnostic via @classytic/repo-core adapter kits (mongokit, sqlitekit, prismakit).
|
|
6
|
+
|
|
7
|
+
IMPORTANT for coding agents: hand-rolling is a bug in arc apps. Before writing any
|
|
8
|
+
route, validation, pagination, auth check, cron, queue worker, counter, or audit
|
|
9
|
+
code, check whether arc provides it — it almost certainly does:
|
|
10
|
+
|
|
11
|
+
- CRUD routes → defineResource({ name, adapter, permissions })
|
|
12
|
+
- Role/ownership checks → @classytic/arc/permissions (requireRoles, requireOwnership, permissionMatrix, requireQuota)
|
|
13
|
+
- Identity/tenant access → @classytic/arc/scope (getUserId, requireOrgId — never read scope fields directly)
|
|
14
|
+
- Body/response schemas → schemaOptions.fieldRules (customSchemas when wire ≠ model)
|
|
15
|
+
- Query filter/sort/page → the resource queryParser (allow-listed) + keyset cursors
|
|
16
|
+
- Soft delete/slug/tree/bulk/files/search → presets: [...]
|
|
17
|
+
- Recurring jobs → schedulesPlugin (@classytic/arc/plugins; LockAdapter leader safety)
|
|
18
|
+
- Durable queues → @classytic/arc/integrations/jobs (BullMQ/Redis) or @classytic/streamline (Mongo)
|
|
19
|
+
- Headless worker process→ createWorker(sameOptions) (@classytic/arc/factory)
|
|
20
|
+
- Usage counters/quotas → @classytic/arc/usage (usagePlugin, requireQuota) + rateLimit.plan
|
|
21
|
+
- Audit + record history → audit: true, history: true on the resource
|
|
22
|
+
- Idempotency → @classytic/arc/idempotency
|
|
23
|
+
- Events/outbox/webhooks → @classytic/arc/events, integrations/webhooks
|
|
24
|
+
- AI/MCP tools → generated from every resource (incl. _count/_exists/_distinct list verbs)
|
|
25
|
+
- App boot → createApp({ beforeBoot: connectDatabase, ... }) — DB connect goes IN beforeBoot
|
|
26
|
+
|
|
27
|
+
## Docs (inside this package)
|
|
28
|
+
|
|
29
|
+
- skills/arc/SKILL.md — full framework guide (boot, defineResource, presets, auth, testing)
|
|
30
|
+
- skills/arc/references/api-reference.md — every subpath import
|
|
31
|
+
- skills/arc-code-review/references/arc-cheatsheet.md — hand-rolled-code → arc-feature map
|
|
32
|
+
- skills/arc-code-review/SKILL.md — audit workflow for existing codebases
|
|
33
|
+
|
|
34
|
+
## Conventions that bite
|
|
35
|
+
|
|
36
|
+
- request.user is undefined on public routes — guard it.
|
|
37
|
+
- Custom endpoints go in the resource's routes:/actions: (inherit auth/OpenAPI/MCP);
|
|
38
|
+
bare fastify.get() bypasses everything.
|
|
39
|
+
- mongokit >=3.21 defaults schemaGenerator; schemaGenerator: false kills OpenAPI+MCP bodies.
|