@ienlab/cloud-functions-library 1.0.0-dev.12 → 1.0.0-dev.13

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,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;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;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});let e=require("firebase-admin/firestore"),t=require("firebase-functions/v2/https");var n=[`ko`,`en`],r=null;function i(e){r=e}var a={get(e,t=`ko`){let i=r?.();return e[n.includes(i)?i:t]??e[t]},ko(e){return e.ko}};function o(e){return{...e.data(),id:e.id}}function s(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 c=()=>({updateAt:e.FieldValue.serverTimestamp(),deletedAt:e.FieldValue.serverTimestamp()}),l=()=>({updateAt:e.FieldValue.serverTimestamp(),deletedAt:null});function u(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;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.Localized=a,exports.SUPPORTED_LOCALES=n,exports.applyCors=s,exports.createSSRDynamicOG=u,exports.del=c,exports.setLocalizedLocaleResolver=i,exports.snapshotToData=o,exports.undel=l;
package/dist/index.mjs CHANGED
@@ -1,7 +1,22 @@
1
1
  import { FieldValue as e } from "firebase-admin/firestore";
2
2
  import { onRequest as t } from "firebase-functions/v2/https";
3
+ //#region src/types/localized.ts
4
+ var n = ["ko", "en"], r = null;
5
+ function i(e) {
6
+ r = e;
7
+ }
8
+ var a = {
9
+ get(e, t = "ko") {
10
+ let i = r?.();
11
+ return e[n.includes(i) ? i : t] ?? e[t];
12
+ },
13
+ ko(e) {
14
+ return e.ko;
15
+ }
16
+ };
17
+ //#endregion
3
18
  //#region src/utils/firestore.ts
4
- function n(e) {
19
+ function o(e) {
5
20
  return {
6
21
  ...e.data(),
7
22
  id: e.id
@@ -9,22 +24,22 @@ function n(e) {
9
24
  }
10
25
  //#endregion
11
26
  //#region src/utils/cors.ts
12
- function r(e, t, n) {
27
+ function s(e, t, n) {
13
28
  let r = e.headers.origin;
14
29
  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);
15
30
  }
16
31
  //#endregion
17
32
  //#region src/constant/firestore.ts
18
- var i = () => ({
33
+ var c = () => ({
19
34
  updateAt: e.serverTimestamp(),
20
35
  deletedAt: e.serverTimestamp()
21
- }), a = () => ({
36
+ }), l = () => ({
22
37
  updateAt: e.serverTimestamp(),
23
38
  deletedAt: null
24
39
  });
25
40
  //#endregion
26
41
  //#region src/handlers/ssr-dynamic-og.ts
27
- function o(e) {
42
+ function u(e) {
28
43
  let { spaUrl: n, defaultOG: r, resolvers: i, region: a = "asia-northeast3" } = e, o = null, s = 0;
29
44
  function c() {
30
45
  let e = Date.now();
@@ -81,4 +96,4 @@ function o(e) {
81
96
  });
82
97
  }
83
98
  //#endregion
84
- export { r as applyCors, o as createSSRDynamicOG, i as del, n as snapshotToData, a as undel };
99
+ export { a as Localized, n as SUPPORTED_LOCALES, s as applyCors, u as createSSRDynamicOG, c as del, i as setLocalizedLocaleResolver, o as snapshotToData, l as undel };
@@ -1 +1,2 @@
1
1
  export * from './firestore';
2
+ export * from './localized';
@@ -0,0 +1,8 @@
1
+ export declare const SUPPORTED_LOCALES: readonly ["ko", "en"];
2
+ export type Locale = (typeof SUPPORTED_LOCALES)[number];
3
+ export type Localized<T, TLocale extends string = Locale> = Record<TLocale, T>;
4
+ export declare function setLocalizedLocaleResolver(resolver: () => string | undefined): void;
5
+ export declare const Localized: {
6
+ get<T>(value: Localized<T>, fallback?: Locale): T;
7
+ ko<T>(value: Localized<T>): T;
8
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ienlab/cloud-functions-library",
3
- "version": "1.0.0-dev.12",
3
+ "version": "1.0.0-dev.13",
4
4
  "main": "./dist/index.js",
5
5
  "module": "./dist/index.mjs",
6
6
  "types": "./dist/index.d.ts",