@agent-scope/cli 1.16.0 → 1.17.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/cli.js +236 -120
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +191 -81
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +193 -83
- package/dist/index.js.map +1 -1
- package/package.json +7 -6
package/dist/index.cjs
CHANGED
|
@@ -9,8 +9,10 @@ var commander = require('commander');
|
|
|
9
9
|
var esbuild = require('esbuild');
|
|
10
10
|
var module$1 = require('module');
|
|
11
11
|
var readline = require('readline');
|
|
12
|
-
var playwright$1 = require('playwright');
|
|
13
12
|
var playwright = require('@agent-scope/playwright');
|
|
13
|
+
var playwright$1 = require('playwright');
|
|
14
|
+
var http = require('http');
|
|
15
|
+
var site = require('@agent-scope/site');
|
|
14
16
|
|
|
15
17
|
function _interopNamespace(e) {
|
|
16
18
|
if (e && e.__esModule) return e;
|
|
@@ -1130,9 +1132,9 @@ function createRL() {
|
|
|
1130
1132
|
});
|
|
1131
1133
|
}
|
|
1132
1134
|
async function ask(rl, question) {
|
|
1133
|
-
return new Promise((
|
|
1135
|
+
return new Promise((resolve17) => {
|
|
1134
1136
|
rl.question(question, (answer) => {
|
|
1135
|
-
|
|
1137
|
+
resolve17(answer.trim());
|
|
1136
1138
|
});
|
|
1137
1139
|
});
|
|
1138
1140
|
}
|
|
@@ -1704,6 +1706,7 @@ async function runHooksProfiling(componentName, filePath, props) {
|
|
|
1704
1706
|
try {
|
|
1705
1707
|
const context = await browser.newContext();
|
|
1706
1708
|
const page = await context.newPage();
|
|
1709
|
+
await page.addInitScript({ content: playwright.getBrowserEntryScript() });
|
|
1707
1710
|
const htmlHarness = await buildComponentHarness(filePath, componentName, props, 1280);
|
|
1708
1711
|
await page.setContent(htmlHarness, { waitUntil: "load" });
|
|
1709
1712
|
await page.waitForFunction(
|
|
@@ -2087,24 +2090,6 @@ Available: ${available}`
|
|
|
2087
2090
|
var MANIFEST_PATH4 = ".reactscope/manifest.json";
|
|
2088
2091
|
var DEFAULT_VIEWPORT_WIDTH = 375;
|
|
2089
2092
|
var DEFAULT_VIEWPORT_HEIGHT = 812;
|
|
2090
|
-
var _pool2 = null;
|
|
2091
|
-
async function getPool2() {
|
|
2092
|
-
if (_pool2 === null) {
|
|
2093
|
-
_pool2 = new render.BrowserPool({
|
|
2094
|
-
size: { browsers: 1, pagesPerBrowser: 1 },
|
|
2095
|
-
viewportWidth: DEFAULT_VIEWPORT_WIDTH,
|
|
2096
|
-
viewportHeight: DEFAULT_VIEWPORT_HEIGHT
|
|
2097
|
-
});
|
|
2098
|
-
await _pool2.init();
|
|
2099
|
-
}
|
|
2100
|
-
return _pool2;
|
|
2101
|
-
}
|
|
2102
|
-
async function shutdownPool2() {
|
|
2103
|
-
if (_pool2 !== null) {
|
|
2104
|
-
await _pool2.close();
|
|
2105
|
-
_pool2 = null;
|
|
2106
|
-
}
|
|
2107
|
-
}
|
|
2108
2093
|
function mapNodeType(node) {
|
|
2109
2094
|
if (node.type === "forward_ref") return "forwardRef";
|
|
2110
2095
|
if (node.type === "host") return "host";
|
|
@@ -2314,10 +2299,12 @@ function formatInstrumentTree(root, showProviderDepth = false) {
|
|
|
2314
2299
|
}
|
|
2315
2300
|
async function runInstrumentTree(options) {
|
|
2316
2301
|
const { componentName, filePath } = options;
|
|
2317
|
-
const
|
|
2318
|
-
const slot = await pool.acquire();
|
|
2319
|
-
const { page } = slot;
|
|
2302
|
+
const browser = await playwright$1.chromium.launch({ headless: true });
|
|
2320
2303
|
try {
|
|
2304
|
+
const context = await browser.newContext({
|
|
2305
|
+
viewport: { width: DEFAULT_VIEWPORT_WIDTH, height: DEFAULT_VIEWPORT_HEIGHT }
|
|
2306
|
+
});
|
|
2307
|
+
const page = await context.newPage();
|
|
2321
2308
|
await page.addInitScript({ content: playwright.getBrowserEntryScript() });
|
|
2322
2309
|
const htmlHarness = await buildComponentHarness(
|
|
2323
2310
|
filePath,
|
|
@@ -2371,7 +2358,7 @@ async function runInstrumentTree(options) {
|
|
|
2371
2358
|
}
|
|
2372
2359
|
return instrumentRoot;
|
|
2373
2360
|
} finally {
|
|
2374
|
-
|
|
2361
|
+
await browser.close();
|
|
2375
2362
|
}
|
|
2376
2363
|
}
|
|
2377
2364
|
function createInstrumentTreeCommand() {
|
|
@@ -2411,7 +2398,6 @@ Available: ${available}`
|
|
|
2411
2398
|
providerDepth: opts.providerDepth,
|
|
2412
2399
|
wastedRenders: opts.wastedRenders
|
|
2413
2400
|
});
|
|
2414
|
-
await shutdownPool2();
|
|
2415
2401
|
const fmt2 = resolveFormat2(opts.format);
|
|
2416
2402
|
if (fmt2 === "json") {
|
|
2417
2403
|
process.stdout.write(`${JSON.stringify(instrumentRoot, null, 2)}
|
|
@@ -2422,7 +2408,6 @@ Available: ${available}`
|
|
|
2422
2408
|
`);
|
|
2423
2409
|
}
|
|
2424
2410
|
} catch (err) {
|
|
2425
|
-
await shutdownPool2();
|
|
2426
2411
|
process.stderr.write(`Error: ${err instanceof Error ? err.message : String(err)}
|
|
2427
2412
|
`);
|
|
2428
2413
|
process.exit(1);
|
|
@@ -2740,22 +2725,22 @@ async function replayInteraction2(page, steps) {
|
|
|
2740
2725
|
}
|
|
2741
2726
|
}
|
|
2742
2727
|
}
|
|
2743
|
-
var
|
|
2744
|
-
async function
|
|
2745
|
-
if (
|
|
2746
|
-
|
|
2728
|
+
var _pool2 = null;
|
|
2729
|
+
async function getPool2() {
|
|
2730
|
+
if (_pool2 === null) {
|
|
2731
|
+
_pool2 = new render.BrowserPool({
|
|
2747
2732
|
size: { browsers: 1, pagesPerBrowser: 2 },
|
|
2748
2733
|
viewportWidth: 1280,
|
|
2749
2734
|
viewportHeight: 800
|
|
2750
2735
|
});
|
|
2751
|
-
await
|
|
2736
|
+
await _pool2.init();
|
|
2752
2737
|
}
|
|
2753
|
-
return
|
|
2738
|
+
return _pool2;
|
|
2754
2739
|
}
|
|
2755
|
-
async function
|
|
2756
|
-
if (
|
|
2757
|
-
await
|
|
2758
|
-
|
|
2740
|
+
async function shutdownPool2() {
|
|
2741
|
+
if (_pool2 !== null) {
|
|
2742
|
+
await _pool2.close();
|
|
2743
|
+
_pool2 = null;
|
|
2759
2744
|
}
|
|
2760
2745
|
}
|
|
2761
2746
|
async function analyzeRenders(options) {
|
|
@@ -2772,7 +2757,7 @@ Available: ${available}`
|
|
|
2772
2757
|
const rootDir = process.cwd();
|
|
2773
2758
|
const filePath = path.resolve(rootDir, descriptor.filePath);
|
|
2774
2759
|
const htmlHarness = await buildComponentHarness(filePath, options.componentName, {}, 1280);
|
|
2775
|
-
const pool = await
|
|
2760
|
+
const pool = await getPool2();
|
|
2776
2761
|
const slot = await pool.acquire();
|
|
2777
2762
|
const { page } = slot;
|
|
2778
2763
|
const startMs = performance.now();
|
|
@@ -2880,7 +2865,7 @@ function createInstrumentRendersCommand() {
|
|
|
2880
2865
|
interaction,
|
|
2881
2866
|
manifestPath: opts.manifest
|
|
2882
2867
|
});
|
|
2883
|
-
await
|
|
2868
|
+
await shutdownPool2();
|
|
2884
2869
|
if (opts.json || !isTTY()) {
|
|
2885
2870
|
process.stdout.write(`${JSON.stringify(result, null, 2)}
|
|
2886
2871
|
`);
|
|
@@ -2889,7 +2874,7 @@ function createInstrumentRendersCommand() {
|
|
|
2889
2874
|
`);
|
|
2890
2875
|
}
|
|
2891
2876
|
} catch (err) {
|
|
2892
|
-
await
|
|
2877
|
+
await shutdownPool2();
|
|
2893
2878
|
process.stderr.write(`Error: ${err instanceof Error ? err.message : String(err)}
|
|
2894
2879
|
`);
|
|
2895
2880
|
process.exit(1);
|
|
@@ -2949,22 +2934,22 @@ function writeReportToFile(report, outputPath, pretty) {
|
|
|
2949
2934
|
}
|
|
2950
2935
|
var MANIFEST_PATH6 = ".reactscope/manifest.json";
|
|
2951
2936
|
var DEFAULT_OUTPUT_DIR = ".reactscope/renders";
|
|
2952
|
-
var
|
|
2953
|
-
async function
|
|
2954
|
-
if (
|
|
2955
|
-
|
|
2937
|
+
var _pool3 = null;
|
|
2938
|
+
async function getPool3(viewportWidth, viewportHeight) {
|
|
2939
|
+
if (_pool3 === null) {
|
|
2940
|
+
_pool3 = new render.BrowserPool({
|
|
2956
2941
|
size: { browsers: 1, pagesPerBrowser: 4 },
|
|
2957
2942
|
viewportWidth,
|
|
2958
2943
|
viewportHeight
|
|
2959
2944
|
});
|
|
2960
|
-
await
|
|
2945
|
+
await _pool3.init();
|
|
2961
2946
|
}
|
|
2962
|
-
return
|
|
2947
|
+
return _pool3;
|
|
2963
2948
|
}
|
|
2964
|
-
async function
|
|
2965
|
-
if (
|
|
2966
|
-
await
|
|
2967
|
-
|
|
2949
|
+
async function shutdownPool3() {
|
|
2950
|
+
if (_pool3 !== null) {
|
|
2951
|
+
await _pool3.close();
|
|
2952
|
+
_pool3 = null;
|
|
2968
2953
|
}
|
|
2969
2954
|
}
|
|
2970
2955
|
function buildRenderer(filePath, componentName, viewportWidth, viewportHeight) {
|
|
@@ -2975,7 +2960,7 @@ function buildRenderer(filePath, componentName, viewportWidth, viewportHeight) {
|
|
|
2975
2960
|
_satori: satori,
|
|
2976
2961
|
async renderCell(props, _complexityClass) {
|
|
2977
2962
|
const startMs = performance.now();
|
|
2978
|
-
const pool = await
|
|
2963
|
+
const pool = await getPool3(viewportWidth, viewportHeight);
|
|
2979
2964
|
const htmlHarness = await buildComponentHarness(
|
|
2980
2965
|
filePath,
|
|
2981
2966
|
componentName,
|
|
@@ -3111,7 +3096,7 @@ Available: ${available}`
|
|
|
3111
3096
|
}
|
|
3112
3097
|
}
|
|
3113
3098
|
);
|
|
3114
|
-
await
|
|
3099
|
+
await shutdownPool3();
|
|
3115
3100
|
if (outcome.crashed) {
|
|
3116
3101
|
process.stderr.write(`\u2717 Render failed: ${outcome.error.message}
|
|
3117
3102
|
`);
|
|
@@ -3159,7 +3144,7 @@ Available: ${available}`
|
|
|
3159
3144
|
);
|
|
3160
3145
|
}
|
|
3161
3146
|
} catch (err) {
|
|
3162
|
-
await
|
|
3147
|
+
await shutdownPool3();
|
|
3163
3148
|
process.stderr.write(`Error: ${err instanceof Error ? err.message : String(err)}
|
|
3164
3149
|
`);
|
|
3165
3150
|
process.exit(1);
|
|
@@ -3244,7 +3229,7 @@ Available: ${available}`
|
|
|
3244
3229
|
concurrency
|
|
3245
3230
|
});
|
|
3246
3231
|
const result = await matrix.render();
|
|
3247
|
-
await
|
|
3232
|
+
await shutdownPool3();
|
|
3248
3233
|
process.stderr.write(
|
|
3249
3234
|
`Done. ${result.stats.totalCells} cells, avg ${result.stats.avgRenderTimeMs.toFixed(1)}ms
|
|
3250
3235
|
`
|
|
@@ -3289,7 +3274,7 @@ Available: ${available}`
|
|
|
3289
3274
|
process.stdout.write(formatMatrixCsv(componentName, result));
|
|
3290
3275
|
}
|
|
3291
3276
|
} catch (err) {
|
|
3292
|
-
await
|
|
3277
|
+
await shutdownPool3();
|
|
3293
3278
|
process.stderr.write(`Error: ${err instanceof Error ? err.message : String(err)}
|
|
3294
3279
|
`);
|
|
3295
3280
|
process.exit(1);
|
|
@@ -3386,13 +3371,13 @@ function registerRenderAll(renderCmd) {
|
|
|
3386
3371
|
workers.push(worker());
|
|
3387
3372
|
}
|
|
3388
3373
|
await Promise.all(workers);
|
|
3389
|
-
await
|
|
3374
|
+
await shutdownPool3();
|
|
3390
3375
|
process.stderr.write("\n");
|
|
3391
3376
|
const summary = formatSummaryText(results, outputDir);
|
|
3392
3377
|
process.stderr.write(`${summary}
|
|
3393
3378
|
`);
|
|
3394
3379
|
} catch (err) {
|
|
3395
|
-
await
|
|
3380
|
+
await shutdownPool3();
|
|
3396
3381
|
process.stderr.write(`Error: ${err instanceof Error ? err.message : String(err)}
|
|
3397
3382
|
`);
|
|
3398
3383
|
process.exit(1);
|
|
@@ -3434,26 +3419,26 @@ function createRenderCommand() {
|
|
|
3434
3419
|
return renderCmd;
|
|
3435
3420
|
}
|
|
3436
3421
|
var DEFAULT_BASELINE_DIR = ".reactscope/baseline";
|
|
3437
|
-
var
|
|
3438
|
-
async function
|
|
3439
|
-
if (
|
|
3440
|
-
|
|
3422
|
+
var _pool4 = null;
|
|
3423
|
+
async function getPool4(viewportWidth, viewportHeight) {
|
|
3424
|
+
if (_pool4 === null) {
|
|
3425
|
+
_pool4 = new render.BrowserPool({
|
|
3441
3426
|
size: { browsers: 1, pagesPerBrowser: 4 },
|
|
3442
3427
|
viewportWidth,
|
|
3443
3428
|
viewportHeight
|
|
3444
3429
|
});
|
|
3445
|
-
await
|
|
3430
|
+
await _pool4.init();
|
|
3446
3431
|
}
|
|
3447
|
-
return
|
|
3432
|
+
return _pool4;
|
|
3448
3433
|
}
|
|
3449
|
-
async function
|
|
3450
|
-
if (
|
|
3451
|
-
await
|
|
3452
|
-
|
|
3434
|
+
async function shutdownPool4() {
|
|
3435
|
+
if (_pool4 !== null) {
|
|
3436
|
+
await _pool4.close();
|
|
3437
|
+
_pool4 = null;
|
|
3453
3438
|
}
|
|
3454
3439
|
}
|
|
3455
3440
|
async function renderComponent2(filePath, componentName, props, viewportWidth, viewportHeight) {
|
|
3456
|
-
const pool = await
|
|
3441
|
+
const pool = await getPool4(viewportWidth, viewportHeight);
|
|
3457
3442
|
const htmlHarness = await buildComponentHarness(filePath, componentName, props, viewportWidth);
|
|
3458
3443
|
const slot = await pool.acquire();
|
|
3459
3444
|
const { page } = slot;
|
|
@@ -3703,7 +3688,7 @@ async function runBaseline(options = {}) {
|
|
|
3703
3688
|
workers.push(worker());
|
|
3704
3689
|
}
|
|
3705
3690
|
await Promise.all(workers);
|
|
3706
|
-
await
|
|
3691
|
+
await shutdownPool4();
|
|
3707
3692
|
if (isTTY()) {
|
|
3708
3693
|
process.stderr.write("\n");
|
|
3709
3694
|
}
|
|
@@ -3764,26 +3749,26 @@ function loadBaselineRenderJson2(baselineDir, componentName) {
|
|
|
3764
3749
|
if (!fs.existsSync(jsonPath)) return null;
|
|
3765
3750
|
return JSON.parse(fs.readFileSync(jsonPath, "utf-8"));
|
|
3766
3751
|
}
|
|
3767
|
-
var
|
|
3768
|
-
async function
|
|
3769
|
-
if (
|
|
3770
|
-
|
|
3752
|
+
var _pool5 = null;
|
|
3753
|
+
async function getPool5(viewportWidth, viewportHeight) {
|
|
3754
|
+
if (_pool5 === null) {
|
|
3755
|
+
_pool5 = new render.BrowserPool({
|
|
3771
3756
|
size: { browsers: 1, pagesPerBrowser: 4 },
|
|
3772
3757
|
viewportWidth,
|
|
3773
3758
|
viewportHeight
|
|
3774
3759
|
});
|
|
3775
|
-
await
|
|
3760
|
+
await _pool5.init();
|
|
3776
3761
|
}
|
|
3777
|
-
return
|
|
3762
|
+
return _pool5;
|
|
3778
3763
|
}
|
|
3779
|
-
async function
|
|
3780
|
-
if (
|
|
3781
|
-
await
|
|
3782
|
-
|
|
3764
|
+
async function shutdownPool5() {
|
|
3765
|
+
if (_pool5 !== null) {
|
|
3766
|
+
await _pool5.close();
|
|
3767
|
+
_pool5 = null;
|
|
3783
3768
|
}
|
|
3784
3769
|
}
|
|
3785
3770
|
async function renderComponent3(filePath, componentName, props, viewportWidth, viewportHeight) {
|
|
3786
|
-
const pool = await
|
|
3771
|
+
const pool = await getPool5(viewportWidth, viewportHeight);
|
|
3787
3772
|
const htmlHarness = await buildComponentHarness(filePath, componentName, props, viewportWidth);
|
|
3788
3773
|
const slot = await pool.acquire();
|
|
3789
3774
|
const { page } = slot;
|
|
@@ -4032,7 +4017,7 @@ async function runDiff(options = {}) {
|
|
|
4032
4017
|
}
|
|
4033
4018
|
await Promise.all(workers);
|
|
4034
4019
|
}
|
|
4035
|
-
await
|
|
4020
|
+
await shutdownPool5();
|
|
4036
4021
|
if (isTTY() && total > 0) {
|
|
4037
4022
|
process.stderr.write("\n");
|
|
4038
4023
|
}
|
|
@@ -4632,6 +4617,130 @@ function buildStructuredReport(report) {
|
|
|
4632
4617
|
route: report.route?.pattern ?? null
|
|
4633
4618
|
};
|
|
4634
4619
|
}
|
|
4620
|
+
var MIME_TYPES = {
|
|
4621
|
+
".html": "text/html; charset=utf-8",
|
|
4622
|
+
".css": "text/css; charset=utf-8",
|
|
4623
|
+
".js": "application/javascript; charset=utf-8",
|
|
4624
|
+
".json": "application/json; charset=utf-8",
|
|
4625
|
+
".png": "image/png",
|
|
4626
|
+
".jpg": "image/jpeg",
|
|
4627
|
+
".jpeg": "image/jpeg",
|
|
4628
|
+
".svg": "image/svg+xml",
|
|
4629
|
+
".ico": "image/x-icon"
|
|
4630
|
+
};
|
|
4631
|
+
function registerBuild(siteCmd) {
|
|
4632
|
+
siteCmd.command("build").description("Build a static HTML gallery from .reactscope/ output").option("-i, --input <path>", "Path to .reactscope input directory", ".reactscope").option("-o, --output <path>", "Output directory for generated site", ".reactscope/site").option("--base-path <path>", "Base URL path prefix for subdirectory deployment", "/").option("--compliance <path>", "Path to compliance batch report JSON").option("--title <text>", "Site title", "Scope \u2014 Component Gallery").action(
|
|
4633
|
+
async (opts) => {
|
|
4634
|
+
try {
|
|
4635
|
+
const inputDir = path.resolve(process.cwd(), opts.input);
|
|
4636
|
+
const outputDir = path.resolve(process.cwd(), opts.output);
|
|
4637
|
+
if (!fs.existsSync(inputDir)) {
|
|
4638
|
+
throw new Error(
|
|
4639
|
+
`Input directory not found: ${inputDir}
|
|
4640
|
+
Run \`scope manifest generate\` and \`scope render\` first.`
|
|
4641
|
+
);
|
|
4642
|
+
}
|
|
4643
|
+
const manifestPath = path.join(inputDir, "manifest.json");
|
|
4644
|
+
if (!fs.existsSync(manifestPath)) {
|
|
4645
|
+
throw new Error(
|
|
4646
|
+
`Manifest not found at ${manifestPath}
|
|
4647
|
+
Run \`scope manifest generate\` first.`
|
|
4648
|
+
);
|
|
4649
|
+
}
|
|
4650
|
+
process.stderr.write(`Building site from ${inputDir}\u2026
|
|
4651
|
+
`);
|
|
4652
|
+
await site.buildSite({
|
|
4653
|
+
inputDir,
|
|
4654
|
+
outputDir,
|
|
4655
|
+
basePath: opts.basePath,
|
|
4656
|
+
...opts.compliance !== void 0 && {
|
|
4657
|
+
compliancePath: path.resolve(process.cwd(), opts.compliance)
|
|
4658
|
+
},
|
|
4659
|
+
title: opts.title
|
|
4660
|
+
});
|
|
4661
|
+
process.stderr.write(`Site written to ${outputDir}
|
|
4662
|
+
`);
|
|
4663
|
+
process.stdout.write(`${outputDir}
|
|
4664
|
+
`);
|
|
4665
|
+
} catch (err) {
|
|
4666
|
+
process.stderr.write(`Error: ${err instanceof Error ? err.message : String(err)}
|
|
4667
|
+
`);
|
|
4668
|
+
process.exit(1);
|
|
4669
|
+
}
|
|
4670
|
+
}
|
|
4671
|
+
);
|
|
4672
|
+
}
|
|
4673
|
+
function registerServe(siteCmd) {
|
|
4674
|
+
siteCmd.command("serve").description("Serve the built static site locally").option("-p, --port <number>", "Port to listen on", "3000").option("-d, --dir <path>", "Directory to serve", ".reactscope/site").action((opts) => {
|
|
4675
|
+
try {
|
|
4676
|
+
const port = Number.parseInt(opts.port, 10);
|
|
4677
|
+
if (Number.isNaN(port) || port < 1 || port > 65535) {
|
|
4678
|
+
throw new Error(`Invalid port: ${opts.port}`);
|
|
4679
|
+
}
|
|
4680
|
+
const serveDir = path.resolve(process.cwd(), opts.dir);
|
|
4681
|
+
if (!fs.existsSync(serveDir)) {
|
|
4682
|
+
throw new Error(
|
|
4683
|
+
`Serve directory not found: ${serveDir}
|
|
4684
|
+
Run \`scope site build\` first.`
|
|
4685
|
+
);
|
|
4686
|
+
}
|
|
4687
|
+
const server = http.createServer((req, res) => {
|
|
4688
|
+
const rawUrl = req.url ?? "/";
|
|
4689
|
+
const urlPath = decodeURIComponent(rawUrl.split("?")[0] ?? "/");
|
|
4690
|
+
const filePath = path.join(serveDir, urlPath.endsWith("/") ? `${urlPath}index.html` : urlPath);
|
|
4691
|
+
if (!filePath.startsWith(serveDir)) {
|
|
4692
|
+
res.writeHead(403, { "Content-Type": "text/plain" });
|
|
4693
|
+
res.end("Forbidden");
|
|
4694
|
+
return;
|
|
4695
|
+
}
|
|
4696
|
+
if (fs.existsSync(filePath) && fs.statSync(filePath).isFile()) {
|
|
4697
|
+
const ext = path.extname(filePath).toLowerCase();
|
|
4698
|
+
const contentType = MIME_TYPES[ext] ?? "application/octet-stream";
|
|
4699
|
+
res.writeHead(200, { "Content-Type": contentType });
|
|
4700
|
+
fs.createReadStream(filePath).pipe(res);
|
|
4701
|
+
return;
|
|
4702
|
+
}
|
|
4703
|
+
const htmlPath = `${filePath}.html`;
|
|
4704
|
+
if (fs.existsSync(htmlPath) && fs.statSync(htmlPath).isFile()) {
|
|
4705
|
+
res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
|
|
4706
|
+
fs.createReadStream(htmlPath).pipe(res);
|
|
4707
|
+
return;
|
|
4708
|
+
}
|
|
4709
|
+
res.writeHead(404, { "Content-Type": "text/plain" });
|
|
4710
|
+
res.end(`Not found: ${urlPath}`);
|
|
4711
|
+
});
|
|
4712
|
+
server.listen(port, () => {
|
|
4713
|
+
process.stderr.write(`Scope site running at http://localhost:${port}
|
|
4714
|
+
`);
|
|
4715
|
+
process.stderr.write(`Serving ${serveDir}
|
|
4716
|
+
`);
|
|
4717
|
+
process.stderr.write("Press Ctrl+C to stop.\n");
|
|
4718
|
+
});
|
|
4719
|
+
server.on("error", (err) => {
|
|
4720
|
+
if (err.code === "EADDRINUSE") {
|
|
4721
|
+
process.stderr.write(`Error: Port ${port} is already in use.
|
|
4722
|
+
`);
|
|
4723
|
+
} else {
|
|
4724
|
+
process.stderr.write(`Server error: ${err.message}
|
|
4725
|
+
`);
|
|
4726
|
+
}
|
|
4727
|
+
process.exit(1);
|
|
4728
|
+
});
|
|
4729
|
+
} catch (err) {
|
|
4730
|
+
process.stderr.write(`Error: ${err instanceof Error ? err.message : String(err)}
|
|
4731
|
+
`);
|
|
4732
|
+
process.exit(1);
|
|
4733
|
+
}
|
|
4734
|
+
});
|
|
4735
|
+
}
|
|
4736
|
+
function createSiteCommand() {
|
|
4737
|
+
const siteCmd = new commander.Command("site").description(
|
|
4738
|
+
"Build and serve the static component gallery site"
|
|
4739
|
+
);
|
|
4740
|
+
registerBuild(siteCmd);
|
|
4741
|
+
registerServe(siteCmd);
|
|
4742
|
+
return siteCmd;
|
|
4743
|
+
}
|
|
4635
4744
|
var DEFAULT_STYLES_PATH = ".reactscope/compliance-styles.json";
|
|
4636
4745
|
function loadStylesFile(stylesPath) {
|
|
4637
4746
|
const absPath = path.resolve(process.cwd(), stylesPath);
|
|
@@ -5651,6 +5760,7 @@ function createProgram(options = {}) {
|
|
|
5651
5760
|
registerDiffSubCommand(existingReportCmd);
|
|
5652
5761
|
registerPrCommentSubCommand(existingReportCmd);
|
|
5653
5762
|
}
|
|
5763
|
+
program.addCommand(createSiteCommand());
|
|
5654
5764
|
return program;
|
|
5655
5765
|
}
|
|
5656
5766
|
|