@dirxai/core 0.3.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunk-AMKKT77F.js +177 -0
- package/dist/chunk-VTJP4C2Q.js +30 -0
- package/dist/index.cjs +259 -2
- package/dist/index.d.cts +22 -1
- package/dist/index.d.ts +22 -1
- package/dist/index.js +65 -1
- package/dist/scanner/index.cjs +209 -0
- package/dist/scanner/index.d.cts +60 -0
- package/dist/scanner/index.d.ts +60 -0
- package/dist/scanner/index.js +18 -0
- package/dist/types.cjs +54 -0
- package/dist/types.d.cts +56 -0
- package/dist/types.d.ts +56 -0
- package/dist/types.js +6 -0
- package/package.json +13 -2
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
// src/scanner/detect.ts
|
|
2
|
+
import { existsSync, readFileSync } from "fs";
|
|
3
|
+
import { join } from "path";
|
|
4
|
+
var FRAMEWORK_PACKAGES = {
|
|
5
|
+
next: "nextjs",
|
|
6
|
+
hono: "hono",
|
|
7
|
+
fastify: "fastify",
|
|
8
|
+
express: "express",
|
|
9
|
+
"@hono/node-server": "hono",
|
|
10
|
+
koa: "koa"
|
|
11
|
+
};
|
|
12
|
+
function detectFramework(target) {
|
|
13
|
+
if (existsSync(join(target, "Cargo.toml"))) {
|
|
14
|
+
return { lang: "rust", framework: "axum" };
|
|
15
|
+
}
|
|
16
|
+
if (existsSync(join(target, "go.mod"))) {
|
|
17
|
+
return { lang: "go", framework: "net/http" };
|
|
18
|
+
}
|
|
19
|
+
if (existsSync(join(target, "package.json"))) {
|
|
20
|
+
const detected = detectFrameworkFromDeps(target);
|
|
21
|
+
if (detected) return { lang: "node", framework: detected };
|
|
22
|
+
return { lang: "node", framework: "express" };
|
|
23
|
+
}
|
|
24
|
+
if (existsSync(join(target, "requirements.txt")) || existsSync(join(target, "pyproject.toml"))) {
|
|
25
|
+
return { lang: "python", framework: "fastapi" };
|
|
26
|
+
}
|
|
27
|
+
return { lang: "unknown", framework: "generic" };
|
|
28
|
+
}
|
|
29
|
+
function detectFrameworkFromDeps(target) {
|
|
30
|
+
const pkgPath = join(target, "package.json");
|
|
31
|
+
if (!existsSync(pkgPath)) return null;
|
|
32
|
+
try {
|
|
33
|
+
const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
|
|
34
|
+
const deps = {
|
|
35
|
+
...pkg.dependencies,
|
|
36
|
+
...pkg.devDependencies
|
|
37
|
+
};
|
|
38
|
+
for (const [pkg2, fw] of Object.entries(FRAMEWORK_PACKAGES)) {
|
|
39
|
+
if (pkg2 in deps) return fw;
|
|
40
|
+
}
|
|
41
|
+
} catch {
|
|
42
|
+
}
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
function hasDirxSdk(target) {
|
|
46
|
+
const pkgPath = join(target, "package.json");
|
|
47
|
+
if (!existsSync(pkgPath)) return false;
|
|
48
|
+
try {
|
|
49
|
+
const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
|
|
50
|
+
const deps = {
|
|
51
|
+
...pkg.dependencies,
|
|
52
|
+
...pkg.devDependencies
|
|
53
|
+
};
|
|
54
|
+
return "@dirxai/core" in deps;
|
|
55
|
+
} catch {
|
|
56
|
+
return false;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// src/scanner/routes.ts
|
|
61
|
+
import { readFileSync as readFileSync2, readdirSync, statSync } from "fs";
|
|
62
|
+
import { join as join2, relative, extname } from "path";
|
|
63
|
+
var MAX_SCAN_DEPTH = 8;
|
|
64
|
+
var SKIP_DIRS = /* @__PURE__ */ new Set([
|
|
65
|
+
"node_modules",
|
|
66
|
+
".git",
|
|
67
|
+
"target",
|
|
68
|
+
"__pycache__",
|
|
69
|
+
"vendor",
|
|
70
|
+
"dist",
|
|
71
|
+
"build",
|
|
72
|
+
".next"
|
|
73
|
+
]);
|
|
74
|
+
var SCAN_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
75
|
+
".ts",
|
|
76
|
+
".tsx",
|
|
77
|
+
".js",
|
|
78
|
+
".jsx",
|
|
79
|
+
".py",
|
|
80
|
+
".go",
|
|
81
|
+
".rs"
|
|
82
|
+
]);
|
|
83
|
+
function getRoutePatterns(framework) {
|
|
84
|
+
switch (framework) {
|
|
85
|
+
case "express":
|
|
86
|
+
case "hono":
|
|
87
|
+
case "fastify":
|
|
88
|
+
case "koa":
|
|
89
|
+
return [".get(", ".post(", ".put(", ".delete(", ".patch(", "router."];
|
|
90
|
+
case "nextjs":
|
|
91
|
+
return ["export default", "export async function"];
|
|
92
|
+
case "fastapi":
|
|
93
|
+
return ["@app.get", "@app.post", "@app.put", "@app.delete", "@router."];
|
|
94
|
+
case "go":
|
|
95
|
+
case "net/http":
|
|
96
|
+
return ["HandleFunc(", "Get(", "Post(", "Put(", "Delete(", "r.Route("];
|
|
97
|
+
case "axum":
|
|
98
|
+
return [".route(", ".get(", ".post(", ".put(", ".delete("];
|
|
99
|
+
default:
|
|
100
|
+
return [];
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
function extractRoutesRegex(content) {
|
|
104
|
+
const regex = /\.\s*(get|post|put|patch|delete)\s*\(\s*["'`](\/[^"'`]*)["'`]/gi;
|
|
105
|
+
const results = [];
|
|
106
|
+
let match;
|
|
107
|
+
while ((match = regex.exec(content)) !== null) {
|
|
108
|
+
results.push({
|
|
109
|
+
method: match[1].toUpperCase(),
|
|
110
|
+
path: match[2]
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
return results;
|
|
114
|
+
}
|
|
115
|
+
function scanRoutes(root, framework) {
|
|
116
|
+
const patterns = getRoutePatterns(framework);
|
|
117
|
+
if (patterns.length === 0) return [];
|
|
118
|
+
const routes = [];
|
|
119
|
+
walkDir(root, root, patterns, framework, routes, 0);
|
|
120
|
+
return routes;
|
|
121
|
+
}
|
|
122
|
+
function walkDir(root, dir, patterns, framework, routes, depth) {
|
|
123
|
+
if (depth > MAX_SCAN_DEPTH) return;
|
|
124
|
+
let entries;
|
|
125
|
+
try {
|
|
126
|
+
entries = readdirSync(dir);
|
|
127
|
+
} catch {
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
for (const name of entries) {
|
|
131
|
+
if (SKIP_DIRS.has(name)) continue;
|
|
132
|
+
const fullPath = join2(dir, name);
|
|
133
|
+
let stat;
|
|
134
|
+
try {
|
|
135
|
+
stat = statSync(fullPath);
|
|
136
|
+
} catch {
|
|
137
|
+
continue;
|
|
138
|
+
}
|
|
139
|
+
if (stat.isDirectory()) {
|
|
140
|
+
walkDir(root, fullPath, patterns, framework, routes, depth + 1);
|
|
141
|
+
continue;
|
|
142
|
+
}
|
|
143
|
+
if (!stat.isFile()) continue;
|
|
144
|
+
if (!SCAN_EXTENSIONS.has(extname(name))) continue;
|
|
145
|
+
try {
|
|
146
|
+
const content = readFileSync2(fullPath, "utf-8");
|
|
147
|
+
if (patterns.some((p) => content.includes(p))) {
|
|
148
|
+
routes.push({
|
|
149
|
+
file: relative(root, fullPath),
|
|
150
|
+
framework
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
} catch {
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// src/scanner/schema.ts
|
|
159
|
+
function extractPrismaModelNames(content) {
|
|
160
|
+
const models = [];
|
|
161
|
+
const regex = /model\s+(\w+)\s*\{/g;
|
|
162
|
+
let match;
|
|
163
|
+
while ((match = regex.exec(content)) !== null) {
|
|
164
|
+
models.push(match[1]);
|
|
165
|
+
}
|
|
166
|
+
return models;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
export {
|
|
170
|
+
detectFramework,
|
|
171
|
+
detectFrameworkFromDeps,
|
|
172
|
+
hasDirxSdk,
|
|
173
|
+
getRoutePatterns,
|
|
174
|
+
extractRoutesRegex,
|
|
175
|
+
scanRoutes,
|
|
176
|
+
extractPrismaModelNames
|
|
177
|
+
};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
// src/types.ts
|
|
2
|
+
var KNOWN_PROVIDERS = {
|
|
3
|
+
"api.github.com": {
|
|
4
|
+
envVar: "GITHUB_TOKEN",
|
|
5
|
+
guideUrl: "https://github.com/settings/tokens"
|
|
6
|
+
},
|
|
7
|
+
"api.openai.com": {
|
|
8
|
+
envVar: "OPENAI_API_KEY",
|
|
9
|
+
guideUrl: "https://platform.openai.com/api-keys"
|
|
10
|
+
},
|
|
11
|
+
"api.anthropic.com": {
|
|
12
|
+
envVar: "ANTHROPIC_API_KEY",
|
|
13
|
+
guideUrl: "https://console.anthropic.com/settings/keys"
|
|
14
|
+
},
|
|
15
|
+
"generativelanguage.googleapis.com": {
|
|
16
|
+
envVar: "GOOGLE_API_KEY",
|
|
17
|
+
guideUrl: "https://aistudio.google.com/apikey"
|
|
18
|
+
},
|
|
19
|
+
"api.stripe.com": {
|
|
20
|
+
envVar: "STRIPE_SECRET_KEY",
|
|
21
|
+
guideUrl: "https://dashboard.stripe.com/apikeys"
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
function getAuthHint(domain) {
|
|
25
|
+
return KNOWN_PROVIDERS[domain] ?? null;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export {
|
|
29
|
+
getAuthHint
|
|
30
|
+
};
|
package/dist/index.cjs
CHANGED
|
@@ -25,10 +25,215 @@ __export(index_exports, {
|
|
|
25
25
|
DirxErrorCode: () => DirxErrorCode,
|
|
26
26
|
Guard: () => Guard,
|
|
27
27
|
JwksClient: () => JwksClient,
|
|
28
|
-
createGuard: () => createGuard
|
|
28
|
+
createGuard: () => createGuard,
|
|
29
|
+
detectFramework: () => detectFramework,
|
|
30
|
+
detectFrameworkFromDeps: () => detectFrameworkFromDeps,
|
|
31
|
+
extractPrismaModelNames: () => extractPrismaModelNames,
|
|
32
|
+
extractRoutesRegex: () => extractRoutesRegex,
|
|
33
|
+
generateDirJson: () => generateDirJson,
|
|
34
|
+
generateDirMd: () => generateDirMd,
|
|
35
|
+
getAuthHint: () => getAuthHint,
|
|
36
|
+
getRoutePatterns: () => getRoutePatterns,
|
|
37
|
+
hasDirxSdk: () => hasDirxSdk,
|
|
38
|
+
scanRoutes: () => scanRoutes
|
|
29
39
|
});
|
|
30
40
|
module.exports = __toCommonJS(index_exports);
|
|
31
41
|
|
|
42
|
+
// src/scanner/detect.ts
|
|
43
|
+
var import_node_fs = require("fs");
|
|
44
|
+
var import_node_path = require("path");
|
|
45
|
+
var FRAMEWORK_PACKAGES = {
|
|
46
|
+
next: "nextjs",
|
|
47
|
+
hono: "hono",
|
|
48
|
+
fastify: "fastify",
|
|
49
|
+
express: "express",
|
|
50
|
+
"@hono/node-server": "hono",
|
|
51
|
+
koa: "koa"
|
|
52
|
+
};
|
|
53
|
+
function detectFramework(target) {
|
|
54
|
+
if ((0, import_node_fs.existsSync)((0, import_node_path.join)(target, "Cargo.toml"))) {
|
|
55
|
+
return { lang: "rust", framework: "axum" };
|
|
56
|
+
}
|
|
57
|
+
if ((0, import_node_fs.existsSync)((0, import_node_path.join)(target, "go.mod"))) {
|
|
58
|
+
return { lang: "go", framework: "net/http" };
|
|
59
|
+
}
|
|
60
|
+
if ((0, import_node_fs.existsSync)((0, import_node_path.join)(target, "package.json"))) {
|
|
61
|
+
const detected = detectFrameworkFromDeps(target);
|
|
62
|
+
if (detected) return { lang: "node", framework: detected };
|
|
63
|
+
return { lang: "node", framework: "express" };
|
|
64
|
+
}
|
|
65
|
+
if ((0, import_node_fs.existsSync)((0, import_node_path.join)(target, "requirements.txt")) || (0, import_node_fs.existsSync)((0, import_node_path.join)(target, "pyproject.toml"))) {
|
|
66
|
+
return { lang: "python", framework: "fastapi" };
|
|
67
|
+
}
|
|
68
|
+
return { lang: "unknown", framework: "generic" };
|
|
69
|
+
}
|
|
70
|
+
function detectFrameworkFromDeps(target) {
|
|
71
|
+
const pkgPath = (0, import_node_path.join)(target, "package.json");
|
|
72
|
+
if (!(0, import_node_fs.existsSync)(pkgPath)) return null;
|
|
73
|
+
try {
|
|
74
|
+
const pkg = JSON.parse((0, import_node_fs.readFileSync)(pkgPath, "utf-8"));
|
|
75
|
+
const deps = {
|
|
76
|
+
...pkg.dependencies,
|
|
77
|
+
...pkg.devDependencies
|
|
78
|
+
};
|
|
79
|
+
for (const [pkg2, fw] of Object.entries(FRAMEWORK_PACKAGES)) {
|
|
80
|
+
if (pkg2 in deps) return fw;
|
|
81
|
+
}
|
|
82
|
+
} catch {
|
|
83
|
+
}
|
|
84
|
+
return null;
|
|
85
|
+
}
|
|
86
|
+
function hasDirxSdk(target) {
|
|
87
|
+
const pkgPath = (0, import_node_path.join)(target, "package.json");
|
|
88
|
+
if (!(0, import_node_fs.existsSync)(pkgPath)) return false;
|
|
89
|
+
try {
|
|
90
|
+
const pkg = JSON.parse((0, import_node_fs.readFileSync)(pkgPath, "utf-8"));
|
|
91
|
+
const deps = {
|
|
92
|
+
...pkg.dependencies,
|
|
93
|
+
...pkg.devDependencies
|
|
94
|
+
};
|
|
95
|
+
return "@dirxai/core" in deps;
|
|
96
|
+
} catch {
|
|
97
|
+
return false;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// src/scanner/routes.ts
|
|
102
|
+
var import_node_fs2 = require("fs");
|
|
103
|
+
var import_node_path2 = require("path");
|
|
104
|
+
var MAX_SCAN_DEPTH = 8;
|
|
105
|
+
var SKIP_DIRS = /* @__PURE__ */ new Set([
|
|
106
|
+
"node_modules",
|
|
107
|
+
".git",
|
|
108
|
+
"target",
|
|
109
|
+
"__pycache__",
|
|
110
|
+
"vendor",
|
|
111
|
+
"dist",
|
|
112
|
+
"build",
|
|
113
|
+
".next"
|
|
114
|
+
]);
|
|
115
|
+
var SCAN_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
116
|
+
".ts",
|
|
117
|
+
".tsx",
|
|
118
|
+
".js",
|
|
119
|
+
".jsx",
|
|
120
|
+
".py",
|
|
121
|
+
".go",
|
|
122
|
+
".rs"
|
|
123
|
+
]);
|
|
124
|
+
function getRoutePatterns(framework) {
|
|
125
|
+
switch (framework) {
|
|
126
|
+
case "express":
|
|
127
|
+
case "hono":
|
|
128
|
+
case "fastify":
|
|
129
|
+
case "koa":
|
|
130
|
+
return [".get(", ".post(", ".put(", ".delete(", ".patch(", "router."];
|
|
131
|
+
case "nextjs":
|
|
132
|
+
return ["export default", "export async function"];
|
|
133
|
+
case "fastapi":
|
|
134
|
+
return ["@app.get", "@app.post", "@app.put", "@app.delete", "@router."];
|
|
135
|
+
case "go":
|
|
136
|
+
case "net/http":
|
|
137
|
+
return ["HandleFunc(", "Get(", "Post(", "Put(", "Delete(", "r.Route("];
|
|
138
|
+
case "axum":
|
|
139
|
+
return [".route(", ".get(", ".post(", ".put(", ".delete("];
|
|
140
|
+
default:
|
|
141
|
+
return [];
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
function extractRoutesRegex(content) {
|
|
145
|
+
const regex = /\.\s*(get|post|put|patch|delete)\s*\(\s*["'`](\/[^"'`]*)["'`]/gi;
|
|
146
|
+
const results = [];
|
|
147
|
+
let match;
|
|
148
|
+
while ((match = regex.exec(content)) !== null) {
|
|
149
|
+
results.push({
|
|
150
|
+
method: match[1].toUpperCase(),
|
|
151
|
+
path: match[2]
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
return results;
|
|
155
|
+
}
|
|
156
|
+
function scanRoutes(root, framework) {
|
|
157
|
+
const patterns = getRoutePatterns(framework);
|
|
158
|
+
if (patterns.length === 0) return [];
|
|
159
|
+
const routes = [];
|
|
160
|
+
walkDir(root, root, patterns, framework, routes, 0);
|
|
161
|
+
return routes;
|
|
162
|
+
}
|
|
163
|
+
function walkDir(root, dir, patterns, framework, routes, depth) {
|
|
164
|
+
if (depth > MAX_SCAN_DEPTH) return;
|
|
165
|
+
let entries;
|
|
166
|
+
try {
|
|
167
|
+
entries = (0, import_node_fs2.readdirSync)(dir);
|
|
168
|
+
} catch {
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
for (const name of entries) {
|
|
172
|
+
if (SKIP_DIRS.has(name)) continue;
|
|
173
|
+
const fullPath = (0, import_node_path2.join)(dir, name);
|
|
174
|
+
let stat;
|
|
175
|
+
try {
|
|
176
|
+
stat = (0, import_node_fs2.statSync)(fullPath);
|
|
177
|
+
} catch {
|
|
178
|
+
continue;
|
|
179
|
+
}
|
|
180
|
+
if (stat.isDirectory()) {
|
|
181
|
+
walkDir(root, fullPath, patterns, framework, routes, depth + 1);
|
|
182
|
+
continue;
|
|
183
|
+
}
|
|
184
|
+
if (!stat.isFile()) continue;
|
|
185
|
+
if (!SCAN_EXTENSIONS.has((0, import_node_path2.extname)(name))) continue;
|
|
186
|
+
try {
|
|
187
|
+
const content = (0, import_node_fs2.readFileSync)(fullPath, "utf-8");
|
|
188
|
+
if (patterns.some((p) => content.includes(p))) {
|
|
189
|
+
routes.push({
|
|
190
|
+
file: (0, import_node_path2.relative)(root, fullPath),
|
|
191
|
+
framework
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
} catch {
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
// src/scanner/schema.ts
|
|
200
|
+
function extractPrismaModelNames(content) {
|
|
201
|
+
const models = [];
|
|
202
|
+
const regex = /model\s+(\w+)\s*\{/g;
|
|
203
|
+
let match;
|
|
204
|
+
while ((match = regex.exec(content)) !== null) {
|
|
205
|
+
models.push(match[1]);
|
|
206
|
+
}
|
|
207
|
+
return models;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// src/types.ts
|
|
211
|
+
var KNOWN_PROVIDERS = {
|
|
212
|
+
"api.github.com": {
|
|
213
|
+
envVar: "GITHUB_TOKEN",
|
|
214
|
+
guideUrl: "https://github.com/settings/tokens"
|
|
215
|
+
},
|
|
216
|
+
"api.openai.com": {
|
|
217
|
+
envVar: "OPENAI_API_KEY",
|
|
218
|
+
guideUrl: "https://platform.openai.com/api-keys"
|
|
219
|
+
},
|
|
220
|
+
"api.anthropic.com": {
|
|
221
|
+
envVar: "ANTHROPIC_API_KEY",
|
|
222
|
+
guideUrl: "https://console.anthropic.com/settings/keys"
|
|
223
|
+
},
|
|
224
|
+
"generativelanguage.googleapis.com": {
|
|
225
|
+
envVar: "GOOGLE_API_KEY",
|
|
226
|
+
guideUrl: "https://aistudio.google.com/apikey"
|
|
227
|
+
},
|
|
228
|
+
"api.stripe.com": {
|
|
229
|
+
envVar: "STRIPE_SECRET_KEY",
|
|
230
|
+
guideUrl: "https://dashboard.stripe.com/apikeys"
|
|
231
|
+
}
|
|
232
|
+
};
|
|
233
|
+
function getAuthHint(domain) {
|
|
234
|
+
return KNOWN_PROVIDERS[domain] ?? null;
|
|
235
|
+
}
|
|
236
|
+
|
|
32
237
|
// src/auth/jwks.ts
|
|
33
238
|
var import_jose = require("jose");
|
|
34
239
|
|
|
@@ -217,6 +422,48 @@ var Guard = class {
|
|
|
217
422
|
function createGuard(options) {
|
|
218
423
|
return new Guard(options);
|
|
219
424
|
}
|
|
425
|
+
|
|
426
|
+
// src/generator.ts
|
|
427
|
+
function generateDirMd(service, options) {
|
|
428
|
+
const sections = [];
|
|
429
|
+
sections.push(`# ${service.title}`);
|
|
430
|
+
if (service.description) {
|
|
431
|
+
sections.push(service.description);
|
|
432
|
+
}
|
|
433
|
+
if (service.base_url) {
|
|
434
|
+
sections.push(`## Base URL
|
|
435
|
+
|
|
436
|
+
\`${service.base_url}\``);
|
|
437
|
+
}
|
|
438
|
+
if (service.actions.length > 0) {
|
|
439
|
+
sections.push(
|
|
440
|
+
`## Actions
|
|
441
|
+
|
|
442
|
+
${service.actions.map((a) => `- \`${a}\``).join("\n")}`
|
|
443
|
+
);
|
|
444
|
+
}
|
|
445
|
+
if (service.endpoints.length > 0) {
|
|
446
|
+
const lines = ["## Endpoints", ""];
|
|
447
|
+
lines.push("| Method | Path | Description |");
|
|
448
|
+
lines.push("|--------|------|-------------|");
|
|
449
|
+
for (const ep of service.endpoints) {
|
|
450
|
+
const desc = ep.description ?? "";
|
|
451
|
+
lines.push(`| ${ep.method} | \`${ep.path}\` | ${desc} |`);
|
|
452
|
+
}
|
|
453
|
+
sections.push(lines.join("\n"));
|
|
454
|
+
}
|
|
455
|
+
if (options?.includeTimestamp) {
|
|
456
|
+
sections.push(
|
|
457
|
+
`---
|
|
458
|
+
|
|
459
|
+
*Generated at ${(/* @__PURE__ */ new Date()).toISOString()}*`
|
|
460
|
+
);
|
|
461
|
+
}
|
|
462
|
+
return sections.join("\n\n") + "\n";
|
|
463
|
+
}
|
|
464
|
+
function generateDirJson(service) {
|
|
465
|
+
return JSON.stringify(service, null, 2);
|
|
466
|
+
}
|
|
220
467
|
// Annotate the CommonJS export names for ESM import in node:
|
|
221
468
|
0 && (module.exports = {
|
|
222
469
|
AgentContext,
|
|
@@ -224,5 +471,15 @@ function createGuard(options) {
|
|
|
224
471
|
DirxErrorCode,
|
|
225
472
|
Guard,
|
|
226
473
|
JwksClient,
|
|
227
|
-
createGuard
|
|
474
|
+
createGuard,
|
|
475
|
+
detectFramework,
|
|
476
|
+
detectFrameworkFromDeps,
|
|
477
|
+
extractPrismaModelNames,
|
|
478
|
+
extractRoutesRegex,
|
|
479
|
+
generateDirJson,
|
|
480
|
+
generateDirMd,
|
|
481
|
+
getAuthHint,
|
|
482
|
+
getRoutePatterns,
|
|
483
|
+
hasDirxSdk,
|
|
484
|
+
scanRoutes
|
|
228
485
|
});
|
package/dist/index.d.cts
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
export { DetectedStack, RouteHint, detectFramework, detectFrameworkFromDeps, extractPrismaModelNames, extractRoutesRegex, getRoutePatterns, hasDirxSdk, scanRoutes } from './scanner/index.cjs';
|
|
2
|
+
import { DirxService } from './types.cjs';
|
|
3
|
+
export { ByokAuth, DirxEndpoint, DirxEnvelope, EndpointMatch, ProviderHint, SearchResult, getAuthHint } from './types.cjs';
|
|
1
4
|
import { J as JwksClientOptions, A as AgentContext } from './context-C7RRNS5U.cjs';
|
|
2
5
|
export { D as DirxTokenPayload, a as JwksClient } from './context-C7RRNS5U.cjs';
|
|
3
6
|
import 'jose';
|
|
@@ -57,6 +60,24 @@ declare class Guard {
|
|
|
57
60
|
}
|
|
58
61
|
declare function createGuard(options?: GuardOptions): Guard;
|
|
59
62
|
|
|
63
|
+
/**
|
|
64
|
+
* DIR.md generator — produces a DirX service description from structured input.
|
|
65
|
+
*
|
|
66
|
+
* Third-party projects can use this to programmatically generate DIR.md files.
|
|
67
|
+
*/
|
|
68
|
+
|
|
69
|
+
interface GenerateOptions {
|
|
70
|
+
includeTimestamp?: boolean;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Generate a DIR.md markdown string from a DirxService definition.
|
|
74
|
+
*/
|
|
75
|
+
declare function generateDirMd(service: DirxService, options?: GenerateOptions): string;
|
|
76
|
+
/**
|
|
77
|
+
* Generate a dir.json object from a DirxService definition.
|
|
78
|
+
*/
|
|
79
|
+
declare function generateDirJson(service: DirxService): string;
|
|
80
|
+
|
|
60
81
|
/**
|
|
61
82
|
* DirX error codes and typed error class.
|
|
62
83
|
*
|
|
@@ -87,4 +108,4 @@ declare class DirxError extends Error {
|
|
|
87
108
|
};
|
|
88
109
|
}
|
|
89
110
|
|
|
90
|
-
export { AgentContext, DirxError, DirxErrorCode, Guard, type GuardOptions, JwksClientOptions, createGuard };
|
|
111
|
+
export { AgentContext, DirxError, DirxErrorCode, DirxService, type GenerateOptions, Guard, type GuardOptions, JwksClientOptions, createGuard, generateDirJson, generateDirMd };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
export { DetectedStack, RouteHint, detectFramework, detectFrameworkFromDeps, extractPrismaModelNames, extractRoutesRegex, getRoutePatterns, hasDirxSdk, scanRoutes } from './scanner/index.js';
|
|
2
|
+
import { DirxService } from './types.js';
|
|
3
|
+
export { ByokAuth, DirxEndpoint, DirxEnvelope, EndpointMatch, ProviderHint, SearchResult, getAuthHint } from './types.js';
|
|
1
4
|
import { J as JwksClientOptions, A as AgentContext } from './context-C7RRNS5U.js';
|
|
2
5
|
export { D as DirxTokenPayload, a as JwksClient } from './context-C7RRNS5U.js';
|
|
3
6
|
import 'jose';
|
|
@@ -57,6 +60,24 @@ declare class Guard {
|
|
|
57
60
|
}
|
|
58
61
|
declare function createGuard(options?: GuardOptions): Guard;
|
|
59
62
|
|
|
63
|
+
/**
|
|
64
|
+
* DIR.md generator — produces a DirX service description from structured input.
|
|
65
|
+
*
|
|
66
|
+
* Third-party projects can use this to programmatically generate DIR.md files.
|
|
67
|
+
*/
|
|
68
|
+
|
|
69
|
+
interface GenerateOptions {
|
|
70
|
+
includeTimestamp?: boolean;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Generate a DIR.md markdown string from a DirxService definition.
|
|
74
|
+
*/
|
|
75
|
+
declare function generateDirMd(service: DirxService, options?: GenerateOptions): string;
|
|
76
|
+
/**
|
|
77
|
+
* Generate a dir.json object from a DirxService definition.
|
|
78
|
+
*/
|
|
79
|
+
declare function generateDirJson(service: DirxService): string;
|
|
80
|
+
|
|
60
81
|
/**
|
|
61
82
|
* DirX error codes and typed error class.
|
|
62
83
|
*
|
|
@@ -87,4 +108,4 @@ declare class DirxError extends Error {
|
|
|
87
108
|
};
|
|
88
109
|
}
|
|
89
110
|
|
|
90
|
-
export { AgentContext, DirxError, DirxErrorCode, Guard, type GuardOptions, JwksClientOptions, createGuard };
|
|
111
|
+
export { AgentContext, DirxError, DirxErrorCode, DirxService, type GenerateOptions, Guard, type GuardOptions, JwksClientOptions, createGuard, generateDirJson, generateDirMd };
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,18 @@
|
|
|
1
1
|
import {
|
|
2
2
|
AgentContext
|
|
3
3
|
} from "./chunk-5BEMU43U.js";
|
|
4
|
+
import {
|
|
5
|
+
getAuthHint
|
|
6
|
+
} from "./chunk-VTJP4C2Q.js";
|
|
7
|
+
import {
|
|
8
|
+
detectFramework,
|
|
9
|
+
detectFrameworkFromDeps,
|
|
10
|
+
extractPrismaModelNames,
|
|
11
|
+
extractRoutesRegex,
|
|
12
|
+
getRoutePatterns,
|
|
13
|
+
hasDirxSdk,
|
|
14
|
+
scanRoutes
|
|
15
|
+
} from "./chunk-AMKKT77F.js";
|
|
4
16
|
|
|
5
17
|
// src/auth/jwks.ts
|
|
6
18
|
import { createRemoteJWKSet, jwtVerify } from "jose";
|
|
@@ -159,11 +171,63 @@ var Guard = class {
|
|
|
159
171
|
function createGuard(options) {
|
|
160
172
|
return new Guard(options);
|
|
161
173
|
}
|
|
174
|
+
|
|
175
|
+
// src/generator.ts
|
|
176
|
+
function generateDirMd(service, options) {
|
|
177
|
+
const sections = [];
|
|
178
|
+
sections.push(`# ${service.title}`);
|
|
179
|
+
if (service.description) {
|
|
180
|
+
sections.push(service.description);
|
|
181
|
+
}
|
|
182
|
+
if (service.base_url) {
|
|
183
|
+
sections.push(`## Base URL
|
|
184
|
+
|
|
185
|
+
\`${service.base_url}\``);
|
|
186
|
+
}
|
|
187
|
+
if (service.actions.length > 0) {
|
|
188
|
+
sections.push(
|
|
189
|
+
`## Actions
|
|
190
|
+
|
|
191
|
+
${service.actions.map((a) => `- \`${a}\``).join("\n")}`
|
|
192
|
+
);
|
|
193
|
+
}
|
|
194
|
+
if (service.endpoints.length > 0) {
|
|
195
|
+
const lines = ["## Endpoints", ""];
|
|
196
|
+
lines.push("| Method | Path | Description |");
|
|
197
|
+
lines.push("|--------|------|-------------|");
|
|
198
|
+
for (const ep of service.endpoints) {
|
|
199
|
+
const desc = ep.description ?? "";
|
|
200
|
+
lines.push(`| ${ep.method} | \`${ep.path}\` | ${desc} |`);
|
|
201
|
+
}
|
|
202
|
+
sections.push(lines.join("\n"));
|
|
203
|
+
}
|
|
204
|
+
if (options?.includeTimestamp) {
|
|
205
|
+
sections.push(
|
|
206
|
+
`---
|
|
207
|
+
|
|
208
|
+
*Generated at ${(/* @__PURE__ */ new Date()).toISOString()}*`
|
|
209
|
+
);
|
|
210
|
+
}
|
|
211
|
+
return sections.join("\n\n") + "\n";
|
|
212
|
+
}
|
|
213
|
+
function generateDirJson(service) {
|
|
214
|
+
return JSON.stringify(service, null, 2);
|
|
215
|
+
}
|
|
162
216
|
export {
|
|
163
217
|
AgentContext,
|
|
164
218
|
DirxError,
|
|
165
219
|
DirxErrorCode,
|
|
166
220
|
Guard,
|
|
167
221
|
JwksClient,
|
|
168
|
-
createGuard
|
|
222
|
+
createGuard,
|
|
223
|
+
detectFramework,
|
|
224
|
+
detectFrameworkFromDeps,
|
|
225
|
+
extractPrismaModelNames,
|
|
226
|
+
extractRoutesRegex,
|
|
227
|
+
generateDirJson,
|
|
228
|
+
generateDirMd,
|
|
229
|
+
getAuthHint,
|
|
230
|
+
getRoutePatterns,
|
|
231
|
+
hasDirxSdk,
|
|
232
|
+
scanRoutes
|
|
169
233
|
};
|
|
@@ -0,0 +1,209 @@
|
|
|
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/scanner/index.ts
|
|
21
|
+
var scanner_exports = {};
|
|
22
|
+
__export(scanner_exports, {
|
|
23
|
+
detectFramework: () => detectFramework,
|
|
24
|
+
detectFrameworkFromDeps: () => detectFrameworkFromDeps,
|
|
25
|
+
extractPrismaModelNames: () => extractPrismaModelNames,
|
|
26
|
+
extractRoutesRegex: () => extractRoutesRegex,
|
|
27
|
+
getRoutePatterns: () => getRoutePatterns,
|
|
28
|
+
hasDirxSdk: () => hasDirxSdk,
|
|
29
|
+
scanRoutes: () => scanRoutes
|
|
30
|
+
});
|
|
31
|
+
module.exports = __toCommonJS(scanner_exports);
|
|
32
|
+
|
|
33
|
+
// src/scanner/detect.ts
|
|
34
|
+
var import_node_fs = require("fs");
|
|
35
|
+
var import_node_path = require("path");
|
|
36
|
+
var FRAMEWORK_PACKAGES = {
|
|
37
|
+
next: "nextjs",
|
|
38
|
+
hono: "hono",
|
|
39
|
+
fastify: "fastify",
|
|
40
|
+
express: "express",
|
|
41
|
+
"@hono/node-server": "hono",
|
|
42
|
+
koa: "koa"
|
|
43
|
+
};
|
|
44
|
+
function detectFramework(target) {
|
|
45
|
+
if ((0, import_node_fs.existsSync)((0, import_node_path.join)(target, "Cargo.toml"))) {
|
|
46
|
+
return { lang: "rust", framework: "axum" };
|
|
47
|
+
}
|
|
48
|
+
if ((0, import_node_fs.existsSync)((0, import_node_path.join)(target, "go.mod"))) {
|
|
49
|
+
return { lang: "go", framework: "net/http" };
|
|
50
|
+
}
|
|
51
|
+
if ((0, import_node_fs.existsSync)((0, import_node_path.join)(target, "package.json"))) {
|
|
52
|
+
const detected = detectFrameworkFromDeps(target);
|
|
53
|
+
if (detected) return { lang: "node", framework: detected };
|
|
54
|
+
return { lang: "node", framework: "express" };
|
|
55
|
+
}
|
|
56
|
+
if ((0, import_node_fs.existsSync)((0, import_node_path.join)(target, "requirements.txt")) || (0, import_node_fs.existsSync)((0, import_node_path.join)(target, "pyproject.toml"))) {
|
|
57
|
+
return { lang: "python", framework: "fastapi" };
|
|
58
|
+
}
|
|
59
|
+
return { lang: "unknown", framework: "generic" };
|
|
60
|
+
}
|
|
61
|
+
function detectFrameworkFromDeps(target) {
|
|
62
|
+
const pkgPath = (0, import_node_path.join)(target, "package.json");
|
|
63
|
+
if (!(0, import_node_fs.existsSync)(pkgPath)) return null;
|
|
64
|
+
try {
|
|
65
|
+
const pkg = JSON.parse((0, import_node_fs.readFileSync)(pkgPath, "utf-8"));
|
|
66
|
+
const deps = {
|
|
67
|
+
...pkg.dependencies,
|
|
68
|
+
...pkg.devDependencies
|
|
69
|
+
};
|
|
70
|
+
for (const [pkg2, fw] of Object.entries(FRAMEWORK_PACKAGES)) {
|
|
71
|
+
if (pkg2 in deps) return fw;
|
|
72
|
+
}
|
|
73
|
+
} catch {
|
|
74
|
+
}
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
function hasDirxSdk(target) {
|
|
78
|
+
const pkgPath = (0, import_node_path.join)(target, "package.json");
|
|
79
|
+
if (!(0, import_node_fs.existsSync)(pkgPath)) return false;
|
|
80
|
+
try {
|
|
81
|
+
const pkg = JSON.parse((0, import_node_fs.readFileSync)(pkgPath, "utf-8"));
|
|
82
|
+
const deps = {
|
|
83
|
+
...pkg.dependencies,
|
|
84
|
+
...pkg.devDependencies
|
|
85
|
+
};
|
|
86
|
+
return "@dirxai/core" in deps;
|
|
87
|
+
} catch {
|
|
88
|
+
return false;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// src/scanner/routes.ts
|
|
93
|
+
var import_node_fs2 = require("fs");
|
|
94
|
+
var import_node_path2 = require("path");
|
|
95
|
+
var MAX_SCAN_DEPTH = 8;
|
|
96
|
+
var SKIP_DIRS = /* @__PURE__ */ new Set([
|
|
97
|
+
"node_modules",
|
|
98
|
+
".git",
|
|
99
|
+
"target",
|
|
100
|
+
"__pycache__",
|
|
101
|
+
"vendor",
|
|
102
|
+
"dist",
|
|
103
|
+
"build",
|
|
104
|
+
".next"
|
|
105
|
+
]);
|
|
106
|
+
var SCAN_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
107
|
+
".ts",
|
|
108
|
+
".tsx",
|
|
109
|
+
".js",
|
|
110
|
+
".jsx",
|
|
111
|
+
".py",
|
|
112
|
+
".go",
|
|
113
|
+
".rs"
|
|
114
|
+
]);
|
|
115
|
+
function getRoutePatterns(framework) {
|
|
116
|
+
switch (framework) {
|
|
117
|
+
case "express":
|
|
118
|
+
case "hono":
|
|
119
|
+
case "fastify":
|
|
120
|
+
case "koa":
|
|
121
|
+
return [".get(", ".post(", ".put(", ".delete(", ".patch(", "router."];
|
|
122
|
+
case "nextjs":
|
|
123
|
+
return ["export default", "export async function"];
|
|
124
|
+
case "fastapi":
|
|
125
|
+
return ["@app.get", "@app.post", "@app.put", "@app.delete", "@router."];
|
|
126
|
+
case "go":
|
|
127
|
+
case "net/http":
|
|
128
|
+
return ["HandleFunc(", "Get(", "Post(", "Put(", "Delete(", "r.Route("];
|
|
129
|
+
case "axum":
|
|
130
|
+
return [".route(", ".get(", ".post(", ".put(", ".delete("];
|
|
131
|
+
default:
|
|
132
|
+
return [];
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
function extractRoutesRegex(content) {
|
|
136
|
+
const regex = /\.\s*(get|post|put|patch|delete)\s*\(\s*["'`](\/[^"'`]*)["'`]/gi;
|
|
137
|
+
const results = [];
|
|
138
|
+
let match;
|
|
139
|
+
while ((match = regex.exec(content)) !== null) {
|
|
140
|
+
results.push({
|
|
141
|
+
method: match[1].toUpperCase(),
|
|
142
|
+
path: match[2]
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
return results;
|
|
146
|
+
}
|
|
147
|
+
function scanRoutes(root, framework) {
|
|
148
|
+
const patterns = getRoutePatterns(framework);
|
|
149
|
+
if (patterns.length === 0) return [];
|
|
150
|
+
const routes = [];
|
|
151
|
+
walkDir(root, root, patterns, framework, routes, 0);
|
|
152
|
+
return routes;
|
|
153
|
+
}
|
|
154
|
+
function walkDir(root, dir, patterns, framework, routes, depth) {
|
|
155
|
+
if (depth > MAX_SCAN_DEPTH) return;
|
|
156
|
+
let entries;
|
|
157
|
+
try {
|
|
158
|
+
entries = (0, import_node_fs2.readdirSync)(dir);
|
|
159
|
+
} catch {
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
for (const name of entries) {
|
|
163
|
+
if (SKIP_DIRS.has(name)) continue;
|
|
164
|
+
const fullPath = (0, import_node_path2.join)(dir, name);
|
|
165
|
+
let stat;
|
|
166
|
+
try {
|
|
167
|
+
stat = (0, import_node_fs2.statSync)(fullPath);
|
|
168
|
+
} catch {
|
|
169
|
+
continue;
|
|
170
|
+
}
|
|
171
|
+
if (stat.isDirectory()) {
|
|
172
|
+
walkDir(root, fullPath, patterns, framework, routes, depth + 1);
|
|
173
|
+
continue;
|
|
174
|
+
}
|
|
175
|
+
if (!stat.isFile()) continue;
|
|
176
|
+
if (!SCAN_EXTENSIONS.has((0, import_node_path2.extname)(name))) continue;
|
|
177
|
+
try {
|
|
178
|
+
const content = (0, import_node_fs2.readFileSync)(fullPath, "utf-8");
|
|
179
|
+
if (patterns.some((p) => content.includes(p))) {
|
|
180
|
+
routes.push({
|
|
181
|
+
file: (0, import_node_path2.relative)(root, fullPath),
|
|
182
|
+
framework
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
} catch {
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// src/scanner/schema.ts
|
|
191
|
+
function extractPrismaModelNames(content) {
|
|
192
|
+
const models = [];
|
|
193
|
+
const regex = /model\s+(\w+)\s*\{/g;
|
|
194
|
+
let match;
|
|
195
|
+
while ((match = regex.exec(content)) !== null) {
|
|
196
|
+
models.push(match[1]);
|
|
197
|
+
}
|
|
198
|
+
return models;
|
|
199
|
+
}
|
|
200
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
201
|
+
0 && (module.exports = {
|
|
202
|
+
detectFramework,
|
|
203
|
+
detectFrameworkFromDeps,
|
|
204
|
+
extractPrismaModelNames,
|
|
205
|
+
extractRoutesRegex,
|
|
206
|
+
getRoutePatterns,
|
|
207
|
+
hasDirxSdk,
|
|
208
|
+
scanRoutes
|
|
209
|
+
});
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Framework detection from project files and dependencies.
|
|
3
|
+
*
|
|
4
|
+
* Detects language and framework by inspecting dependency manifests
|
|
5
|
+
* (package.json, go.mod, Cargo.toml, requirements.txt, pyproject.toml).
|
|
6
|
+
*/
|
|
7
|
+
interface DetectedStack {
|
|
8
|
+
lang: string;
|
|
9
|
+
framework: string;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Detect framework from a project directory by inspecting manifest files.
|
|
13
|
+
*/
|
|
14
|
+
declare function detectFramework(target: string): DetectedStack;
|
|
15
|
+
/**
|
|
16
|
+
* Detect framework from package.json dependencies.
|
|
17
|
+
* Returns null if no known framework is found.
|
|
18
|
+
*/
|
|
19
|
+
declare function detectFrameworkFromDeps(target: string): string | null;
|
|
20
|
+
/**
|
|
21
|
+
* Check if a project has @dirxai/core in its dependencies.
|
|
22
|
+
*/
|
|
23
|
+
declare function hasDirxSdk(target: string): boolean;
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Route extraction from source code.
|
|
27
|
+
*
|
|
28
|
+
* Uses pattern matching to detect route definitions across
|
|
29
|
+
* multiple frameworks (Express, Hono, Fastify, Next.js, FastAPI, Go, Axum).
|
|
30
|
+
*/
|
|
31
|
+
interface RouteHint {
|
|
32
|
+
file: string;
|
|
33
|
+
framework: string;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Get route detection patterns for a given framework.
|
|
37
|
+
*/
|
|
38
|
+
declare function getRoutePatterns(framework: string): string[];
|
|
39
|
+
/**
|
|
40
|
+
* Extract routes from source code using regex.
|
|
41
|
+
* Returns method + path pairs found in the content.
|
|
42
|
+
*/
|
|
43
|
+
declare function extractRoutesRegex(content: string): {
|
|
44
|
+
method: string;
|
|
45
|
+
path: string;
|
|
46
|
+
}[];
|
|
47
|
+
/**
|
|
48
|
+
* Scan a directory tree for files containing route definitions.
|
|
49
|
+
*/
|
|
50
|
+
declare function scanRoutes(root: string, framework: string): RouteHint[];
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Schema extraction from Prisma and other ORM definitions.
|
|
54
|
+
*/
|
|
55
|
+
/**
|
|
56
|
+
* Extract model names from a Prisma schema file content.
|
|
57
|
+
*/
|
|
58
|
+
declare function extractPrismaModelNames(content: string): string[];
|
|
59
|
+
|
|
60
|
+
export { type DetectedStack, type RouteHint, detectFramework, detectFrameworkFromDeps, extractPrismaModelNames, extractRoutesRegex, getRoutePatterns, hasDirxSdk, scanRoutes };
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Framework detection from project files and dependencies.
|
|
3
|
+
*
|
|
4
|
+
* Detects language and framework by inspecting dependency manifests
|
|
5
|
+
* (package.json, go.mod, Cargo.toml, requirements.txt, pyproject.toml).
|
|
6
|
+
*/
|
|
7
|
+
interface DetectedStack {
|
|
8
|
+
lang: string;
|
|
9
|
+
framework: string;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Detect framework from a project directory by inspecting manifest files.
|
|
13
|
+
*/
|
|
14
|
+
declare function detectFramework(target: string): DetectedStack;
|
|
15
|
+
/**
|
|
16
|
+
* Detect framework from package.json dependencies.
|
|
17
|
+
* Returns null if no known framework is found.
|
|
18
|
+
*/
|
|
19
|
+
declare function detectFrameworkFromDeps(target: string): string | null;
|
|
20
|
+
/**
|
|
21
|
+
* Check if a project has @dirxai/core in its dependencies.
|
|
22
|
+
*/
|
|
23
|
+
declare function hasDirxSdk(target: string): boolean;
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Route extraction from source code.
|
|
27
|
+
*
|
|
28
|
+
* Uses pattern matching to detect route definitions across
|
|
29
|
+
* multiple frameworks (Express, Hono, Fastify, Next.js, FastAPI, Go, Axum).
|
|
30
|
+
*/
|
|
31
|
+
interface RouteHint {
|
|
32
|
+
file: string;
|
|
33
|
+
framework: string;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Get route detection patterns for a given framework.
|
|
37
|
+
*/
|
|
38
|
+
declare function getRoutePatterns(framework: string): string[];
|
|
39
|
+
/**
|
|
40
|
+
* Extract routes from source code using regex.
|
|
41
|
+
* Returns method + path pairs found in the content.
|
|
42
|
+
*/
|
|
43
|
+
declare function extractRoutesRegex(content: string): {
|
|
44
|
+
method: string;
|
|
45
|
+
path: string;
|
|
46
|
+
}[];
|
|
47
|
+
/**
|
|
48
|
+
* Scan a directory tree for files containing route definitions.
|
|
49
|
+
*/
|
|
50
|
+
declare function scanRoutes(root: string, framework: string): RouteHint[];
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Schema extraction from Prisma and other ORM definitions.
|
|
54
|
+
*/
|
|
55
|
+
/**
|
|
56
|
+
* Extract model names from a Prisma schema file content.
|
|
57
|
+
*/
|
|
58
|
+
declare function extractPrismaModelNames(content: string): string[];
|
|
59
|
+
|
|
60
|
+
export { type DetectedStack, type RouteHint, detectFramework, detectFrameworkFromDeps, extractPrismaModelNames, extractRoutesRegex, getRoutePatterns, hasDirxSdk, scanRoutes };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import {
|
|
2
|
+
detectFramework,
|
|
3
|
+
detectFrameworkFromDeps,
|
|
4
|
+
extractPrismaModelNames,
|
|
5
|
+
extractRoutesRegex,
|
|
6
|
+
getRoutePatterns,
|
|
7
|
+
hasDirxSdk,
|
|
8
|
+
scanRoutes
|
|
9
|
+
} from "../chunk-AMKKT77F.js";
|
|
10
|
+
export {
|
|
11
|
+
detectFramework,
|
|
12
|
+
detectFrameworkFromDeps,
|
|
13
|
+
extractPrismaModelNames,
|
|
14
|
+
extractRoutesRegex,
|
|
15
|
+
getRoutePatterns,
|
|
16
|
+
hasDirxSdk,
|
|
17
|
+
scanRoutes
|
|
18
|
+
};
|
package/dist/types.cjs
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
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/types.ts
|
|
21
|
+
var types_exports = {};
|
|
22
|
+
__export(types_exports, {
|
|
23
|
+
getAuthHint: () => getAuthHint
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(types_exports);
|
|
26
|
+
var KNOWN_PROVIDERS = {
|
|
27
|
+
"api.github.com": {
|
|
28
|
+
envVar: "GITHUB_TOKEN",
|
|
29
|
+
guideUrl: "https://github.com/settings/tokens"
|
|
30
|
+
},
|
|
31
|
+
"api.openai.com": {
|
|
32
|
+
envVar: "OPENAI_API_KEY",
|
|
33
|
+
guideUrl: "https://platform.openai.com/api-keys"
|
|
34
|
+
},
|
|
35
|
+
"api.anthropic.com": {
|
|
36
|
+
envVar: "ANTHROPIC_API_KEY",
|
|
37
|
+
guideUrl: "https://console.anthropic.com/settings/keys"
|
|
38
|
+
},
|
|
39
|
+
"generativelanguage.googleapis.com": {
|
|
40
|
+
envVar: "GOOGLE_API_KEY",
|
|
41
|
+
guideUrl: "https://aistudio.google.com/apikey"
|
|
42
|
+
},
|
|
43
|
+
"api.stripe.com": {
|
|
44
|
+
envVar: "STRIPE_SECRET_KEY",
|
|
45
|
+
guideUrl: "https://dashboard.stripe.com/apikeys"
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
function getAuthHint(domain) {
|
|
49
|
+
return KNOWN_PROVIDERS[domain] ?? null;
|
|
50
|
+
}
|
|
51
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
52
|
+
0 && (module.exports = {
|
|
53
|
+
getAuthHint
|
|
54
|
+
});
|
package/dist/types.d.cts
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared DirX types for CLI, SDK, and server interop.
|
|
3
|
+
*
|
|
4
|
+
* DirxEnvelope is the canonical response wrapper used by the gateway.
|
|
5
|
+
* All other types define the domain model for DirX services.
|
|
6
|
+
*/
|
|
7
|
+
interface DirxEnvelope<T = unknown> {
|
|
8
|
+
ok: boolean;
|
|
9
|
+
data?: T;
|
|
10
|
+
error?: string | {
|
|
11
|
+
code: string;
|
|
12
|
+
message: string;
|
|
13
|
+
};
|
|
14
|
+
meta?: Record<string, unknown>;
|
|
15
|
+
}
|
|
16
|
+
interface DirxEndpoint {
|
|
17
|
+
path: string;
|
|
18
|
+
method: string;
|
|
19
|
+
description?: string;
|
|
20
|
+
}
|
|
21
|
+
interface DirxService {
|
|
22
|
+
title: string;
|
|
23
|
+
description?: string;
|
|
24
|
+
base_url: string;
|
|
25
|
+
actions: string[];
|
|
26
|
+
endpoints: DirxEndpoint[];
|
|
27
|
+
}
|
|
28
|
+
interface SearchResult {
|
|
29
|
+
domain: string;
|
|
30
|
+
title: string;
|
|
31
|
+
description?: string;
|
|
32
|
+
path?: string;
|
|
33
|
+
score?: number;
|
|
34
|
+
matched_endpoints?: EndpointMatch[];
|
|
35
|
+
}
|
|
36
|
+
interface EndpointMatch {
|
|
37
|
+
method: string;
|
|
38
|
+
path: string;
|
|
39
|
+
description?: string;
|
|
40
|
+
}
|
|
41
|
+
interface ByokAuth {
|
|
42
|
+
type: string;
|
|
43
|
+
token?: string;
|
|
44
|
+
header?: string;
|
|
45
|
+
key?: string;
|
|
46
|
+
}
|
|
47
|
+
interface ProviderHint {
|
|
48
|
+
envVar?: string;
|
|
49
|
+
guideUrl: string;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Get authentication hint for a known provider domain.
|
|
53
|
+
*/
|
|
54
|
+
declare function getAuthHint(domain: string): ProviderHint | null;
|
|
55
|
+
|
|
56
|
+
export { type ByokAuth, type DirxEndpoint, type DirxEnvelope, type DirxService, type EndpointMatch, type ProviderHint, type SearchResult, getAuthHint };
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared DirX types for CLI, SDK, and server interop.
|
|
3
|
+
*
|
|
4
|
+
* DirxEnvelope is the canonical response wrapper used by the gateway.
|
|
5
|
+
* All other types define the domain model for DirX services.
|
|
6
|
+
*/
|
|
7
|
+
interface DirxEnvelope<T = unknown> {
|
|
8
|
+
ok: boolean;
|
|
9
|
+
data?: T;
|
|
10
|
+
error?: string | {
|
|
11
|
+
code: string;
|
|
12
|
+
message: string;
|
|
13
|
+
};
|
|
14
|
+
meta?: Record<string, unknown>;
|
|
15
|
+
}
|
|
16
|
+
interface DirxEndpoint {
|
|
17
|
+
path: string;
|
|
18
|
+
method: string;
|
|
19
|
+
description?: string;
|
|
20
|
+
}
|
|
21
|
+
interface DirxService {
|
|
22
|
+
title: string;
|
|
23
|
+
description?: string;
|
|
24
|
+
base_url: string;
|
|
25
|
+
actions: string[];
|
|
26
|
+
endpoints: DirxEndpoint[];
|
|
27
|
+
}
|
|
28
|
+
interface SearchResult {
|
|
29
|
+
domain: string;
|
|
30
|
+
title: string;
|
|
31
|
+
description?: string;
|
|
32
|
+
path?: string;
|
|
33
|
+
score?: number;
|
|
34
|
+
matched_endpoints?: EndpointMatch[];
|
|
35
|
+
}
|
|
36
|
+
interface EndpointMatch {
|
|
37
|
+
method: string;
|
|
38
|
+
path: string;
|
|
39
|
+
description?: string;
|
|
40
|
+
}
|
|
41
|
+
interface ByokAuth {
|
|
42
|
+
type: string;
|
|
43
|
+
token?: string;
|
|
44
|
+
header?: string;
|
|
45
|
+
key?: string;
|
|
46
|
+
}
|
|
47
|
+
interface ProviderHint {
|
|
48
|
+
envVar?: string;
|
|
49
|
+
guideUrl: string;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Get authentication hint for a known provider domain.
|
|
53
|
+
*/
|
|
54
|
+
declare function getAuthHint(domain: string): ProviderHint | null;
|
|
55
|
+
|
|
56
|
+
export { type ByokAuth, type DirxEndpoint, type DirxEnvelope, type DirxService, type EndpointMatch, type ProviderHint, type SearchResult, getAuthHint };
|
package/dist/types.js
ADDED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dirxai/core",
|
|
3
|
-
"version": "0.3.
|
|
4
|
-
"description": "DirX
|
|
3
|
+
"version": "0.3.1",
|
|
4
|
+
"description": "DirX SDK — scanner, types, Guard middleware, JWKS auth, error model",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"main": "./dist/index.cjs",
|
|
@@ -17,6 +17,16 @@
|
|
|
17
17
|
"types": "./dist/testing.d.ts",
|
|
18
18
|
"import": "./dist/testing.js",
|
|
19
19
|
"require": "./dist/testing.cjs"
|
|
20
|
+
},
|
|
21
|
+
"./scanner": {
|
|
22
|
+
"types": "./dist/scanner/index.d.ts",
|
|
23
|
+
"import": "./dist/scanner/index.js",
|
|
24
|
+
"require": "./dist/scanner/index.cjs"
|
|
25
|
+
},
|
|
26
|
+
"./types": {
|
|
27
|
+
"types": "./dist/types.d.ts",
|
|
28
|
+
"import": "./dist/types.js",
|
|
29
|
+
"require": "./dist/types.cjs"
|
|
20
30
|
}
|
|
21
31
|
},
|
|
22
32
|
"scripts": {
|
|
@@ -36,6 +46,7 @@
|
|
|
36
46
|
"dirx",
|
|
37
47
|
"agent",
|
|
38
48
|
"sdk",
|
|
49
|
+
"scanner",
|
|
39
50
|
"gateway",
|
|
40
51
|
"guard",
|
|
41
52
|
"jwks",
|