@classytic/arc 1.1.0 → 2.1.2
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 +247 -794
- package/bin/arc.js +91 -52
- package/dist/EventTransport-BD2U0BTc.d.mts +100 -0
- package/dist/EventTransport-BD2U0BTc.d.mts.map +1 -0
- package/dist/HookSystem-BsGV-j2l.mjs +405 -0
- package/dist/HookSystem-BsGV-j2l.mjs.map +1 -0
- package/dist/ResourceRegistry-DsN4KJjV.mjs +250 -0
- package/dist/ResourceRegistry-DsN4KJjV.mjs.map +1 -0
- package/dist/adapters/index.d.mts +5 -0
- package/dist/adapters/index.mjs +3 -0
- package/dist/audit/index.d.mts +82 -0
- package/dist/audit/index.d.mts.map +1 -0
- package/dist/audit/index.mjs +276 -0
- package/dist/audit/index.mjs.map +1 -0
- package/dist/audit/mongodb.d.mts +5 -0
- package/dist/audit/mongodb.mjs +3 -0
- package/dist/audited-C3T5DTUx.mjs +141 -0
- package/dist/audited-C3T5DTUx.mjs.map +1 -0
- package/dist/auth/index.d.mts +189 -0
- package/dist/auth/index.d.mts.map +1 -0
- package/dist/auth/index.mjs +1102 -0
- package/dist/auth/index.mjs.map +1 -0
- package/dist/auth/redis-session.d.mts +44 -0
- package/dist/auth/redis-session.d.mts.map +1 -0
- package/dist/auth/redis-session.mjs +76 -0
- package/dist/auth/redis-session.mjs.map +1 -0
- package/dist/betterAuthOpenApi-BrHKeSAx.mjs +250 -0
- package/dist/betterAuthOpenApi-BrHKeSAx.mjs.map +1 -0
- package/dist/cache/index.d.mts +146 -0
- package/dist/cache/index.d.mts.map +1 -0
- package/dist/cache/index.mjs +92 -0
- package/dist/cache/index.mjs.map +1 -0
- package/dist/caching-Bl28lYsR.mjs +94 -0
- package/dist/caching-Bl28lYsR.mjs.map +1 -0
- package/dist/chunk-C7Uep-_p.mjs +20 -0
- package/dist/circuitBreaker-DeY4FCjs.mjs +1097 -0
- package/dist/circuitBreaker-DeY4FCjs.mjs.map +1 -0
- package/dist/cli/commands/describe.d.mts +19 -0
- package/dist/cli/commands/describe.d.mts.map +1 -0
- package/dist/cli/commands/describe.mjs +239 -0
- package/dist/cli/commands/describe.mjs.map +1 -0
- package/dist/cli/commands/docs.d.mts +14 -0
- package/dist/cli/commands/docs.d.mts.map +1 -0
- package/dist/cli/commands/docs.mjs +53 -0
- package/dist/cli/commands/docs.mjs.map +1 -0
- package/dist/cli/commands/{generate.d.ts → generate.d.mts} +3 -1
- package/dist/cli/commands/generate.d.mts.map +1 -0
- package/dist/cli/commands/generate.mjs +358 -0
- package/dist/cli/commands/generate.mjs.map +1 -0
- package/dist/cli/commands/{init.d.ts → init.d.mts} +12 -8
- package/dist/cli/commands/init.d.mts.map +1 -0
- package/dist/cli/commands/{init.js → init.mjs} +807 -616
- package/dist/cli/commands/init.mjs.map +1 -0
- package/dist/cli/commands/introspect.d.mts +11 -0
- package/dist/cli/commands/introspect.d.mts.map +1 -0
- package/dist/cli/commands/introspect.mjs +76 -0
- package/dist/cli/commands/introspect.mjs.map +1 -0
- package/dist/cli/index.d.mts +17 -0
- package/dist/cli/index.d.mts.map +1 -0
- package/dist/cli/index.mjs +157 -0
- package/dist/cli/index.mjs.map +1 -0
- package/dist/constants-DdXFXQtN.mjs +85 -0
- package/dist/constants-DdXFXQtN.mjs.map +1 -0
- package/dist/core/index.d.mts +5 -0
- package/dist/core/index.mjs +4 -0
- package/dist/createApp-CUgNqegw.mjs +560 -0
- package/dist/createApp-CUgNqegw.mjs.map +1 -0
- package/dist/defineResource-k0_BDn8v.mjs +2197 -0
- package/dist/defineResource-k0_BDn8v.mjs.map +1 -0
- package/dist/discovery/index.d.mts +47 -0
- package/dist/discovery/index.d.mts.map +1 -0
- package/dist/discovery/index.mjs +110 -0
- package/dist/discovery/index.mjs.map +1 -0
- package/dist/docs/index.d.mts +163 -0
- package/dist/docs/index.d.mts.map +1 -0
- package/dist/docs/index.mjs +73 -0
- package/dist/docs/index.mjs.map +1 -0
- package/dist/elevation-BRy3yFWT.mjs +113 -0
- package/dist/elevation-BRy3yFWT.mjs.map +1 -0
- package/dist/elevation-B_2dRLVP.d.mts +88 -0
- package/dist/elevation-B_2dRLVP.d.mts.map +1 -0
- package/dist/errorHandler-BbcgBmIH.d.mts +73 -0
- package/dist/errorHandler-BbcgBmIH.d.mts.map +1 -0
- package/dist/errorHandler-C1okiriz.mjs +109 -0
- package/dist/errorHandler-C1okiriz.mjs.map +1 -0
- package/dist/errors-B9bZok84.mjs +212 -0
- package/dist/errors-B9bZok84.mjs.map +1 -0
- package/dist/errors-ChKiFz62.d.mts +125 -0
- package/dist/errors-ChKiFz62.d.mts.map +1 -0
- package/dist/eventPlugin-CTrLH3mt.d.mts +125 -0
- package/dist/eventPlugin-CTrLH3mt.d.mts.map +1 -0
- package/dist/eventPlugin-DGR_B2on.mjs +230 -0
- package/dist/eventPlugin-DGR_B2on.mjs.map +1 -0
- package/dist/events/index.d.mts +54 -0
- package/dist/events/index.d.mts.map +1 -0
- package/dist/events/index.mjs +52 -0
- package/dist/events/index.mjs.map +1 -0
- package/dist/events/transports/redis-stream-entry.d.mts +2 -0
- package/dist/events/transports/redis-stream-entry.mjs +178 -0
- package/dist/events/transports/redis-stream-entry.mjs.map +1 -0
- package/dist/events/transports/redis.d.mts +77 -0
- package/dist/events/transports/redis.d.mts.map +1 -0
- package/dist/events/transports/redis.mjs +125 -0
- package/dist/events/transports/redis.mjs.map +1 -0
- package/dist/externalPaths-DlINfKbP.d.mts +51 -0
- package/dist/externalPaths-DlINfKbP.d.mts.map +1 -0
- package/dist/factory/index.d.mts +64 -0
- package/dist/factory/index.d.mts.map +1 -0
- package/dist/factory/index.mjs +3 -0
- package/dist/fastifyAdapter-BkrGrlFi.d.mts +217 -0
- package/dist/fastifyAdapter-BkrGrlFi.d.mts.map +1 -0
- package/dist/fields-DyaDVX4J.d.mts +110 -0
- package/dist/fields-DyaDVX4J.d.mts.map +1 -0
- package/dist/fields-iagOozy0.mjs +115 -0
- package/dist/fields-iagOozy0.mjs.map +1 -0
- package/dist/hooks/index.d.mts +4 -0
- package/dist/hooks/index.mjs +3 -0
- package/dist/idempotency/index.d.mts +97 -0
- package/dist/idempotency/index.d.mts.map +1 -0
- package/dist/idempotency/index.mjs +320 -0
- package/dist/idempotency/index.mjs.map +1 -0
- package/dist/idempotency/mongodb.d.mts +2 -0
- package/dist/idempotency/mongodb.mjs +115 -0
- package/dist/idempotency/mongodb.mjs.map +1 -0
- package/dist/idempotency/redis.d.mts +2 -0
- package/dist/idempotency/redis.mjs +104 -0
- package/dist/idempotency/redis.mjs.map +1 -0
- package/dist/index.d.mts +261 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +105 -0
- package/dist/index.mjs.map +1 -0
- package/dist/integrations/event-gateway.d.mts +47 -0
- package/dist/integrations/event-gateway.d.mts.map +1 -0
- package/dist/integrations/event-gateway.mjs +44 -0
- package/dist/integrations/event-gateway.mjs.map +1 -0
- package/dist/integrations/index.d.mts +5 -0
- package/dist/integrations/index.mjs +1 -0
- package/dist/integrations/jobs.d.mts +104 -0
- package/dist/integrations/jobs.d.mts.map +1 -0
- package/dist/integrations/jobs.mjs +124 -0
- package/dist/integrations/jobs.mjs.map +1 -0
- package/dist/integrations/streamline.d.mts +61 -0
- package/dist/integrations/streamline.d.mts.map +1 -0
- package/dist/integrations/streamline.mjs +126 -0
- package/dist/integrations/streamline.mjs.map +1 -0
- package/dist/integrations/websocket.d.mts +83 -0
- package/dist/integrations/websocket.d.mts.map +1 -0
- package/dist/integrations/websocket.mjs +289 -0
- package/dist/integrations/websocket.mjs.map +1 -0
- package/dist/interface-B01JvPVc.d.mts +78 -0
- package/dist/interface-B01JvPVc.d.mts.map +1 -0
- package/dist/interface-CZe8IkMf.d.mts +55 -0
- package/dist/interface-CZe8IkMf.d.mts.map +1 -0
- package/dist/interface-Ch8HU9uM.d.mts +1098 -0
- package/dist/interface-Ch8HU9uM.d.mts.map +1 -0
- package/dist/introspectionPlugin-rFdO8ZUa.mjs +54 -0
- package/dist/introspectionPlugin-rFdO8ZUa.mjs.map +1 -0
- package/dist/keys-BqNejWup.mjs +43 -0
- package/dist/keys-BqNejWup.mjs.map +1 -0
- package/dist/logger-Df2O2WsW.mjs +79 -0
- package/dist/logger-Df2O2WsW.mjs.map +1 -0
- package/dist/memory-cQgelFOj.mjs +144 -0
- package/dist/memory-cQgelFOj.mjs.map +1 -0
- package/dist/migrations/index.d.mts +157 -0
- package/dist/migrations/index.d.mts.map +1 -0
- package/dist/migrations/index.mjs +261 -0
- package/dist/migrations/index.mjs.map +1 -0
- package/dist/mongodb-BfJVlUJH.mjs +94 -0
- package/dist/mongodb-BfJVlUJH.mjs.map +1 -0
- package/dist/mongodb-CGzRbfAK.d.mts +119 -0
- package/dist/mongodb-CGzRbfAK.d.mts.map +1 -0
- package/dist/mongodb-JN-9JA7K.d.mts +72 -0
- package/dist/mongodb-JN-9JA7K.d.mts.map +1 -0
- package/dist/openapi-G3Cw7XuM.mjs +524 -0
- package/dist/openapi-G3Cw7XuM.mjs.map +1 -0
- package/dist/org/index.d.mts +69 -0
- package/dist/org/index.d.mts.map +1 -0
- package/dist/org/index.mjs +514 -0
- package/dist/org/index.mjs.map +1 -0
- package/dist/org/types.d.mts +83 -0
- package/dist/org/types.d.mts.map +1 -0
- package/dist/org/types.mjs +1 -0
- package/dist/permissions/index.d.mts +279 -0
- package/dist/permissions/index.d.mts.map +1 -0
- package/dist/permissions/index.mjs +579 -0
- package/dist/permissions/index.mjs.map +1 -0
- package/dist/plugins/index.d.mts +173 -0
- package/dist/plugins/index.d.mts.map +1 -0
- package/dist/plugins/index.mjs +523 -0
- package/dist/plugins/index.mjs.map +1 -0
- package/dist/plugins/response-cache.d.mts +88 -0
- package/dist/plugins/response-cache.d.mts.map +1 -0
- package/dist/plugins/response-cache.mjs +284 -0
- package/dist/plugins/response-cache.mjs.map +1 -0
- package/dist/plugins/tracing-entry.d.mts +2 -0
- package/dist/plugins/tracing-entry.mjs +186 -0
- package/dist/plugins/tracing-entry.mjs.map +1 -0
- package/dist/pluralize-CEweyOEm.mjs +87 -0
- package/dist/pluralize-CEweyOEm.mjs.map +1 -0
- package/dist/policies/{index.d.ts → index.d.mts} +204 -169
- package/dist/policies/index.d.mts.map +1 -0
- package/dist/policies/index.mjs +322 -0
- package/dist/policies/index.mjs.map +1 -0
- package/dist/presets/{index.d.ts → index.d.mts} +63 -131
- package/dist/presets/index.d.mts.map +1 -0
- package/dist/presets/index.mjs +144 -0
- package/dist/presets/index.mjs.map +1 -0
- package/dist/presets/multiTenant.d.mts +25 -0
- package/dist/presets/multiTenant.d.mts.map +1 -0
- package/dist/presets/multiTenant.mjs +114 -0
- package/dist/presets/multiTenant.mjs.map +1 -0
- package/dist/presets-BITljm96.mjs +120 -0
- package/dist/presets-BITljm96.mjs.map +1 -0
- package/dist/presets-DzSMwlKj.d.mts +58 -0
- package/dist/presets-DzSMwlKj.d.mts.map +1 -0
- package/dist/prisma-DJbMt3yf.mjs +628 -0
- package/dist/prisma-DJbMt3yf.mjs.map +1 -0
- package/dist/prisma-Dg9GoVdj.d.mts +275 -0
- package/dist/prisma-Dg9GoVdj.d.mts.map +1 -0
- package/dist/queryCachePlugin-7THaI5mt.d.mts +72 -0
- package/dist/queryCachePlugin-7THaI5mt.d.mts.map +1 -0
- package/dist/queryCachePlugin-DMBnp2Q0.mjs +139 -0
- package/dist/queryCachePlugin-DMBnp2Q0.mjs.map +1 -0
- package/dist/redis-D-JAeLtm.d.mts +50 -0
- package/dist/redis-D-JAeLtm.d.mts.map +1 -0
- package/dist/redis-stream-Bdh_vUU8.d.mts +104 -0
- package/dist/redis-stream-Bdh_vUU8.d.mts.map +1 -0
- package/dist/registry/index.d.mts +12 -0
- package/dist/registry/index.d.mts.map +1 -0
- package/dist/registry/index.mjs +4 -0
- package/dist/requestContext-QQD6ROJc.mjs +56 -0
- package/dist/requestContext-QQD6ROJc.mjs.map +1 -0
- package/dist/schemaConverter-BwrmWroW.mjs +99 -0
- package/dist/schemaConverter-BwrmWroW.mjs.map +1 -0
- package/dist/schemas/index.d.mts +64 -0
- package/dist/schemas/index.d.mts.map +1 -0
- package/dist/schemas/index.mjs +83 -0
- package/dist/schemas/index.mjs.map +1 -0
- package/dist/scope/index.d.mts +22 -0
- package/dist/scope/index.d.mts.map +1 -0
- package/dist/scope/index.mjs +66 -0
- package/dist/scope/index.mjs.map +1 -0
- package/dist/sessionManager-jPKLbHE0.d.mts +187 -0
- package/dist/sessionManager-jPKLbHE0.d.mts.map +1 -0
- package/dist/sse-B3c3_yZp.mjs +124 -0
- package/dist/sse-B3c3_yZp.mjs.map +1 -0
- package/dist/testing/index.d.mts +908 -0
- package/dist/testing/index.d.mts.map +1 -0
- package/dist/testing/index.mjs +1977 -0
- package/dist/testing/index.mjs.map +1 -0
- package/dist/tracing-Cc7vVQPp.d.mts +71 -0
- package/dist/tracing-Cc7vVQPp.d.mts.map +1 -0
- package/dist/typeGuards-DhMNLuvU.mjs +10 -0
- package/dist/typeGuards-DhMNLuvU.mjs.map +1 -0
- package/dist/types/index.d.mts +947 -0
- package/dist/types/index.d.mts.map +1 -0
- package/dist/types/index.mjs +15 -0
- package/dist/types/index.mjs.map +1 -0
- package/dist/types-Beqn1Un7.mjs +39 -0
- package/dist/types-Beqn1Un7.mjs.map +1 -0
- package/dist/types-CIgB7UUl.d.mts +446 -0
- package/dist/types-CIgB7UUl.d.mts.map +1 -0
- package/dist/types-aYB4V7uN.d.mts +87 -0
- package/dist/types-aYB4V7uN.d.mts.map +1 -0
- package/dist/utils/index.d.mts +748 -0
- package/dist/utils/index.d.mts.map +1 -0
- package/dist/utils/index.mjs +6 -0
- package/package.json +194 -68
- package/dist/BaseController-DVAiHxEQ.d.ts +0 -233
- package/dist/adapters/index.d.ts +0 -237
- package/dist/adapters/index.js +0 -668
- package/dist/arcCorePlugin-CsShQdyP.d.ts +0 -273
- package/dist/audit/index.d.ts +0 -195
- package/dist/audit/index.js +0 -319
- package/dist/auth/index.d.ts +0 -47
- package/dist/auth/index.js +0 -174
- package/dist/cli/commands/docs.d.ts +0 -11
- package/dist/cli/commands/docs.js +0 -474
- package/dist/cli/commands/generate.js +0 -334
- package/dist/cli/commands/introspect.d.ts +0 -8
- package/dist/cli/commands/introspect.js +0 -338
- package/dist/cli/index.d.ts +0 -4
- package/dist/cli/index.js +0 -3269
- package/dist/core/index.d.ts +0 -220
- package/dist/core/index.js +0 -2786
- package/dist/createApp-Ce9wl8W9.d.ts +0 -77
- package/dist/docs/index.d.ts +0 -166
- package/dist/docs/index.js +0 -658
- package/dist/errors-8WIxGS_6.d.ts +0 -122
- package/dist/events/index.d.ts +0 -117
- package/dist/events/index.js +0 -89
- package/dist/factory/index.d.ts +0 -38
- package/dist/factory/index.js +0 -1652
- package/dist/hooks/index.d.ts +0 -4
- package/dist/hooks/index.js +0 -199
- package/dist/idempotency/index.d.ts +0 -323
- package/dist/idempotency/index.js +0 -500
- package/dist/index-B4t03KQ0.d.ts +0 -1366
- package/dist/index.d.ts +0 -135
- package/dist/index.js +0 -4756
- package/dist/migrations/index.d.ts +0 -185
- package/dist/migrations/index.js +0 -274
- package/dist/org/index.d.ts +0 -129
- package/dist/org/index.js +0 -220
- package/dist/permissions/index.d.ts +0 -144
- package/dist/permissions/index.js +0 -103
- package/dist/plugins/index.d.ts +0 -46
- package/dist/plugins/index.js +0 -1069
- package/dist/policies/index.js +0 -196
- package/dist/presets/index.js +0 -384
- package/dist/presets/multiTenant.d.ts +0 -39
- package/dist/presets/multiTenant.js +0 -112
- package/dist/registry/index.d.ts +0 -16
- package/dist/registry/index.js +0 -253
- package/dist/testing/index.d.ts +0 -618
- package/dist/testing/index.js +0 -48020
- package/dist/types/index.d.ts +0 -4
- package/dist/types/index.js +0 -8
- package/dist/types-B99TBmFV.d.ts +0 -76
- package/dist/types-BvckRbs2.d.ts +0 -143
- package/dist/utils/index.d.ts +0 -679
- package/dist/utils/index.js +0 -931
package/dist/audit/index.js
DELETED
|
@@ -1,319 +0,0 @@
|
|
|
1
|
-
import fp from 'fastify-plugin';
|
|
2
|
-
|
|
3
|
-
// src/audit/auditPlugin.ts
|
|
4
|
-
|
|
5
|
-
// src/audit/stores/interface.ts
|
|
6
|
-
function createAuditEntry(resource, documentId, action, context, data) {
|
|
7
|
-
const changes = data?.before && data?.after ? detectChanges(data.before, data.after) : void 0;
|
|
8
|
-
return {
|
|
9
|
-
id: generateAuditId(),
|
|
10
|
-
resource,
|
|
11
|
-
documentId,
|
|
12
|
-
action,
|
|
13
|
-
userId: context.user?._id?.toString() ?? context.user?.id,
|
|
14
|
-
organizationId: context.organizationId,
|
|
15
|
-
before: data?.before,
|
|
16
|
-
after: data?.after,
|
|
17
|
-
changes,
|
|
18
|
-
requestId: context.requestId,
|
|
19
|
-
ipAddress: context.ipAddress,
|
|
20
|
-
userAgent: context.userAgent,
|
|
21
|
-
metadata: data?.metadata,
|
|
22
|
-
timestamp: /* @__PURE__ */ new Date()
|
|
23
|
-
};
|
|
24
|
-
}
|
|
25
|
-
function detectChanges(before, after) {
|
|
26
|
-
const changes = [];
|
|
27
|
-
const allKeys = /* @__PURE__ */ new Set([...Object.keys(before), ...Object.keys(after)]);
|
|
28
|
-
for (const key of allKeys) {
|
|
29
|
-
if (key.startsWith("_") || key === "updatedAt") continue;
|
|
30
|
-
const oldVal = JSON.stringify(before[key]);
|
|
31
|
-
const newVal = JSON.stringify(after[key]);
|
|
32
|
-
if (oldVal !== newVal) {
|
|
33
|
-
changes.push(key);
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
return changes;
|
|
37
|
-
}
|
|
38
|
-
function generateAuditId() {
|
|
39
|
-
const timestamp = Date.now().toString(36);
|
|
40
|
-
const random = Math.random().toString(36).substring(2, 10);
|
|
41
|
-
return `aud_${timestamp}${random}`;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
// src/audit/stores/memory.ts
|
|
45
|
-
var MemoryAuditStore = class {
|
|
46
|
-
name = "memory";
|
|
47
|
-
entries = [];
|
|
48
|
-
maxEntries;
|
|
49
|
-
constructor(options = {}) {
|
|
50
|
-
this.maxEntries = options.maxEntries ?? 1e3;
|
|
51
|
-
}
|
|
52
|
-
async log(entry) {
|
|
53
|
-
this.entries.unshift(entry);
|
|
54
|
-
if (this.entries.length > this.maxEntries) {
|
|
55
|
-
this.entries = this.entries.slice(0, this.maxEntries);
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
async query(options = {}) {
|
|
59
|
-
let results = [...this.entries];
|
|
60
|
-
if (options.resource) {
|
|
61
|
-
results = results.filter((e) => e.resource === options.resource);
|
|
62
|
-
}
|
|
63
|
-
if (options.documentId) {
|
|
64
|
-
results = results.filter((e) => e.documentId === options.documentId);
|
|
65
|
-
}
|
|
66
|
-
if (options.userId) {
|
|
67
|
-
results = results.filter((e) => e.userId === options.userId);
|
|
68
|
-
}
|
|
69
|
-
if (options.organizationId) {
|
|
70
|
-
results = results.filter((e) => e.organizationId === options.organizationId);
|
|
71
|
-
}
|
|
72
|
-
if (options.action) {
|
|
73
|
-
const actions = Array.isArray(options.action) ? options.action : [options.action];
|
|
74
|
-
results = results.filter((e) => actions.includes(e.action));
|
|
75
|
-
}
|
|
76
|
-
if (options.from) {
|
|
77
|
-
results = results.filter((e) => e.timestamp >= options.from);
|
|
78
|
-
}
|
|
79
|
-
if (options.to) {
|
|
80
|
-
results = results.filter((e) => e.timestamp <= options.to);
|
|
81
|
-
}
|
|
82
|
-
const offset = options.offset ?? 0;
|
|
83
|
-
const limit = options.limit ?? 100;
|
|
84
|
-
results = results.slice(offset, offset + limit);
|
|
85
|
-
return results;
|
|
86
|
-
}
|
|
87
|
-
async close() {
|
|
88
|
-
this.entries = [];
|
|
89
|
-
}
|
|
90
|
-
/** Get all entries (for testing) */
|
|
91
|
-
getAll() {
|
|
92
|
-
return [...this.entries];
|
|
93
|
-
}
|
|
94
|
-
/** Clear all entries (for testing) */
|
|
95
|
-
clear() {
|
|
96
|
-
this.entries = [];
|
|
97
|
-
}
|
|
98
|
-
};
|
|
99
|
-
|
|
100
|
-
// src/audit/stores/mongodb.ts
|
|
101
|
-
var MongoAuditStore = class {
|
|
102
|
-
constructor(options) {
|
|
103
|
-
this.options = options;
|
|
104
|
-
const collectionName = options.collection ?? "audit_logs";
|
|
105
|
-
this.collection = options.connection.collection(collectionName);
|
|
106
|
-
this.ttlDays = options.ttlDays ?? 90;
|
|
107
|
-
}
|
|
108
|
-
name = "mongodb";
|
|
109
|
-
collection;
|
|
110
|
-
initialized = false;
|
|
111
|
-
ttlDays;
|
|
112
|
-
async ensureIndexes() {
|
|
113
|
-
if (this.initialized) return;
|
|
114
|
-
try {
|
|
115
|
-
await this.collection.createIndex({
|
|
116
|
-
resource: 1,
|
|
117
|
-
documentId: 1,
|
|
118
|
-
timestamp: -1
|
|
119
|
-
});
|
|
120
|
-
await this.collection.createIndex({ userId: 1, timestamp: -1 });
|
|
121
|
-
await this.collection.createIndex({ organizationId: 1, timestamp: -1 });
|
|
122
|
-
if (this.ttlDays > 0) {
|
|
123
|
-
await this.collection.createIndex(
|
|
124
|
-
{ timestamp: 1 },
|
|
125
|
-
{ expireAfterSeconds: this.ttlDays * 24 * 60 * 60 }
|
|
126
|
-
);
|
|
127
|
-
}
|
|
128
|
-
this.initialized = true;
|
|
129
|
-
} catch {
|
|
130
|
-
this.initialized = true;
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
async log(entry) {
|
|
134
|
-
await this.ensureIndexes();
|
|
135
|
-
await this.collection.insertOne({
|
|
136
|
-
_id: entry.id,
|
|
137
|
-
resource: entry.resource,
|
|
138
|
-
documentId: entry.documentId,
|
|
139
|
-
action: entry.action,
|
|
140
|
-
userId: entry.userId,
|
|
141
|
-
organizationId: entry.organizationId,
|
|
142
|
-
before: entry.before,
|
|
143
|
-
after: entry.after,
|
|
144
|
-
changes: entry.changes,
|
|
145
|
-
requestId: entry.requestId,
|
|
146
|
-
ipAddress: entry.ipAddress,
|
|
147
|
-
userAgent: entry.userAgent,
|
|
148
|
-
metadata: entry.metadata,
|
|
149
|
-
timestamp: entry.timestamp
|
|
150
|
-
});
|
|
151
|
-
}
|
|
152
|
-
async query(options = {}) {
|
|
153
|
-
await this.ensureIndexes();
|
|
154
|
-
const query = {};
|
|
155
|
-
if (options.resource) {
|
|
156
|
-
query.resource = options.resource;
|
|
157
|
-
}
|
|
158
|
-
if (options.documentId) {
|
|
159
|
-
query.documentId = options.documentId;
|
|
160
|
-
}
|
|
161
|
-
if (options.userId) {
|
|
162
|
-
query.userId = options.userId;
|
|
163
|
-
}
|
|
164
|
-
if (options.organizationId) {
|
|
165
|
-
query.organizationId = options.organizationId;
|
|
166
|
-
}
|
|
167
|
-
if (options.action) {
|
|
168
|
-
const actions = Array.isArray(options.action) ? options.action : [options.action];
|
|
169
|
-
query.action = actions.length === 1 ? actions[0] : { $in: actions };
|
|
170
|
-
}
|
|
171
|
-
if (options.from || options.to) {
|
|
172
|
-
query.timestamp = {};
|
|
173
|
-
if (options.from) {
|
|
174
|
-
query.timestamp.$gte = options.from;
|
|
175
|
-
}
|
|
176
|
-
if (options.to) {
|
|
177
|
-
query.timestamp.$lte = options.to;
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
const offset = options.offset ?? 0;
|
|
181
|
-
const limit = options.limit ?? 100;
|
|
182
|
-
const docs = await this.collection.find(query).sort({ timestamp: -1 }).skip(offset).limit(limit).toArray();
|
|
183
|
-
return docs.map((doc) => ({
|
|
184
|
-
id: String(doc._id),
|
|
185
|
-
resource: doc.resource,
|
|
186
|
-
documentId: doc.documentId,
|
|
187
|
-
action: doc.action,
|
|
188
|
-
userId: doc.userId,
|
|
189
|
-
organizationId: doc.organizationId,
|
|
190
|
-
before: doc.before,
|
|
191
|
-
after: doc.after,
|
|
192
|
-
changes: doc.changes,
|
|
193
|
-
requestId: doc.requestId,
|
|
194
|
-
ipAddress: doc.ipAddress,
|
|
195
|
-
userAgent: doc.userAgent,
|
|
196
|
-
metadata: doc.metadata,
|
|
197
|
-
timestamp: doc.timestamp
|
|
198
|
-
}));
|
|
199
|
-
}
|
|
200
|
-
};
|
|
201
|
-
|
|
202
|
-
// src/audit/auditPlugin.ts
|
|
203
|
-
var auditPlugin = async (fastify, opts = {}) => {
|
|
204
|
-
const {
|
|
205
|
-
enabled = false,
|
|
206
|
-
stores: storeTypes = ["memory"],
|
|
207
|
-
mongoConnection,
|
|
208
|
-
mongoCollection = "audit_logs",
|
|
209
|
-
ttlDays = 90,
|
|
210
|
-
customStores = []
|
|
211
|
-
} = opts;
|
|
212
|
-
if (!enabled) {
|
|
213
|
-
fastify.decorate("audit", createNoopLogger());
|
|
214
|
-
fastify.decorateRequest("auditContext", void 0);
|
|
215
|
-
fastify.log?.debug?.("Audit plugin disabled");
|
|
216
|
-
return;
|
|
217
|
-
}
|
|
218
|
-
const stores = [...customStores];
|
|
219
|
-
for (const type of storeTypes) {
|
|
220
|
-
switch (type) {
|
|
221
|
-
case "memory":
|
|
222
|
-
stores.push(new MemoryAuditStore());
|
|
223
|
-
break;
|
|
224
|
-
case "mongodb":
|
|
225
|
-
if (!mongoConnection) {
|
|
226
|
-
throw new Error("Audit: mongoConnection required for mongodb store");
|
|
227
|
-
}
|
|
228
|
-
stores.push(new MongoAuditStore({
|
|
229
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
230
|
-
connection: mongoConnection,
|
|
231
|
-
collection: mongoCollection,
|
|
232
|
-
ttlDays
|
|
233
|
-
}));
|
|
234
|
-
break;
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
if (stores.length === 0) {
|
|
238
|
-
throw new Error("Audit: at least one store must be configured");
|
|
239
|
-
}
|
|
240
|
-
async function logToStores(entry) {
|
|
241
|
-
await Promise.all(stores.map((store) => store.log(entry)));
|
|
242
|
-
}
|
|
243
|
-
const audit = {
|
|
244
|
-
async create(resource, documentId, data, context) {
|
|
245
|
-
const entry = createAuditEntry(resource, documentId, "create", context ?? {}, {
|
|
246
|
-
after: data
|
|
247
|
-
});
|
|
248
|
-
await logToStores(entry);
|
|
249
|
-
},
|
|
250
|
-
async update(resource, documentId, before, after, context) {
|
|
251
|
-
const entry = createAuditEntry(resource, documentId, "update", context ?? {}, {
|
|
252
|
-
before,
|
|
253
|
-
after
|
|
254
|
-
});
|
|
255
|
-
await logToStores(entry);
|
|
256
|
-
},
|
|
257
|
-
async delete(resource, documentId, data, context) {
|
|
258
|
-
const entry = createAuditEntry(resource, documentId, "delete", context ?? {}, {
|
|
259
|
-
before: data
|
|
260
|
-
});
|
|
261
|
-
await logToStores(entry);
|
|
262
|
-
},
|
|
263
|
-
async restore(resource, documentId, data, context) {
|
|
264
|
-
const entry = createAuditEntry(resource, documentId, "restore", context ?? {}, {
|
|
265
|
-
after: data
|
|
266
|
-
});
|
|
267
|
-
await logToStores(entry);
|
|
268
|
-
},
|
|
269
|
-
async custom(resource, documentId, action, data, context) {
|
|
270
|
-
const entry = createAuditEntry(resource, documentId, "custom", context ?? {}, {
|
|
271
|
-
metadata: { customAction: action, ...data }
|
|
272
|
-
});
|
|
273
|
-
await logToStores(entry);
|
|
274
|
-
},
|
|
275
|
-
async query(options) {
|
|
276
|
-
for (const store of stores) {
|
|
277
|
-
if (store.query) {
|
|
278
|
-
return store.query(options);
|
|
279
|
-
}
|
|
280
|
-
}
|
|
281
|
-
return [];
|
|
282
|
-
}
|
|
283
|
-
};
|
|
284
|
-
fastify.decorate("audit", audit);
|
|
285
|
-
fastify.decorateRequest("auditContext", void 0);
|
|
286
|
-
fastify.addHook("onRequest", async (request) => {
|
|
287
|
-
const user = request.user;
|
|
288
|
-
const context = request.context;
|
|
289
|
-
request.auditContext = {
|
|
290
|
-
user,
|
|
291
|
-
organizationId: context?.organizationId ?? void 0,
|
|
292
|
-
requestId: request.id,
|
|
293
|
-
ipAddress: request.ip,
|
|
294
|
-
userAgent: request.headers["user-agent"]
|
|
295
|
-
};
|
|
296
|
-
});
|
|
297
|
-
fastify.addHook("onClose", async () => {
|
|
298
|
-
await Promise.all(stores.map((store) => store.close?.()));
|
|
299
|
-
});
|
|
300
|
-
fastify.log?.info?.({ stores: storeTypes }, "Audit plugin enabled");
|
|
301
|
-
};
|
|
302
|
-
function createNoopLogger() {
|
|
303
|
-
const noop = async () => {
|
|
304
|
-
};
|
|
305
|
-
return {
|
|
306
|
-
create: noop,
|
|
307
|
-
update: noop,
|
|
308
|
-
delete: noop,
|
|
309
|
-
restore: noop,
|
|
310
|
-
custom: noop,
|
|
311
|
-
query: async () => []
|
|
312
|
-
};
|
|
313
|
-
}
|
|
314
|
-
var auditPlugin_default = fp(auditPlugin, {
|
|
315
|
-
name: "arc-audit",
|
|
316
|
-
fastify: "5.x"
|
|
317
|
-
});
|
|
318
|
-
|
|
319
|
-
export { MemoryAuditStore, MongoAuditStore, auditPlugin_default as auditPlugin, auditPlugin as auditPluginFn, createAuditEntry };
|
package/dist/auth/index.d.ts
DELETED
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import { FastifyPluginAsync } from 'fastify';
|
|
2
|
-
import { g as AuthHelpers, h as AuthPluginOptions } from '../index-B4t03KQ0.js';
|
|
3
|
-
import 'mongoose';
|
|
4
|
-
import '../types-B99TBmFV.js';
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Auth Plugin - Flexible, Database-Agnostic Authentication
|
|
8
|
-
*
|
|
9
|
-
* Arc provides JWT infrastructure and calls your authenticator.
|
|
10
|
-
* You control ALL authentication logic.
|
|
11
|
-
*
|
|
12
|
-
* Design principles:
|
|
13
|
-
* - Arc handles plumbing (JWT sign/verify utilities)
|
|
14
|
-
* - App handles business logic (how to authenticate, where users live)
|
|
15
|
-
* - Works with any database (Prisma, MongoDB, Postgres, none)
|
|
16
|
-
* - Supports multiple auth strategies (JWT, API keys, sessions, etc.)
|
|
17
|
-
*
|
|
18
|
-
* @example
|
|
19
|
-
* ```typescript
|
|
20
|
-
* // In createApp
|
|
21
|
-
* auth: {
|
|
22
|
-
* jwt: { secret: process.env.JWT_SECRET },
|
|
23
|
-
* authenticate: async (request, { jwt }) => {
|
|
24
|
-
* // Your auth logic - Arc never touches your database
|
|
25
|
-
* const token = request.headers.authorization?.split(' ')[1];
|
|
26
|
-
* if (!token) return null;
|
|
27
|
-
* const decoded = jwt.verify(token);
|
|
28
|
-
* return userRepo.findById(decoded.id);
|
|
29
|
-
* },
|
|
30
|
-
* }
|
|
31
|
-
* ```
|
|
32
|
-
*/
|
|
33
|
-
|
|
34
|
-
declare module 'fastify' {
|
|
35
|
-
interface FastifyInstance {
|
|
36
|
-
/** Authenticate middleware - use in preHandler for protected routes */
|
|
37
|
-
authenticate: (request: FastifyRequest, reply: FastifyReply) => Promise<void>;
|
|
38
|
-
/** Authorize middleware factory - checks if user has required roles */
|
|
39
|
-
authorize: (...roles: string[]) => (request: FastifyRequest, reply: FastifyReply) => Promise<void>;
|
|
40
|
-
/** Auth helpers - issueTokens, jwt utilities */
|
|
41
|
-
auth: AuthHelpers;
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
declare const authPlugin: FastifyPluginAsync<AuthPluginOptions>;
|
|
45
|
-
declare const _default: FastifyPluginAsync<AuthPluginOptions>;
|
|
46
|
-
|
|
47
|
-
export { AuthPluginOptions, _default as authPlugin, authPlugin as authPluginFn };
|
package/dist/auth/index.js
DELETED
|
@@ -1,174 +0,0 @@
|
|
|
1
|
-
import fp from 'fastify-plugin';
|
|
2
|
-
|
|
3
|
-
// src/auth/authPlugin.ts
|
|
4
|
-
function parseExpiresIn(input, defaultValue) {
|
|
5
|
-
if (!input) return defaultValue;
|
|
6
|
-
if (/^\d+$/.test(input)) return parseInt(input, 10);
|
|
7
|
-
const match = /^(\d+)\s*([smhd])$/i.exec(input);
|
|
8
|
-
if (!match) return defaultValue;
|
|
9
|
-
const value = parseInt(match[1], 10);
|
|
10
|
-
const unit = match[2].toLowerCase();
|
|
11
|
-
const multipliers = { s: 1, m: 60, h: 3600, d: 86400 };
|
|
12
|
-
return value * (multipliers[unit] ?? 1);
|
|
13
|
-
}
|
|
14
|
-
function extractBearerToken(request) {
|
|
15
|
-
const auth = request.headers.authorization;
|
|
16
|
-
if (!auth?.startsWith("Bearer ")) return null;
|
|
17
|
-
return auth.slice(7);
|
|
18
|
-
}
|
|
19
|
-
var authPlugin = async (fastify, opts = {}) => {
|
|
20
|
-
const { jwt: jwtConfig, authenticate: appAuthenticator, onFailure, userProperty = "user" } = opts;
|
|
21
|
-
let jwtContext = null;
|
|
22
|
-
if (jwtConfig?.secret) {
|
|
23
|
-
if (jwtConfig.secret.length < 32) {
|
|
24
|
-
throw new Error(
|
|
25
|
-
`JWT secret must be at least 32 characters (current: ${jwtConfig.secret.length}).
|
|
26
|
-
Use a strong random secret for production.`
|
|
27
|
-
);
|
|
28
|
-
}
|
|
29
|
-
const jwtPlugin = await import('@fastify/jwt');
|
|
30
|
-
await fastify.register(jwtPlugin.default ?? jwtPlugin, {
|
|
31
|
-
secret: jwtConfig.secret,
|
|
32
|
-
sign: {
|
|
33
|
-
expiresIn: jwtConfig.expiresIn ?? "15m",
|
|
34
|
-
...jwtConfig.sign ?? {}
|
|
35
|
-
},
|
|
36
|
-
verify: { ...jwtConfig.verify ?? {} }
|
|
37
|
-
});
|
|
38
|
-
const fastifyWithJwt = fastify;
|
|
39
|
-
jwtContext = {
|
|
40
|
-
verify: (token) => {
|
|
41
|
-
return fastifyWithJwt.jwt.verify(token);
|
|
42
|
-
},
|
|
43
|
-
sign: (payload, options) => {
|
|
44
|
-
return fastifyWithJwt.jwt.sign(payload, options);
|
|
45
|
-
},
|
|
46
|
-
decode: (token) => {
|
|
47
|
-
try {
|
|
48
|
-
return fastifyWithJwt.jwt.decode(token);
|
|
49
|
-
} catch {
|
|
50
|
-
return null;
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
};
|
|
54
|
-
fastify.log.info("Auth: JWT infrastructure enabled");
|
|
55
|
-
}
|
|
56
|
-
const authContext = {
|
|
57
|
-
jwt: jwtContext,
|
|
58
|
-
fastify
|
|
59
|
-
};
|
|
60
|
-
const authenticate = async (request, reply) => {
|
|
61
|
-
try {
|
|
62
|
-
let user = null;
|
|
63
|
-
if (appAuthenticator) {
|
|
64
|
-
user = await appAuthenticator(request, authContext);
|
|
65
|
-
} else if (jwtContext) {
|
|
66
|
-
const token = extractBearerToken(request);
|
|
67
|
-
if (token) {
|
|
68
|
-
const decoded = jwtContext.verify(token);
|
|
69
|
-
user = decoded;
|
|
70
|
-
}
|
|
71
|
-
} else {
|
|
72
|
-
throw new Error(
|
|
73
|
-
"No authenticator configured. Provide auth.authenticate function or auth.jwt.secret."
|
|
74
|
-
);
|
|
75
|
-
}
|
|
76
|
-
if (!user) {
|
|
77
|
-
throw new Error("Authentication required");
|
|
78
|
-
}
|
|
79
|
-
request[userProperty] = user;
|
|
80
|
-
} catch (err) {
|
|
81
|
-
const error = err instanceof Error ? err : new Error(String(err));
|
|
82
|
-
if (onFailure) {
|
|
83
|
-
await onFailure(request, reply, error);
|
|
84
|
-
return;
|
|
85
|
-
}
|
|
86
|
-
const message = process.env.NODE_ENV === "production" ? "Authentication required" : error.message;
|
|
87
|
-
reply.code(401).send({
|
|
88
|
-
success: false,
|
|
89
|
-
error: "Unauthorized",
|
|
90
|
-
message
|
|
91
|
-
});
|
|
92
|
-
}
|
|
93
|
-
};
|
|
94
|
-
const refreshSecret = jwtConfig?.refreshSecret ?? jwtConfig?.secret;
|
|
95
|
-
const accessExpiresIn = jwtConfig?.expiresIn ?? "15m";
|
|
96
|
-
const refreshExpiresIn = jwtConfig?.refreshExpiresIn ?? "7d";
|
|
97
|
-
const issueTokens = (payload, options) => {
|
|
98
|
-
if (!jwtContext) {
|
|
99
|
-
throw new Error("JWT not configured. Provide auth.jwt.secret to use issueTokens.");
|
|
100
|
-
}
|
|
101
|
-
const accessTtl = options?.expiresIn ?? accessExpiresIn;
|
|
102
|
-
const refreshTtl = options?.refreshExpiresIn ?? refreshExpiresIn;
|
|
103
|
-
const accessToken = jwtContext.sign(payload, { expiresIn: accessTtl });
|
|
104
|
-
const refreshPayload = payload.id ? { id: payload.id, type: "refresh" } : payload._id ? { id: payload._id, type: "refresh" } : { ...payload, type: "refresh" };
|
|
105
|
-
let refreshToken;
|
|
106
|
-
if (refreshSecret) {
|
|
107
|
-
const fastifyWithJwt = fastify;
|
|
108
|
-
refreshToken = fastifyWithJwt.jwt.sign(refreshPayload, {
|
|
109
|
-
expiresIn: refreshTtl,
|
|
110
|
-
// Use refresh secret if different from main secret
|
|
111
|
-
...refreshSecret !== jwtConfig?.secret ? { secret: refreshSecret } : {}
|
|
112
|
-
});
|
|
113
|
-
}
|
|
114
|
-
return {
|
|
115
|
-
accessToken,
|
|
116
|
-
refreshToken,
|
|
117
|
-
expiresIn: parseExpiresIn(accessTtl, 900),
|
|
118
|
-
refreshExpiresIn: refreshToken ? parseExpiresIn(refreshTtl, 604800) : void 0,
|
|
119
|
-
tokenType: "Bearer"
|
|
120
|
-
};
|
|
121
|
-
};
|
|
122
|
-
const verifyRefreshToken = (token) => {
|
|
123
|
-
if (!jwtContext) {
|
|
124
|
-
throw new Error("JWT not configured. Provide auth.jwt.secret to use verifyRefreshToken.");
|
|
125
|
-
}
|
|
126
|
-
const fastifyWithJwt = fastify;
|
|
127
|
-
return fastifyWithJwt.jwt.verify(token, {
|
|
128
|
-
...refreshSecret !== jwtConfig?.secret ? { secret: refreshSecret } : {}
|
|
129
|
-
});
|
|
130
|
-
};
|
|
131
|
-
const authorize = (...allowedRoles) => {
|
|
132
|
-
return async (request, reply) => {
|
|
133
|
-
const user = request[userProperty];
|
|
134
|
-
if (!user) {
|
|
135
|
-
reply.code(401).send({
|
|
136
|
-
success: false,
|
|
137
|
-
error: "Unauthorized",
|
|
138
|
-
message: "No user context"
|
|
139
|
-
});
|
|
140
|
-
return;
|
|
141
|
-
}
|
|
142
|
-
const userRoles = user.roles ?? [];
|
|
143
|
-
if (allowedRoles.length === 1 && allowedRoles[0] === "*") {
|
|
144
|
-
return;
|
|
145
|
-
}
|
|
146
|
-
const hasRole = allowedRoles.some((role) => userRoles.includes(role));
|
|
147
|
-
if (!hasRole) {
|
|
148
|
-
reply.code(403).send({
|
|
149
|
-
success: false,
|
|
150
|
-
error: "Forbidden",
|
|
151
|
-
message: `Requires one of: ${allowedRoles.join(", ")}`
|
|
152
|
-
});
|
|
153
|
-
return;
|
|
154
|
-
}
|
|
155
|
-
};
|
|
156
|
-
};
|
|
157
|
-
const authHelpers = {
|
|
158
|
-
jwt: jwtContext,
|
|
159
|
-
issueTokens,
|
|
160
|
-
verifyRefreshToken
|
|
161
|
-
};
|
|
162
|
-
fastify.decorate("authenticate", authenticate);
|
|
163
|
-
fastify.decorate("authorize", authorize);
|
|
164
|
-
fastify.decorate("auth", authHelpers);
|
|
165
|
-
fastify.log.info(
|
|
166
|
-
`Auth: Plugin registered (jwt=${!!jwtContext}, customAuth=${!!appAuthenticator})`
|
|
167
|
-
);
|
|
168
|
-
};
|
|
169
|
-
var authPlugin_default = fp(authPlugin, {
|
|
170
|
-
name: "arc-auth",
|
|
171
|
-
fastify: "5.x"
|
|
172
|
-
});
|
|
173
|
-
|
|
174
|
-
export { authPlugin_default as authPlugin, authPlugin as authPluginFn };
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Arc CLI - Docs Command
|
|
3
|
-
*
|
|
4
|
-
* Export OpenAPI specification from registered resources
|
|
5
|
-
*/
|
|
6
|
-
declare function exportDocs(args: string[]): Promise<void>;
|
|
7
|
-
declare const _default: {
|
|
8
|
-
exportDocs: typeof exportDocs;
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
export { _default as default, exportDocs };
|