@symbo.ls/utils 3.14.0 → 3.14.2
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/README.md +2 -2
- package/assets.js +117 -0
- package/cookie.js +20 -13
- package/index.js +1 -0
- package/methods.js +51 -3
- package/object.js +36 -2
- package/package.json +1 -1
- package/dist/cjs/array.js +0 -168
- package/dist/cjs/browser.js +0 -34
- package/dist/cjs/cache.js +0 -26
- package/dist/cjs/cdn.js +0 -85
- package/dist/cjs/component.js +0 -45
- package/dist/cjs/cookie.js +0 -75
- package/dist/cjs/date.js +0 -31
- package/dist/cjs/detectHeight.js +0 -62
- package/dist/cjs/element.js +0 -136
- package/dist/cjs/env.js +0 -43
- package/dist/cjs/events.js +0 -39
- package/dist/cjs/extends.js +0 -434
- package/dist/cjs/fibonacci.js +0 -30
- package/dist/cjs/files.js +0 -24
- package/dist/cjs/function.js +0 -114
- package/dist/cjs/globals.js +0 -30
- package/dist/cjs/if.js +0 -48
- package/dist/cjs/index.js +0 -54
- package/dist/cjs/key.js +0 -38
- package/dist/cjs/keys.js +0 -201
- package/dist/cjs/load.js +0 -171
- package/dist/cjs/log.js +0 -34
- package/dist/cjs/metadata.js +0 -310
- package/dist/cjs/methods.js +0 -599
- package/dist/cjs/node.js +0 -35
- package/dist/cjs/object.js +0 -634
- package/dist/cjs/projectKeys.js +0 -35
- package/dist/cjs/props.js +0 -282
- package/dist/cjs/scaling.js +0 -35
- package/dist/cjs/scope.js +0 -44
- package/dist/cjs/sharedLibraries.js +0 -146
- package/dist/cjs/state.js +0 -173
- package/dist/cjs/string-extra.js +0 -72
- package/dist/cjs/string.js +0 -183
- package/dist/cjs/style.js +0 -40
- package/dist/cjs/tags.js +0 -220
- package/dist/cjs/triggerEvent.js +0 -112
- package/dist/cjs/types.js +0 -74
- package/dist/cjs/update.js +0 -42
- package/dist/esm/array.js +0 -148
- package/dist/esm/browser.js +0 -14
- package/dist/esm/cache.js +0 -6
- package/dist/esm/cdn.js +0 -65
- package/dist/esm/component.js +0 -25
- package/dist/esm/cookie.js +0 -55
- package/dist/esm/date.js +0 -11
- package/dist/esm/detectHeight.js +0 -42
- package/dist/esm/element.js +0 -116
- package/dist/esm/env.js +0 -23
- package/dist/esm/events.js +0 -19
- package/dist/esm/extends.js +0 -414
- package/dist/esm/fibonacci.js +0 -10
- package/dist/esm/files.js +0 -4
- package/dist/esm/function.js +0 -94
- package/dist/esm/globals.js +0 -10
- package/dist/esm/if.js +0 -28
- package/dist/esm/index.js +0 -37
- package/dist/esm/key.js +0 -18
- package/dist/esm/keys.js +0 -181
- package/dist/esm/load.js +0 -151
- package/dist/esm/log.js +0 -14
- package/dist/esm/metadata.js +0 -290
- package/dist/esm/methods.js +0 -569
- package/dist/esm/node.js +0 -15
- package/dist/esm/object.js +0 -621
- package/dist/esm/projectKeys.js +0 -16
- package/dist/esm/props.js +0 -262
- package/dist/esm/scaling.js +0 -15
- package/dist/esm/scope.js +0 -24
- package/dist/esm/sharedLibraries.js +0 -126
- package/dist/esm/state.js +0 -163
- package/dist/esm/string-extra.js +0 -52
- package/dist/esm/string.js +0 -163
- package/dist/esm/style.js +0 -20
- package/dist/esm/tags.js +0 -200
- package/dist/esm/triggerEvent.js +0 -92
- package/dist/esm/types.js +0 -54
- package/dist/esm/update.js +0 -22
- 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
|
-
};
|
package/dist/esm/metadata.js
DELETED
|
@@ -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 = { "&": "&", "<": "<", ">": ">", '"': """, "'": "'" };
|
|
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
|
-
};
|