designmaker-cli 0.1.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/commands/doctor.d.ts +1 -0
- package/dist/commands/doctor.js +26 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/import.d.ts +1 -0
- package/dist/commands/import.js +45 -0
- package/dist/commands/import.js.map +1 -0
- package/dist/commands/rebuild.d.ts +1 -0
- package/dist/commands/rebuild.js +32 -0
- package/dist/commands/rebuild.js.map +1 -0
- package/dist/commands/start.d.ts +1 -0
- package/dist/commands/start.js +103 -0
- package/dist/commands/start.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +65 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/ai/build-annotation-prompt.d.ts +6 -0
- package/dist/lib/ai/build-annotation-prompt.js +40 -0
- package/dist/lib/ai/build-annotation-prompt.js.map +1 -0
- package/dist/lib/ai/providers/index.d.ts +10 -0
- package/dist/lib/ai/providers/index.js +27 -0
- package/dist/lib/ai/providers/index.js.map +1 -0
- package/dist/lib/ai/providers/openai.d.ts +9 -0
- package/dist/lib/ai/providers/openai.js +77 -0
- package/dist/lib/ai/providers/openai.js.map +1 -0
- package/dist/lib/ai/providers/response-schema.d.ts +159 -0
- package/dist/lib/ai/providers/response-schema.js +21 -0
- package/dist/lib/ai/providers/response-schema.js.map +1 -0
- package/dist/lib/annotations/annotation-generator.d.ts +9 -0
- package/dist/lib/annotations/annotation-generator.js +90 -0
- package/dist/lib/annotations/annotation-generator.js.map +1 -0
- package/dist/lib/annotations/run-annotation-generation.d.ts +13 -0
- package/dist/lib/annotations/run-annotation-generation.js +52 -0
- package/dist/lib/annotations/run-annotation-generation.js.map +1 -0
- package/dist/lib/bundle/annotated-bundle.d.ts +15 -0
- package/dist/lib/bundle/annotated-bundle.js +63 -0
- package/dist/lib/bundle/annotated-bundle.js.map +1 -0
- package/dist/lib/bundle/shell-dist.d.ts +1 -0
- package/dist/lib/bundle/shell-dist.js +29 -0
- package/dist/lib/bundle/shell-dist.js.map +1 -0
- package/dist/lib/config.d.ts +13 -0
- package/dist/lib/config.js +84 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/doctor/doctor-checks.d.ts +12 -0
- package/dist/lib/doctor/doctor-checks.js +98 -0
- package/dist/lib/doctor/doctor-checks.js.map +1 -0
- package/dist/lib/env.d.ts +1 -0
- package/dist/lib/env.js +5 -0
- package/dist/lib/env.js.map +1 -0
- package/dist/lib/logger.d.ts +6 -0
- package/dist/lib/logger.js +15 -0
- package/dist/lib/logger.js.map +1 -0
- package/dist/lib/project/detect-artifacts.d.ts +1 -0
- package/dist/lib/project/detect-artifacts.js +10 -0
- package/dist/lib/project/detect-artifacts.js.map +1 -0
- package/dist/lib/project/detect-framework.d.ts +3 -0
- package/dist/lib/project/detect-framework.js +14 -0
- package/dist/lib/project/detect-framework.js.map +1 -0
- package/dist/lib/project/detect-package-manager.d.ts +3 -0
- package/dist/lib/project/detect-package-manager.js +33 -0
- package/dist/lib/project/detect-package-manager.js.map +1 -0
- package/dist/lib/project/detect-scripts.d.ts +6 -0
- package/dist/lib/project/detect-scripts.js +8 -0
- package/dist/lib/project/detect-scripts.js.map +1 -0
- package/dist/lib/project/package-json.d.ts +23 -0
- package/dist/lib/project/package-json.js +20 -0
- package/dist/lib/project/package-json.js.map +1 -0
- package/dist/lib/project/project-scan.d.ts +2 -0
- package/dist/lib/project/project-scan.js +35 -0
- package/dist/lib/project/project-scan.js.map +1 -0
- package/dist/lib/prompt/is-tty.d.ts +1 -0
- package/dist/lib/prompt/is-tty.js +5 -0
- package/dist/lib/prompt/is-tty.js.map +1 -0
- package/dist/lib/prototype/browser.d.ts +2 -0
- package/dist/lib/prototype/browser.js +5 -0
- package/dist/lib/prototype/browser.js.map +1 -0
- package/dist/lib/prototype/capture-all-pages.d.ts +13 -0
- package/dist/lib/prototype/capture-all-pages.js +22 -0
- package/dist/lib/prototype/capture-all-pages.js.map +1 -0
- package/dist/lib/prototype/dom-summary.d.ts +3 -0
- package/dist/lib/prototype/dom-summary.js +56 -0
- package/dist/lib/prototype/dom-summary.js.map +1 -0
- package/dist/lib/prototype/page-capture.d.ts +6 -0
- package/dist/lib/prototype/page-capture.js +36 -0
- package/dist/lib/prototype/page-capture.js.map +1 -0
- package/dist/lib/prototype/page-metadata.d.ts +7 -0
- package/dist/lib/prototype/page-metadata.js +9 -0
- package/dist/lib/prototype/page-metadata.js.map +1 -0
- package/dist/lib/prototype/prototype-session.d.ts +22 -0
- package/dist/lib/prototype/prototype-session.js +82 -0
- package/dist/lib/prototype/prototype-session.js.map +1 -0
- package/dist/lib/prototype/run-package-script.d.ts +2 -0
- package/dist/lib/prototype/run-package-script.js +21 -0
- package/dist/lib/prototype/run-package-script.js.map +1 -0
- package/dist/lib/prototype/start-static-preview.d.ts +5 -0
- package/dist/lib/prototype/start-static-preview.js +74 -0
- package/dist/lib/prototype/start-static-preview.js.map +1 -0
- package/dist/lib/prototype/startup-strategy.d.ts +7 -0
- package/dist/lib/prototype/startup-strategy.js +32 -0
- package/dist/lib/prototype/startup-strategy.js.map +1 -0
- package/dist/lib/prototype/visible-text.d.ts +2 -0
- package/dist/lib/prototype/visible-text.js +5 -0
- package/dist/lib/prototype/visible-text.js.map +1 -0
- package/dist/lib/prototype/wait-for-url.d.ts +1 -0
- package/dist/lib/prototype/wait-for-url.js +16 -0
- package/dist/lib/prototype/wait-for-url.js.map +1 -0
- package/dist/lib/requirements/parse-file.d.ts +1 -0
- package/dist/lib/requirements/parse-file.js +7 -0
- package/dist/lib/requirements/parse-file.js.map +1 -0
- package/dist/lib/requirements/parse-text.d.ts +1 -0
- package/dist/lib/requirements/parse-text.js +4 -0
- package/dist/lib/requirements/parse-text.js.map +1 -0
- package/dist/lib/requirements/requirements-discovery.d.ts +2 -0
- package/dist/lib/requirements/requirements-discovery.js +62 -0
- package/dist/lib/requirements/requirements-discovery.js.map +1 -0
- package/dist/lib/requirements/requirements-ranking.d.ts +1 -0
- package/dist/lib/requirements/requirements-ranking.js +41 -0
- package/dist/lib/requirements/requirements-ranking.js.map +1 -0
- package/dist/lib/routes/confirm-ai-routes.d.ts +10 -0
- package/dist/lib/routes/confirm-ai-routes.js +70 -0
- package/dist/lib/routes/confirm-ai-routes.js.map +1 -0
- package/dist/lib/routes/crawl-internal-links.d.ts +4 -0
- package/dist/lib/routes/crawl-internal-links.js +42 -0
- package/dist/lib/routes/crawl-internal-links.js.map +1 -0
- package/dist/lib/routes/normalize-route-path.d.ts +5 -0
- package/dist/lib/routes/normalize-route-path.js +52 -0
- package/dist/lib/routes/normalize-route-path.js.map +1 -0
- package/dist/lib/routes/resolve-capture-routes.d.ts +18 -0
- package/dist/lib/routes/resolve-capture-routes.js +47 -0
- package/dist/lib/routes/resolve-capture-routes.js.map +1 -0
- package/dist/lib/routes/routes-config.d.ts +21 -0
- package/dist/lib/routes/routes-config.js +31 -0
- package/dist/lib/routes/routes-config.js.map +1 -0
- package/dist/lib/workspace/paths.d.ts +8 -0
- package/dist/lib/workspace/paths.js +19 -0
- package/dist/lib/workspace/paths.js.map +1 -0
- package/dist/lib/workspace/read-json.d.ts +2 -0
- package/dist/lib/workspace/read-json.js +26 -0
- package/dist/lib/workspace/read-json.js.map +1 -0
- package/dist/lib/workspace/schema.d.ts +355 -0
- package/dist/lib/workspace/schema.js +71 -0
- package/dist/lib/workspace/schema.js.map +1 -0
- package/dist/lib/workspace/types.d.ts +81 -0
- package/dist/lib/workspace/types.js +2 -0
- package/dist/lib/workspace/types.js.map +1 -0
- package/dist/lib/workspace/workspace-store.d.ts +27 -0
- package/dist/lib/workspace/workspace-store.js +75 -0
- package/dist/lib/workspace/workspace-store.js.map +1 -0
- package/dist/lib/workspace/write-json.d.ts +1 -0
- package/dist/lib/workspace/write-json.js +10 -0
- package/dist/lib/workspace/write-json.js.map +1 -0
- package/package.json +34 -0
- package/templates/vercel.json +5 -0
- package/vendor/annotation-shell/annotation-shell.css +1 -0
- package/vendor/annotation-shell/annotation-shell.js +379 -0
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { join } from 'node:path';
|
|
2
|
+
import { logger } from '../logger.js';
|
|
3
|
+
import { scanProject } from '../project/project-scan.js';
|
|
4
|
+
import { launchBrowser } from './browser.js';
|
|
5
|
+
import { captureAllPages } from './capture-all-pages.js';
|
|
6
|
+
import { runPackageScript } from './run-package-script.js';
|
|
7
|
+
import { startStaticPreview } from './start-static-preview.js';
|
|
8
|
+
import { resolveStartupPlan } from './startup-strategy.js';
|
|
9
|
+
import { waitForUrl } from './wait-for-url.js';
|
|
10
|
+
import { resolveCaptureRoutes } from '../routes/resolve-capture-routes.js';
|
|
11
|
+
import { resolveAiRoutes } from '../routes/confirm-ai-routes.js';
|
|
12
|
+
export async function capturePrototype(projectRoot, initialScan, paths, options) {
|
|
13
|
+
let scan = initialScan;
|
|
14
|
+
let plan = resolveStartupPlan(scan);
|
|
15
|
+
if (plan.kind === 'build') {
|
|
16
|
+
logger.info('未发现静态产物,开始执行项目 build 脚本...');
|
|
17
|
+
await runPackageScript(projectRoot, scan.package_manager, 'build');
|
|
18
|
+
scan = await scanProject(projectRoot);
|
|
19
|
+
plan = resolveStartupPlan(scan);
|
|
20
|
+
}
|
|
21
|
+
if (plan.kind !== 'static' || !plan.artifactDir) {
|
|
22
|
+
logger.warn('当前仅支持静态产物采集;dev/preview 脚本采集将在后续任务补齐。');
|
|
23
|
+
return emptyCaptureResult(scan);
|
|
24
|
+
}
|
|
25
|
+
const artifactRoot = join(projectRoot, plan.artifactDir);
|
|
26
|
+
const server = await startStaticPreview(artifactRoot);
|
|
27
|
+
let browser = null;
|
|
28
|
+
try {
|
|
29
|
+
browser = await launchBrowser();
|
|
30
|
+
await waitForUrl(server.url);
|
|
31
|
+
const resolvedRoutes = await resolveCaptureRoutes({
|
|
32
|
+
cwd: options.cwd,
|
|
33
|
+
workspace: options.workspace,
|
|
34
|
+
pages: options.pages,
|
|
35
|
+
maxPages: options.maxPages,
|
|
36
|
+
noCrawl: options.noCrawl,
|
|
37
|
+
yes: options.yes,
|
|
38
|
+
browser,
|
|
39
|
+
baseUrl: server.url,
|
|
40
|
+
});
|
|
41
|
+
const aiRoutes = await resolveAiRoutes({
|
|
42
|
+
routes: resolvedRoutes.routes,
|
|
43
|
+
routesConfig: resolvedRoutes.routesConfig,
|
|
44
|
+
aiPages: options.aiPages,
|
|
45
|
+
yes: options.yes,
|
|
46
|
+
prompt: options.prompt,
|
|
47
|
+
});
|
|
48
|
+
const snapshots = await captureAllPages(browser, server.url, resolvedRoutes.routes, paths.pageSnapshotsDir);
|
|
49
|
+
const firstSnapshot = snapshots[0]?.snapshot ?? null;
|
|
50
|
+
const entryUrl = firstSnapshot?.url ?? null;
|
|
51
|
+
return {
|
|
52
|
+
scan: {
|
|
53
|
+
...scan,
|
|
54
|
+
resolved_entry_url: entryUrl,
|
|
55
|
+
},
|
|
56
|
+
entryUrl,
|
|
57
|
+
routes: resolvedRoutes.routes,
|
|
58
|
+
aiRoutes,
|
|
59
|
+
snapshots,
|
|
60
|
+
snapshot: firstSnapshot,
|
|
61
|
+
snapshotFileName: snapshots[0]?.fileName ?? null,
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
finally {
|
|
65
|
+
if (browser) {
|
|
66
|
+
await browser.close();
|
|
67
|
+
}
|
|
68
|
+
await server.close();
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
function emptyCaptureResult(scan) {
|
|
72
|
+
return {
|
|
73
|
+
scan,
|
|
74
|
+
entryUrl: null,
|
|
75
|
+
routes: ['/'],
|
|
76
|
+
aiRoutes: ['/'],
|
|
77
|
+
snapshots: [],
|
|
78
|
+
snapshot: null,
|
|
79
|
+
snapshotFileName: null,
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=prototype-session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prototype-session.js","sourceRoot":"","sources":["../../../src/lib/prototype/prototype-session.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { spawn } from 'node:child_process';
|
|
2
|
+
export async function runPackageScript(projectRoot, packageManager, scriptName) {
|
|
3
|
+
const command = packageManager === 'yarn' ? 'yarn' : packageManager === 'pnpm' ? 'pnpm' : 'npm';
|
|
4
|
+
const args = command === 'yarn' ? [scriptName] : ['run', scriptName];
|
|
5
|
+
await new Promise((resolve, reject) => {
|
|
6
|
+
const child = spawn(command, args, {
|
|
7
|
+
cwd: projectRoot,
|
|
8
|
+
stdio: 'inherit',
|
|
9
|
+
shell: false,
|
|
10
|
+
});
|
|
11
|
+
child.on('error', reject);
|
|
12
|
+
child.on('exit', (code) => {
|
|
13
|
+
if (code === 0) {
|
|
14
|
+
resolve();
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
reject(new Error(`${command} ${args.join(' ')} 执行失败,退出码:${code ?? 'unknown'}`));
|
|
18
|
+
});
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=run-package-script.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-package-script.js","sourceRoot":"","sources":["../../../src/lib/prototype/run-package-script.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAG3C,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,WAAmB,EACnB,cAAoD,EACpD,UAAkB;IAElB,MAAM,OAAO,GAAG,cAAc,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,cAAc,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC;IAChG,MAAM,IAAI,GAAG,OAAO,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;IAErE,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QAC1C,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,EAAE,IAAI,EAAE;YACjC,GAAG,EAAE,WAAW;YAChB,KAAK,EAAE,SAAS;YAChB,KAAK,EAAE,KAAK;SACb,CAAC,CAAC;QAEH,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAC1B,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;YACxB,IAAI,IAAI,KAAK,CAAC,EAAE,CAAC;gBACf,OAAO,EAAE,CAAC;gBACV,OAAO;YACT,CAAC;YACD,MAAM,CAAC,IAAI,KAAK,CAAC,GAAG,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,aAAa,IAAI,IAAI,SAAS,EAAE,CAAC,CAAC,CAAC;QAClF,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { createReadStream, existsSync, statSync } from 'node:fs';
|
|
2
|
+
import { createServer } from 'node:http';
|
|
3
|
+
import { extname, join, normalize } from 'node:path';
|
|
4
|
+
export async function startStaticPreview(rootDir) {
|
|
5
|
+
const server = createServer((request, response) => {
|
|
6
|
+
const requestUrl = new URL(request.url ?? '/', 'http://127.0.0.1');
|
|
7
|
+
const safePath = normalize(decodeURIComponent(requestUrl.pathname)).replace(/^(\.\.[/\\])+/, '');
|
|
8
|
+
const requestedPath = join(rootDir, safePath);
|
|
9
|
+
const filePath = resolveFilePath(rootDir, requestedPath, requestUrl.pathname);
|
|
10
|
+
if (!filePath) {
|
|
11
|
+
response.statusCode = 404;
|
|
12
|
+
response.end('Not found');
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
response.setHeader('Content-Type', getContentType(filePath));
|
|
16
|
+
createReadStream(filePath).pipe(response);
|
|
17
|
+
});
|
|
18
|
+
const url = await listen(server);
|
|
19
|
+
return {
|
|
20
|
+
url,
|
|
21
|
+
close: () => new Promise((resolve, reject) => {
|
|
22
|
+
server.close((error) => (error ? reject(error) : resolve()));
|
|
23
|
+
}),
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
function resolveFilePath(rootDir, requestedPath, pathname) {
|
|
27
|
+
if (existsSync(requestedPath) && statSync(requestedPath).isFile()) {
|
|
28
|
+
return requestedPath;
|
|
29
|
+
}
|
|
30
|
+
if (pathname.endsWith('/')) {
|
|
31
|
+
const indexPath = join(requestedPath, 'index.html');
|
|
32
|
+
if (existsSync(indexPath) && statSync(indexPath).isFile())
|
|
33
|
+
return indexPath;
|
|
34
|
+
}
|
|
35
|
+
const spaFallback = join(rootDir, 'index.html');
|
|
36
|
+
if (existsSync(spaFallback) && statSync(spaFallback).isFile())
|
|
37
|
+
return spaFallback;
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
function listen(server) {
|
|
41
|
+
return new Promise((resolve, reject) => {
|
|
42
|
+
server.on('error', reject);
|
|
43
|
+
server.listen(0, '127.0.0.1', () => {
|
|
44
|
+
const address = server.address();
|
|
45
|
+
if (!address || typeof address === 'string') {
|
|
46
|
+
reject(new Error('无法获取静态预览端口'));
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
resolve(`http://127.0.0.1:${address.port}`);
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
function getContentType(path) {
|
|
54
|
+
switch (extname(path)) {
|
|
55
|
+
case '.html':
|
|
56
|
+
return 'text/html; charset=utf-8';
|
|
57
|
+
case '.js':
|
|
58
|
+
return 'text/javascript; charset=utf-8';
|
|
59
|
+
case '.css':
|
|
60
|
+
return 'text/css; charset=utf-8';
|
|
61
|
+
case '.json':
|
|
62
|
+
return 'application/json; charset=utf-8';
|
|
63
|
+
case '.png':
|
|
64
|
+
return 'image/png';
|
|
65
|
+
case '.jpg':
|
|
66
|
+
case '.jpeg':
|
|
67
|
+
return 'image/jpeg';
|
|
68
|
+
case '.svg':
|
|
69
|
+
return 'image/svg+xml';
|
|
70
|
+
default:
|
|
71
|
+
return 'application/octet-stream';
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=start-static-preview.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"start-static-preview.js","sourceRoot":"","sources":["../../../src/lib/prototype/start-static-preview.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { ProjectScanResult } from '../workspace/types.js';
|
|
2
|
+
export interface StartupPlan {
|
|
3
|
+
kind: 'static' | 'build' | 'script' | 'none';
|
|
4
|
+
artifactDir: string | null;
|
|
5
|
+
scriptName: string | null;
|
|
6
|
+
}
|
|
7
|
+
export declare function resolveStartupPlan(scan: ProjectScanResult): StartupPlan;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export function resolveStartupPlan(scan) {
|
|
2
|
+
const staticDir = scan.artifact_dirs[0];
|
|
3
|
+
if (staticDir) {
|
|
4
|
+
return {
|
|
5
|
+
kind: 'static',
|
|
6
|
+
artifactDir: staticDir,
|
|
7
|
+
scriptName: null,
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
if (scan.scripts.build) {
|
|
11
|
+
return {
|
|
12
|
+
kind: 'build',
|
|
13
|
+
artifactDir: null,
|
|
14
|
+
scriptName: 'build',
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
for (const scriptName of ['preview', 'dev', 'start']) {
|
|
18
|
+
if (scan.scripts[scriptName]) {
|
|
19
|
+
return {
|
|
20
|
+
kind: 'script',
|
|
21
|
+
artifactDir: null,
|
|
22
|
+
scriptName,
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return {
|
|
27
|
+
kind: 'none',
|
|
28
|
+
artifactDir: null,
|
|
29
|
+
scriptName: null,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=startup-strategy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"startup-strategy.js","sourceRoot":"","sources":["../../../src/lib/prototype/startup-strategy.ts"],"names":[],"mappings":"AAQA,MAAM,UAAU,kBAAkB,CAAC,IAAuB;IACxD,MAAM,SAAS,GAAG,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;IACxC,IAAI,SAAS,EAAE,CAAC;QACd,OAAO;YACL,IAAI,EAAE,QAAQ;YACd,WAAW,EAAE,SAAS;YACtB,UAAU,EAAE,IAAI;SACjB,CAAC;IACJ,CAAC;IAED,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;QACvB,OAAO;YACL,IAAI,EAAE,OAAO;YACb,WAAW,EAAE,IAAI;YACjB,UAAU,EAAE,OAAO;SACpB,CAAC;IACJ,CAAC;IAED,KAAK,MAAM,UAAU,IAAI,CAAC,SAAS,EAAE,KAAK,EAAE,OAAO,CAAC,EAAE,CAAC;QACrD,IAAI,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;YAC7B,OAAO;gBACL,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,IAAI;gBACjB,UAAU;aACX,CAAC;QACJ,CAAC;IACH,CAAC;IAED,OAAO;QACL,IAAI,EAAE,MAAM;QACZ,WAAW,EAAE,IAAI;QACjB,UAAU,EAAE,IAAI;KACjB,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"visible-text.js","sourceRoot":"","sources":["../../../src/lib/prototype/visible-text.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,IAAU;IACjD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,gCAAgC,CAAC,CAAC;IACrE,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC;AACxB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function waitForUrl(url: string, timeoutMs?: number): Promise<void>;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export async function waitForUrl(url, timeoutMs = 10000) {
|
|
2
|
+
const startedAt = Date.now();
|
|
3
|
+
while (Date.now() - startedAt < timeoutMs) {
|
|
4
|
+
try {
|
|
5
|
+
const response = await fetch(url);
|
|
6
|
+
if (response.ok)
|
|
7
|
+
return;
|
|
8
|
+
}
|
|
9
|
+
catch {
|
|
10
|
+
// retry until timeout
|
|
11
|
+
}
|
|
12
|
+
await new Promise((resolve) => setTimeout(resolve, 250));
|
|
13
|
+
}
|
|
14
|
+
throw new Error(`等待 URL 可访问超时:${url}`);
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=wait-for-url.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wait-for-url.js","sourceRoot":"","sources":["../../../src/lib/prototype/wait-for-url.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,GAAW,EAAE,SAAS,GAAG,KAAK;IAC7D,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAE7B,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,GAAG,SAAS,EAAE,CAAC;QAC1C,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,CAAC;YAClC,IAAI,QAAQ,CAAC,EAAE;gBAAE,OAAO;QAC1B,CAAC;QAAC,MAAM,CAAC;YACP,sBAAsB;QACxB,CAAC;QACD,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC;IAC3D,CAAC;IAED,MAAM,IAAI,KAAK,CAAC,gBAAgB,GAAG,EAAE,CAAC,CAAC;AACzC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function parseMarkdownFile(path: string): Promise<string>;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { readFile } from 'node:fs/promises';
|
|
2
|
+
import { normalizeMarkdownText } from './parse-text.js';
|
|
3
|
+
export async function parseMarkdownFile(path) {
|
|
4
|
+
const raw = await readFile(path, 'utf8');
|
|
5
|
+
return normalizeMarkdownText(raw);
|
|
6
|
+
}
|
|
7
|
+
//# sourceMappingURL=parse-file.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse-file.js","sourceRoot":"","sources":["../../../src/lib/requirements/parse-file.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAExD,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,IAAY;IAClD,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACzC,OAAO,qBAAqB,CAAC,GAAG,CAAC,CAAC;AACpC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function normalizeMarkdownText(text: string): string;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse-text.js","sourceRoot":"","sources":["../../../src/lib/requirements/parse-text.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,qBAAqB,CAAC,IAAY;IAChD,OAAO,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;AAC5C,CAAC"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { existsSync, readdirSync, statSync } from 'node:fs';
|
|
2
|
+
import { join, relative } from 'node:path';
|
|
3
|
+
import { parseMarkdownFile } from './parse-file.js';
|
|
4
|
+
import { rankRequirementFiles } from './requirements-ranking.js';
|
|
5
|
+
const CANDIDATE_DIRS = ['docs', 'prd', 'requirements'];
|
|
6
|
+
const IGNORED_DIRS = new Set(['.designmaker', 'node_modules', 'dist', 'build', 'out', '.git']);
|
|
7
|
+
const MAX_SELECTED_FILES = 5;
|
|
8
|
+
export async function discoverRequirements(projectRoot) {
|
|
9
|
+
const candidateFiles = discoverCandidateFiles(projectRoot);
|
|
10
|
+
const rankedFiles = rankRequirementFiles(candidateFiles);
|
|
11
|
+
const selectedFiles = rankedFiles.slice(0, MAX_SELECTED_FILES);
|
|
12
|
+
const combinedText = await combineMarkdownFiles(projectRoot, selectedFiles);
|
|
13
|
+
return {
|
|
14
|
+
candidate_files: rankedFiles,
|
|
15
|
+
selected_files: selectedFiles,
|
|
16
|
+
combined_text: combinedText,
|
|
17
|
+
updated_at: new Date().toISOString(),
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
function discoverCandidateFiles(projectRoot) {
|
|
21
|
+
const files = new Set();
|
|
22
|
+
for (const dir of CANDIDATE_DIRS) {
|
|
23
|
+
const absoluteDir = join(projectRoot, dir);
|
|
24
|
+
if (existsSync(absoluteDir) && statSync(absoluteDir).isDirectory()) {
|
|
25
|
+
for (const file of walkMarkdownFiles(projectRoot, absoluteDir)) {
|
|
26
|
+
files.add(file);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
for (const item of readdirSync(projectRoot, { withFileTypes: true })) {
|
|
31
|
+
if (item.isFile() && item.name.toLowerCase().endsWith('.md')) {
|
|
32
|
+
files.add(item.name);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return [...files];
|
|
36
|
+
}
|
|
37
|
+
function walkMarkdownFiles(projectRoot, dir) {
|
|
38
|
+
const files = [];
|
|
39
|
+
for (const item of readdirSync(dir, { withFileTypes: true })) {
|
|
40
|
+
if (item.isDirectory()) {
|
|
41
|
+
if (IGNORED_DIRS.has(item.name))
|
|
42
|
+
continue;
|
|
43
|
+
files.push(...walkMarkdownFiles(projectRoot, join(dir, item.name)));
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
if (item.isFile() && item.name.toLowerCase().endsWith('.md')) {
|
|
47
|
+
files.push(relative(projectRoot, join(dir, item.name)));
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return files;
|
|
51
|
+
}
|
|
52
|
+
async function combineMarkdownFiles(projectRoot, files) {
|
|
53
|
+
const chunks = [];
|
|
54
|
+
for (const file of files) {
|
|
55
|
+
const text = await parseMarkdownFile(join(projectRoot, file));
|
|
56
|
+
if (!text)
|
|
57
|
+
continue;
|
|
58
|
+
chunks.push(`<!-- source: ${file} -->\n${text}`);
|
|
59
|
+
}
|
|
60
|
+
return chunks.join('\n\n---\n\n');
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=requirements-discovery.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"requirements-discovery.js","sourceRoot":"","sources":["../../../src/lib/requirements/requirements-discovery.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function rankRequirementFiles(files: string[]): string[];
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { basename, dirname } from 'node:path';
|
|
2
|
+
const KEYWORD_WEIGHTS = [
|
|
3
|
+
{ keyword: 'prd', weight: 100 },
|
|
4
|
+
{ keyword: 'requirement', weight: 90 },
|
|
5
|
+
{ keyword: 'requirements', weight: 90 },
|
|
6
|
+
{ keyword: '需求', weight: 90 },
|
|
7
|
+
{ keyword: '要件', weight: 90 },
|
|
8
|
+
{ keyword: 'design', weight: 70 },
|
|
9
|
+
{ keyword: '设计', weight: 70 },
|
|
10
|
+
{ keyword: '設計', weight: 70 },
|
|
11
|
+
];
|
|
12
|
+
const DIRECTORY_WEIGHTS = [
|
|
13
|
+
{ segment: 'docs', weight: 30 },
|
|
14
|
+
{ segment: 'prd', weight: 40 },
|
|
15
|
+
{ segment: 'requirements', weight: 40 },
|
|
16
|
+
];
|
|
17
|
+
export function rankRequirementFiles(files) {
|
|
18
|
+
return [...files].sort((a, b) => {
|
|
19
|
+
const scoreDelta = scoreFile(b) - scoreFile(a);
|
|
20
|
+
if (scoreDelta !== 0)
|
|
21
|
+
return scoreDelta;
|
|
22
|
+
return a.localeCompare(b);
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
function scoreFile(path) {
|
|
26
|
+
const lowerName = basename(path).toLowerCase();
|
|
27
|
+
const lowerDir = dirname(path).toLowerCase();
|
|
28
|
+
let score = 0;
|
|
29
|
+
for (const item of KEYWORD_WEIGHTS) {
|
|
30
|
+
if (lowerName.includes(item.keyword))
|
|
31
|
+
score += item.weight;
|
|
32
|
+
}
|
|
33
|
+
for (const item of DIRECTORY_WEIGHTS) {
|
|
34
|
+
if (lowerDir.split('/').includes(item.segment))
|
|
35
|
+
score += item.weight;
|
|
36
|
+
}
|
|
37
|
+
if (lowerName === 'readme.md')
|
|
38
|
+
score -= 20;
|
|
39
|
+
return score;
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=requirements-ranking.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"requirements-ranking.js","sourceRoot":"","sources":["../../../src/lib/requirements/requirements-ranking.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAE9C,MAAM,eAAe,GAAG;IACtB,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE;IAC/B,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,EAAE,EAAE,EAAE;IACtC,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,EAAE,EAAE,EAAE;IACvC,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE;IAC7B,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE;IAC7B,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE;IACjC,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE;IAC7B,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE;CAC9B,CAAC;AAEF,MAAM,iBAAiB,GAAG;IACxB,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE;IAC/B,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE;IAC9B,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,EAAE,EAAE,EAAE;CACxC,CAAC;AAEF,MAAM,UAAU,oBAAoB,CAAC,KAAe;IAClD,OAAO,CAAC,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QAC9B,MAAM,UAAU,GAAG,SAAS,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;QAC/C,IAAI,UAAU,KAAK,CAAC;YAAE,OAAO,UAAU,CAAC;QACxC,OAAO,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;IAC5B,CAAC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,SAAS,CAAC,IAAY;IAC7B,MAAM,SAAS,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC;IAC/C,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC;IAC7C,IAAI,KAAK,GAAG,CAAC,CAAC;IAEd,KAAK,MAAM,IAAI,IAAI,eAAe,EAAE,CAAC;QACnC,IAAI,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC;YAAE,KAAK,IAAI,IAAI,CAAC,MAAM,CAAC;IAC7D,CAAC;IAED,KAAK,MAAM,IAAI,IAAI,iBAAiB,EAAE,CAAC;QACrC,IAAI,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC;YAAE,KAAK,IAAI,IAAI,CAAC,MAAM,CAAC;IACvE,CAAC;IAED,IAAI,SAAS,KAAK,WAAW;QAAE,KAAK,IAAI,EAAE,CAAC;IAE3C,OAAO,KAAK,CAAC;AACf,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { LoadedRoutesConfig } from './routes-config.js';
|
|
2
|
+
export interface ResolveAiRoutesOptions {
|
|
3
|
+
routes: string[];
|
|
4
|
+
routesConfig: LoadedRoutesConfig | null;
|
|
5
|
+
aiPages?: string[];
|
|
6
|
+
yes: boolean;
|
|
7
|
+
prompt?: (message: string) => Promise<string>;
|
|
8
|
+
}
|
|
9
|
+
export declare function resolveAiRoutes(options: ResolveAiRoutesOptions): Promise<string[]>;
|
|
10
|
+
export declare function confirmAiRoutes(routes: string[], promptFn?: (message: string) => Promise<string>): Promise<string[]>;
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { createInterface } from 'node:readline/promises';
|
|
2
|
+
import { stdin, stdout } from 'node:process';
|
|
3
|
+
import { logger } from '../logger.js';
|
|
4
|
+
import { isInteractiveTty } from '../prompt/is-tty.js';
|
|
5
|
+
import { assertAiRoutesSubset, normalizeRouteList } from './normalize-route-path.js';
|
|
6
|
+
export async function resolveAiRoutes(options) {
|
|
7
|
+
const { routes, routesConfig } = options;
|
|
8
|
+
if (options.aiPages && options.aiPages.length > 0) {
|
|
9
|
+
const aiRoutes = normalizeRouteList(options.aiPages);
|
|
10
|
+
assertAiRoutesSubset(routes, aiRoutes);
|
|
11
|
+
return aiRoutes;
|
|
12
|
+
}
|
|
13
|
+
if (routesConfig?.aiRoutes) {
|
|
14
|
+
assertAiRoutesSubset(routes, routesConfig.aiRoutes);
|
|
15
|
+
return routesConfig.aiRoutes;
|
|
16
|
+
}
|
|
17
|
+
if (isInteractiveTty() && !options.yes) {
|
|
18
|
+
return confirmAiRoutes(routes, options.prompt);
|
|
19
|
+
}
|
|
20
|
+
return ['/'];
|
|
21
|
+
}
|
|
22
|
+
export async function confirmAiRoutes(routes, promptFn) {
|
|
23
|
+
const selected = new Set([findDefaultIndex(routes)]);
|
|
24
|
+
logger.info('');
|
|
25
|
+
logger.info(`发现 ${routes.length} 条路由:`);
|
|
26
|
+
printRouteList(routes, selected);
|
|
27
|
+
const prompt = promptFn ?? defaultPrompt;
|
|
28
|
+
const input = await prompt('请选择要生成 AI 标注的页面(逗号分隔序号,回车=当前勾选): ');
|
|
29
|
+
applySelectionInput(input, routes.length, selected);
|
|
30
|
+
printRouteList(routes, selected);
|
|
31
|
+
const aiRoutes = [...selected]
|
|
32
|
+
.sort((left, right) => left - right)
|
|
33
|
+
.map((index) => routes[index - 1])
|
|
34
|
+
.filter((route) => Boolean(route));
|
|
35
|
+
return aiRoutes.length > 0 ? aiRoutes : ['/'];
|
|
36
|
+
}
|
|
37
|
+
function findDefaultIndex(routes) {
|
|
38
|
+
const rootIndex = routes.findIndex((route) => route === '/');
|
|
39
|
+
return rootIndex >= 0 ? rootIndex + 1 : 1;
|
|
40
|
+
}
|
|
41
|
+
function printRouteList(routes, selected) {
|
|
42
|
+
routes.forEach((route, index) => {
|
|
43
|
+
const marker = selected.has(index + 1) ? 'x' : ' ';
|
|
44
|
+
logger.info(` [${marker}] ${index + 1}. ${route}`);
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
function applySelectionInput(input, routeCount, selected) {
|
|
48
|
+
const trimmed = input.trim();
|
|
49
|
+
if (!trimmed) {
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
selected.clear();
|
|
53
|
+
for (const part of trimmed.split(',')) {
|
|
54
|
+
const index = Number.parseInt(part.trim(), 10);
|
|
55
|
+
if (Number.isNaN(index) || index < 1 || index > routeCount) {
|
|
56
|
+
throw new Error(`无效序号:${part.trim()}(有效范围 1-${routeCount})`);
|
|
57
|
+
}
|
|
58
|
+
selected.add(index);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
async function defaultPrompt(message) {
|
|
62
|
+
const rl = createInterface({ input: stdin, output: stdout });
|
|
63
|
+
try {
|
|
64
|
+
return await rl.question(`${message} `);
|
|
65
|
+
}
|
|
66
|
+
finally {
|
|
67
|
+
rl.close();
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=confirm-ai-routes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"confirm-ai-routes.js","sourceRoot":"","sources":["../../../src/lib/routes/confirm-ai-routes.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { normalizeRouteList } from './normalize-route-path.js';
|
|
2
|
+
export async function crawlInternalLinks(browser, baseUrl, options = {}) {
|
|
3
|
+
const page = await browser.newPage({ viewport: { width: 1440, height: 1000 } });
|
|
4
|
+
try {
|
|
5
|
+
await page.goto(`${trimTrailingSlash(baseUrl)}/`, { waitUntil: 'networkidle' });
|
|
6
|
+
const hrefs = await page.$$eval('a[href]', (anchors) => anchors.map((anchor) => anchor.getAttribute('href') ?? ''));
|
|
7
|
+
const origin = new URL(baseUrl).origin;
|
|
8
|
+
const discovered = ['/'];
|
|
9
|
+
for (const href of hrefs) {
|
|
10
|
+
const path = hrefToPath(href, origin);
|
|
11
|
+
if (path) {
|
|
12
|
+
discovered.push(path);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
return normalizeRouteList(discovered, { maxPages: options.maxPages });
|
|
16
|
+
}
|
|
17
|
+
finally {
|
|
18
|
+
await page.close();
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
function hrefToPath(href, origin) {
|
|
22
|
+
const trimmed = href.trim();
|
|
23
|
+
if (!trimmed || trimmed.startsWith('#') || trimmed.startsWith('mailto:') || trimmed.startsWith('javascript:')) {
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
try {
|
|
27
|
+
const url = trimmed.startsWith('/')
|
|
28
|
+
? new URL(trimmed, origin)
|
|
29
|
+
: new URL(trimmed);
|
|
30
|
+
if (url.origin !== origin) {
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
return url.pathname + url.search;
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
function trimTrailingSlash(url) {
|
|
40
|
+
return url.endsWith('/') ? url.slice(0, -1) : url;
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=crawl-internal-links.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crawl-internal-links.js","sourceRoot":"","sources":["../../../src/lib/routes/crawl-internal-links.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAE/D,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,OAAgB,EAChB,OAAe,EACf,UAAiC,EAAE;IAEnC,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,EAAE,QAAQ,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC;IAEhF,IAAI,CAAC;QACH,MAAM,IAAI,CAAC,IAAI,CAAC,GAAG,iBAAiB,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,aAAa,EAAE,CAAC,CAAC;QAEhF,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,OAAO,EAAE,EAAE,CACrD,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAC3D,CAAC;QAEF,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC;QACvC,MAAM,UAAU,GAAa,CAAC,GAAG,CAAC,CAAC;QAEnC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,MAAM,IAAI,GAAG,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;YACtC,IAAI,IAAI,EAAE,CAAC;gBACT,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACxB,CAAC;QACH,CAAC;QAED,OAAO,kBAAkB,CAAC,UAAU,EAAE,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;IACxE,CAAC;YAAS,CAAC;QACT,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC;IACrB,CAAC;AACH,CAAC;AAED,SAAS,UAAU,CAAC,IAAY,EAAE,MAAc;IAC9C,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;IAC5B,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,EAAE,CAAC;QAC9G,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC;YACjC,CAAC,CAAC,IAAI,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC;YAC1B,CAAC,CAAC,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC;QAErB,IAAI,GAAG,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;YAC1B,OAAO,IAAI,CAAC;QACd,CAAC;QAED,OAAO,GAAG,CAAC,QAAQ,GAAG,GAAG,CAAC,MAAM,CAAC;IACnC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,SAAS,iBAAiB,CAAC,GAAW;IACpC,OAAO,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;AACpD,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export declare function normalizeRoutePath(input: string): string | null;
|
|
2
|
+
export declare function normalizeRouteList(routes: string[], options?: {
|
|
3
|
+
maxPages?: number;
|
|
4
|
+
}): string[];
|
|
5
|
+
export declare function assertAiRoutesSubset(routes: string[], aiRoutes: string[]): void;
|