@ienlab/cloud-functions-library 1.0.0-dev.11 → 1.0.0-dev.12
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/handlers/ssr-dynamic-og.d.ts +8 -2
- package/dist/index.js +1 -1
- package/dist/index.mjs +21 -17
- package/package.json +1 -1
|
@@ -1,12 +1,18 @@
|
|
|
1
|
-
import { HttpsFunction } from 'firebase-functions/v2/https';
|
|
1
|
+
import { HttpsFunction, Request } from 'firebase-functions/v2/https';
|
|
2
2
|
export interface OGData {
|
|
3
3
|
title: string;
|
|
4
4
|
description: string;
|
|
5
5
|
image: string;
|
|
6
6
|
}
|
|
7
|
+
export interface SSRResolveContext {
|
|
8
|
+
req: Request;
|
|
9
|
+
pathname: string;
|
|
10
|
+
searchParams: URLSearchParams;
|
|
11
|
+
match: RegExpMatchArray;
|
|
12
|
+
}
|
|
7
13
|
export interface SSRResolver {
|
|
8
14
|
pattern: RegExp;
|
|
9
|
-
resolve: (id: string) => Promise<OGData | null>;
|
|
15
|
+
resolve: (id: string, context: SSRResolveContext) => Promise<OGData | null>;
|
|
10
16
|
}
|
|
11
17
|
export interface SSRDynamicOGConfig {
|
|
12
18
|
spaUrl: string;
|
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,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,`&`).replace(/</g,`<`).replace(/>/g,`>`).replace(/"/g,`"`).replace(/'/g,`'`):``}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`)
|
|
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,`&`).replace(/</g,`<`).replace(/>/g,`>`).replace(/"/g,`"`).replace(/'/g,`'`):``}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;return a=/<title>.*<\/title>/i.test(a)?a.replace(/(<title>)[^<]*(<\/title>)/i,`$1${i}$2`):a.replace(/(<\/head>)/i,`<title>${i}</title>\n$1`),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,`property`,`og:type`,`website`),a=u(a,`name`,`twitter:card`,`summary_large_image`),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,s=new URL(e.url,n),l=s.searchParams;try{let n=r;for(let t of i){let r=o.match(t.pattern);if(!r)continue;let i=r[1]??r[0];try{let a=await t.resolve(i,{req:e,pathname:o,searchParams:l,match:r});if(a){n=a;break}}catch(e){console.error(`[SSRDynamicOG] Failed to resolve "${o}${s.search}" with pattern ${t.pattern}:`,e)}}let u=d(await c(),n.title,n.description,n.image);console.log(`[SSRDynamicOG] ${o}${s.search} → ${n.title} (${Date.now()-a}ms)`),t.setHeader(`Content-Type`,`text/html; charset=utf-8`),t.status(200).send(u)}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
|
@@ -47,30 +47,34 @@ function o(e) {
|
|
|
47
47
|
return s;
|
|
48
48
|
}
|
|
49
49
|
function d(e, t, n, r) {
|
|
50
|
-
let i = l(t), a = e
|
|
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;
|
|
50
|
+
let i = l(t), a = e;
|
|
51
|
+
return a = /<title>.*<\/title>/i.test(a) ? a.replace(/(<title>)[^<]*(<\/title>)/i, `$1${i}$2`) : a.replace(/(<\/head>)/i, `<title>${i}</title>\n$1`), 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, "property", "og:type", "website"), a = u(a, "name", "twitter:card", "summary_large_image"), a = u(a, "name", "twitter:title", t), a = u(a, "name", "twitter:description", n), a = u(a, "name", "twitter:image", r), a;
|
|
52
52
|
}
|
|
53
53
|
return t({ region: a }, async (e, t) => {
|
|
54
|
-
let a = Date.now(), o = e.path;
|
|
54
|
+
let a = Date.now(), o = e.path, s = new URL(e.url, n), l = s.searchParams;
|
|
55
55
|
try {
|
|
56
|
-
let
|
|
56
|
+
let n = r;
|
|
57
57
|
for (let t of i) {
|
|
58
|
-
let
|
|
59
|
-
if (
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
}
|
|
68
|
-
|
|
58
|
+
let r = o.match(t.pattern);
|
|
59
|
+
if (!r) continue;
|
|
60
|
+
let i = r[1] ?? r[0];
|
|
61
|
+
try {
|
|
62
|
+
let a = await t.resolve(i, {
|
|
63
|
+
req: e,
|
|
64
|
+
pathname: o,
|
|
65
|
+
searchParams: l,
|
|
66
|
+
match: r
|
|
67
|
+
});
|
|
68
|
+
if (a) {
|
|
69
|
+
n = a;
|
|
70
|
+
break;
|
|
69
71
|
}
|
|
72
|
+
} catch (e) {
|
|
73
|
+
console.error(`[SSRDynamicOG] Failed to resolve "${o}${s.search}" with pattern ${t.pattern}:`, e);
|
|
70
74
|
}
|
|
71
75
|
}
|
|
72
|
-
let
|
|
73
|
-
console.log(`[SSRDynamicOG] ${o} → ${
|
|
76
|
+
let u = d(await c(), n.title, n.description, n.image);
|
|
77
|
+
console.log(`[SSRDynamicOG] ${o}${s.search} → ${n.title} (${Date.now() - a}ms)`), t.setHeader("Content-Type", "text/html; charset=utf-8"), t.status(200).send(u);
|
|
74
78
|
} catch (e) {
|
|
75
79
|
console.error("[SSRDynamicOG] error:", e), t.redirect(302, n);
|
|
76
80
|
}
|