@dirxai/core 0.3.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/chunk-5BEMU43U.js +34 -0
- package/dist/context-C7RRNS5U.d.cts +59 -0
- package/dist/context-C7RRNS5U.d.ts +59 -0
- package/dist/index.cjs +228 -0
- package/dist/index.d.cts +90 -0
- package/dist/index.d.ts +90 -0
- package/dist/index.js +169 -0
- package/dist/testing.cjs +79 -0
- package/dist/testing.d.cts +26 -0
- package/dist/testing.d.ts +26 -0
- package/dist/testing.js +24 -0
- package/package.json +53 -0
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
// src/auth/context.ts
|
|
2
|
+
var AgentContext = class {
|
|
3
|
+
sub;
|
|
4
|
+
svc;
|
|
5
|
+
roles;
|
|
6
|
+
orgId;
|
|
7
|
+
teamId;
|
|
8
|
+
raw;
|
|
9
|
+
constructor(payload) {
|
|
10
|
+
this.sub = payload.sub;
|
|
11
|
+
this.svc = payload.svc ?? "unknown";
|
|
12
|
+
this.roles = Object.freeze(payload.roles ?? []);
|
|
13
|
+
this.orgId = payload.org_id;
|
|
14
|
+
this.teamId = payload.team_id;
|
|
15
|
+
this.raw = payload;
|
|
16
|
+
}
|
|
17
|
+
hasRole(role) {
|
|
18
|
+
return this.roles.includes(role);
|
|
19
|
+
}
|
|
20
|
+
isAgent() {
|
|
21
|
+
return this.hasRole("agent");
|
|
22
|
+
}
|
|
23
|
+
isAdmin() {
|
|
24
|
+
return this.hasRole("admin");
|
|
25
|
+
}
|
|
26
|
+
/** Token expiry as Date, or null if no exp claim. */
|
|
27
|
+
get expiresAt() {
|
|
28
|
+
return this.raw.exp ? new Date(this.raw.exp * 1e3) : null;
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export {
|
|
33
|
+
AgentContext
|
|
34
|
+
};
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { JWTPayload } from 'jose';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* JWKS client — fetches and caches the DirX gateway's public key set.
|
|
5
|
+
*
|
|
6
|
+
* Uses the `jose` library for JWK parsing and JWT verification.
|
|
7
|
+
* Keys are cached in memory with a configurable TTL (default 5 min).
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
interface JwksClientOptions {
|
|
11
|
+
/** JWKS endpoint URL. Default: https://api.dirx.ai/.well-known/jwks.json */
|
|
12
|
+
jwksUrl?: string;
|
|
13
|
+
/** Expected JWT issuer. Default: https://api.dirx.ai */
|
|
14
|
+
issuer?: string;
|
|
15
|
+
/** Expected JWT audience. Default: dirx */
|
|
16
|
+
audience?: string;
|
|
17
|
+
}
|
|
18
|
+
interface DirxTokenPayload extends JWTPayload {
|
|
19
|
+
sub: string;
|
|
20
|
+
svc?: string;
|
|
21
|
+
roles?: string[];
|
|
22
|
+
org_id?: string;
|
|
23
|
+
team_id?: string;
|
|
24
|
+
}
|
|
25
|
+
declare class JwksClient {
|
|
26
|
+
private readonly jwks;
|
|
27
|
+
private readonly issuer;
|
|
28
|
+
private readonly audience;
|
|
29
|
+
constructor(options?: JwksClientOptions);
|
|
30
|
+
/**
|
|
31
|
+
* Verify a JWT token against the JWKS endpoint.
|
|
32
|
+
* Returns the decoded payload on success, throws DirxError on failure.
|
|
33
|
+
*/
|
|
34
|
+
verify(token: string): Promise<DirxTokenPayload>;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* AgentContext — request-scoped context extracted from a verified JWT.
|
|
39
|
+
*
|
|
40
|
+
* Provides typed access to the agent identity, roles, and org/team scope.
|
|
41
|
+
* Created by the Guard middleware and attached to the request.
|
|
42
|
+
*/
|
|
43
|
+
|
|
44
|
+
declare class AgentContext {
|
|
45
|
+
readonly sub: string;
|
|
46
|
+
readonly svc: string;
|
|
47
|
+
readonly roles: readonly string[];
|
|
48
|
+
readonly orgId: string | undefined;
|
|
49
|
+
readonly teamId: string | undefined;
|
|
50
|
+
readonly raw: DirxTokenPayload;
|
|
51
|
+
constructor(payload: DirxTokenPayload);
|
|
52
|
+
hasRole(role: string): boolean;
|
|
53
|
+
isAgent(): boolean;
|
|
54
|
+
isAdmin(): boolean;
|
|
55
|
+
/** Token expiry as Date, or null if no exp claim. */
|
|
56
|
+
get expiresAt(): Date | null;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export { AgentContext as A, type DirxTokenPayload as D, type JwksClientOptions as J, JwksClient as a };
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { JWTPayload } from 'jose';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* JWKS client — fetches and caches the DirX gateway's public key set.
|
|
5
|
+
*
|
|
6
|
+
* Uses the `jose` library for JWK parsing and JWT verification.
|
|
7
|
+
* Keys are cached in memory with a configurable TTL (default 5 min).
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
interface JwksClientOptions {
|
|
11
|
+
/** JWKS endpoint URL. Default: https://api.dirx.ai/.well-known/jwks.json */
|
|
12
|
+
jwksUrl?: string;
|
|
13
|
+
/** Expected JWT issuer. Default: https://api.dirx.ai */
|
|
14
|
+
issuer?: string;
|
|
15
|
+
/** Expected JWT audience. Default: dirx */
|
|
16
|
+
audience?: string;
|
|
17
|
+
}
|
|
18
|
+
interface DirxTokenPayload extends JWTPayload {
|
|
19
|
+
sub: string;
|
|
20
|
+
svc?: string;
|
|
21
|
+
roles?: string[];
|
|
22
|
+
org_id?: string;
|
|
23
|
+
team_id?: string;
|
|
24
|
+
}
|
|
25
|
+
declare class JwksClient {
|
|
26
|
+
private readonly jwks;
|
|
27
|
+
private readonly issuer;
|
|
28
|
+
private readonly audience;
|
|
29
|
+
constructor(options?: JwksClientOptions);
|
|
30
|
+
/**
|
|
31
|
+
* Verify a JWT token against the JWKS endpoint.
|
|
32
|
+
* Returns the decoded payload on success, throws DirxError on failure.
|
|
33
|
+
*/
|
|
34
|
+
verify(token: string): Promise<DirxTokenPayload>;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* AgentContext — request-scoped context extracted from a verified JWT.
|
|
39
|
+
*
|
|
40
|
+
* Provides typed access to the agent identity, roles, and org/team scope.
|
|
41
|
+
* Created by the Guard middleware and attached to the request.
|
|
42
|
+
*/
|
|
43
|
+
|
|
44
|
+
declare class AgentContext {
|
|
45
|
+
readonly sub: string;
|
|
46
|
+
readonly svc: string;
|
|
47
|
+
readonly roles: readonly string[];
|
|
48
|
+
readonly orgId: string | undefined;
|
|
49
|
+
readonly teamId: string | undefined;
|
|
50
|
+
readonly raw: DirxTokenPayload;
|
|
51
|
+
constructor(payload: DirxTokenPayload);
|
|
52
|
+
hasRole(role: string): boolean;
|
|
53
|
+
isAgent(): boolean;
|
|
54
|
+
isAdmin(): boolean;
|
|
55
|
+
/** Token expiry as Date, or null if no exp claim. */
|
|
56
|
+
get expiresAt(): Date | null;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export { AgentContext as A, type DirxTokenPayload as D, type JwksClientOptions as J, JwksClient as a };
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var index_exports = {};
|
|
22
|
+
__export(index_exports, {
|
|
23
|
+
AgentContext: () => AgentContext,
|
|
24
|
+
DirxError: () => DirxError,
|
|
25
|
+
DirxErrorCode: () => DirxErrorCode,
|
|
26
|
+
Guard: () => Guard,
|
|
27
|
+
JwksClient: () => JwksClient,
|
|
28
|
+
createGuard: () => createGuard
|
|
29
|
+
});
|
|
30
|
+
module.exports = __toCommonJS(index_exports);
|
|
31
|
+
|
|
32
|
+
// src/auth/jwks.ts
|
|
33
|
+
var import_jose = require("jose");
|
|
34
|
+
|
|
35
|
+
// src/errors.ts
|
|
36
|
+
var DirxErrorCode = {
|
|
37
|
+
UNAUTHORIZED: "UNAUTHORIZED",
|
|
38
|
+
FORBIDDEN: "FORBIDDEN",
|
|
39
|
+
NOT_FOUND: "NOT_FOUND",
|
|
40
|
+
BAD_REQUEST: "BAD_REQUEST",
|
|
41
|
+
RATE_LIMITED: "RATE_LIMITED",
|
|
42
|
+
UPSTREAM_ERROR: "UPSTREAM_ERROR",
|
|
43
|
+
INTERNAL: "INTERNAL",
|
|
44
|
+
TOKEN_EXPIRED: "TOKEN_EXPIRED",
|
|
45
|
+
TOKEN_INVALID: "TOKEN_INVALID",
|
|
46
|
+
JWKS_FETCH_FAILED: "JWKS_FETCH_FAILED"
|
|
47
|
+
};
|
|
48
|
+
var HTTP_STATUS = {
|
|
49
|
+
UNAUTHORIZED: 401,
|
|
50
|
+
FORBIDDEN: 403,
|
|
51
|
+
NOT_FOUND: 404,
|
|
52
|
+
BAD_REQUEST: 400,
|
|
53
|
+
RATE_LIMITED: 429,
|
|
54
|
+
UPSTREAM_ERROR: 502,
|
|
55
|
+
INTERNAL: 500,
|
|
56
|
+
TOKEN_EXPIRED: 401,
|
|
57
|
+
TOKEN_INVALID: 401,
|
|
58
|
+
JWKS_FETCH_FAILED: 502
|
|
59
|
+
};
|
|
60
|
+
var DirxError = class extends Error {
|
|
61
|
+
code;
|
|
62
|
+
statusCode;
|
|
63
|
+
constructor(code, message) {
|
|
64
|
+
super(message);
|
|
65
|
+
this.name = "DirxError";
|
|
66
|
+
this.code = code;
|
|
67
|
+
this.statusCode = HTTP_STATUS[code];
|
|
68
|
+
}
|
|
69
|
+
toJSON() {
|
|
70
|
+
return {
|
|
71
|
+
code: this.code,
|
|
72
|
+
message: this.message,
|
|
73
|
+
statusCode: this.statusCode
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
// src/auth/jwks.ts
|
|
79
|
+
var JwksClient = class {
|
|
80
|
+
jwks;
|
|
81
|
+
issuer;
|
|
82
|
+
audience;
|
|
83
|
+
constructor(options) {
|
|
84
|
+
const jwksUrl = options?.jwksUrl ?? "https://api.dirx.ai/.well-known/jwks.json";
|
|
85
|
+
this.issuer = options?.issuer ?? "https://api.dirx.ai";
|
|
86
|
+
this.audience = options?.audience ?? "dirx";
|
|
87
|
+
this.jwks = (0, import_jose.createRemoteJWKSet)(new URL(jwksUrl));
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Verify a JWT token against the JWKS endpoint.
|
|
91
|
+
* Returns the decoded payload on success, throws DirxError on failure.
|
|
92
|
+
*/
|
|
93
|
+
async verify(token) {
|
|
94
|
+
try {
|
|
95
|
+
const { payload } = await (0, import_jose.jwtVerify)(token, this.jwks, {
|
|
96
|
+
issuer: this.issuer,
|
|
97
|
+
audience: this.audience
|
|
98
|
+
});
|
|
99
|
+
return payload;
|
|
100
|
+
} catch (err) {
|
|
101
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
102
|
+
if (message.includes("expired")) {
|
|
103
|
+
throw new DirxError(
|
|
104
|
+
DirxErrorCode.TOKEN_EXPIRED,
|
|
105
|
+
"Token has expired"
|
|
106
|
+
);
|
|
107
|
+
}
|
|
108
|
+
throw new DirxError(
|
|
109
|
+
DirxErrorCode.TOKEN_INVALID,
|
|
110
|
+
`Token verification failed: ${message}`
|
|
111
|
+
);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
// src/auth/context.ts
|
|
117
|
+
var AgentContext = class {
|
|
118
|
+
sub;
|
|
119
|
+
svc;
|
|
120
|
+
roles;
|
|
121
|
+
orgId;
|
|
122
|
+
teamId;
|
|
123
|
+
raw;
|
|
124
|
+
constructor(payload) {
|
|
125
|
+
this.sub = payload.sub;
|
|
126
|
+
this.svc = payload.svc ?? "unknown";
|
|
127
|
+
this.roles = Object.freeze(payload.roles ?? []);
|
|
128
|
+
this.orgId = payload.org_id;
|
|
129
|
+
this.teamId = payload.team_id;
|
|
130
|
+
this.raw = payload;
|
|
131
|
+
}
|
|
132
|
+
hasRole(role) {
|
|
133
|
+
return this.roles.includes(role);
|
|
134
|
+
}
|
|
135
|
+
isAgent() {
|
|
136
|
+
return this.hasRole("agent");
|
|
137
|
+
}
|
|
138
|
+
isAdmin() {
|
|
139
|
+
return this.hasRole("admin");
|
|
140
|
+
}
|
|
141
|
+
/** Token expiry as Date, or null if no exp claim. */
|
|
142
|
+
get expiresAt() {
|
|
143
|
+
return this.raw.exp ? new Date(this.raw.exp * 1e3) : null;
|
|
144
|
+
}
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
// src/middleware/guard.ts
|
|
148
|
+
var Guard = class {
|
|
149
|
+
client;
|
|
150
|
+
required;
|
|
151
|
+
constructor(options) {
|
|
152
|
+
this.client = new JwksClient(options);
|
|
153
|
+
this.required = options?.required !== false;
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Authenticate a raw Bearer token string.
|
|
157
|
+
* Returns AgentContext on success.
|
|
158
|
+
*/
|
|
159
|
+
async authenticate(token) {
|
|
160
|
+
const payload = await this.client.verify(token);
|
|
161
|
+
return new AgentContext(payload);
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Extract Bearer token from an Authorization header value.
|
|
165
|
+
* Returns null if not present or malformed.
|
|
166
|
+
*/
|
|
167
|
+
extractToken(authHeader) {
|
|
168
|
+
if (!authHeader) return null;
|
|
169
|
+
const parts = authHeader.split(" ");
|
|
170
|
+
if (parts.length !== 2 || parts[0].toLowerCase() !== "bearer") {
|
|
171
|
+
return null;
|
|
172
|
+
}
|
|
173
|
+
return parts[1];
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Full flow: extract token from header → verify → return AgentContext.
|
|
177
|
+
* Throws DirxError if required and no/invalid token.
|
|
178
|
+
*/
|
|
179
|
+
async fromHeader(authHeader) {
|
|
180
|
+
const token = this.extractToken(authHeader);
|
|
181
|
+
if (!token) {
|
|
182
|
+
if (this.required) {
|
|
183
|
+
throw new DirxError(
|
|
184
|
+
DirxErrorCode.UNAUTHORIZED,
|
|
185
|
+
"Missing or malformed Authorization header"
|
|
186
|
+
);
|
|
187
|
+
}
|
|
188
|
+
return null;
|
|
189
|
+
}
|
|
190
|
+
return this.authenticate(token);
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Express/Connect-style middleware factory.
|
|
194
|
+
* Attaches `req.agent` (AgentContext) on success.
|
|
195
|
+
*/
|
|
196
|
+
express() {
|
|
197
|
+
return async (req, res, next) => {
|
|
198
|
+
try {
|
|
199
|
+
const ctx = await this.fromHeader(req.headers.authorization);
|
|
200
|
+
if (ctx) {
|
|
201
|
+
req.agent = ctx;
|
|
202
|
+
}
|
|
203
|
+
next();
|
|
204
|
+
} catch (err) {
|
|
205
|
+
if (err instanceof DirxError) {
|
|
206
|
+
res.status(err.statusCode).json({
|
|
207
|
+
ok: false,
|
|
208
|
+
error: { code: err.code, message: err.message }
|
|
209
|
+
});
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
next(err);
|
|
213
|
+
}
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
};
|
|
217
|
+
function createGuard(options) {
|
|
218
|
+
return new Guard(options);
|
|
219
|
+
}
|
|
220
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
221
|
+
0 && (module.exports = {
|
|
222
|
+
AgentContext,
|
|
223
|
+
DirxError,
|
|
224
|
+
DirxErrorCode,
|
|
225
|
+
Guard,
|
|
226
|
+
JwksClient,
|
|
227
|
+
createGuard
|
|
228
|
+
});
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { J as JwksClientOptions, A as AgentContext } from './context-C7RRNS5U.cjs';
|
|
2
|
+
export { D as DirxTokenPayload, a as JwksClient } from './context-C7RRNS5U.cjs';
|
|
3
|
+
import 'jose';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Guard middleware — extracts and verifies Bearer tokens from incoming requests.
|
|
7
|
+
*
|
|
8
|
+
* Framework-agnostic: works with any Node.js HTTP framework that provides
|
|
9
|
+
* standard Request/Response objects (Express, Hono, Fastify, etc.).
|
|
10
|
+
*
|
|
11
|
+
* Usage:
|
|
12
|
+
* import { createGuard } from "@dirxai/core";
|
|
13
|
+
* const guard = createGuard({ jwksUrl: "..." });
|
|
14
|
+
*
|
|
15
|
+
* // Express
|
|
16
|
+
* app.use(guard.express());
|
|
17
|
+
*
|
|
18
|
+
* // Generic (any framework)
|
|
19
|
+
* const ctx = await guard.authenticate(bearerToken);
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
interface GuardOptions extends JwksClientOptions {
|
|
23
|
+
/** If true, requests without a token are rejected. Default: true */
|
|
24
|
+
required?: boolean;
|
|
25
|
+
}
|
|
26
|
+
declare class Guard {
|
|
27
|
+
private readonly client;
|
|
28
|
+
private readonly required;
|
|
29
|
+
constructor(options?: GuardOptions);
|
|
30
|
+
/**
|
|
31
|
+
* Authenticate a raw Bearer token string.
|
|
32
|
+
* Returns AgentContext on success.
|
|
33
|
+
*/
|
|
34
|
+
authenticate(token: string): Promise<AgentContext>;
|
|
35
|
+
/**
|
|
36
|
+
* Extract Bearer token from an Authorization header value.
|
|
37
|
+
* Returns null if not present or malformed.
|
|
38
|
+
*/
|
|
39
|
+
extractToken(authHeader: string | null | undefined): string | null;
|
|
40
|
+
/**
|
|
41
|
+
* Full flow: extract token from header → verify → return AgentContext.
|
|
42
|
+
* Throws DirxError if required and no/invalid token.
|
|
43
|
+
*/
|
|
44
|
+
fromHeader(authHeader: string | null | undefined): Promise<AgentContext | null>;
|
|
45
|
+
/**
|
|
46
|
+
* Express/Connect-style middleware factory.
|
|
47
|
+
* Attaches `req.agent` (AgentContext) on success.
|
|
48
|
+
*/
|
|
49
|
+
express(): (req: {
|
|
50
|
+
headers: Record<string, string | undefined>;
|
|
51
|
+
agent?: AgentContext;
|
|
52
|
+
}, res: {
|
|
53
|
+
status: (code: number) => {
|
|
54
|
+
json: (body: unknown) => void;
|
|
55
|
+
};
|
|
56
|
+
}, next: (err?: unknown) => void) => Promise<void>;
|
|
57
|
+
}
|
|
58
|
+
declare function createGuard(options?: GuardOptions): Guard;
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* DirX error codes and typed error class.
|
|
62
|
+
*
|
|
63
|
+
* Mirrors the server-side DirxEnvelope error model so SDK consumers
|
|
64
|
+
* can handle errors uniformly across CLI, SDK, and server.
|
|
65
|
+
*/
|
|
66
|
+
declare const DirxErrorCode: {
|
|
67
|
+
readonly UNAUTHORIZED: "UNAUTHORIZED";
|
|
68
|
+
readonly FORBIDDEN: "FORBIDDEN";
|
|
69
|
+
readonly NOT_FOUND: "NOT_FOUND";
|
|
70
|
+
readonly BAD_REQUEST: "BAD_REQUEST";
|
|
71
|
+
readonly RATE_LIMITED: "RATE_LIMITED";
|
|
72
|
+
readonly UPSTREAM_ERROR: "UPSTREAM_ERROR";
|
|
73
|
+
readonly INTERNAL: "INTERNAL";
|
|
74
|
+
readonly TOKEN_EXPIRED: "TOKEN_EXPIRED";
|
|
75
|
+
readonly TOKEN_INVALID: "TOKEN_INVALID";
|
|
76
|
+
readonly JWKS_FETCH_FAILED: "JWKS_FETCH_FAILED";
|
|
77
|
+
};
|
|
78
|
+
type DirxErrorCode = (typeof DirxErrorCode)[keyof typeof DirxErrorCode];
|
|
79
|
+
declare class DirxError extends Error {
|
|
80
|
+
readonly code: DirxErrorCode;
|
|
81
|
+
readonly statusCode: number;
|
|
82
|
+
constructor(code: DirxErrorCode, message: string);
|
|
83
|
+
toJSON(): {
|
|
84
|
+
code: DirxErrorCode;
|
|
85
|
+
message: string;
|
|
86
|
+
statusCode: number;
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export { AgentContext, DirxError, DirxErrorCode, Guard, type GuardOptions, JwksClientOptions, createGuard };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { J as JwksClientOptions, A as AgentContext } from './context-C7RRNS5U.js';
|
|
2
|
+
export { D as DirxTokenPayload, a as JwksClient } from './context-C7RRNS5U.js';
|
|
3
|
+
import 'jose';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Guard middleware — extracts and verifies Bearer tokens from incoming requests.
|
|
7
|
+
*
|
|
8
|
+
* Framework-agnostic: works with any Node.js HTTP framework that provides
|
|
9
|
+
* standard Request/Response objects (Express, Hono, Fastify, etc.).
|
|
10
|
+
*
|
|
11
|
+
* Usage:
|
|
12
|
+
* import { createGuard } from "@dirxai/core";
|
|
13
|
+
* const guard = createGuard({ jwksUrl: "..." });
|
|
14
|
+
*
|
|
15
|
+
* // Express
|
|
16
|
+
* app.use(guard.express());
|
|
17
|
+
*
|
|
18
|
+
* // Generic (any framework)
|
|
19
|
+
* const ctx = await guard.authenticate(bearerToken);
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
interface GuardOptions extends JwksClientOptions {
|
|
23
|
+
/** If true, requests without a token are rejected. Default: true */
|
|
24
|
+
required?: boolean;
|
|
25
|
+
}
|
|
26
|
+
declare class Guard {
|
|
27
|
+
private readonly client;
|
|
28
|
+
private readonly required;
|
|
29
|
+
constructor(options?: GuardOptions);
|
|
30
|
+
/**
|
|
31
|
+
* Authenticate a raw Bearer token string.
|
|
32
|
+
* Returns AgentContext on success.
|
|
33
|
+
*/
|
|
34
|
+
authenticate(token: string): Promise<AgentContext>;
|
|
35
|
+
/**
|
|
36
|
+
* Extract Bearer token from an Authorization header value.
|
|
37
|
+
* Returns null if not present or malformed.
|
|
38
|
+
*/
|
|
39
|
+
extractToken(authHeader: string | null | undefined): string | null;
|
|
40
|
+
/**
|
|
41
|
+
* Full flow: extract token from header → verify → return AgentContext.
|
|
42
|
+
* Throws DirxError if required and no/invalid token.
|
|
43
|
+
*/
|
|
44
|
+
fromHeader(authHeader: string | null | undefined): Promise<AgentContext | null>;
|
|
45
|
+
/**
|
|
46
|
+
* Express/Connect-style middleware factory.
|
|
47
|
+
* Attaches `req.agent` (AgentContext) on success.
|
|
48
|
+
*/
|
|
49
|
+
express(): (req: {
|
|
50
|
+
headers: Record<string, string | undefined>;
|
|
51
|
+
agent?: AgentContext;
|
|
52
|
+
}, res: {
|
|
53
|
+
status: (code: number) => {
|
|
54
|
+
json: (body: unknown) => void;
|
|
55
|
+
};
|
|
56
|
+
}, next: (err?: unknown) => void) => Promise<void>;
|
|
57
|
+
}
|
|
58
|
+
declare function createGuard(options?: GuardOptions): Guard;
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* DirX error codes and typed error class.
|
|
62
|
+
*
|
|
63
|
+
* Mirrors the server-side DirxEnvelope error model so SDK consumers
|
|
64
|
+
* can handle errors uniformly across CLI, SDK, and server.
|
|
65
|
+
*/
|
|
66
|
+
declare const DirxErrorCode: {
|
|
67
|
+
readonly UNAUTHORIZED: "UNAUTHORIZED";
|
|
68
|
+
readonly FORBIDDEN: "FORBIDDEN";
|
|
69
|
+
readonly NOT_FOUND: "NOT_FOUND";
|
|
70
|
+
readonly BAD_REQUEST: "BAD_REQUEST";
|
|
71
|
+
readonly RATE_LIMITED: "RATE_LIMITED";
|
|
72
|
+
readonly UPSTREAM_ERROR: "UPSTREAM_ERROR";
|
|
73
|
+
readonly INTERNAL: "INTERNAL";
|
|
74
|
+
readonly TOKEN_EXPIRED: "TOKEN_EXPIRED";
|
|
75
|
+
readonly TOKEN_INVALID: "TOKEN_INVALID";
|
|
76
|
+
readonly JWKS_FETCH_FAILED: "JWKS_FETCH_FAILED";
|
|
77
|
+
};
|
|
78
|
+
type DirxErrorCode = (typeof DirxErrorCode)[keyof typeof DirxErrorCode];
|
|
79
|
+
declare class DirxError extends Error {
|
|
80
|
+
readonly code: DirxErrorCode;
|
|
81
|
+
readonly statusCode: number;
|
|
82
|
+
constructor(code: DirxErrorCode, message: string);
|
|
83
|
+
toJSON(): {
|
|
84
|
+
code: DirxErrorCode;
|
|
85
|
+
message: string;
|
|
86
|
+
statusCode: number;
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export { AgentContext, DirxError, DirxErrorCode, Guard, type GuardOptions, JwksClientOptions, createGuard };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AgentContext
|
|
3
|
+
} from "./chunk-5BEMU43U.js";
|
|
4
|
+
|
|
5
|
+
// src/auth/jwks.ts
|
|
6
|
+
import { createRemoteJWKSet, jwtVerify } from "jose";
|
|
7
|
+
|
|
8
|
+
// src/errors.ts
|
|
9
|
+
var DirxErrorCode = {
|
|
10
|
+
UNAUTHORIZED: "UNAUTHORIZED",
|
|
11
|
+
FORBIDDEN: "FORBIDDEN",
|
|
12
|
+
NOT_FOUND: "NOT_FOUND",
|
|
13
|
+
BAD_REQUEST: "BAD_REQUEST",
|
|
14
|
+
RATE_LIMITED: "RATE_LIMITED",
|
|
15
|
+
UPSTREAM_ERROR: "UPSTREAM_ERROR",
|
|
16
|
+
INTERNAL: "INTERNAL",
|
|
17
|
+
TOKEN_EXPIRED: "TOKEN_EXPIRED",
|
|
18
|
+
TOKEN_INVALID: "TOKEN_INVALID",
|
|
19
|
+
JWKS_FETCH_FAILED: "JWKS_FETCH_FAILED"
|
|
20
|
+
};
|
|
21
|
+
var HTTP_STATUS = {
|
|
22
|
+
UNAUTHORIZED: 401,
|
|
23
|
+
FORBIDDEN: 403,
|
|
24
|
+
NOT_FOUND: 404,
|
|
25
|
+
BAD_REQUEST: 400,
|
|
26
|
+
RATE_LIMITED: 429,
|
|
27
|
+
UPSTREAM_ERROR: 502,
|
|
28
|
+
INTERNAL: 500,
|
|
29
|
+
TOKEN_EXPIRED: 401,
|
|
30
|
+
TOKEN_INVALID: 401,
|
|
31
|
+
JWKS_FETCH_FAILED: 502
|
|
32
|
+
};
|
|
33
|
+
var DirxError = class extends Error {
|
|
34
|
+
code;
|
|
35
|
+
statusCode;
|
|
36
|
+
constructor(code, message) {
|
|
37
|
+
super(message);
|
|
38
|
+
this.name = "DirxError";
|
|
39
|
+
this.code = code;
|
|
40
|
+
this.statusCode = HTTP_STATUS[code];
|
|
41
|
+
}
|
|
42
|
+
toJSON() {
|
|
43
|
+
return {
|
|
44
|
+
code: this.code,
|
|
45
|
+
message: this.message,
|
|
46
|
+
statusCode: this.statusCode
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
// src/auth/jwks.ts
|
|
52
|
+
var JwksClient = class {
|
|
53
|
+
jwks;
|
|
54
|
+
issuer;
|
|
55
|
+
audience;
|
|
56
|
+
constructor(options) {
|
|
57
|
+
const jwksUrl = options?.jwksUrl ?? "https://api.dirx.ai/.well-known/jwks.json";
|
|
58
|
+
this.issuer = options?.issuer ?? "https://api.dirx.ai";
|
|
59
|
+
this.audience = options?.audience ?? "dirx";
|
|
60
|
+
this.jwks = createRemoteJWKSet(new URL(jwksUrl));
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Verify a JWT token against the JWKS endpoint.
|
|
64
|
+
* Returns the decoded payload on success, throws DirxError on failure.
|
|
65
|
+
*/
|
|
66
|
+
async verify(token) {
|
|
67
|
+
try {
|
|
68
|
+
const { payload } = await jwtVerify(token, this.jwks, {
|
|
69
|
+
issuer: this.issuer,
|
|
70
|
+
audience: this.audience
|
|
71
|
+
});
|
|
72
|
+
return payload;
|
|
73
|
+
} catch (err) {
|
|
74
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
75
|
+
if (message.includes("expired")) {
|
|
76
|
+
throw new DirxError(
|
|
77
|
+
DirxErrorCode.TOKEN_EXPIRED,
|
|
78
|
+
"Token has expired"
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
throw new DirxError(
|
|
82
|
+
DirxErrorCode.TOKEN_INVALID,
|
|
83
|
+
`Token verification failed: ${message}`
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
// src/middleware/guard.ts
|
|
90
|
+
var Guard = class {
|
|
91
|
+
client;
|
|
92
|
+
required;
|
|
93
|
+
constructor(options) {
|
|
94
|
+
this.client = new JwksClient(options);
|
|
95
|
+
this.required = options?.required !== false;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Authenticate a raw Bearer token string.
|
|
99
|
+
* Returns AgentContext on success.
|
|
100
|
+
*/
|
|
101
|
+
async authenticate(token) {
|
|
102
|
+
const payload = await this.client.verify(token);
|
|
103
|
+
return new AgentContext(payload);
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Extract Bearer token from an Authorization header value.
|
|
107
|
+
* Returns null if not present or malformed.
|
|
108
|
+
*/
|
|
109
|
+
extractToken(authHeader) {
|
|
110
|
+
if (!authHeader) return null;
|
|
111
|
+
const parts = authHeader.split(" ");
|
|
112
|
+
if (parts.length !== 2 || parts[0].toLowerCase() !== "bearer") {
|
|
113
|
+
return null;
|
|
114
|
+
}
|
|
115
|
+
return parts[1];
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Full flow: extract token from header → verify → return AgentContext.
|
|
119
|
+
* Throws DirxError if required and no/invalid token.
|
|
120
|
+
*/
|
|
121
|
+
async fromHeader(authHeader) {
|
|
122
|
+
const token = this.extractToken(authHeader);
|
|
123
|
+
if (!token) {
|
|
124
|
+
if (this.required) {
|
|
125
|
+
throw new DirxError(
|
|
126
|
+
DirxErrorCode.UNAUTHORIZED,
|
|
127
|
+
"Missing or malformed Authorization header"
|
|
128
|
+
);
|
|
129
|
+
}
|
|
130
|
+
return null;
|
|
131
|
+
}
|
|
132
|
+
return this.authenticate(token);
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Express/Connect-style middleware factory.
|
|
136
|
+
* Attaches `req.agent` (AgentContext) on success.
|
|
137
|
+
*/
|
|
138
|
+
express() {
|
|
139
|
+
return async (req, res, next) => {
|
|
140
|
+
try {
|
|
141
|
+
const ctx = await this.fromHeader(req.headers.authorization);
|
|
142
|
+
if (ctx) {
|
|
143
|
+
req.agent = ctx;
|
|
144
|
+
}
|
|
145
|
+
next();
|
|
146
|
+
} catch (err) {
|
|
147
|
+
if (err instanceof DirxError) {
|
|
148
|
+
res.status(err.statusCode).json({
|
|
149
|
+
ok: false,
|
|
150
|
+
error: { code: err.code, message: err.message }
|
|
151
|
+
});
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
next(err);
|
|
155
|
+
}
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
};
|
|
159
|
+
function createGuard(options) {
|
|
160
|
+
return new Guard(options);
|
|
161
|
+
}
|
|
162
|
+
export {
|
|
163
|
+
AgentContext,
|
|
164
|
+
DirxError,
|
|
165
|
+
DirxErrorCode,
|
|
166
|
+
Guard,
|
|
167
|
+
JwksClient,
|
|
168
|
+
createGuard
|
|
169
|
+
};
|
package/dist/testing.cjs
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/testing.ts
|
|
21
|
+
var testing_exports = {};
|
|
22
|
+
__export(testing_exports, {
|
|
23
|
+
AgentContext: () => AgentContext,
|
|
24
|
+
createMockAgent: () => createMockAgent
|
|
25
|
+
});
|
|
26
|
+
module.exports = __toCommonJS(testing_exports);
|
|
27
|
+
|
|
28
|
+
// src/auth/context.ts
|
|
29
|
+
var AgentContext = class {
|
|
30
|
+
sub;
|
|
31
|
+
svc;
|
|
32
|
+
roles;
|
|
33
|
+
orgId;
|
|
34
|
+
teamId;
|
|
35
|
+
raw;
|
|
36
|
+
constructor(payload) {
|
|
37
|
+
this.sub = payload.sub;
|
|
38
|
+
this.svc = payload.svc ?? "unknown";
|
|
39
|
+
this.roles = Object.freeze(payload.roles ?? []);
|
|
40
|
+
this.orgId = payload.org_id;
|
|
41
|
+
this.teamId = payload.team_id;
|
|
42
|
+
this.raw = payload;
|
|
43
|
+
}
|
|
44
|
+
hasRole(role) {
|
|
45
|
+
return this.roles.includes(role);
|
|
46
|
+
}
|
|
47
|
+
isAgent() {
|
|
48
|
+
return this.hasRole("agent");
|
|
49
|
+
}
|
|
50
|
+
isAdmin() {
|
|
51
|
+
return this.hasRole("admin");
|
|
52
|
+
}
|
|
53
|
+
/** Token expiry as Date, or null if no exp claim. */
|
|
54
|
+
get expiresAt() {
|
|
55
|
+
return this.raw.exp ? new Date(this.raw.exp * 1e3) : null;
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
// src/testing.ts
|
|
60
|
+
function createMockAgent(options) {
|
|
61
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
62
|
+
const payload = {
|
|
63
|
+
sub: options?.sub ?? "test-agent",
|
|
64
|
+
svc: options?.svc ?? "test",
|
|
65
|
+
roles: options?.roles ?? ["agent"],
|
|
66
|
+
org_id: options?.orgId,
|
|
67
|
+
team_id: options?.teamId,
|
|
68
|
+
iat: now,
|
|
69
|
+
exp: now + (options?.expiresInSeconds ?? 3600),
|
|
70
|
+
iss: "https://api.dirx.ai",
|
|
71
|
+
aud: "dirx"
|
|
72
|
+
};
|
|
73
|
+
return new AgentContext(payload);
|
|
74
|
+
}
|
|
75
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
76
|
+
0 && (module.exports = {
|
|
77
|
+
AgentContext,
|
|
78
|
+
createMockAgent
|
|
79
|
+
});
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { A as AgentContext } from './context-C7RRNS5U.cjs';
|
|
2
|
+
export { D as DirxTokenPayload } from './context-C7RRNS5U.cjs';
|
|
3
|
+
import 'jose';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @dirxai/core/testing — Test utilities for DirX SDK consumers.
|
|
7
|
+
*
|
|
8
|
+
* Provides helpers to create mock AgentContext and tokens for unit tests
|
|
9
|
+
* without requiring a real JWKS endpoint.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
interface MockAgentOptions {
|
|
13
|
+
sub?: string;
|
|
14
|
+
svc?: string;
|
|
15
|
+
roles?: string[];
|
|
16
|
+
orgId?: string;
|
|
17
|
+
teamId?: string;
|
|
18
|
+
expiresInSeconds?: number;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Create a mock AgentContext for testing.
|
|
22
|
+
* No real JWT or JWKS involved — purely in-memory.
|
|
23
|
+
*/
|
|
24
|
+
declare function createMockAgent(options?: MockAgentOptions): AgentContext;
|
|
25
|
+
|
|
26
|
+
export { AgentContext, type MockAgentOptions, createMockAgent };
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { A as AgentContext } from './context-C7RRNS5U.js';
|
|
2
|
+
export { D as DirxTokenPayload } from './context-C7RRNS5U.js';
|
|
3
|
+
import 'jose';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @dirxai/core/testing — Test utilities for DirX SDK consumers.
|
|
7
|
+
*
|
|
8
|
+
* Provides helpers to create mock AgentContext and tokens for unit tests
|
|
9
|
+
* without requiring a real JWKS endpoint.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
interface MockAgentOptions {
|
|
13
|
+
sub?: string;
|
|
14
|
+
svc?: string;
|
|
15
|
+
roles?: string[];
|
|
16
|
+
orgId?: string;
|
|
17
|
+
teamId?: string;
|
|
18
|
+
expiresInSeconds?: number;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Create a mock AgentContext for testing.
|
|
22
|
+
* No real JWT or JWKS involved — purely in-memory.
|
|
23
|
+
*/
|
|
24
|
+
declare function createMockAgent(options?: MockAgentOptions): AgentContext;
|
|
25
|
+
|
|
26
|
+
export { AgentContext, type MockAgentOptions, createMockAgent };
|
package/dist/testing.js
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AgentContext
|
|
3
|
+
} from "./chunk-5BEMU43U.js";
|
|
4
|
+
|
|
5
|
+
// src/testing.ts
|
|
6
|
+
function createMockAgent(options) {
|
|
7
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
8
|
+
const payload = {
|
|
9
|
+
sub: options?.sub ?? "test-agent",
|
|
10
|
+
svc: options?.svc ?? "test",
|
|
11
|
+
roles: options?.roles ?? ["agent"],
|
|
12
|
+
org_id: options?.orgId,
|
|
13
|
+
team_id: options?.teamId,
|
|
14
|
+
iat: now,
|
|
15
|
+
exp: now + (options?.expiresInSeconds ?? 3600),
|
|
16
|
+
iss: "https://api.dirx.ai",
|
|
17
|
+
aud: "dirx"
|
|
18
|
+
};
|
|
19
|
+
return new AgentContext(payload);
|
|
20
|
+
}
|
|
21
|
+
export {
|
|
22
|
+
AgentContext,
|
|
23
|
+
createMockAgent
|
|
24
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@dirxai/core",
|
|
3
|
+
"version": "0.3.0",
|
|
4
|
+
"description": "DirX server-side SDK — Guard middleware, JWKS auth, AgentContext, error codes",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"main": "./dist/index.cjs",
|
|
8
|
+
"module": "./dist/index.js",
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"types": "./dist/index.d.ts",
|
|
13
|
+
"import": "./dist/index.js",
|
|
14
|
+
"require": "./dist/index.cjs"
|
|
15
|
+
},
|
|
16
|
+
"./testing": {
|
|
17
|
+
"types": "./dist/testing.d.ts",
|
|
18
|
+
"import": "./dist/testing.js",
|
|
19
|
+
"require": "./dist/testing.cjs"
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
"scripts": {
|
|
23
|
+
"build": "tsup",
|
|
24
|
+
"dev": "tsup --watch"
|
|
25
|
+
},
|
|
26
|
+
"dependencies": {
|
|
27
|
+
"jose": "^6.1.3"
|
|
28
|
+
},
|
|
29
|
+
"repository": {
|
|
30
|
+
"type": "git",
|
|
31
|
+
"url": "https://github.com/dirxai/dirx.git",
|
|
32
|
+
"directory": "packages/core"
|
|
33
|
+
},
|
|
34
|
+
"homepage": "https://dirx.ai",
|
|
35
|
+
"keywords": [
|
|
36
|
+
"dirx",
|
|
37
|
+
"agent",
|
|
38
|
+
"sdk",
|
|
39
|
+
"gateway",
|
|
40
|
+
"guard",
|
|
41
|
+
"jwks",
|
|
42
|
+
"jwt"
|
|
43
|
+
],
|
|
44
|
+
"publishConfig": {
|
|
45
|
+
"access": "public"
|
|
46
|
+
},
|
|
47
|
+
"files": [
|
|
48
|
+
"dist"
|
|
49
|
+
],
|
|
50
|
+
"engines": {
|
|
51
|
+
"node": ">=18"
|
|
52
|
+
}
|
|
53
|
+
}
|