@xdsjs/dossierx-daemon 0.1.15 → 0.1.17

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.
Files changed (2) hide show
  1. package/dist/index.js +115 -12
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -2290,7 +2290,7 @@ function createTaskArchive(options) {
2290
2290
 
2291
2291
  // src/version.ts
2292
2292
  var DAEMON_PACKAGE_NAME = "@xdsjs/dossierx-daemon";
2293
- var DAEMON_VERSION = "0.1.15";
2293
+ var DAEMON_VERSION = "0.1.17";
2294
2294
 
2295
2295
  // src/local-api/server.ts
2296
2296
  var DEFAULT_MAX_FILE_BYTES = 5 * 1024 * 1024;
@@ -2300,18 +2300,58 @@ function json(response, status, body, origin) {
2300
2300
  response.writeHead(status, {
2301
2301
  "content-type": "application/json; charset=utf-8",
2302
2302
  ...origin ? { "access-control-allow-origin": origin } : {},
2303
+ ...origin ? { "access-control-allow-private-network": "true" } : {},
2303
2304
  "access-control-allow-methods": "GET, POST, OPTIONS",
2304
2305
  "access-control-allow-headers": "content-type",
2305
2306
  vary: "Origin"
2306
2307
  });
2307
2308
  response.end(JSON.stringify(body));
2308
2309
  }
2310
+ function vercelProjectNameFromAllowedOrigin(origin) {
2311
+ try {
2312
+ const url = new URL(origin);
2313
+ if (url.protocol !== "https:" || !url.hostname.endsWith(".vercel.app")) {
2314
+ return null;
2315
+ }
2316
+ const label = url.hostname.slice(0, -".vercel.app".length);
2317
+ for (const suffix of ["-beta", "-production", "-prod", "-preview", "-staging"]) {
2318
+ if (label.endsWith(suffix) && label.length > suffix.length) {
2319
+ return label.slice(0, -suffix.length);
2320
+ }
2321
+ }
2322
+ return label;
2323
+ } catch {
2324
+ return null;
2325
+ }
2326
+ }
2327
+ function isVercelDeploymentOriginAllowed(origin, allowedOrigins) {
2328
+ let requested;
2329
+ try {
2330
+ requested = new URL(origin);
2331
+ } catch {
2332
+ return false;
2333
+ }
2334
+ if (requested.protocol !== "https:" || !requested.hostname.endsWith(".vercel.app")) {
2335
+ return false;
2336
+ }
2337
+ const requestedLabel = requested.hostname.slice(0, -".vercel.app".length);
2338
+ return allowedOrigins.some((allowedOriginValue) => {
2339
+ const projectName = vercelProjectNameFromAllowedOrigin(allowedOriginValue);
2340
+ if (!projectName) {
2341
+ return false;
2342
+ }
2343
+ const deploymentPattern = new RegExp(
2344
+ `^${projectName.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}-[a-z0-9]+-[a-z0-9-]+$`
2345
+ );
2346
+ return requestedLabel === projectName || deploymentPattern.test(requestedLabel);
2347
+ });
2348
+ }
2309
2349
  function allowedOrigin(request, allowedOrigins) {
2310
2350
  const origin = request.headers.origin;
2311
2351
  if (!origin) {
2312
2352
  return "";
2313
2353
  }
2314
- return allowedOrigins.includes(origin) ? origin : null;
2354
+ return allowedOrigins.includes(origin) || isVercelDeploymentOriginAllowed(origin, allowedOrigins) ? origin : null;
2315
2355
  }
2316
2356
  function requestUrl(request) {
2317
2357
  return new URL(request.url ?? "/", "http://127.0.0.1");
@@ -2544,16 +2584,40 @@ async function startWorkspaceReadServer(options) {
2544
2584
  const taskArchive = options.taskArchive ?? createTaskArchive({ workspaceRoot: options.workspaceRoot });
2545
2585
  const server = createServer((request, response) => {
2546
2586
  void (async () => {
2587
+ const url = requestUrl(request);
2547
2588
  const origin = allowedOrigin(request, options.allowedOrigins);
2548
2589
  if (origin === null) {
2590
+ if (url.pathname === "/workspace/manifest") {
2591
+ console.warn(
2592
+ JSON.stringify({
2593
+ msg: "workspace manifest cors rejected",
2594
+ origin: request.headers.origin ?? null,
2595
+ requestedMethod: request.headers["access-control-request-method"] ?? null,
2596
+ requestedPrivateNetwork: request.headers["access-control-request-private-network"] ?? null,
2597
+ status: 403,
2598
+ error: "Origin not allowed"
2599
+ })
2600
+ );
2601
+ }
2549
2602
  json(response, 403, { error: "Origin not allowed" });
2550
2603
  return;
2551
2604
  }
2552
2605
  if (request.method === "OPTIONS") {
2606
+ if (url.pathname === "/workspace/manifest") {
2607
+ console.info(
2608
+ JSON.stringify({
2609
+ msg: "workspace manifest preflight served",
2610
+ origin,
2611
+ requestedMethod: request.headers["access-control-request-method"] ?? null,
2612
+ requestedPrivateNetwork: request.headers["access-control-request-private-network"] ?? null,
2613
+ status: 204,
2614
+ allowPrivateNetwork: true
2615
+ })
2616
+ );
2617
+ }
2553
2618
  json(response, 204, {}, origin);
2554
2619
  return;
2555
2620
  }
2556
- const url = requestUrl(request);
2557
2621
  if (request.method === "GET" && url.pathname === "/runtime/codex") {
2558
2622
  json(
2559
2623
  response,
@@ -2613,26 +2677,65 @@ async function startWorkspaceReadServer(options) {
2613
2677
  const ticker = url.searchParams.get("ticker");
2614
2678
  const market = url.searchParams.get("market");
2615
2679
  if (!ticker || !market) {
2680
+ console.warn(
2681
+ JSON.stringify({
2682
+ msg: "workspace manifest request rejected",
2683
+ origin,
2684
+ ticker,
2685
+ market,
2686
+ status: 400,
2687
+ error: "Missing ticker or market"
2688
+ })
2689
+ );
2616
2690
  json(response, 400, { error: "Missing ticker or market" }, origin);
2617
2691
  return;
2618
2692
  }
2619
2693
  try {
2620
- json(
2621
- response,
2622
- 200,
2623
- await readCompanyManifest({
2624
- workspaceRoot: options.workspaceRoot,
2694
+ const body = await readCompanyManifest({
2695
+ workspaceRoot: options.workspaceRoot,
2696
+ ticker,
2697
+ market
2698
+ });
2699
+ const paths = body.manifest.pages.map((page) => page.path);
2700
+ console.info(
2701
+ JSON.stringify({
2702
+ msg: "workspace manifest served",
2703
+ origin,
2625
2704
  ticker,
2626
- market
2627
- }),
2628
- origin
2705
+ market,
2706
+ status: 200,
2707
+ pageCount: paths.length,
2708
+ hasNotebook: paths.some(
2709
+ (item) => item.endsWith("/financial-reports/notebooklm/notebook.json")
2710
+ ),
2711
+ hasFactsBundle: paths.some(
2712
+ (item) => item.endsWith("/financial-reports/ingest/facts-bundle.json")
2713
+ ),
2714
+ hasFinancialWiki: paths.some(
2715
+ (item) => item.endsWith(
2716
+ "/financial-reports/wiki/financial-report-analysis.md"
2717
+ )
2718
+ )
2719
+ })
2629
2720
  );
2721
+ json(response, 200, body, origin);
2630
2722
  } catch (error) {
2723
+ const message = error instanceof Error ? error.message : "Workspace manifest failed";
2724
+ console.warn(
2725
+ JSON.stringify({
2726
+ msg: "workspace manifest request failed",
2727
+ origin,
2728
+ ticker,
2729
+ market,
2730
+ status: 400,
2731
+ error: message
2732
+ })
2733
+ );
2631
2734
  json(
2632
2735
  response,
2633
2736
  400,
2634
2737
  {
2635
- error: error instanceof Error ? error.message : "Workspace manifest failed"
2738
+ error: message
2636
2739
  },
2637
2740
  origin
2638
2741
  );
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xdsjs/dossierx-daemon",
3
- "version": "0.1.15",
3
+ "version": "0.1.17",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",