@ienlab/cloud-functions-library 1.0.0-dev.10 → 1.0.0-dev.11

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.js CHANGED
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});let e=require("firebase-admin/firestore"),t=require("firebase-functions/v2/https");function n(e){return{...e.data(),id:e.id}}function r(e,t,n){let r=e.headers.origin;return r&&n.includes(r)&&(t.set(`Access-Control-Allow-Origin`,r),t.set(`Vary`,`Origin`)),t.set(`Access-Control-Allow-Methods`,`POST, OPTIONS`),t.set(`Access-Control-Allow-Headers`,`Content-Type, Authorization`),e.method===`OPTIONS`?(t.status(204).send(),!1):e.method===`POST`?!0:(t.status(405).send({error:`Method Not Allowed`}),!1)}var i=()=>({updateAt:e.FieldValue.serverTimestamp(),deletedAt:e.FieldValue.serverTimestamp()}),a=()=>({updateAt:e.FieldValue.serverTimestamp(),deletedAt:null});function o(e){let{spaUrl:n,defaultOG:r,resolvers:i,region:a=`asia-northeast3`}=e,o=null;async function s(){if(o)return o;let e=await fetch(n);if(!e.ok)throw Error(`Failed to fetch template: ${e.status}`);return o=await e.text(),o}function c(e,t,n,r){return e.replace(/(<title>)[^<]*(<\/title>)/,`$1${t}$2`).replace(/(<meta\s+name="description"\s+content=")[^"]*(")/,`$1${n}$2`).replace(/(<meta\s+property="og:title"\s+content=")[^"]*(")/,`$1${t}$2`).replace(/(<meta\s+property="og:description"\s+content=")[^"]*(")/,`$1${n}$2`).replace(/(<meta\s+property="og:image"\s+content=")[^"]*(")/,`$1${r}$2`).replace(/(<meta\s+name="twitter:title"\s+content=")[^"]*(")/,`$1${t}$2`).replace(/(<meta\s+name="twitter:description"\s+content=")[^"]*(")/,`$1${n}$2`).replace(/(<meta\s+name="twitter:image"\s+content=")[^"]*(")/,`$1${r}$2`)}return(0,t.onRequest)({region:a},async(e,t)=>{let a=Date.now();try{let n=new URL(e.url,`https://${e.headers.host??`localhost`}`).pathname,o=r;for(let e of i){let t=n.match(e.pattern);if(t){let n=await e.resolve(t[1]);if(n){o=n;break}}}let l=c(await s(),o.title,o.description,o.image);console.log(`[SSRDynamicOG] ${n} → ${o.title} (${Date.now()-a}ms)`),t.setHeader(`Content-Type`,`text/html; charset=utf-8`),t.status(200).send(l)}catch(e){console.error(`[SSRDynamicOG] error:`,e),t.redirect(302,n)}})}exports.applyCors=r,exports.createSSRDynamicOG=o,exports.del=i,exports.snapshotToData=n,exports.undel=a;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});let e=require("firebase-admin/firestore"),t=require("firebase-functions/v2/https");function n(e){return{...e.data(),id:e.id}}function r(e,t,n){let r=e.headers.origin;return r&&n.includes(r)&&(t.set(`Access-Control-Allow-Origin`,r),t.set(`Vary`,`Origin`)),t.set(`Access-Control-Allow-Methods`,`POST, OPTIONS`),t.set(`Access-Control-Allow-Headers`,`Content-Type, Authorization`),e.method===`OPTIONS`?(t.status(204).send(),!1):e.method===`POST`?!0:(t.status(405).send({error:`Method Not Allowed`}),!1)}var i=()=>({updateAt:e.FieldValue.serverTimestamp(),deletedAt:e.FieldValue.serverTimestamp()}),a=()=>({updateAt:e.FieldValue.serverTimestamp(),deletedAt:null});function o(e){let{spaUrl:n,defaultOG:r,resolvers:i,region:a=`asia-northeast3`}=e,o=null,s=0;function c(){let e=Date.now();return(!o||e-s>18e5)&&(s=e,o=fetch(n,{signal:AbortSignal.timeout(5e3)}).then(async e=>{if(!e.ok)throw o=null,s=0,Error(`Failed to fetch template: ${e.status}`);return e.text()}).catch(e=>{throw o=null,s=0,e})),o}function l(e){return e?String(e).replace(/&/g,`&amp;`).replace(/</g,`&lt;`).replace(/>/g,`&gt;`).replace(/"/g,`&quot;`).replace(/'/g,`&#039;`):``}function u(e,t,n,r){let i=l(r),a=RegExp(`(<meta\\s+[^>]*${t}=["']${n}["'][^>]*>)`,`gi`),o=!1,s=e.replace(a,e=>(o=!0,/\bcontent=/i.test(e)?e.replace(/\bcontent=(["'])(.*?)\1/i,`content=$1${i}$1`):e.replace(/(\/?>)$/,` content="${i}"$1`)));if(!o){let e=`<meta ${t}="${n}" content="${i}">`;return s.replace(/(<\/head>)/i,`${e}\n$1`)}return s}function d(e,t,n,r){let i=l(t),a=e.replace(/(<title>)[^<]*(<\/title>)/i,`$1${i}$2`);return a=u(a,`name`,`description`,n),a=u(a,`property`,`og:title`,t),a=u(a,`property`,`og:description`,n),a=u(a,`property`,`og:image`,r),a=u(a,`name`,`twitter:title`,t),a=u(a,`name`,`twitter:description`,n),a=u(a,`name`,`twitter:image`,r),a}return(0,t.onRequest)({region:a},async(e,t)=>{let a=Date.now(),o=e.path;try{let e=r;for(let t of i){let n=o.match(t.pattern);if(n){let r=n[1]??n[0];try{let n=await t.resolve(r);if(n){e=n;break}}catch(e){console.error(`[SSRDynamicOG] Failed to resolve ID "${r}" for pattern ${t.pattern}:`,e)}}}let n=d(await c(),e.title,e.description,e.image);console.log(`[SSRDynamicOG] ${o} → ${e.title} (${Date.now()-a}ms)`),t.setHeader(`Content-Type`,`text/html; charset=utf-8`),t.status(200).send(n)}catch(e){console.error(`[SSRDynamicOG] error:`,e),t.redirect(302,n)}})}exports.applyCors=r,exports.createSSRDynamicOG=o,exports.del=i,exports.snapshotToData=n,exports.undel=a;
package/dist/index.mjs CHANGED
@@ -25,32 +25,52 @@ var i = () => ({
25
25
  //#endregion
26
26
  //#region src/handlers/ssr-dynamic-og.ts
27
27
  function o(e) {
28
- let { spaUrl: n, defaultOG: r, resolvers: i, region: a = "asia-northeast3" } = e, o = null;
29
- async function s() {
30
- if (o) return o;
31
- let e = await fetch(n);
32
- if (!e.ok) throw Error(`Failed to fetch template: ${e.status}`);
33
- return o = await e.text(), o;
28
+ let { spaUrl: n, defaultOG: r, resolvers: i, region: a = "asia-northeast3" } = e, o = null, s = 0;
29
+ function c() {
30
+ let e = Date.now();
31
+ return (!o || e - s > 18e5) && (s = e, o = fetch(n, { signal: AbortSignal.timeout(5e3) }).then(async (e) => {
32
+ if (!e.ok) throw o = null, s = 0, Error(`Failed to fetch template: ${e.status}`);
33
+ return e.text();
34
+ }).catch((e) => {
35
+ throw o = null, s = 0, e;
36
+ })), o;
34
37
  }
35
- function c(e, t, n, r) {
36
- return e.replace(/(<title>)[^<]*(<\/title>)/, `$1${t}$2`).replace(/(<meta\s+name="description"\s+content=")[^"]*(")/, `$1${n}$2`).replace(/(<meta\s+property="og:title"\s+content=")[^"]*(")/, `$1${t}$2`).replace(/(<meta\s+property="og:description"\s+content=")[^"]*(")/, `$1${n}$2`).replace(/(<meta\s+property="og:image"\s+content=")[^"]*(")/, `$1${r}$2`).replace(/(<meta\s+name="twitter:title"\s+content=")[^"]*(")/, `$1${t}$2`).replace(/(<meta\s+name="twitter:description"\s+content=")[^"]*(")/, `$1${n}$2`).replace(/(<meta\s+name="twitter:image"\s+content=")[^"]*(")/, `$1${r}$2`);
38
+ function l(e) {
39
+ return e ? String(e).replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#039;") : "";
40
+ }
41
+ function u(e, t, n, r) {
42
+ let i = l(r), a = RegExp(`(<meta\\s+[^>]*${t}=["']${n}["'][^>]*>)`, "gi"), o = !1, s = e.replace(a, (e) => (o = !0, /\bcontent=/i.test(e) ? e.replace(/\bcontent=(["'])(.*?)\1/i, `content=$1${i}$1`) : e.replace(/(\/?>)$/, ` content="${i}"$1`)));
43
+ if (!o) {
44
+ let e = `<meta ${t}="${n}" content="${i}">`;
45
+ return s.replace(/(<\/head>)/i, `${e}\n$1`);
46
+ }
47
+ return s;
48
+ }
49
+ function d(e, t, n, r) {
50
+ let i = l(t), a = e.replace(/(<title>)[^<]*(<\/title>)/i, `$1${i}$2`);
51
+ return a = u(a, "name", "description", n), a = u(a, "property", "og:title", t), a = u(a, "property", "og:description", n), a = u(a, "property", "og:image", r), a = u(a, "name", "twitter:title", t), a = u(a, "name", "twitter:description", n), a = u(a, "name", "twitter:image", r), a;
37
52
  }
38
53
  return t({ region: a }, async (e, t) => {
39
- let a = Date.now();
54
+ let a = Date.now(), o = e.path;
40
55
  try {
41
- let n = new URL(e.url, `https://${e.headers.host ?? "localhost"}`).pathname, o = r;
42
- for (let e of i) {
43
- let t = n.match(e.pattern);
44
- if (t) {
45
- let n = await e.resolve(t[1]);
46
- if (n) {
47
- o = n;
48
- break;
56
+ let e = r;
57
+ for (let t of i) {
58
+ let n = o.match(t.pattern);
59
+ if (n) {
60
+ let r = n[1] ?? n[0];
61
+ try {
62
+ let n = await t.resolve(r);
63
+ if (n) {
64
+ e = n;
65
+ break;
66
+ }
67
+ } catch (e) {
68
+ console.error(`[SSRDynamicOG] Failed to resolve ID "${r}" for pattern ${t.pattern}:`, e);
49
69
  }
50
70
  }
51
71
  }
52
- let l = c(await s(), o.title, o.description, o.image);
53
- console.log(`[SSRDynamicOG] ${n} → ${o.title} (${Date.now() - a}ms)`), t.setHeader("Content-Type", "text/html; charset=utf-8"), t.status(200).send(l);
72
+ let n = d(await c(), e.title, e.description, e.image);
73
+ console.log(`[SSRDynamicOG] ${o} → ${e.title} (${Date.now() - a}ms)`), t.setHeader("Content-Type", "text/html; charset=utf-8"), t.status(200).send(n);
54
74
  } catch (e) {
55
75
  console.error("[SSRDynamicOG] error:", e), t.redirect(302, n);
56
76
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ienlab/cloud-functions-library",
3
- "version": "1.0.0-dev.10",
3
+ "version": "1.0.0-dev.11",
4
4
  "main": "./dist/index.js",
5
5
  "module": "./dist/index.mjs",
6
6
  "types": "./dist/index.d.ts",