@symbo.ls/utils 3.14.0 → 3.14.1

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.
Files changed (88) hide show
  1. package/README.md +2 -2
  2. package/assets.js +117 -0
  3. package/cookie.js +20 -13
  4. package/dist/cjs/browser.js +2 -0
  5. package/dist/cjs/date.js +3 -1
  6. package/dist/cjs/detectHeight.js +13 -22
  7. package/dist/cjs/domqlv3hacks.js +3845 -0
  8. package/dist/cjs/fibonacci.js +3 -1
  9. package/dist/cjs/files.js +3 -1
  10. package/dist/cjs/index.js +4084 -38
  11. package/dist/cjs/load.js +7 -5
  12. package/dist/cjs/package.json +4 -0
  13. package/dist/cjs/scaling.js +23 -5
  14. package/dist/cjs/style.js +3 -1
  15. package/index.js +1 -0
  16. package/methods.js +51 -3
  17. package/object.js +36 -2
  18. package/package.json +1 -1
  19. package/dist/cjs/array.js +0 -168
  20. package/dist/cjs/cache.js +0 -26
  21. package/dist/cjs/cdn.js +0 -85
  22. package/dist/cjs/component.js +0 -45
  23. package/dist/cjs/cookie.js +0 -75
  24. package/dist/cjs/element.js +0 -136
  25. package/dist/cjs/env.js +0 -43
  26. package/dist/cjs/events.js +0 -39
  27. package/dist/cjs/extends.js +0 -434
  28. package/dist/cjs/function.js +0 -114
  29. package/dist/cjs/globals.js +0 -30
  30. package/dist/cjs/if.js +0 -48
  31. package/dist/cjs/key.js +0 -38
  32. package/dist/cjs/keys.js +0 -201
  33. package/dist/cjs/log.js +0 -34
  34. package/dist/cjs/metadata.js +0 -310
  35. package/dist/cjs/methods.js +0 -599
  36. package/dist/cjs/node.js +0 -35
  37. package/dist/cjs/object.js +0 -634
  38. package/dist/cjs/projectKeys.js +0 -35
  39. package/dist/cjs/props.js +0 -282
  40. package/dist/cjs/scope.js +0 -44
  41. package/dist/cjs/sharedLibraries.js +0 -146
  42. package/dist/cjs/state.js +0 -173
  43. package/dist/cjs/string-extra.js +0 -72
  44. package/dist/cjs/string.js +0 -183
  45. package/dist/cjs/tags.js +0 -220
  46. package/dist/cjs/triggerEvent.js +0 -112
  47. package/dist/cjs/types.js +0 -74
  48. package/dist/cjs/update.js +0 -42
  49. package/dist/esm/array.js +0 -148
  50. package/dist/esm/browser.js +0 -14
  51. package/dist/esm/cache.js +0 -6
  52. package/dist/esm/cdn.js +0 -65
  53. package/dist/esm/component.js +0 -25
  54. package/dist/esm/cookie.js +0 -55
  55. package/dist/esm/date.js +0 -11
  56. package/dist/esm/detectHeight.js +0 -42
  57. package/dist/esm/element.js +0 -116
  58. package/dist/esm/env.js +0 -23
  59. package/dist/esm/events.js +0 -19
  60. package/dist/esm/extends.js +0 -414
  61. package/dist/esm/fibonacci.js +0 -10
  62. package/dist/esm/files.js +0 -4
  63. package/dist/esm/function.js +0 -94
  64. package/dist/esm/globals.js +0 -10
  65. package/dist/esm/if.js +0 -28
  66. package/dist/esm/index.js +0 -37
  67. package/dist/esm/key.js +0 -18
  68. package/dist/esm/keys.js +0 -181
  69. package/dist/esm/load.js +0 -151
  70. package/dist/esm/log.js +0 -14
  71. package/dist/esm/metadata.js +0 -290
  72. package/dist/esm/methods.js +0 -569
  73. package/dist/esm/node.js +0 -15
  74. package/dist/esm/object.js +0 -621
  75. package/dist/esm/projectKeys.js +0 -16
  76. package/dist/esm/props.js +0 -262
  77. package/dist/esm/scaling.js +0 -15
  78. package/dist/esm/scope.js +0 -24
  79. package/dist/esm/sharedLibraries.js +0 -126
  80. package/dist/esm/state.js +0 -163
  81. package/dist/esm/string-extra.js +0 -52
  82. package/dist/esm/string.js +0 -163
  83. package/dist/esm/style.js +0 -20
  84. package/dist/esm/tags.js +0 -200
  85. package/dist/esm/triggerEvent.js +0 -92
  86. package/dist/esm/types.js +0 -54
  87. package/dist/esm/update.js +0 -22
  88. package/dist/iife/index.js +0 -5818
package/dist/esm/keys.js DELETED
@@ -1,181 +0,0 @@
1
- const DOMQ_PROPERTIES = /* @__PURE__ */ new Set([
2
- "attr",
3
- "style",
4
- "text",
5
- "html",
6
- "content",
7
- "data",
8
- "classlist",
9
- "state",
10
- "scope",
11
- "root",
12
- "deps",
13
- "extend",
14
- "extends",
15
- "$router",
16
- "routes",
17
- "children",
18
- "childExtend",
19
- "childExtends",
20
- "childExtendRecursive",
21
- "childExtendsRecursive",
22
- "props",
23
- "if",
24
- "define",
25
- "__name",
26
- "__ref",
27
- "__hash",
28
- "__text",
29
- "key",
30
- "tag",
31
- "query",
32
- "parent",
33
- "node",
34
- "variables",
35
- "on",
36
- "fetch",
37
- "component",
38
- "context",
39
- "preventContentUpdate",
40
- "preventContentRecreate"
41
- ]);
42
- const PARSED_DOMQ_PROPERTIES = /* @__PURE__ */ new Set([
43
- "attr",
44
- "style",
45
- "text",
46
- "html",
47
- "content",
48
- "data",
49
- "class",
50
- "state",
51
- "scope",
52
- "children",
53
- "props",
54
- "if",
55
- "key",
56
- "tag",
57
- "query",
58
- "on",
59
- "context"
60
- ]);
61
- const STATE_PROPERTIES = [
62
- "ref",
63
- "parent",
64
- "__element",
65
- "__depends",
66
- "__ref",
67
- "__children",
68
- "root"
69
- ];
70
- const STATE_METHODS = /* @__PURE__ */ new Set([
71
- "update",
72
- "parse",
73
- "clean",
74
- "create",
75
- "destroy",
76
- "add",
77
- "toggle",
78
- "remove",
79
- "apply",
80
- "set",
81
- "reset",
82
- "replace",
83
- "quietReplace",
84
- "quietUpdate",
85
- "applyReplace",
86
- "applyFunction",
87
- "keys",
88
- "values",
89
- "ref",
90
- "rootUpdate",
91
- "parentUpdate",
92
- "parent",
93
- "__element",
94
- "__depends",
95
- "__ref",
96
- "__children",
97
- "root",
98
- "setByPath",
99
- "setPathCollection",
100
- "removeByPath",
101
- "removePathCollection",
102
- "getByPath"
103
- ]);
104
- const PROPS_METHODS = /* @__PURE__ */ new Set(["update", "__element"]);
105
- const METHODS = /* @__PURE__ */ new Set([
106
- "set",
107
- "reset",
108
- "update",
109
- "remove",
110
- "updateContent",
111
- "removeContent",
112
- "lookup",
113
- "lookdown",
114
- "lookdownAll",
115
- "getRef",
116
- "getPath",
117
- "setNodeStyles",
118
- "spotByPath",
119
- "keys",
120
- "parse",
121
- "setProps",
122
- "parseDeep",
123
- "variables",
124
- "if",
125
- "log",
126
- "verbose",
127
- "warn",
128
- "error",
129
- "call",
130
- "nextElement",
131
- "previousElement",
132
- "getRootState",
133
- "getRoot",
134
- "getRootData",
135
- "getRootContext",
136
- "getContext",
137
- "getQuery",
138
- "getDB",
139
- "getChildren",
140
- "preventContentUpdate",
141
- "preventContentRecreate"
142
- ]);
143
- const METHODS_EXL = /* @__PURE__ */ new Set([
144
- "node",
145
- "context",
146
- "extends",
147
- "__element",
148
- "__ref",
149
- ...METHODS,
150
- ...STATE_METHODS,
151
- ...PROPS_METHODS
152
- ]);
153
- const DOMQL_EVENTS = /* @__PURE__ */ new Set([
154
- "init",
155
- "beforeClassAssign",
156
- "render",
157
- "renderRouter",
158
- "attachNode",
159
- "stateInit",
160
- "stateCreated",
161
- "beforeStateUpdate",
162
- "stateUpdate",
163
- "beforeUpdate",
164
- "done",
165
- "create",
166
- "complete",
167
- "frame",
168
- "update",
169
- "fetchError",
170
- "fetchComplete"
171
- ]);
172
- export {
173
- DOMQL_EVENTS,
174
- DOMQ_PROPERTIES,
175
- METHODS,
176
- METHODS_EXL,
177
- PARSED_DOMQ_PROPERTIES,
178
- PROPS_METHODS,
179
- STATE_METHODS,
180
- STATE_PROPERTIES
181
- };
package/dist/esm/load.js DELETED
@@ -1,151 +0,0 @@
1
- const loadJavascriptFile = (FILE_URL, async = false, doc = document, type = "text/javascript") => {
2
- return new Promise((resolve, reject) => {
3
- try {
4
- const scriptEle = doc.createElement("script");
5
- scriptEle.type = type;
6
- scriptEle.async = async;
7
- scriptEle.src = FILE_URL;
8
- scriptEle.addEventListener("load", (ev) => {
9
- resolve({
10
- status: true
11
- });
12
- });
13
- scriptEle.addEventListener("error", (ev) => {
14
- reject(
15
- new Error({
16
- status: false,
17
- message: `Failed to load the script ${FILE_URL}`
18
- })
19
- );
20
- });
21
- doc.body.appendChild(scriptEle);
22
- } catch (error) {
23
- reject(error);
24
- }
25
- });
26
- };
27
- const loadJavascriptFileSync = (fileUrl, doc = document, type = "text/javascript") => {
28
- return new Promise((resolve, reject) => {
29
- const scriptEle = doc.createElement("script");
30
- scriptEle.type = type;
31
- scriptEle.src = fileUrl;
32
- const blocker = doc.createElement("div");
33
- blocker.style.cssText = "position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(255,255,255,0.8);z-index:9999;";
34
- doc.body.appendChild(blocker);
35
- scriptEle.onload = () => {
36
- console.log(`Successfully loaded: ${fileUrl}`);
37
- doc.body.removeChild(blocker);
38
- resolve();
39
- };
40
- scriptEle.onerror = () => {
41
- doc.body.removeChild(blocker);
42
- reject(new Error(`Failed to load: ${fileUrl}`));
43
- };
44
- doc.body.appendChild(scriptEle);
45
- });
46
- };
47
- const loadJavascriptFileEmbedSync = (FILE_URL, doc = document, fallback, type = "text/javascript") => {
48
- const xhr = new window.XMLHttpRequest();
49
- xhr.open("GET", FILE_URL, false);
50
- xhr.send();
51
- if (xhr.status === 200) {
52
- const scriptEle = doc.createElement("script");
53
- scriptEle.type = type;
54
- scriptEle.text = xhr.responseText;
55
- doc.body.appendChild(scriptEle);
56
- if (typeof fallback === "function") fallback();
57
- } else {
58
- throw new Error(`Failed to load the script ${FILE_URL}`);
59
- }
60
- };
61
- const loadCssFile = (FILE_URL, async = false, doc = document, type = "text/javascript") => {
62
- return new Promise((resolve, reject) => {
63
- try {
64
- const linkElem = doc.createElement("link");
65
- linkElem.rel = "stylesheet";
66
- linkElem.href = FILE_URL;
67
- linkElem.addEventListener("load", (ev) => {
68
- resolve({
69
- status: true
70
- });
71
- });
72
- doc.head.appendChild(linkElem);
73
- } catch (error) {
74
- reject(error);
75
- }
76
- });
77
- };
78
- const loadJavascript = (body, async = false, doc = document, type = "text/javascript", id = "smbls-script") => {
79
- try {
80
- const scriptEle = doc.createElement("script");
81
- scriptEle.type = type;
82
- scriptEle.async = async;
83
- scriptEle.id = id;
84
- scriptEle.innerHTML = body;
85
- doc.body.appendChild(scriptEle);
86
- } catch (error) {
87
- console.warn(error);
88
- }
89
- };
90
- function loadRemoteScript(url, options = {}) {
91
- const { window: window2 = globalThis } = options;
92
- const { document: document2 = window2.document } = options;
93
- return new Promise((resolve, reject) => {
94
- const existingScript = document2.querySelector(`script[src="${url}"]`);
95
- if (existingScript) {
96
- return resolve(existingScript);
97
- }
98
- const script = document2.createElement("script");
99
- script.src = url;
100
- script.async = options.async === true;
101
- script.type = options.type || "text/javascript";
102
- if (options.id) script.id = options.id;
103
- if (options.integrity) script.integrity = options.integrity;
104
- if (options.crossOrigin) script.crossOrigin = options.crossOrigin;
105
- script.onload = () => {
106
- script.onerror = script.onload = null;
107
- resolve(script);
108
- };
109
- script.onerror = () => {
110
- script.onerror = script.onload = null;
111
- reject(new Error(`Failed to load script: ${url}`));
112
- };
113
- document2.head.appendChild(script);
114
- });
115
- }
116
- async function loadRemoteCSS(url, options = {}) {
117
- const { window: window2 = globalThis } = options;
118
- const { document: document2 = window2.document } = options;
119
- return new Promise((resolve, reject) => {
120
- const existingLink = document2.querySelector(`link[href="${url}"]`);
121
- if (existingLink) {
122
- return resolve(existingLink);
123
- }
124
- const link = document2.createElement("link");
125
- link.href = url;
126
- link.rel = options.rel || "stylesheet";
127
- link.type = "text/css";
128
- link.media = options.media || "all";
129
- if (options.id) link.id = options.id;
130
- if (options.integrity) link.integrity = options.integrity;
131
- if (options.crossOrigin) link.crossOrigin = options.crossOrigin;
132
- link.onload = () => {
133
- link.onerror = link.onload = null;
134
- resolve(link);
135
- };
136
- link.onerror = () => {
137
- link.onerror = link.onload = null;
138
- reject(new Error(`Failed to load stylesheet: ${url}`));
139
- };
140
- document2.head.appendChild(link);
141
- });
142
- }
143
- export {
144
- loadCssFile,
145
- loadJavascript,
146
- loadJavascriptFile,
147
- loadJavascriptFileEmbedSync,
148
- loadJavascriptFileSync,
149
- loadRemoteCSS,
150
- loadRemoteScript
151
- };
package/dist/esm/log.js DELETED
@@ -1,14 +0,0 @@
1
- const logIf = (bool, ...arg) => {
2
- if (bool) arg.map((v) => console.log(v));
3
- };
4
- const logGroupIf = (bool, key, ...arg) => {
5
- if (bool) {
6
- console.group(key);
7
- arg.map((v) => console.log(v));
8
- console.groupEnd(key);
9
- }
10
- };
11
- export {
12
- logGroupIf,
13
- logIf
14
- };
@@ -1,290 +0,0 @@
1
- import { isObject } from "./types.js";
2
- const escapeHtml = (text) => {
3
- if (text === null || text === void 0) return "";
4
- const map = { "&": "&amp;", "<": "&lt;", ">": "&gt;", '"': "&quot;", "'": "&#039;" };
5
- return text.toString().replace(/[&<>"']/g, (m) => map[m]);
6
- };
7
- const buildAttrs = (obj) => Object.entries(obj || {}).filter(([_, v]) => v !== void 0).map(([k, v]) => `${k}="${escapeHtml(v)}"`).join(" ");
8
- const generateMetaTags = (metadata, isProduction) => {
9
- if (!isProduction) {
10
- metadata = { ...metadata, robots: "noindex" };
11
- }
12
- const tags = Object.entries(metadata).reduce(
13
- (acc, [key, value]) => {
14
- if (!value && value !== 0 && value !== false) return acc;
15
- if (key === "title") {
16
- acc.push(`<title>${escapeHtml(value)}</title>`);
17
- return acc;
18
- }
19
- if (key === "canonical") {
20
- acc.push(`<link rel="canonical" href="${escapeHtml(value)}">`);
21
- return acc;
22
- }
23
- if (key === "manifest") {
24
- acc.push(`<link rel="manifest" href="${escapeHtml(value)}">`);
25
- return acc;
26
- }
27
- if (key === "favicon" || key === "favicons" || key === "icon" || key === "icons") {
28
- const items = Array.isArray(value) ? value : [value];
29
- items.forEach((item) => {
30
- if (typeof item === "string") {
31
- acc.push(`<link rel="icon" href="${escapeHtml(item)}">`);
32
- } else if (typeof item === "object") {
33
- const attrs = buildAttrs(item);
34
- if (!/rel=/.test(attrs)) {
35
- acc.push(`<link rel="icon" ${attrs}>`);
36
- } else {
37
- acc.push(`<link ${attrs}>`);
38
- }
39
- }
40
- });
41
- return acc;
42
- }
43
- if (key === "alternate") {
44
- const alternates = Array.isArray(value) ? value : [value];
45
- alternates.forEach((alt) => {
46
- if (typeof alt === "object") {
47
- const attrs = Object.entries(alt).filter(([_, attrValue]) => attrValue !== void 0).map(([attrKey, attrValue]) => `${attrKey}="${escapeHtml(attrValue)}"`).join(" ");
48
- acc.push(`<link rel="alternate" ${attrs}>`);
49
- }
50
- });
51
- return acc;
52
- }
53
- const processMetaTag = (tagKey, tagValue, attrType = "name") => {
54
- if (typeof tagValue === "string" || typeof tagValue === "number" || typeof tagValue === "boolean") {
55
- acc.push(`<meta ${attrType}="${escapeHtml(tagKey)}" content="${escapeHtml(tagValue)}">`);
56
- } else if (Array.isArray(tagValue)) {
57
- tagValue.forEach((item) => {
58
- if (typeof item === "string" || typeof item === "number" || typeof item === "boolean") {
59
- acc.push(`<meta ${attrType}="${escapeHtml(tagKey)}" content="${escapeHtml(item)}">`);
60
- } else if (typeof item === "object") {
61
- const attrs = Object.entries(item).filter(([_, attrValue]) => attrValue !== void 0).map(([attrKey, attrValue]) => `${attrKey}="${escapeHtml(attrValue)}"`).join(" ");
62
- acc.push(`<meta ${attrs}>`);
63
- }
64
- });
65
- } else if (typeof tagValue === "object") {
66
- const attrs = Object.entries(tagValue).filter(([_, attrValue]) => attrValue !== void 0).map(([attrKey, attrValue]) => `${attrKey}="${escapeHtml(attrValue)}"`).join(" ");
67
- acc.push(`<meta ${attrs}>`);
68
- }
69
- };
70
- if (key.startsWith("http-equiv:")) {
71
- const httpEquivKey = key.replace("http-equiv:", "");
72
- processMetaTag(httpEquivKey, value, "http-equiv");
73
- return acc;
74
- }
75
- if (key.startsWith("itemprop:")) {
76
- const itempropKey = key.replace("itemprop:", "");
77
- processMetaTag(itempropKey, value, "itemprop");
78
- return acc;
79
- }
80
- const prefixes = [
81
- "og:",
82
- "twitter:",
83
- "fb:",
84
- "article:",
85
- "profile:",
86
- "book:",
87
- "business:",
88
- "music:",
89
- "product:",
90
- "video:",
91
- "DC:",
92
- "DCTERMS:"
93
- ];
94
- const prefix = prefixes.find((p) => key.startsWith(p));
95
- if (prefix) {
96
- const tagKey = key.replace(prefix, "");
97
- processMetaTag(
98
- `${prefix.replace(":", "")}:${tagKey}`,
99
- value,
100
- prefix === "twitter:" || prefix === "DC:" || prefix === "DCTERMS:" ? "name" : "property"
101
- );
102
- return acc;
103
- }
104
- if (key.startsWith("apple:") || key.startsWith("msapplication:")) {
105
- const pfx = key.startsWith("apple:") ? "apple-" : "msapplication-";
106
- const tagKey = key.replace(/^apple:|^msapplication:/, "");
107
- processMetaTag(`${pfx}${tagKey}`, value, "name");
108
- return acc;
109
- }
110
- processMetaTag(key, value);
111
- return acc;
112
- },
113
- [
114
- '<meta charset="UTF-8">',
115
- '<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1, user-scalable=no">'
116
- ]
117
- );
118
- return tags.join("\n");
119
- };
120
- const isBareFilename = (val) => typeof val === "string" && val.length > 0 && !val.startsWith("/") && !val.startsWith("http");
121
- function resolveFileReferences(metadata, files) {
122
- if (!files || typeof files !== "object") return metadata;
123
- const resolve = (val) => {
124
- if (!isBareFilename(val)) return val;
125
- const fileEntry = files[val];
126
- if (fileEntry?.src) return fileEntry.src;
127
- return val;
128
- };
129
- const result = { ...metadata };
130
- for (const [key, value] of Object.entries(result)) {
131
- if (typeof value === "string") {
132
- result[key] = resolve(value);
133
- } else if (Array.isArray(value)) {
134
- result[key] = value.map(
135
- (item) => typeof item === "string" ? resolve(item) : item
136
- );
137
- }
138
- }
139
- return result;
140
- }
141
- function resolveDotPath(obj, path) {
142
- if (!obj || !path) return void 0;
143
- const parts = path.split(".");
144
- let v = obj;
145
- for (const p of parts) {
146
- if (v == null || typeof v !== "object") return void 0;
147
- v = v[p];
148
- }
149
- return v;
150
- }
151
- function resolveMetadataTemplates(metadata, data, ssrContext) {
152
- const config = data.config || data.settings || {};
153
- const polyglot = config.polyglot || data.polyglot;
154
- const defaultLang = ssrContext?.lang || polyglot?.defaultLang || "en";
155
- const translations = polyglot?.translations || {};
156
- const langMap = translations[defaultLang] || {};
157
- const state = ssrContext?.state || {};
158
- const result = { ...metadata };
159
- for (const [key, value] of Object.entries(result)) {
160
- if (typeof value !== "string" || !value.includes("{{")) continue;
161
- result[key] = value.replace(/\{\{\s*([^|{}]+?)\s*(?:\|\s*(\w+)\s*)?\}\}/g, (match, k, filter) => {
162
- const trimmed = k.trim();
163
- if (filter === "polyglot") {
164
- return langMap[trimmed] ?? resolveDotPath(langMap, trimmed) ?? match;
165
- }
166
- if (filter === "getLocalStateLang") {
167
- const resolved = resolveDotPath(state, trimmed + defaultLang);
168
- return resolved ?? match;
169
- }
170
- const fromState = resolveDotPath(state, trimmed);
171
- if (fromState !== void 0) return fromState;
172
- return langMap[trimmed] ?? resolveDotPath(langMap, trimmed) ?? match;
173
- });
174
- }
175
- return result;
176
- }
177
- function convertFunctionMetaToTemplates(metadata) {
178
- const result = { ...metadata };
179
- for (const [key, value] of Object.entries(result)) {
180
- if (typeof value === "function") {
181
- const src = value.toString();
182
- const langMatch = src.match(/el\.call\(\s*["']getLocalStateLang["']\s*,\s*["']([^"']+)["']\s*\)/);
183
- if (langMatch) {
184
- result[key] = `{{ ${langMatch[1]} | getLocalStateLang }}`;
185
- continue;
186
- }
187
- const polyMatch = src.match(/el\.call\(\s*["']polyglot["']\s*,\s*["']([^"']+)["']\s*\)/);
188
- if (polyMatch) {
189
- result[key] = `{{ ${polyMatch[1]} | polyglot }}`;
190
- continue;
191
- }
192
- const stateMatch = src.match(/s\.(\w+(?:\.\w+)+)/);
193
- if (stateMatch) {
194
- result[key] = `{{ ${stateMatch[1]} }}`;
195
- continue;
196
- }
197
- delete result[key];
198
- } else if (typeof value === "string") {
199
- const langMatch = value.match(/el\.call\(\s*["']getLocalStateLang["']\s*,\s*["']([^"']+)["']\s*\)/);
200
- if (langMatch) {
201
- result[key] = `{{ ${langMatch[1]} | getLocalStateLang }}`;
202
- continue;
203
- }
204
- const polyMatch = value.match(/el\.call\(\s*["']polyglot["']\s*,\s*["']([^"']+)["']\s*\)/);
205
- if (polyMatch) {
206
- result[key] = `{{ ${polyMatch[1]} | polyglot }}`;
207
- continue;
208
- }
209
- if (value.includes("=>") && value.includes("s.")) {
210
- const stateMatch = value.match(/s\.(\w+(?:\.\w+)+)/);
211
- if (stateMatch) {
212
- result[key] = `{{ ${stateMatch[1]} }}`;
213
- continue;
214
- }
215
- }
216
- }
217
- }
218
- return result;
219
- }
220
- function getPageMetadata(data, pathname, ssrContext, { isProduction = false, channel = "production" } = {}) {
221
- const currentPage = data.pages?.[pathname];
222
- const stateObject = isObject(currentPage?.state) && currentPage?.state;
223
- const rawPageMeta = currentPage?.metadata || currentPage?.helmet || stateObject || {};
224
- const pageMetadata = convertFunctionMetaToTemplates(rawPageMeta);
225
- const pageExplicitKeys = new Set(Object.keys(pageMetadata));
226
- const appMetadata = data.app?.metadata || {};
227
- const cleanAppMeta = convertFunctionMetaToTemplates(appMetadata);
228
- let merged = {};
229
- if (data.integrations?.seo) {
230
- merged = { ...data.integrations.seo, ...cleanAppMeta, ...pageMetadata };
231
- } else if (Object.keys(cleanAppMeta).length) {
232
- merged = { ...cleanAppMeta, ...pageMetadata };
233
- } else {
234
- merged = { ...pageMetadata };
235
- }
236
- if (!merged.title) {
237
- const label = data.name || data.key;
238
- if (label) {
239
- if (isProduction) merged.title = label;
240
- else if (channel === "development") merged.title = `${label} / dev:symbo.ls`;
241
- else if (channel === "staging") merged.title = `${label} / staging:symbo.ls`;
242
- else merged.title = `${label} / symbo.ls`;
243
- } else {
244
- merged.title = "Symbols demo";
245
- }
246
- }
247
- merged = resolveMetadataTemplates(merged, data, ssrContext);
248
- if (merged.title && (pageExplicitKeys.has("title") || !merged["og:title"])) {
249
- if (!pageExplicitKeys.has("og:title")) {
250
- merged["og:title"] = merged.title;
251
- }
252
- }
253
- if (merged.description && (pageExplicitKeys.has("description") || !merged["og:description"])) {
254
- if (!pageExplicitKeys.has("og:description")) {
255
- merged["og:description"] = merged.description;
256
- }
257
- }
258
- if (merged.title && !merged["twitter:title"]) {
259
- merged["twitter:title"] = merged.title;
260
- }
261
- if (merged.description && !merged["twitter:description"]) {
262
- merged["twitter:description"] = merged.description;
263
- }
264
- const routeForUrl = ssrContext?.actualPathname || pathname;
265
- if (merged["og:url"] || merged.url) {
266
- const baseUrl = (merged["og:url"] || merged.url || "").replace(/\/$/, "");
267
- if (baseUrl && routeForUrl && routeForUrl !== "/") {
268
- const cleanRoute = routeForUrl.startsWith("/") ? routeForUrl : "/" + routeForUrl;
269
- merged["og:url"] = baseUrl + cleanRoute;
270
- }
271
- }
272
- merged = resolveFileReferences(merged, data.files);
273
- const siteName = data.name || data.app?.metadata?.title || data.app?.name || "";
274
- for (const [key, value] of Object.entries(merged)) {
275
- if (typeof value === "string" && value.includes("{{")) {
276
- const cleaned = value.replace(/\{\{[^}]*\}\}/g, "").trim();
277
- if (!cleaned) {
278
- if (key === "title") merged[key] = siteName;
279
- else delete merged[key];
280
- } else {
281
- merged[key] = cleaned;
282
- }
283
- }
284
- }
285
- return merged;
286
- }
287
- export {
288
- generateMetaTags,
289
- getPageMetadata
290
- };