{"version":3,"file":"https-hooks.mjs","sources":["../../../src/packages/https-hooks.mts"],"sourcesContent":["import { get as httpGet } from \"node:http\";\nimport { get } from \"node:https\";\n\n/**\n * Node.js module loader hooks that enable importing from HTTP/HTTPS URLs.\n * See: https://nodejs.org/docs/latest-v24.x/api/module.html#import-from-https\n */\n\ntype ResolveContext = { parentURL?: string; conditions?: string[] };\ntype ResolveResult = {\n  url: string;\n  shortCircuit?: boolean;\n  format?: string;\n};\ntype NextResolve = (\n  specifier: string,\n  context: ResolveContext,\n) => Promise<ResolveResult>;\n\ntype LoadContext = { format?: string };\ntype LoadResult = { format: string; shortCircuit?: boolean; source: string };\ntype NextLoad = (url: string, context: LoadContext) => Promise<LoadResult>;\n\n/**\n * Resolve hook: resolves relative specifiers against HTTP/HTTPS parent URLs.\n */\nexport async function resolve(\n  specifier: string,\n  context: ResolveContext,\n  nextResolve: NextResolve,\n): Promise<ResolveResult> {\n  const { parentURL } = context;\n\n  // If the specifier is already an HTTP(S) URL, resolve it directly\n  if (specifier.startsWith(\"https://\") || specifier.startsWith(\"http://\")) {\n    return { url: specifier, shortCircuit: true, format: \"module\" };\n  }\n\n  // If the parent is an HTTP(S) URL and specifier is relative, resolve against it.\n  // Only handle relative specifiers (./ or ../), not bare package specifiers.\n  if (\n    parentURL &&\n    (parentURL.startsWith(\"https://\") || parentURL.startsWith(\"http://\")) &&\n    (specifier.startsWith(\"./\") || specifier.startsWith(\"../\"))\n  ) {\n    const resolved = new URL(specifier, parentURL).href;\n    return { url: resolved, shortCircuit: true, format: \"module\" };\n  }\n\n  // Bare specifiers from HTTP modules need a node_modules root to resolve\n  // against. Under pnpm's strict isolation the deps a registry-built bundle\n  // needs split into two classes:\n  //   - Peer deps the *consumer* declared (react, react-dom, graphql, …) —\n  //     live at the consumer project root.\n  //   - Things reactor-api keeps external by design (the reactor-api package\n  //     itself, for class identity; internal helpers) — live in reactor-api's\n  //     own tree.\n  // Neither root sees the other under strict mode, so try the consumer first\n  // (its declared peers win on version) and fall back to reactor-api's tree.\n  //\n  // At this point: specifier is not an http(s):// URL (branch 1) and not\n  // relative (branch 2). Only redirect bare package specifiers; let absolute\n  // paths and other URL schemes (e.g. \"node:fs\", \"file://…\") fall through.\n  if (\n    parentURL &&\n    (parentURL.startsWith(\"https://\") || parentURL.startsWith(\"http://\"))\n  ) {\n    const isBareSpecifier =\n      !specifier.startsWith(\"/\") && !/^[a-z][a-z0-9+.-]*:/i.test(specifier);\n    if (isBareSpecifier) {\n      const { pathToFileURL } = await import(\"node:url\");\n      const consumerRoot = pathToFileURL(process.cwd() + \"/\").href;\n      try {\n        return await nextResolve(specifier, {\n          ...context,\n          parentURL: consumerRoot,\n        });\n      } catch (e) {\n        const code = (e as NodeJS.ErrnoException | undefined)?.code;\n        if (code !== \"ERR_MODULE_NOT_FOUND\") throw e;\n        return nextResolve(specifier, {\n          ...context,\n          parentURL: import.meta.url,\n        });\n      }\n    }\n  }\n\n  // Let Node.js handle all other specifiers\n  return nextResolve(specifier, context);\n}\n\n/**\n * Load hook: fetches module source from HTTP/HTTPS URLs.\n */\nexport async function load(\n  url: string,\n  context: LoadContext,\n  nextLoad: NextLoad,\n): Promise<LoadResult> {\n  // Handle HTTPS URLs\n  if (url.startsWith(\"https://\")) {\n    const source = await fetchModule(url, get);\n    return {\n      format: \"module\",\n      shortCircuit: true,\n      source: patchCreateRequire(source),\n    };\n  }\n\n  // Handle HTTP URLs (for local development)\n  if (url.startsWith(\"http://\")) {\n    const source = await fetchModule(url, httpGet);\n    return {\n      format: \"module\",\n      shortCircuit: true,\n      source: patchCreateRequire(source),\n    };\n  }\n\n  // Let Node.js handle all other URLs\n  return nextLoad(url, context);\n}\n\n/**\n * Rewrite `createRequire(import.meta.url)` in HTTP-loaded modules so that\n * `createRequire` receives a local file URL instead of an HTTP URL it cannot handle.\n */\nfunction patchCreateRequire(source: string): string {\n  return source.replace(\n    /createRequire\\(import\\.meta\\.url\\)/g,\n    `createRequire(new URL(\"file://\" + process.cwd() + \"/\"))`,\n  );\n}\n\nfunction fetchModule(\n  url: string,\n  getter: typeof get | typeof httpGet,\n): Promise<string> {\n  return new Promise((resolve, reject) => {\n    getter(url, (res) => {\n      // Handle redirects\n      if (\n        res.statusCode &&\n        res.statusCode >= 300 &&\n        res.statusCode < 400 &&\n        res.headers.location\n      ) {\n        const redirectUrl = res.headers.location;\n        const redirectGetter = redirectUrl.startsWith(\"https://\")\n          ? get\n          : httpGet;\n        fetchModule(redirectUrl, redirectGetter).then(resolve).catch(reject);\n        return;\n      }\n\n      if (res.statusCode && res.statusCode >= 400) {\n        reject(new Error(`Failed to fetch ${url}: ${res.statusCode}`));\n        return;\n      }\n\n      let data = \"\";\n      res.setEncoding(\"utf8\");\n      res.on(\"data\", (chunk) => (data += chunk));\n      res.on(\"end\", () => resolve(data));\n      res.on(\"error\", reject);\n    }).on(\"error\", reject);\n  });\n}\n\n/**\n * Path to this hooks file for use with node:module register()\n */\nexport const httpsHooksPath: string = import.meta.url;\n"],"names":["get","httpGet"],"mappings":";;;;;;;;AA0BA,eAAsB,QACpB,WACA,SACA,aACwB;CACxB,MAAM,EAAE,cAAc;AAGtB,KAAI,UAAU,WAAW,WAAW,IAAI,UAAU,WAAW,UAAU,CACrE,QAAO;EAAE,KAAK;EAAW,cAAc;EAAM,QAAQ;EAAU;AAKjE,KACE,cACC,UAAU,WAAW,WAAW,IAAI,UAAU,WAAW,UAAU,MACnE,UAAU,WAAW,KAAK,IAAI,UAAU,WAAW,MAAM,EAG1D,QAAO;EAAE,KADQ,IAAI,IAAI,WAAW,UAAU,CAAC;EACvB,cAAc;EAAM,QAAQ;EAAU;AAiBhE,KACE,cACC,UAAU,WAAW,WAAW,IAAI,UAAU,WAAW,UAAU;MAGlE,CAAC,UAAU,WAAW,IAAI,IAAI,CAAC,uBAAuB,KAAK,UAAU,EAClD;GACnB,MAAM,EAAE,kBAAkB,MAAM,OAAO;GACvC,MAAM,eAAe,cAAc,QAAQ,KAAK,GAAG,IAAI,CAAC;AACxD,OAAI;AACF,WAAO,MAAM,YAAY,WAAW;KAClC,GAAG;KACH,WAAW;KACZ,CAAC;YACK,GAAG;AAEV,QADc,GAAyC,SAC1C,uBAAwB,OAAM;AAC3C,WAAO,YAAY,WAAW;KAC5B,GAAG;KACH,WAAW,OAAO,KAAK;KACxB,CAAC;;;;AAMR,QAAO,YAAY,WAAW,QAAQ;;;;;AAMxC,eAAsB,KACpB,KACA,SACA,UACqB;AAErB,KAAI,IAAI,WAAW,WAAW,CAE5B,QAAO;EACL,QAAQ;EACR,cAAc;EACd,QAAQ,mBAJK,MAAM,YAAY,KAAKA,MAAI,CAIN;EACnC;AAIH,KAAI,IAAI,WAAW,UAAU,CAE3B,QAAO;EACL,QAAQ;EACR,cAAc;EACd,QAAQ,mBAJK,MAAM,YAAY,KAAKC,IAAQ,CAIV;EACnC;AAIH,QAAO,SAAS,KAAK,QAAQ;;;;;;AAO/B,SAAS,mBAAmB,QAAwB;AAClD,QAAO,OAAO,QACZ,uCACA,0DACD;;AAGH,SAAS,YACP,KACA,QACiB;AACjB,QAAO,IAAI,SAAS,SAAS,WAAW;AACtC,SAAO,MAAM,QAAQ;AAEnB,OACE,IAAI,cACJ,IAAI,cAAc,OAClB,IAAI,aAAa,OACjB,IAAI,QAAQ,UACZ;IACA,MAAM,cAAc,IAAI,QAAQ;AAIhC,gBAAY,aAHW,YAAY,WAAW,WAAW,GACrDD,QACAC,IACoC,CAAC,KAAK,QAAQ,CAAC,MAAM,OAAO;AACpE;;AAGF,OAAI,IAAI,cAAc,IAAI,cAAc,KAAK;AAC3C,2BAAO,IAAI,MAAM,mBAAmB,IAAI,IAAI,IAAI,aAAa,CAAC;AAC9D;;GAGF,IAAI,OAAO;AACX,OAAI,YAAY,OAAO;AACvB,OAAI,GAAG,SAAS,UAAW,QAAQ,MAAO;AAC1C,OAAI,GAAG,aAAa,QAAQ,KAAK,CAAC;AAClC,OAAI,GAAG,SAAS,OAAO;IACvB,CAAC,GAAG,SAAS,OAAO;GACtB;;;;;AAMJ,MAAa,iBAAyB,OAAO,KAAK","debug_id":"0a57348f-eab9-5103-83ff-b067482a7ea8"}