@classytic/arc 2.19.0 → 2.20.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.
Files changed (90) hide show
  1. package/README.md +1 -1
  2. package/bin/arc.js +37 -0
  3. package/dist/{BaseController-Dy6EQHjM.mjs → BaseController-D-MHZ27_.mjs} +4 -4
  4. package/dist/{ResourceRegistry-5fKZwhK_.mjs → ResourceRegistry-7RnrEWNP.mjs} +1 -1
  5. package/dist/{actionPermissions-D7NGwcAR.mjs → actionPermissions-C9RMiIpc.mjs} +1 -1
  6. package/dist/audit/index.mjs +1 -1
  7. package/dist/auth/index.d.mts +1 -1
  8. package/dist/auth/index.mjs +7 -5
  9. package/dist/{buildHandler-B0qvAguf.mjs → buildHandler-D_2ULWxZ.mjs} +3 -3
  10. package/dist/cache/index.mjs +2 -2
  11. package/dist/cli/commands/describe.d.mts +1 -1
  12. package/dist/cli/commands/describe.mjs +2 -2
  13. package/dist/cli/commands/docs.mjs +2 -2
  14. package/dist/cli/commands/generate.mjs +1 -1
  15. package/dist/cli/commands/init.mjs +1 -1
  16. package/dist/cli/commands/introspect.mjs +4 -13
  17. package/dist/cli/index.mjs +2 -2
  18. package/dist/{constants-gaEeMlz-.mjs → constants-DNre0wRg.mjs} +1 -1
  19. package/dist/core/index.d.mts +2 -2
  20. package/dist/core/index.mjs +4 -4
  21. package/dist/{core-Ba-6Sue6.mjs → core-CWhyGkiM.mjs} +125 -53
  22. package/dist/{createActionRouter-B_WzBFyf.mjs → createActionRouter-HlQso0jO.mjs} +4 -4
  23. package/dist/{createAggregationRouter-B_G_nIjm.mjs → createAggregationRouter-5LzPzgw1.mjs} +5 -4
  24. package/dist/{createApp--703hQE1.mjs → createApp-D6uwzCKu.mjs} +210 -17
  25. package/dist/docs/index.d.mts +1 -1
  26. package/dist/docs/index.mjs +1 -1
  27. package/dist/events/index.mjs +9 -6
  28. package/dist/factory/index.d.mts +3 -2
  29. package/dist/factory/index.mjs +2 -2
  30. package/dist/{fastify-augmentation-D-5_yQJi.d.mts → fastify-augmentation-CCQJEDgh.d.mts} +12 -1
  31. package/dist/{generate-Brans3fW.mjs → generate-usRSdQmP.mjs} +4 -3
  32. package/dist/hooks/index.d.mts +1 -1
  33. package/dist/idempotency/index.mjs +1 -1
  34. package/dist/{index-CRKiiP5o.d.mts → index-CdFkIMEd.d.mts} +5 -0
  35. package/dist/{index-CP6A1Ffj.d.mts → index-DUa8WHz3.d.mts} +1 -1
  36. package/dist/{index-CUTG2Cuo.d.mts → index-_--GyzcO.d.mts} +28 -1
  37. package/dist/index.d.mts +3 -3
  38. package/dist/index.mjs +6 -6
  39. package/dist/{init-Bqpt1Hxf.mjs → init-YH_nslQR.mjs} +87 -5
  40. package/dist/integrations/index.d.mts +1 -1
  41. package/dist/integrations/mcp/index.d.mts +2 -2
  42. package/dist/integrations/mcp/index.mjs +1 -1
  43. package/dist/integrations/mcp/testing.d.mts +1 -1
  44. package/dist/integrations/mcp/testing.mjs +1 -1
  45. package/dist/integrations/streamline.d.mts +17 -5
  46. package/dist/integrations/streamline.mjs +9 -5
  47. package/dist/{loadResourcesFromEntry-BTlFEx05.mjs → loadResourcesFromEntry-OMCvIEE7.mjs} +1 -1
  48. package/dist/{mcpPlugin-C088Nd-G.mjs → mcpPlugin-CuW6L_uD.mjs} +148 -49
  49. package/dist/middleware/index.d.mts +1 -1
  50. package/dist/middleware/index.mjs +1 -1
  51. package/dist/module-JYH9V0I8.d.mts +384 -0
  52. package/dist/{openapi-DZ-5a5Op.mjs → openapi-Dq6RbEGK.mjs} +3 -3
  53. package/dist/permissions/index.d.mts +1 -1
  54. package/dist/permissions/index.mjs +1 -1
  55. package/dist/{permissions-BPB1xqGf.mjs → permissions-CgbOLJZG.mjs} +10 -2
  56. package/dist/pipeline/index.d.mts +1 -1
  57. package/dist/plugins/index.d.mts +10 -5
  58. package/dist/plugins/index.mjs +3 -3
  59. package/dist/plugins/tracing-entry.mjs +1 -1
  60. package/dist/{pluralize-DccFV9R7.mjs → pluralize-BhrgwZb9.mjs} +3 -3
  61. package/dist/presets/filesUpload.d.mts +1 -1
  62. package/dist/presets/filesUpload.mjs +1 -1
  63. package/dist/presets/index.d.mts +16 -2
  64. package/dist/presets/index.mjs +1 -1
  65. package/dist/presets/multiTenant.d.mts +1 -1
  66. package/dist/presets/multiTenant.mjs +1 -1
  67. package/dist/presets/search.d.mts +1 -1
  68. package/dist/presets/search.mjs +3 -2
  69. package/dist/{presets-BtyFwTO4.mjs → presets-DWsYQdbV.mjs} +1 -1
  70. package/dist/{queryCachePlugin-emHb0CuX.mjs → queryCachePlugin-DzqLN904.mjs} +2 -2
  71. package/dist/{registerRoute-BdV8DDwU.mjs → registerRoute-DGSREwPw.mjs} +1 -1
  72. package/dist/registry/index.d.mts +1 -1
  73. package/dist/registry/index.mjs +2 -2
  74. package/dist/{registry-Bm9LjWKs.mjs → registry-vcOCtPij.mjs} +1 -1
  75. package/dist/{schemaIR-D1MJwqmp.mjs → schemaIR-ajetw3Fv.mjs} +1 -42
  76. package/dist/scim/index.mjs +2 -2
  77. package/dist/sync/changelog.d.mts +2 -0
  78. package/dist/sync/changelog.mjs +2 -0
  79. package/dist/testing/index.d.mts +2 -2
  80. package/dist/testing/index.mjs +2 -2
  81. package/dist/types/index.d.mts +1 -1
  82. package/dist/{types-9_wtNPsI.d.mts → types-BHMKlMBU.d.mts} +53 -195
  83. package/dist/{types-DpvSF5Hh.d.mts → types-C9b2HR5W.d.mts} +1 -1
  84. package/dist/utils/index.d.mts +1 -1
  85. package/dist/utils/index.mjs +1 -1
  86. package/dist/{utils-C6QQ9-hd.mjs → utils-ChjYQpjn.mjs} +1400 -1400
  87. package/dist/{validate-CRcaWzp2.mjs → validate-C2mGgSXg.mjs} +3 -3
  88. package/package.json +13 -8
  89. package/skills/arc/SKILL.md +10 -0
  90. package/skills/arc/references/mcp.md +2 -0
@@ -316,14 +316,14 @@ function validateTopNConfig(resource, aggregation, topN, groupBy, measures, buck
316
316
  if (!topN.sortBy || Object.keys(topN.sortBy).length === 0) throw new ArcAggregationConfigError(`Resource "${resource}" aggregation "${aggregation}" topN.sortBy must declare at least one ranking field.`);
317
317
  const partitionList = Array.isArray(topN.partitionBy) ? topN.partitionBy : [topN.partitionBy];
318
318
  if (partitionList.length === 0) throw new ArcAggregationConfigError(`Resource "${resource}" aggregation "${aggregation}" topN.partitionBy must declare at least one partition column.`);
319
- const validKeys = new Set([
319
+ const validKeys = /* @__PURE__ */ new Set([
320
320
  ...groupBy,
321
321
  ...bucketAliases,
322
322
  ...Object.keys(measures)
323
323
  ]);
324
324
  for (const key of partitionList) if (!validKeys.has(key)) throw new ArcAggregationConfigError(`Resource "${resource}" aggregation "${aggregation}" topN.partitionBy "${key}" is not a groupBy field, dateBucket alias, or measure alias. Available: ${[...validKeys].join(", ") || "(none — declare groupBy, dateBuckets, or measures)"}.`);
325
325
  }
326
- const VALID_BUCKET_UNITS = new Set([
326
+ const VALID_BUCKET_UNITS = /* @__PURE__ */ new Set([
327
327
  "minute",
328
328
  "hour",
329
329
  "day",
@@ -332,7 +332,7 @@ const VALID_BUCKET_UNITS = new Set([
332
332
  "quarter",
333
333
  "year"
334
334
  ]);
335
- const CUSTOM_BIN_UNIT_BLOCKLIST = new Set(["quarter", "year"]);
335
+ const CUSTOM_BIN_UNIT_BLOCKLIST = /* @__PURE__ */ new Set(["quarter", "year"]);
336
336
  /**
337
337
  * Validate `dateBuckets`. Catches the two classes of misconfig kits
338
338
  * already throw on at runtime — alias collisions and field-rule
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@classytic/arc",
3
- "version": "2.19.0",
3
+ "version": "2.20.0",
4
4
  "description": "Resource-oriented backend framework for Fastify - clean, minimal, powerful, tree-shakable",
5
5
  "type": "module",
6
6
  "exports": {
@@ -203,6 +203,10 @@
203
203
  "./auth/audit": {
204
204
  "types": "./dist/auth/audit.d.mts",
205
205
  "default": "./dist/auth/audit.mjs"
206
+ },
207
+ "./sync": {
208
+ "types": "./dist/sync/changelog.d.mts",
209
+ "default": "./dist/sync/changelog.mjs"
206
210
  }
207
211
  },
208
212
  "main": "./dist/index.mjs",
@@ -242,15 +246,16 @@
242
246
  "push": "classytic-push",
243
247
  "release:tag": "node -e \"require('child_process').execSync('npm run push -- v'+require('./package.json').version,{stdio:'inherit'})\"",
244
248
  "release": "npm run push -- main && npm run release:tag && npm publish",
245
- "prepublishOnly": "npm run typecheck && npm run lint && npm run build && npm run test:ci && npm run smoke"
249
+ "check:peer-skew": "node scripts/check-peer-skew.mjs",
250
+ "prepublishOnly": "npm run check:peer-skew && npm run typecheck && npm run lint && npm run build && npm run test:ci && npm run smoke"
246
251
  },
247
252
  "engines": {
248
253
  "node": ">=22"
249
254
  },
250
255
  "peerDependencies": {
251
- "@classytic/primitives": ">=0.6.0",
252
- "@classytic/repo-core": ">=0.5.0",
253
- "@classytic/streamline": ">=2.3.3",
256
+ "@classytic/primitives": ">=0.9.0",
257
+ "@classytic/repo-core": ">=0.7.0",
258
+ "@classytic/streamline": ">=2.7.0",
254
259
  "@fastify/cors": ">=11.0.0",
255
260
  "@fastify/helmet": ">=13.0.0",
256
261
  "@fastify/jwt": ">=10.0.0",
@@ -369,10 +374,10 @@
369
374
  "@biomejs/biome": "^2.5.0",
370
375
  "@classytic/dev-tools": "^0.2.0",
371
376
  "@classytic/mongokit": "^3.16.1",
372
- "@classytic/primitives": "^0.7.2",
373
- "@classytic/repo-core": "^0.6.0",
377
+ "@classytic/primitives": "^0.9.1",
378
+ "@classytic/repo-core": "^0.7.0",
374
379
  "@classytic/sqlitekit": "^0.6.0",
375
- "@classytic/streamline": "^2.6.0",
380
+ "@classytic/streamline": "^2.7.0",
376
381
  "@fastify/cors": "^11.2.0",
377
382
  "@fastify/helmet": "^13.0.2",
378
383
  "@fastify/jwt": "^10.1.0",
@@ -706,6 +706,16 @@ routes: [
706
706
  { method: 'GET', path: '/stream', raw: true, handler: async (req, reply) => reply.send(stream) },
707
707
  ]
708
708
 
709
+ // Per-route rate limit (2.20) — overrides the resource/app default for ONE endpoint.
710
+ // `false` = never throttle, object = tighten, omit = inherit. Custom routes only;
711
+ // actions share one POST /:id/action mount, so throttle an action by making it a route.
712
+ routes: [
713
+ { method: 'POST', path: '/export', handler: 'export', permissions: requireAuth(),
714
+ rateLimit: { max: 5, timeWindow: '1 minute' } },
715
+ { method: 'GET', path: '/health', handler: 'health', permissions: allowPublic(),
716
+ rateLimit: false },
717
+ ]
718
+
709
719
  // Per-resource opt-out of resourcePrefix (webhooks / admin routes)
710
720
  defineResource({ name: 'webhook', prefix: '/hooks', skipGlobalPrefix: true });
711
721
 
@@ -50,6 +50,8 @@ Resource `actions` (v2.8) also auto-generate MCP tools — each action becomes a
50
50
 
51
51
  Tool handlers call `BaseController` — same pipeline as REST (auth, org-scoping, hooks, field permissions, cache).
52
52
 
53
+ **Query params on generated tools (2.20):** `list_*` accepts `page`/`limit` (offset) **and** `cursor` (keyset, stable under concurrent inserts — when set, `page` is ignored), plus `sort`/`search`/`select`/`populate`. `get_*` accepts `select` for field projection alongside `id`. Both mirror REST exactly (same `QueryResolver`).
54
+
53
55
  ### McpPluginOptions
54
56
 
55
57
  | Option | Type | Default | Description |