@lunora/browser 1.0.0-alpha.40 → 1.0.0-alpha.41

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/index.mjs CHANGED
@@ -1 +1 @@
1
- import{createBrowser as o}from"./packem_shared/createBrowser-CN6x72HL.mjs";export{o as createBrowser};
1
+ import{createBrowser as o}from"./packem_shared/createBrowser-D8ukzAIM.mjs";export{o as createBrowser};
@@ -1 +1 @@
1
- import{LunoraError as u}from"@lunora/errors";const x=/^\d{1,3}$/u,C=/^::ffff:([\da-f]{1,4}):([\da-f]{1,4})$/u,F=/^::ffff:(\d{1,3}(?:\.\d{1,3}){3})$/u,X=/^::(\d{1,3}(?:\.\d{1,3}){3})$/u,Q=/^::([\da-f]{1,4}):([\da-f]{1,4})$/u,z=/^64:ff9b::[\da-f]{1,4}:[\da-f]{1,4}$/u,G=/^\[|\]$/gu,j=/\.$/u,v=t=>{const e=t.split(".");if(e.length!==4)return;const r=e.map(n=>x.test(n)?Number(n):-1);if(!r.some(n=>n<0||n>255))return[r[0],r[1],r[2],r[3]]},y=([t,e])=>t===0||t===10||t===127||t===100&&e>=64&&e<=127||t===169&&e===254||t===172&&e>=16&&e<=31||t===192&&e===168||t>=224,D=(t,e)=>{const r=Number.parseInt(t??"",16),n=Number.parseInt(e??"",16);return!Number.isFinite(r)||!Number.isFinite(n)?!0:y([Math.floor(r/256),r%256,Math.floor(n/256),n%256])},L=t=>{const e=t.toLowerCase(),r=C.exec(e);if(r)return D(r[1],r[2]);const n=F.exec(e);if(n){const f=v(n[1]??"");return f===void 0||y(f)}const i=X.exec(e);if(i){const f=v(i[1]??"");return f===void 0||y(f)}const c=Q.exec(e);return c?D(c[1],c[2]):z.test(e)||e.startsWith("2002:")||e.startsWith("2001:0:")?!0:e==="::"||e==="::1"||e.startsWith("fc")||e.startsWith("fd")||e.startsWith("fe8")||e.startsWith("fe9")||e.startsWith("fea")||e.startsWith("feb")},q=t=>t==="localhost"||t.endsWith(".localhost")||t.endsWith(".local")||t.endsWith(".internal")||t.endsWith(".home.arpa"),h=t=>t.replaceAll(G,"").replace(j,"").toLowerCase(),O=t=>{const e=h(t);if(e.includes(":"))return L(e);const r=v(e);return r===void 0?q(e):y(r)},Y="https://cloudflare-dns.com/dns-query",T=1,N=28,J=2e3,Z=(t,e)=>{if(e===T){const r=v(t);return r===void 0||y(r)}return L(t.toLowerCase())},S=async(t,e,r)=>{try{const n=await fetch(`${Y}?name=${encodeURIComponent(t)}&type=${String(e)}`,{headers:{accept:"application/dns-json"},signal:AbortSignal.timeout(r)});return n.ok?(await n.json()).Answer??[]:void 0}catch{return}},K=async(t,e=J)=>{const r=h(t);if(r.includes(":")||v(r)!==void 0)return{kind:"unknown"};const[n,i]=await Promise.all([S(r,T,e),S(r,N,e)]);if(n===void 0&&i===void 0)return{kind:"unknown"};for(const c of[...n??[],...i??[]])if((c.type===T||c.type===N)&&Z(c.data,c.type))return{address:c.data,kind:"private"};return{kind:"public"}},A=3e4,tt=12e4,et=3840,rt=4320,R=10,M=600,U=5e3,$=async(t,e=U)=>{const r=h(new URL(t).hostname),n=await K(r,e);if(n.kind==="private")throw new u("FORBIDDEN",`@lunora/browser: url host "${r}" resolves to a private/internal address (${n.address}); refusing to navigate (DNS-rebinding guard)`)},B=(t,e,r)=>{if(typeof t!="string"||t.length===0)throw new u("BAD_REQUEST","@lunora/browser: url must be a non-empty string");let n;try{n=new URL(t)}catch{throw new u("BAD_REQUEST",`@lunora/browser: url must be an absolute http(s) URL (got "${t}")`)}if(n.protocol!=="http:"&&n.protocol!=="https:")throw new u("BAD_REQUEST",`@lunora/browser: url protocol must be http(s) (got "${n.protocol}")`);if(n.username!==""||n.password!=="")throw new u("BAD_REQUEST","@lunora/browser: url must not embed credentials (strip the `user:pass@` userinfo)");if(r&&r.length>0){const i=h(n.hostname);if(!r.some(c=>h(c)===i))throw new u("FORBIDDEN",`@lunora/browser: url host "${n.hostname}" is not in the configured allowedHosts allowlist`)}if(!e&&O(n.hostname))throw new u("FORBIDDEN",`@lunora/browser: url host "${n.hostname}" is a private/internal address; pass createBrowser({ …, allowPrivateTargets: true }) to allow it`);return n.toString()},H=(t,e)=>Number.isFinite(t)?Math.min(Math.max(1,Math.floor(t)),e):e,nt=t=>({height:H(t.height,rt),width:H(t.width,et)}),ot=(t,e)=>{const r=t??e??A,n=Number.isFinite(r)?r:A;return Math.min(Math.max(1,Math.floor(n)),tt)},st=async(t,e)=>{let r;try{return await Promise.race([t(),new Promise((n,i)=>{r=setTimeout(()=>{i(new u("BROWSER_TIMEOUT",`@lunora/browser: navigation + operation exceeded the ${String(e)}ms timeout budget`,{status:504}))},e)})])}finally{r!==void 0&&clearTimeout(r)}},k=async t=>{try{await t.close()}catch{}},ht=t=>{if(!t.binding)throw new TypeError("@lunora/browser: `binding` is required (env.BROWSER)");const e=()=>{if(!t.launch)throw new u("INTERNAL",'@lunora/browser: `launch` is not available — install the `@cloudflare/playwright` peer dependency. The generated worker wires it for you; outside codegen pass it via createBrowser({ binding, launch }) (import { launch } from "@cloudflare/playwright").');return t.launch},r=(s,o)=>{if(!s)throw new u("INTERNAL",`@lunora/browser: \`${o}\` is not available — install the \`@cloudflare/playwright\` peer dependency. The generated worker wires it for you; outside codegen pass it via createBrowser({ binding, ${o} }).`);return s},n=async(s,o)=>{const a=o!==void 0&&Number.isFinite(o)&&o>0?o:void 0;if(a!==void 0&&(a<R||a>M))throw new u("BAD_REQUEST",`@lunora/browser: keepAlive must be between ${String(R)} and ${String(M)} seconds (Browser Rendering accepts keep_alive from 10s to 10min; got ${String(o)})`);const l=await e()(t.binding,a===void 0?void 0:{keep_alive:a*1e3});if(a!==void 0)return await s(l);try{return await s(l)}finally{await k(l)}},i=async(s,o,a,l)=>{const p=t.allowPrivateTargets??!1,_=B(s,p,t.allowedHosts),E=ot(o.timeoutMs,t.timeoutMs),I=t.resolveDns??(t.allowedHosts?.length??0)===0,P=Math.min(E,U);!p&&I&&await $(_,P);const W=async m=>{B(m,p,t.allowedHosts),!p&&I&&await $(m,P)},V=m=>{let g;try{g=new URL(m)}catch{return!1}if(g.protocol!=="http:"&&g.protocol!=="https:")return!1;if(t.allowedHosts&&t.allowedHosts.length>0){const d=h(g.hostname);if(!t.allowedHosts.some(w=>h(w)===d))return!0}return O(g.hostname)};return n(async m=>{const d=await(await m.newContext()).newPage();return d.route&&(!p||(t.allowedHosts?.length??0)>0)&&await d.route("**/*",async w=>{const b=w.request();if(!(b.isNavigationRequest?.()??!0)){if(V(b.url())){await w.abort("blockedbyclient");return}await w.continue();return}try{await W(b.url())}catch{await w.abort("blockedbyclient");return}await w.continue()}),l&&d.setViewportSize&&await d.setViewportSize(nt(l)),st(async()=>(await d.goto(_,{timeout:E,waitUntil:o.waitUntil??"load"}),a(d)),E)})};return{connect:async(s,o,a={})=>{const l=await r(t.connect,"connect")(t.binding,s);if(a.close!==!0)return await o(l);try{return await o(l)}finally{await k(l)}},content:async(s,o={})=>i(s,o,async a=>a.content()),launch:async(s,o={})=>n(s,o.keepAlive),pdf:async(s,o={})=>i(s,o,async a=>a.pdf({format:o.format,printBackground:o.printBackground??!1}),o.viewport),scrape:async(s,o,a={})=>i(s,a,async l=>l.evaluate(o)),screenshot:async(s,o={})=>i(s,o,async a=>a.screenshot({fullPage:o.fullPage??!1,type:o.type??"png"}),o.viewport),sessions:async()=>await r(t.sessions,"sessions")(t.binding)}};export{ht as createBrowser};
1
+ import{LunoraError as u}from"@lunora/errors";const x=/^\d{1,3}$/u,C=/^::ffff:([\da-f]{1,4}):([\da-f]{1,4})$/u,F=/^::ffff:(\d{1,3}(?:\.\d{1,3}){3})$/u,X=/^::(\d{1,3}(?:\.\d{1,3}){3})$/u,Q=/^::([\da-f]{1,4}):([\da-f]{1,4})$/u,z=/^64:ff9b::[\da-f]{1,4}:[\da-f]{1,4}$/u,G=/^\[|\]$/gu,j=/\.$/u,v=t=>{const e=t.split(".");if(e.length!==4)return;const r=e.map(n=>x.test(n)?Number(n):-1);if(!r.some(n=>n<0||n>255))return[r[0],r[1],r[2],r[3]]},y=([t,e])=>t===0||t===10||t===127||t===100&&e>=64&&e<=127||t===169&&e===254||t===172&&e>=16&&e<=31||t===192&&e===168||t>=224,D=(t,e)=>{const r=Number.parseInt(t??"",16),n=Number.parseInt(e??"",16);return!Number.isFinite(r)||!Number.isFinite(n)?!0:y([Math.floor(r/256),r%256,Math.floor(n/256),n%256])},L=t=>{const e=t.toLowerCase(),r=C.exec(e);if(r)return D(r[1],r[2]);const n=F.exec(e);if(n){const f=v(n[1]??"");return f===void 0||y(f)}const i=X.exec(e);if(i){const f=v(i[1]??"");return f===void 0||y(f)}const c=Q.exec(e);return c?D(c[1],c[2]):z.test(e)||e.startsWith("2002:")||e.startsWith("2001:0:")?!0:e==="::"||e==="::1"||e.startsWith("fc")||e.startsWith("fd")||e.startsWith("fe8")||e.startsWith("fe9")||e.startsWith("fea")||e.startsWith("feb")},q=t=>t==="localhost"||t.endsWith(".localhost")||t.endsWith(".local")||t.endsWith(".internal")||t.endsWith(".home.arpa"),h=t=>t.replaceAll(G,"").replace(j,"").toLowerCase(),O=t=>{const e=h(t);if(e.includes(":"))return L(e);const r=v(e);return r===void 0?q(e):y(r)},Y="https://cloudflare-dns.com/dns-query",T=1,N=28,J=2e3,Z=(t,e)=>{if(e===T){const r=v(t);return r===void 0||y(r)}return L(t.toLowerCase())},S=async(t,e,r)=>{try{const n=await fetch(`${Y}?name=${encodeURIComponent(t)}&type=${String(e)}`,{headers:{accept:"application/dns-json"},signal:AbortSignal.timeout(r)});return n.ok?(await n.json()).Answer??[]:void 0}catch{return}},K=async(t,e=J)=>{const r=h(t);if(r.includes(":")||v(r)!==void 0)return{kind:"unknown"};const[n,i]=await Promise.all([S(r,T,e),S(r,N,e)]);if(n===void 0&&i===void 0)return{kind:"unknown"};for(const c of[...n??[],...i??[]])if((c.type===T||c.type===N)&&Z(c.data,c.type))return{address:c.data,kind:"private"};return{kind:"public"}},A=3e4,tt=12e4,et=3840,rt=4320,R=10,M=600,U=5e3,$=async(t,e=U)=>{const r=h(new URL(t).hostname),n=await K(r,e);if(n.kind==="private")throw new u("FORBIDDEN",`@lunora/browser: url host "${r}" resolves to a private/internal address (${n.address}); refusing to navigate (DNS-rebinding guard)`)},B=(t,e,r)=>{if(typeof t!="string"||t.length===0)throw new u("BAD_REQUEST","@lunora/browser: url must be a non-empty string");let n;try{n=new URL(t)}catch{throw new u("BAD_REQUEST",`@lunora/browser: url must be an absolute http(s) URL (got "${t}")`)}if(n.protocol!=="http:"&&n.protocol!=="https:")throw new u("BAD_REQUEST",`@lunora/browser: url protocol must be http(s) (got "${n.protocol}")`);if(n.username!==""||n.password!=="")throw new u("BAD_REQUEST","@lunora/browser: url must not embed credentials (strip the `user:pass@` userinfo)");if(r&&r.length>0){const i=h(n.hostname);if(!r.some(c=>h(c)===i))throw new u("FORBIDDEN",`@lunora/browser: url host "${n.hostname}" is not in the configured allowedHosts allowlist`)}if(!e&&O(n.hostname))throw new u("FORBIDDEN",`@lunora/browser: url host "${n.hostname}" is a private/internal address; pass createBrowser({ …, allowPrivateTargets: true }) to allow it`);return n.toString()},H=(t,e)=>Number.isFinite(t)?Math.min(Math.max(1,Math.floor(t)),e):e,nt=t=>({height:H(t.height,rt),width:H(t.width,et)}),ot=(t,e)=>{const r=t??e??A,n=Number.isFinite(r)?r:A;return Math.min(Math.max(1,Math.floor(n)),tt)},st=async(t,e)=>{let r;try{return await Promise.race([t(),new Promise((n,i)=>{r=setTimeout(()=>{i(new u("BROWSER_TIMEOUT",`@lunora/browser: navigation + operation exceeded the ${String(e)}ms timeout budget`,{status:504}))},e)})])}finally{r!==void 0&&clearTimeout(r)}},k=async t=>{try{await t.close()}catch{}},ht=t=>{if(!t.binding)throw new TypeError("@lunora/browser: `binding` is required (env.BROWSER)");const e=()=>{if(!t.launch)throw new u("INTERNAL",'@lunora/browser: `launch` is not available — install the `@cloudflare/playwright` peer dependency. The generated worker wires it for you; outside codegen pass it via createBrowser({ binding, launch }) (import { launch } from "@cloudflare/playwright").');return t.launch},r=(s,o)=>{if(!s)throw new u("INTERNAL",`@lunora/browser: \`${o}\` is not available — install the \`@cloudflare/playwright\` peer dependency. The generated worker wires it for you; outside codegen pass it via createBrowser({ binding, ${o} }).`);return s},n=async(s,o)=>{const a=o!==void 0&&Number.isFinite(o)&&o>0?o:void 0;if(a!==void 0&&(a<R||a>M))throw new u("BAD_REQUEST",`@lunora/browser: keepAlive must be between ${String(R)} and ${String(M)} seconds (Browser Rendering accepts keep_alive from 10s to 10min; got ${String(o)})`);const l=await e()(t.binding,a===void 0?void 0:{keep_alive:a*1e3});if(a!==void 0)return await s(l);try{return await s(l)}finally{await k(l)}},i=async(s,o,a,l)=>{const m=t.allowPrivateTargets??!1,_=B(s,m,t.allowedHosts),E=ot(o.timeoutMs,t.timeoutMs),I=t.resolveDns??(t.allowedHosts?.length??0)===0,P=Math.min(E,U);!m&&I&&await $(_,P);const W=async g=>{B(g,m,t.allowedHosts),!m&&I&&await $(g,P)},V=g=>{let p;try{p=new URL(g)}catch{return!0}if(p.protocol!=="http:"&&p.protocol!=="https:")return!1;if(t.allowedHosts&&t.allowedHosts.length>0){const d=h(p.hostname);if(!t.allowedHosts.some(w=>h(w)===d))return!0}return!m&&O(p.hostname)};return n(async g=>{const d=await(await g.newContext()).newPage();return d.route&&(!m||(t.allowedHosts?.length??0)>0)&&await d.route("**/*",async w=>{const b=w.request();if(!(b.isNavigationRequest?.()??!0)){if(V(b.url())){await w.abort("blockedbyclient");return}await w.continue();return}try{await W(b.url())}catch{await w.abort("blockedbyclient");return}await w.continue()}),l&&d.setViewportSize&&await d.setViewportSize(nt(l)),st(async()=>(await d.goto(_,{timeout:E,waitUntil:o.waitUntil??"load"}),a(d)),E)})};return{connect:async(s,o,a={})=>{const l=await r(t.connect,"connect")(t.binding,s);if(a.close!==!0)return await o(l);try{return await o(l)}finally{await k(l)}},content:async(s,o={})=>i(s,o,async a=>a.content()),launch:async(s,o={})=>n(s,o.keepAlive),pdf:async(s,o={})=>i(s,o,async a=>a.pdf({format:o.format,printBackground:o.printBackground??!1}),o.viewport),scrape:async(s,o,a={})=>i(s,a,async l=>l.evaluate(o)),screenshot:async(s,o={})=>i(s,o,async a=>a.screenshot({fullPage:o.fullPage??!1,type:o.type??"png"}),o.viewport),sessions:async()=>await r(t.sessions,"sessions")(t.binding)}};export{ht as createBrowser};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lunora/browser",
3
- "version": "1.0.0-alpha.40",
3
+ "version": "1.0.0-alpha.41",
4
4
  "description": "Cloudflare Browser Rendering for Lunora: ctx.browser screenshots, PDF, and scraping in actions",
5
5
  "keywords": [
6
6
  "browser-rendering",
@@ -46,7 +46,7 @@
46
46
  "access": "public"
47
47
  },
48
48
  "dependencies": {
49
- "@lunora/errors": "1.0.0-alpha.31"
49
+ "@lunora/errors": "1.0.0-alpha.32"
50
50
  },
51
51
  "peerDependencies": {
52
52
  "@cloudflare/playwright": ">=1.0.0"