tuijs-meta 0.0.9 → 0.1.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 CHANGED
@@ -1,4 +1,5 @@
1
1
  # TUIJS-Meta
2
+ *** THIS README IS OUT OF DATE AND WILL BE UPDATED SOON ***
2
3
  ## A simple and easy utility that updates a web application's meta tags based on a provided set of site data.
3
4
  ***TUIJS-Meta is built on modules. A bundler is recommended.***
4
5
 
package/bin/index.js ADDED
@@ -0,0 +1,40 @@
1
+ #! /usr/bin/env node
2
+ import { checkUrl } from 'tuijs-util';
3
+ import { consoleLog } from './lib/_logging.js';
4
+ import createSiteMap from './lib/siteMap.js';
5
+
6
+ (async () => {
7
+ try {
8
+ consoleLog({ type: 'info', message: `\n\n--------------------------\n` });
9
+ consoleLog({ type: 'info', message: `Attempting to generate site map...\n` });
10
+ const arg = process.argv.slice(2);
11
+ const data = {
12
+ configFile: '',
13
+ inputFile: '',
14
+ outputFile: 'sitemap.xml'
15
+ }
16
+
17
+ if (!arg[0]) {
18
+ throw new Error(`No arguments provided.`);
19
+ }
20
+ if (!arg[0].toLowerCase().endsWith('.json')) {
21
+ throw new Error(`The first argument must be a valid config JSON file.`);
22
+ }
23
+ data.configFile = arg[0];
24
+
25
+ if (!arg[1]) {
26
+ throw new Error(`No site data input file provided.`);
27
+ }
28
+ data.inputFile = arg[1];
29
+
30
+ if (!arg[2]) {
31
+ consoleLog({ type: 'warning', message: `No output file provided. Using the default 'sitemap.xml'.` });
32
+ }
33
+ data.outputFile = arg[2] || data.outputFile;
34
+ await createSiteMap(data.configFile, data.inputFile, data.outputFile);
35
+ return;
36
+ } catch (er) {
37
+ consoleLog({ type: 'error', message: `Error generating site map.` })
38
+ consoleLog({ type: 'error', message: er.toString() });
39
+ }
40
+ })();
@@ -0,0 +1,8 @@
1
+ import { createSmartLogInstance } from 'smart-log-node';
2
+
3
+ const logger = createSmartLogInstance();
4
+ const { consoleLog } = logger;
5
+
6
+ export default {
7
+ consoleLog
8
+ }
@@ -0,0 +1,123 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+ import { pathToFileURL } from 'url';
4
+
5
+ import { JSDOM } from 'jsdom';
6
+ import { checkIsArray, checkIsObject } from 'tuijs-util';
7
+
8
+ import { consoleLog } from './_logging.js';
9
+
10
+ async function createSiteMap(configFile, inputFile, outputFile) {
11
+ try {
12
+ const data = fs.readFileSync(inputFile, 'utf-8');
13
+ let routeDataArray = [];
14
+
15
+ switch (inputFile.toLowerCase().split('.').pop()) {
16
+ case 'json':
17
+ routeDataArray = JSON.parse(data);
18
+ break;
19
+ case 'js':
20
+ const fileURL = pathToFileURL(path.resolve(inputFile));
21
+ const module = await import(fileURL);
22
+ routeDataArray = module.default || module;
23
+ break;
24
+ default:
25
+ throw new Error(`The provided inputFile is not a .json or .js file.`);
26
+ }
27
+ if (!checkIsArray(routeDataArray)) {
28
+ throw new Error(`The provided site data is not a valid JavaScript Array.`);
29
+ }
30
+
31
+ const dom = new JSDOM(elmSite(), { contentType: "text/xml" });
32
+ const document = dom.window.document;
33
+
34
+ for (let i = 0; i < routeDataArray.length; i++) {
35
+ const routeObject = routeDataArray[i];
36
+ if (!checkIsObject(routeObject)) {
37
+ consoleLog({ type: 'warning', message: `The provided site data array contains a non-object entry at index ${i}. Skipping this entry.` });
38
+ continue;
39
+ }
40
+
41
+ const routeObjectMapData = routeObject['map'];
42
+ if (!routeObjectMapData) {
43
+ consoleLog({ type: 'warning', message: `The provided site data object at index ${i} is missing the required 'map' property.` });
44
+ continue;
45
+ }
46
+
47
+ const routeObjectRoute = routeObject['route'];
48
+ if (!routeObjectRoute) {
49
+ consoleLog({ type: 'warning', message: `The provided site data object at index ${i} is missing the required 'route' property.` });
50
+ continue;
51
+ }
52
+ if (routeObjectRoute === '*') {
53
+ continue;
54
+ }
55
+
56
+ const routeElement = addRouteToMap(rootUrl, routeObjectRoute, routeObjectMapData, document);
57
+ document.querySelector("urlset").appendChild(routeElement);
58
+ }
59
+
60
+ const siteMapSerialized = new dom.window.XMLSerializer().serializeToString(document);
61
+ const xmlDeclaration = '<?xml version="1.0" encoding="UTF-8"?>\n';
62
+ const siteMapFinal = xmlDeclaration + siteMapSerialized;
63
+ createFile(outputFile, siteMapFinal);
64
+ } catch (er) {
65
+ throw new Error(er);
66
+ }
67
+ }
68
+
69
+ function elmSite() {
70
+ return `<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"></urlset>`;
71
+ }
72
+
73
+ function addRouteToMap(root, route, data, document) {
74
+ try {
75
+ const elmUrl = document.createElementNS(null, 'url');
76
+ if (!elmUrl) {
77
+ throw new Error(`Could not create 'url' element.`);
78
+ }
79
+
80
+ const elmLoc = document.createElementNS(null, 'loc');
81
+ if (elmLoc) {
82
+ elmLoc.textContent = `${root}${route.startsWith('/') ? '' : '/'}${route}`;
83
+ elmUrl.appendChild(elmLoc);
84
+ }
85
+
86
+ for (const [key, value] of Object.entries(data)) {
87
+ const elmUrlChild = document.createElementNS(null, `${key}`);
88
+ if (elmUrlChild) {
89
+ elmUrlChild.textContent = value;
90
+ elmUrl.appendChild(elmUrlChild);
91
+ }
92
+ }
93
+
94
+ const elmLastMod = elmUrl.querySelector('lastmod');
95
+ if (elmLastMod) {
96
+ const date = new Date(elmLastMod.textContent || '');
97
+ elmLastMod.textContent = date.toISOString().split('T')[0];
98
+ }
99
+ elmUrl.appendChild(elmLastMod);
100
+
101
+ if (elmUrl.hasAttribute('xmlns')) {
102
+ elmUrl.removeAttribute('xmlns');
103
+ }
104
+
105
+ return elmUrl;
106
+ } catch (er) {
107
+ throw new Error(er);
108
+ }
109
+ }
110
+
111
+ function createFile(filePath, fileTemplate) {
112
+ try {
113
+ fs.writeFileSync(filePath, fileTemplate);
114
+ consoleLog({ type: 'info', message: `File '${filePath}' created.` });
115
+ return;
116
+ } catch (er) {
117
+ throw new Error(er);
118
+ }
119
+ }
120
+
121
+ export default {
122
+ createSiteMap
123
+ }
File without changes
@@ -0,0 +1,601 @@
1
+ {
2
+ "name": "bin",
3
+ "version": "1.0.0",
4
+ "lockfileVersion": 3,
5
+ "requires": true,
6
+ "packages": {
7
+ "": {
8
+ "name": "bin",
9
+ "version": "1.0.0",
10
+ "dependencies": {
11
+ "jsdom": "^27.4.0",
12
+ "smart-log-node": "^1.1.4",
13
+ "tuijs-util": "^1.5.1"
14
+ }
15
+ },
16
+ "node_modules/@acemir/cssom": {
17
+ "version": "0.9.31",
18
+ "resolved": "https://registry.npmjs.org/@acemir/cssom/-/cssom-0.9.31.tgz",
19
+ "integrity": "sha512-ZnR3GSaH+/vJ0YlHau21FjfLYjMpYVIzTD8M8vIEQvIGxeOXyXdzCI140rrCY862p/C/BbzWsjc1dgnM9mkoTA==",
20
+ "license": "MIT"
21
+ },
22
+ "node_modules/@asamuzakjp/css-color": {
23
+ "version": "4.1.1",
24
+ "resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-4.1.1.tgz",
25
+ "integrity": "sha512-B0Hv6G3gWGMn0xKJ0txEi/jM5iFpT3MfDxmhZFb4W047GvytCf1DHQ1D69W3zHI4yWe2aTZAA0JnbMZ7Xc8DuQ==",
26
+ "license": "MIT",
27
+ "dependencies": {
28
+ "@csstools/css-calc": "^2.1.4",
29
+ "@csstools/css-color-parser": "^3.1.0",
30
+ "@csstools/css-parser-algorithms": "^3.0.5",
31
+ "@csstools/css-tokenizer": "^3.0.4",
32
+ "lru-cache": "^11.2.4"
33
+ }
34
+ },
35
+ "node_modules/@asamuzakjp/dom-selector": {
36
+ "version": "6.7.6",
37
+ "resolved": "https://registry.npmjs.org/@asamuzakjp/dom-selector/-/dom-selector-6.7.6.tgz",
38
+ "integrity": "sha512-hBaJER6A9MpdG3WgdlOolHmbOYvSk46y7IQN/1+iqiCuUu6iWdQrs9DGKF8ocqsEqWujWf/V7b7vaDgiUmIvUg==",
39
+ "license": "MIT",
40
+ "dependencies": {
41
+ "@asamuzakjp/nwsapi": "^2.3.9",
42
+ "bidi-js": "^1.0.3",
43
+ "css-tree": "^3.1.0",
44
+ "is-potential-custom-element-name": "^1.0.1",
45
+ "lru-cache": "^11.2.4"
46
+ }
47
+ },
48
+ "node_modules/@asamuzakjp/nwsapi": {
49
+ "version": "2.3.9",
50
+ "resolved": "https://registry.npmjs.org/@asamuzakjp/nwsapi/-/nwsapi-2.3.9.tgz",
51
+ "integrity": "sha512-n8GuYSrI9bF7FFZ/SjhwevlHc8xaVlb/7HmHelnc/PZXBD2ZR49NnN9sMMuDdEGPeeRQ5d0hqlSlEpgCX3Wl0Q==",
52
+ "license": "MIT"
53
+ },
54
+ "node_modules/@csstools/color-helpers": {
55
+ "version": "5.1.0",
56
+ "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-5.1.0.tgz",
57
+ "integrity": "sha512-S11EXWJyy0Mz5SYvRmY8nJYTFFd1LCNV+7cXyAgQtOOuzb4EsgfqDufL+9esx72/eLhsRdGZwaldu/h+E4t4BA==",
58
+ "funding": [
59
+ {
60
+ "type": "github",
61
+ "url": "https://github.com/sponsors/csstools"
62
+ },
63
+ {
64
+ "type": "opencollective",
65
+ "url": "https://opencollective.com/csstools"
66
+ }
67
+ ],
68
+ "license": "MIT-0",
69
+ "engines": {
70
+ "node": ">=18"
71
+ }
72
+ },
73
+ "node_modules/@csstools/css-calc": {
74
+ "version": "2.1.4",
75
+ "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-2.1.4.tgz",
76
+ "integrity": "sha512-3N8oaj+0juUw/1H3YwmDDJXCgTB1gKU6Hc/bB502u9zR0q2vd786XJH9QfrKIEgFlZmhZiq6epXl4rHqhzsIgQ==",
77
+ "funding": [
78
+ {
79
+ "type": "github",
80
+ "url": "https://github.com/sponsors/csstools"
81
+ },
82
+ {
83
+ "type": "opencollective",
84
+ "url": "https://opencollective.com/csstools"
85
+ }
86
+ ],
87
+ "license": "MIT",
88
+ "engines": {
89
+ "node": ">=18"
90
+ },
91
+ "peerDependencies": {
92
+ "@csstools/css-parser-algorithms": "^3.0.5",
93
+ "@csstools/css-tokenizer": "^3.0.4"
94
+ }
95
+ },
96
+ "node_modules/@csstools/css-color-parser": {
97
+ "version": "3.1.0",
98
+ "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-3.1.0.tgz",
99
+ "integrity": "sha512-nbtKwh3a6xNVIp/VRuXV64yTKnb1IjTAEEh3irzS+HkKjAOYLTGNb9pmVNntZ8iVBHcWDA2Dof0QtPgFI1BaTA==",
100
+ "funding": [
101
+ {
102
+ "type": "github",
103
+ "url": "https://github.com/sponsors/csstools"
104
+ },
105
+ {
106
+ "type": "opencollective",
107
+ "url": "https://opencollective.com/csstools"
108
+ }
109
+ ],
110
+ "license": "MIT",
111
+ "dependencies": {
112
+ "@csstools/color-helpers": "^5.1.0",
113
+ "@csstools/css-calc": "^2.1.4"
114
+ },
115
+ "engines": {
116
+ "node": ">=18"
117
+ },
118
+ "peerDependencies": {
119
+ "@csstools/css-parser-algorithms": "^3.0.5",
120
+ "@csstools/css-tokenizer": "^3.0.4"
121
+ }
122
+ },
123
+ "node_modules/@csstools/css-parser-algorithms": {
124
+ "version": "3.0.5",
125
+ "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-3.0.5.tgz",
126
+ "integrity": "sha512-DaDeUkXZKjdGhgYaHNJTV9pV7Y9B3b644jCLs9Upc3VeNGg6LWARAT6O+Q+/COo+2gg/bM5rhpMAtf70WqfBdQ==",
127
+ "funding": [
128
+ {
129
+ "type": "github",
130
+ "url": "https://github.com/sponsors/csstools"
131
+ },
132
+ {
133
+ "type": "opencollective",
134
+ "url": "https://opencollective.com/csstools"
135
+ }
136
+ ],
137
+ "license": "MIT",
138
+ "engines": {
139
+ "node": ">=18"
140
+ },
141
+ "peerDependencies": {
142
+ "@csstools/css-tokenizer": "^3.0.4"
143
+ }
144
+ },
145
+ "node_modules/@csstools/css-syntax-patches-for-csstree": {
146
+ "version": "1.0.25",
147
+ "resolved": "https://registry.npmjs.org/@csstools/css-syntax-patches-for-csstree/-/css-syntax-patches-for-csstree-1.0.25.tgz",
148
+ "integrity": "sha512-g0Kw9W3vjx5BEBAF8c5Fm2NcB/Fs8jJXh85aXqwEXiL+tqtOut07TWgyaGzAAfTM+gKckrrncyeGEZPcaRgm2Q==",
149
+ "funding": [
150
+ {
151
+ "type": "github",
152
+ "url": "https://github.com/sponsors/csstools"
153
+ },
154
+ {
155
+ "type": "opencollective",
156
+ "url": "https://opencollective.com/csstools"
157
+ }
158
+ ],
159
+ "license": "MIT-0",
160
+ "engines": {
161
+ "node": ">=18"
162
+ }
163
+ },
164
+ "node_modules/@csstools/css-tokenizer": {
165
+ "version": "3.0.4",
166
+ "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-3.0.4.tgz",
167
+ "integrity": "sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw==",
168
+ "funding": [
169
+ {
170
+ "type": "github",
171
+ "url": "https://github.com/sponsors/csstools"
172
+ },
173
+ {
174
+ "type": "opencollective",
175
+ "url": "https://opencollective.com/csstools"
176
+ }
177
+ ],
178
+ "license": "MIT",
179
+ "engines": {
180
+ "node": ">=18"
181
+ }
182
+ },
183
+ "node_modules/@exodus/bytes": {
184
+ "version": "1.9.0",
185
+ "resolved": "https://registry.npmjs.org/@exodus/bytes/-/bytes-1.9.0.tgz",
186
+ "integrity": "sha512-lagqsvnk09NKogQaN/XrtlWeUF8SRhT12odMvbTIIaVObqzwAogL6jhR4DAp0gPuKoM1AOVrKUshJpRdpMFrww==",
187
+ "license": "MIT",
188
+ "engines": {
189
+ "node": "^20.19.0 || ^22.12.0 || >=24.0.0"
190
+ },
191
+ "peerDependencies": {
192
+ "@noble/hashes": "^1.8.0 || ^2.0.0"
193
+ },
194
+ "peerDependenciesMeta": {
195
+ "@noble/hashes": {
196
+ "optional": true
197
+ }
198
+ }
199
+ },
200
+ "node_modules/agent-base": {
201
+ "version": "7.1.4",
202
+ "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz",
203
+ "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==",
204
+ "license": "MIT",
205
+ "engines": {
206
+ "node": ">= 14"
207
+ }
208
+ },
209
+ "node_modules/bidi-js": {
210
+ "version": "1.0.3",
211
+ "resolved": "https://registry.npmjs.org/bidi-js/-/bidi-js-1.0.3.tgz",
212
+ "integrity": "sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw==",
213
+ "license": "MIT",
214
+ "dependencies": {
215
+ "require-from-string": "^2.0.2"
216
+ }
217
+ },
218
+ "node_modules/css-tree": {
219
+ "version": "3.1.0",
220
+ "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-3.1.0.tgz",
221
+ "integrity": "sha512-0eW44TGN5SQXU1mWSkKwFstI/22X2bG1nYzZTYMAWjylYURhse752YgbE4Cx46AC+bAvI+/dYTPRk1LqSUnu6w==",
222
+ "license": "MIT",
223
+ "dependencies": {
224
+ "mdn-data": "2.12.2",
225
+ "source-map-js": "^1.0.1"
226
+ },
227
+ "engines": {
228
+ "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0"
229
+ }
230
+ },
231
+ "node_modules/cssstyle": {
232
+ "version": "5.3.7",
233
+ "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-5.3.7.tgz",
234
+ "integrity": "sha512-7D2EPVltRrsTkhpQmksIu+LxeWAIEk6wRDMJ1qljlv+CKHJM+cJLlfhWIzNA44eAsHXSNe3+vO6DW1yCYx8SuQ==",
235
+ "license": "MIT",
236
+ "dependencies": {
237
+ "@asamuzakjp/css-color": "^4.1.1",
238
+ "@csstools/css-syntax-patches-for-csstree": "^1.0.21",
239
+ "css-tree": "^3.1.0",
240
+ "lru-cache": "^11.2.4"
241
+ },
242
+ "engines": {
243
+ "node": ">=20"
244
+ }
245
+ },
246
+ "node_modules/data-urls": {
247
+ "version": "6.0.1",
248
+ "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-6.0.1.tgz",
249
+ "integrity": "sha512-euIQENZg6x8mj3fO6o9+fOW8MimUI4PpD/fZBhJfeioZVy9TUpM4UY7KjQNVZFlqwJ0UdzRDzkycB997HEq1BQ==",
250
+ "license": "MIT",
251
+ "dependencies": {
252
+ "whatwg-mimetype": "^5.0.0",
253
+ "whatwg-url": "^15.1.0"
254
+ },
255
+ "engines": {
256
+ "node": ">=20"
257
+ }
258
+ },
259
+ "node_modules/data-urls/node_modules/whatwg-mimetype": {
260
+ "version": "5.0.0",
261
+ "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-5.0.0.tgz",
262
+ "integrity": "sha512-sXcNcHOC51uPGF0P/D4NVtrkjSU2fNsm9iog4ZvZJsL3rjoDAzXZhkm2MWt1y+PUdggKAYVoMAIYcs78wJ51Cw==",
263
+ "license": "MIT",
264
+ "engines": {
265
+ "node": ">=20"
266
+ }
267
+ },
268
+ "node_modules/debug": {
269
+ "version": "4.4.3",
270
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
271
+ "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
272
+ "license": "MIT",
273
+ "dependencies": {
274
+ "ms": "^2.1.3"
275
+ },
276
+ "engines": {
277
+ "node": ">=6.0"
278
+ },
279
+ "peerDependenciesMeta": {
280
+ "supports-color": {
281
+ "optional": true
282
+ }
283
+ }
284
+ },
285
+ "node_modules/decimal.js": {
286
+ "version": "10.6.0",
287
+ "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.6.0.tgz",
288
+ "integrity": "sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==",
289
+ "license": "MIT"
290
+ },
291
+ "node_modules/entities": {
292
+ "version": "6.0.1",
293
+ "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz",
294
+ "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==",
295
+ "license": "BSD-2-Clause",
296
+ "engines": {
297
+ "node": ">=0.12"
298
+ },
299
+ "funding": {
300
+ "url": "https://github.com/fb55/entities?sponsor=1"
301
+ }
302
+ },
303
+ "node_modules/html-encoding-sniffer": {
304
+ "version": "6.0.0",
305
+ "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-6.0.0.tgz",
306
+ "integrity": "sha512-CV9TW3Y3f8/wT0BRFc1/KAVQ3TUHiXmaAb6VW9vtiMFf7SLoMd1PdAc4W3KFOFETBJUb90KatHqlsZMWV+R9Gg==",
307
+ "license": "MIT",
308
+ "dependencies": {
309
+ "@exodus/bytes": "^1.6.0"
310
+ },
311
+ "engines": {
312
+ "node": "^20.19.0 || ^22.12.0 || >=24.0.0"
313
+ }
314
+ },
315
+ "node_modules/http-proxy-agent": {
316
+ "version": "7.0.2",
317
+ "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz",
318
+ "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==",
319
+ "license": "MIT",
320
+ "dependencies": {
321
+ "agent-base": "^7.1.0",
322
+ "debug": "^4.3.4"
323
+ },
324
+ "engines": {
325
+ "node": ">= 14"
326
+ }
327
+ },
328
+ "node_modules/https-proxy-agent": {
329
+ "version": "7.0.6",
330
+ "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz",
331
+ "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==",
332
+ "license": "MIT",
333
+ "dependencies": {
334
+ "agent-base": "^7.1.2",
335
+ "debug": "4"
336
+ },
337
+ "engines": {
338
+ "node": ">= 14"
339
+ }
340
+ },
341
+ "node_modules/is-potential-custom-element-name": {
342
+ "version": "1.0.1",
343
+ "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz",
344
+ "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==",
345
+ "license": "MIT"
346
+ },
347
+ "node_modules/jsdom": {
348
+ "version": "27.4.0",
349
+ "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-27.4.0.tgz",
350
+ "integrity": "sha512-mjzqwWRD9Y1J1KUi7W97Gja1bwOOM5Ug0EZ6UDK3xS7j7mndrkwozHtSblfomlzyB4NepioNt+B2sOSzczVgtQ==",
351
+ "license": "MIT",
352
+ "dependencies": {
353
+ "@acemir/cssom": "^0.9.28",
354
+ "@asamuzakjp/dom-selector": "^6.7.6",
355
+ "@exodus/bytes": "^1.6.0",
356
+ "cssstyle": "^5.3.4",
357
+ "data-urls": "^6.0.0",
358
+ "decimal.js": "^10.6.0",
359
+ "html-encoding-sniffer": "^6.0.0",
360
+ "http-proxy-agent": "^7.0.2",
361
+ "https-proxy-agent": "^7.0.6",
362
+ "is-potential-custom-element-name": "^1.0.1",
363
+ "parse5": "^8.0.0",
364
+ "saxes": "^6.0.0",
365
+ "symbol-tree": "^3.2.4",
366
+ "tough-cookie": "^6.0.0",
367
+ "w3c-xmlserializer": "^5.0.0",
368
+ "webidl-conversions": "^8.0.0",
369
+ "whatwg-mimetype": "^4.0.0",
370
+ "whatwg-url": "^15.1.0",
371
+ "ws": "^8.18.3",
372
+ "xml-name-validator": "^5.0.0"
373
+ },
374
+ "engines": {
375
+ "node": "^20.19.0 || ^22.12.0 || >=24.0.0"
376
+ },
377
+ "peerDependencies": {
378
+ "canvas": "^3.0.0"
379
+ },
380
+ "peerDependenciesMeta": {
381
+ "canvas": {
382
+ "optional": true
383
+ }
384
+ }
385
+ },
386
+ "node_modules/lru-cache": {
387
+ "version": "11.2.4",
388
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.4.tgz",
389
+ "integrity": "sha512-B5Y16Jr9LB9dHVkh6ZevG+vAbOsNOYCX+sXvFWFu7B3Iz5mijW3zdbMyhsh8ANd2mSWBYdJgnqi+mL7/LrOPYg==",
390
+ "license": "BlueOak-1.0.0",
391
+ "engines": {
392
+ "node": "20 || >=22"
393
+ }
394
+ },
395
+ "node_modules/mdn-data": {
396
+ "version": "2.12.2",
397
+ "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.12.2.tgz",
398
+ "integrity": "sha512-IEn+pegP1aManZuckezWCO+XZQDplx1366JoVhTpMpBB1sPey/SbveZQUosKiKiGYjg1wH4pMlNgXbCiYgihQA==",
399
+ "license": "CC0-1.0"
400
+ },
401
+ "node_modules/ms": {
402
+ "version": "2.1.3",
403
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
404
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
405
+ "license": "MIT"
406
+ },
407
+ "node_modules/parse5": {
408
+ "version": "8.0.0",
409
+ "resolved": "https://registry.npmjs.org/parse5/-/parse5-8.0.0.tgz",
410
+ "integrity": "sha512-9m4m5GSgXjL4AjumKzq1Fgfp3Z8rsvjRNbnkVwfu2ImRqE5D0LnY2QfDen18FSY9C573YU5XxSapdHZTZ2WolA==",
411
+ "license": "MIT",
412
+ "dependencies": {
413
+ "entities": "^6.0.0"
414
+ },
415
+ "funding": {
416
+ "url": "https://github.com/inikulin/parse5?sponsor=1"
417
+ }
418
+ },
419
+ "node_modules/punycode": {
420
+ "version": "2.3.1",
421
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
422
+ "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
423
+ "license": "MIT",
424
+ "engines": {
425
+ "node": ">=6"
426
+ }
427
+ },
428
+ "node_modules/require-from-string": {
429
+ "version": "2.0.2",
430
+ "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
431
+ "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
432
+ "license": "MIT",
433
+ "engines": {
434
+ "node": ">=0.10.0"
435
+ }
436
+ },
437
+ "node_modules/saxes": {
438
+ "version": "6.0.0",
439
+ "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz",
440
+ "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==",
441
+ "license": "ISC",
442
+ "dependencies": {
443
+ "xmlchars": "^2.2.0"
444
+ },
445
+ "engines": {
446
+ "node": ">=v12.22.7"
447
+ }
448
+ },
449
+ "node_modules/smart-log-node": {
450
+ "version": "1.1.4",
451
+ "resolved": "https://registry.npmjs.org/smart-log-node/-/smart-log-node-1.1.4.tgz",
452
+ "integrity": "sha512-fvYkKRHQA7BCNrqwKNYvdowyOU9O6yCeBibQHYwm4DetI+FZkHNwb+TTxbVFDiI+DBN/7rXICylDqPyVS59IHw==",
453
+ "license": "MIT",
454
+ "engines": {
455
+ "node": ">=14.0.0"
456
+ }
457
+ },
458
+ "node_modules/source-map-js": {
459
+ "version": "1.2.1",
460
+ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
461
+ "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
462
+ "license": "BSD-3-Clause",
463
+ "engines": {
464
+ "node": ">=0.10.0"
465
+ }
466
+ },
467
+ "node_modules/symbol-tree": {
468
+ "version": "3.2.4",
469
+ "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz",
470
+ "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==",
471
+ "license": "MIT"
472
+ },
473
+ "node_modules/tldts": {
474
+ "version": "7.0.19",
475
+ "resolved": "https://registry.npmjs.org/tldts/-/tldts-7.0.19.tgz",
476
+ "integrity": "sha512-8PWx8tvC4jDB39BQw1m4x8y5MH1BcQ5xHeL2n7UVFulMPH/3Q0uiamahFJ3lXA0zO2SUyRXuVVbWSDmstlt9YA==",
477
+ "license": "MIT",
478
+ "dependencies": {
479
+ "tldts-core": "^7.0.19"
480
+ },
481
+ "bin": {
482
+ "tldts": "bin/cli.js"
483
+ }
484
+ },
485
+ "node_modules/tldts-core": {
486
+ "version": "7.0.19",
487
+ "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-7.0.19.tgz",
488
+ "integrity": "sha512-lJX2dEWx0SGH4O6p+7FPwYmJ/bu1JbcGJ8RLaG9b7liIgZ85itUVEPbMtWRVrde/0fnDPEPHW10ZsKW3kVsE9A==",
489
+ "license": "MIT"
490
+ },
491
+ "node_modules/tough-cookie": {
492
+ "version": "6.0.0",
493
+ "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-6.0.0.tgz",
494
+ "integrity": "sha512-kXuRi1mtaKMrsLUxz3sQYvVl37B0Ns6MzfrtV5DvJceE9bPyspOqk9xxv7XbZWcfLWbFmm997vl83qUWVJA64w==",
495
+ "license": "BSD-3-Clause",
496
+ "dependencies": {
497
+ "tldts": "^7.0.5"
498
+ },
499
+ "engines": {
500
+ "node": ">=16"
501
+ }
502
+ },
503
+ "node_modules/tr46": {
504
+ "version": "6.0.0",
505
+ "resolved": "https://registry.npmjs.org/tr46/-/tr46-6.0.0.tgz",
506
+ "integrity": "sha512-bLVMLPtstlZ4iMQHpFHTR7GAGj2jxi8Dg0s2h2MafAE4uSWF98FC/3MomU51iQAMf8/qDUbKWf5GxuvvVcXEhw==",
507
+ "license": "MIT",
508
+ "dependencies": {
509
+ "punycode": "^2.3.1"
510
+ },
511
+ "engines": {
512
+ "node": ">=20"
513
+ }
514
+ },
515
+ "node_modules/tuijs-util": {
516
+ "version": "1.5.1",
517
+ "resolved": "https://registry.npmjs.org/tuijs-util/-/tuijs-util-1.5.1.tgz",
518
+ "integrity": "sha512-J+Z3AHwbq8gwqDXysKTGCch/jy01njVZGGQVDWunTsw/SilWCLgoxFu6DrYFgZUtGDjDlUyOE7VN6iyIXFPgWA==",
519
+ "license": "MIT"
520
+ },
521
+ "node_modules/w3c-xmlserializer": {
522
+ "version": "5.0.0",
523
+ "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz",
524
+ "integrity": "sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==",
525
+ "license": "MIT",
526
+ "dependencies": {
527
+ "xml-name-validator": "^5.0.0"
528
+ },
529
+ "engines": {
530
+ "node": ">=18"
531
+ }
532
+ },
533
+ "node_modules/webidl-conversions": {
534
+ "version": "8.0.1",
535
+ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-8.0.1.tgz",
536
+ "integrity": "sha512-BMhLD/Sw+GbJC21C/UgyaZX41nPt8bUTg+jWyDeg7e7YN4xOM05YPSIXceACnXVtqyEw/LMClUQMtMZ+PGGpqQ==",
537
+ "license": "BSD-2-Clause",
538
+ "engines": {
539
+ "node": ">=20"
540
+ }
541
+ },
542
+ "node_modules/whatwg-mimetype": {
543
+ "version": "4.0.0",
544
+ "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz",
545
+ "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==",
546
+ "license": "MIT",
547
+ "engines": {
548
+ "node": ">=18"
549
+ }
550
+ },
551
+ "node_modules/whatwg-url": {
552
+ "version": "15.1.0",
553
+ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-15.1.0.tgz",
554
+ "integrity": "sha512-2ytDk0kiEj/yu90JOAp44PVPUkO9+jVhyf+SybKlRHSDlvOOZhdPIrr7xTH64l4WixO2cP+wQIcgujkGBPPz6g==",
555
+ "license": "MIT",
556
+ "dependencies": {
557
+ "tr46": "^6.0.0",
558
+ "webidl-conversions": "^8.0.0"
559
+ },
560
+ "engines": {
561
+ "node": ">=20"
562
+ }
563
+ },
564
+ "node_modules/ws": {
565
+ "version": "8.19.0",
566
+ "resolved": "https://registry.npmjs.org/ws/-/ws-8.19.0.tgz",
567
+ "integrity": "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==",
568
+ "license": "MIT",
569
+ "engines": {
570
+ "node": ">=10.0.0"
571
+ },
572
+ "peerDependencies": {
573
+ "bufferutil": "^4.0.1",
574
+ "utf-8-validate": ">=5.0.2"
575
+ },
576
+ "peerDependenciesMeta": {
577
+ "bufferutil": {
578
+ "optional": true
579
+ },
580
+ "utf-8-validate": {
581
+ "optional": true
582
+ }
583
+ }
584
+ },
585
+ "node_modules/xml-name-validator": {
586
+ "version": "5.0.0",
587
+ "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz",
588
+ "integrity": "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==",
589
+ "license": "Apache-2.0",
590
+ "engines": {
591
+ "node": ">=18"
592
+ }
593
+ },
594
+ "node_modules/xmlchars": {
595
+ "version": "2.2.0",
596
+ "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz",
597
+ "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==",
598
+ "license": "MIT"
599
+ }
600
+ }
601
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ "name": "bin",
3
+ "version": "1.0.0",
4
+ "description": "",
5
+ "main": "index.js",
6
+ "author": "TechTB",
7
+ "type": "module",
8
+ "dependencies": {
9
+ "jsdom": "^27.4.0",
10
+ "smart-log-node": "^1.1.4",
11
+ "tuijs-util": "^1.5.1"
12
+ }
13
+ }
@@ -0,0 +1,3 @@
1
+ export { createMetaInstance, createMetaInstance as tuijsMeta } from "./lib/service.js";
2
+ export type { MetaRoute, MetaTag, MetaTypeKey } from "./lib/models.js";
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,IAAI,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACvF,YAAY,EAAE,SAAS,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,3 @@
1
+ export { createMetaInstance, createMetaInstance as tuijsMeta } from "./lib/service.js";
2
+ // TO DO - Update readme
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,IAAI,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAGvF,wBAAwB"}
@@ -0,0 +1,19 @@
1
+ export type MetaTypeKey = 'name' | 'property' | 'itemprop';
2
+ export type MetaTag = {
3
+ [K in MetaTypeKey]?: string;
4
+ } & {
5
+ content: string;
6
+ };
7
+ export interface MetaRoute {
8
+ route: string;
9
+ title?: string;
10
+ meta?: Array<MetaTag>;
11
+ map?: Map;
12
+ }
13
+ export interface Map {
14
+ loc: string;
15
+ lastmod?: string;
16
+ changefreq?: 'always' | 'hourly' | 'daily' | 'weekly' | 'monthly' | 'yearly' | 'never';
17
+ priority?: number;
18
+ }
19
+ //# sourceMappingURL=models.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"models.d.ts","sourceRoot":"","sources":["../../src/lib/models.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,UAAU,GAAG,UAAU,CAAC;AAE3D,MAAM,MAAM,OAAO,GAAG;KACjB,CAAC,IAAI,WAAW,CAAC,CAAC,EAAE,MAAM;CAC9B,GAAG;IACA,OAAO,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,WAAW,SAAS;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;IACtB,GAAG,CAAC,EAAE,GAAG,CAAC;CACb;AAED,MAAM,WAAW,GAAG;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,QAAQ,GAAG,QAAQ,GAAG,OAAO,GAAG,QAAQ,GAAG,SAAS,GAAG,QAAQ,GAAG,OAAO,CAAC;IACvF,QAAQ,CAAC,EAAE,MAAM,CAAC;CACrB"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=models.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"models.js","sourceRoot":"","sources":["../../src/lib/models.ts"],"names":[],"mappings":""}
@@ -0,0 +1,7 @@
1
+ import type { MetaRoute, MetaTag } from './models.js';
2
+ export declare function createMetaInstance(): {
3
+ setMetaData: (metaRoutes: MetaRoute[]) => void;
4
+ metaUpdate: (metaData: MetaTag[]) => void;
5
+ metaRouteUpdate: (route: string) => void;
6
+ };
7
+ //# sourceMappingURL=service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../src/lib/service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAEtD,wBAAgB,kBAAkB;8BAGG,SAAS,EAAE;2BAKd,OAAO,EAAE;6BAMP,MAAM;EAkEzC"}
@@ -0,0 +1,78 @@
1
+ export function createMetaInstance() {
2
+ const metaData = [];
3
+ function setMetaData(metaRoutes) {
4
+ metaData.length = 0;
5
+ metaData.push(...metaRoutes);
6
+ }
7
+ function metaUpdate(metaData) {
8
+ for (let i = 0; i < metaData.length; i++) {
9
+ metaUpdateTag(metaData[i]);
10
+ }
11
+ }
12
+ function metaRouteUpdate(route) {
13
+ let globalRouteMeta, specifiedRouteMeta;
14
+ for (let i = 0; i < metaData.length; i++) {
15
+ const item = metaData[i];
16
+ if (item.route === '*')
17
+ globalRouteMeta = item;
18
+ if (item.route === route)
19
+ specifiedRouteMeta = item;
20
+ if (globalRouteMeta && specifiedRouteMeta)
21
+ break;
22
+ }
23
+ if (!globalRouteMeta && !specifiedRouteMeta) {
24
+ console.error(`tuijs-meta: No meta data found for route "${route}", and no global meta route defined.`);
25
+ return;
26
+ }
27
+ if (globalRouteMeta) {
28
+ if (globalRouteMeta.meta) {
29
+ const globalMeta = globalRouteMeta.meta;
30
+ for (let i = 0; i < globalMeta.length; i++) {
31
+ metaUpdateTag(globalMeta[i]);
32
+ }
33
+ }
34
+ }
35
+ if (!specifiedRouteMeta) {
36
+ document.title = globalRouteMeta?.title || 'Unknown Page';
37
+ console.warn(`tuijs-meta: No specific meta data found for route "${route}".`);
38
+ return;
39
+ }
40
+ if (specifiedRouteMeta.title) {
41
+ document.title = specifiedRouteMeta.title;
42
+ }
43
+ else {
44
+ document.title = globalRouteMeta?.title || 'Unknown Page';
45
+ }
46
+ if (specifiedRouteMeta.meta) {
47
+ const dataMeta = specifiedRouteMeta.meta;
48
+ for (let i = 0; i < dataMeta.length; i++) {
49
+ metaUpdateTag(dataMeta[i]);
50
+ }
51
+ }
52
+ return;
53
+ }
54
+ function metaUpdateTag(newMetaTag) {
55
+ const existingMetaTagList = Array.from(document.getElementsByTagName('meta'));
56
+ // Find the meta type key and value dynamically
57
+ const metaEntries = Object.entries(newMetaTag).filter(([key]) => key !== 'content');
58
+ const [typeKey, typeValue] = metaEntries[0];
59
+ // Remove existing meta tags that match the typeKey and typeValue
60
+ existingMetaTagList.forEach(existingMetaTag => {
61
+ if (existingMetaTag.getAttribute(typeKey) === typeValue) {
62
+ existingMetaTag.remove();
63
+ }
64
+ });
65
+ // Create and append the new meta tag
66
+ const elmMeta = document.createElement('meta');
67
+ elmMeta.setAttribute(typeKey, typeValue);
68
+ elmMeta.setAttribute('content', newMetaTag.content);
69
+ document.head.appendChild(elmMeta);
70
+ return true;
71
+ }
72
+ return {
73
+ setMetaData,
74
+ metaUpdate,
75
+ metaRouteUpdate
76
+ };
77
+ }
78
+ //# sourceMappingURL=service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service.js","sourceRoot":"","sources":["../../src/lib/service.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,13 +1,30 @@
1
- {
2
- "name": "tuijs-meta",
3
- "version": "0.0.9",
4
- "description": "A JavaScript utility that manipulates meta data tags based on provided data.",
5
- "main": "src/index.js",
6
- "author": "TechTB",
7
- "license": "MIT",
8
- "repository": "github:TechTB-OpenSource/tuijs-meta",
9
- "type": "module",
10
- "dependencies": {
11
- "tuijs-util": "^1.4.9"
12
- }
13
- }
1
+ {
2
+ "name": "tuijs-meta",
3
+ "version": "0.1.2",
4
+ "description": "A JavaScript utility that manipulates meta data tags based on provided data.",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "exports": {
8
+ ".": {
9
+ "types": "./dist/index.d.ts",
10
+ "import": "./dist/index.js",
11
+ "require": "./dist/index.js"
12
+ }
13
+ },
14
+ "author": "TechTB",
15
+ "license": "MIT",
16
+ "repository": "github:TechTB-OpenSource/tuijs-meta",
17
+ "type": "module",
18
+ "scripts": {
19
+ "clean": "rimraf dist",
20
+ "build": "npm run clean && tsc",
21
+ "sitemap": "node ./bin/index.js"
22
+ },
23
+ "dependencies": {
24
+ "tuijs-util": "^1.5.1"
25
+ },
26
+ "devDependencies": {
27
+ "rimraf": "^6.0.1",
28
+ "typescript": "^5.9.3"
29
+ }
30
+ }
package/src/index.ts ADDED
@@ -0,0 +1,4 @@
1
+ export { createMetaInstance, createMetaInstance as tuijsMeta } from "./lib/service.js";
2
+ export type { MetaRoute, MetaTag, MetaTypeKey } from "./lib/models.js";
3
+
4
+ // TO DO - Update readme
@@ -0,0 +1,21 @@
1
+ export type MetaTypeKey = 'name' | 'property' | 'itemprop';
2
+
3
+ export type MetaTag = {
4
+ [K in MetaTypeKey]?: string;
5
+ } & {
6
+ content: string;
7
+ };
8
+
9
+ export interface MetaRoute {
10
+ route: string;
11
+ title?: string;
12
+ meta?: Array<MetaTag>;
13
+ map?: Map;
14
+ }
15
+
16
+ export interface Map {
17
+ loc: string;
18
+ lastmod?: string;
19
+ changefreq?: 'always' | 'hourly' | 'daily' | 'weekly' | 'monthly' | 'yearly' | 'never';
20
+ priority?: number;
21
+ }
@@ -0,0 +1,83 @@
1
+ import type { MetaRoute, MetaTag } from './models.js';
2
+
3
+ export function createMetaInstance() {
4
+ const metaData: MetaRoute[] = [];
5
+
6
+ function setMetaData(metaRoutes: MetaRoute[]) {
7
+ metaData.length = 0;
8
+ metaData.push(...metaRoutes);
9
+ }
10
+
11
+ function metaUpdate(metaData: MetaTag[]) {
12
+ for (let i = 0; i < metaData.length; i++) {
13
+ metaUpdateTag(metaData[i]);
14
+ }
15
+ }
16
+
17
+ function metaRouteUpdate(route: string) {
18
+ let globalRouteMeta, specifiedRouteMeta: MetaRoute | undefined;
19
+ for (let i = 0; i < metaData.length; i++) {
20
+ const item = metaData[i];
21
+ if (item.route === '*') globalRouteMeta = item;
22
+ if (item.route === route) specifiedRouteMeta = item;
23
+ if (globalRouteMeta && specifiedRouteMeta) break;
24
+ }
25
+ if (!globalRouteMeta && !specifiedRouteMeta) {
26
+ console.error(`tuijs-meta: No meta data found for route "${route}", and no global meta route defined.`);
27
+ return;
28
+ }
29
+ if (globalRouteMeta) {
30
+ if (globalRouteMeta.meta) {
31
+ const globalMeta: MetaTag[] = globalRouteMeta.meta;
32
+ for (let i = 0; i < globalMeta.length; i++) {
33
+ metaUpdateTag(globalMeta[i]);
34
+ }
35
+ }
36
+ }
37
+ if (!specifiedRouteMeta) {
38
+ document.title = globalRouteMeta?.title || 'Unknown Page';
39
+ console.warn(`tuijs-meta: No specific meta data found for route "${route}".`);
40
+ return;
41
+ }
42
+ if (specifiedRouteMeta.title) {
43
+ document.title = specifiedRouteMeta.title;
44
+ } else {
45
+ document.title = globalRouteMeta?.title || 'Unknown Page';
46
+ }
47
+ if (specifiedRouteMeta.meta) {
48
+ const dataMeta: MetaTag[] = specifiedRouteMeta.meta;
49
+ for (let i = 0; i < dataMeta.length; i++) {
50
+ metaUpdateTag(dataMeta[i]);
51
+ }
52
+ }
53
+ return;
54
+ }
55
+
56
+ function metaUpdateTag(newMetaTag: MetaTag) {
57
+ const existingMetaTagList = Array.from(document.getElementsByTagName('meta'));
58
+
59
+ // Find the meta type key and value dynamically
60
+ const metaEntries = Object.entries(newMetaTag).filter(([key]) => key !== 'content');
61
+ const [typeKey, typeValue] = metaEntries[0];
62
+
63
+ // Remove existing meta tags that match the typeKey and typeValue
64
+ existingMetaTagList.forEach(existingMetaTag => {
65
+ if (existingMetaTag.getAttribute(typeKey) === typeValue) {
66
+ existingMetaTag.remove();
67
+ }
68
+ });
69
+
70
+ // Create and append the new meta tag
71
+ const elmMeta = document.createElement('meta');
72
+ elmMeta.setAttribute(typeKey, typeValue);
73
+ elmMeta.setAttribute('content', newMetaTag.content);
74
+ document.head.appendChild(elmMeta);
75
+ return true;
76
+ }
77
+
78
+ return {
79
+ setMetaData,
80
+ metaUpdate,
81
+ metaRouteUpdate
82
+ }
83
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,20 @@
1
+ {
2
+ "compilerOptions": {
3
+ "rootDir": "./src",
4
+ "outDir": "./dist",
5
+ "module": "ES2022",
6
+ "target": "ES2020",
7
+ "lib": ["ES2020", "DOM"],
8
+ "moduleResolution": "node",
9
+ "declaration": true,
10
+ "declarationMap": true,
11
+ "sourceMap": true,
12
+ "strict": true,
13
+ "esModuleInterop": true,
14
+ "allowSyntheticDefaultImports": true,
15
+ "forceConsistentCasingInFileNames": true,
16
+ "skipLibCheck": true
17
+ },
18
+ "include": ["src/**/*"],
19
+ "exclude": ["node_modules", "dist"]
20
+ }
package/src/index.js DELETED
@@ -1,2 +0,0 @@
1
- import { metaUpdateHead as tuiMeta } from './lib/tuiMeta.js';
2
- export default tuiMeta;
@@ -1,93 +0,0 @@
1
- import { checkIsObject, checkIsArray } from 'tuijs-util';
2
-
3
- /**
4
- * @typedef {Object} MetaDataTag - A single meta tag data set.
5
- * @property {string} key - The key of a single meta tag attribute.
6
- * @property {string} value - The value of a single meta tag attribute.
7
- * @property {Object<string, string>} [attributes] - A list of attribute pairs for a single meta tag. No expectation for number of pairs.
8
- */
9
-
10
- /**
11
- * @typedef {MetaDataTag[]} MetaDataArray - A list of meta tag data set objects for a single route or site.
12
- */
13
-
14
- /**
15
- * @typedef {Object} SiteRouteData - The site or route data object.
16
- * @property {string} title - The site or route title.
17
- * @property {MetaDataArray} meta - The meta data for the site or route.
18
- */
19
-
20
- /**
21
- * Updates the document head with the provided site or route data.
22
- * @param {SiteRouteData} data - Site or route data object.
23
- * @returns {void}
24
- * @throws {Error} - If the provided data is not an object or meta data is not an array.
25
- */
26
- export function metaUpdateHead(data) {
27
- try {
28
- if (!checkIsObject(data)) {
29
- throw 'Data provided is not an object.'
30
- }
31
- if (data.title) {
32
- document.title = data.title;
33
- }
34
- if (data.meta) {
35
- let dataMeta = data.meta;
36
- if (!checkIsArray(dataMeta)) {
37
- throw 'Site or page meta data is not an array as expected.'
38
- }
39
- for (let i = 0; i < dataMeta.length; i++) {
40
- metaUpdateTag(dataMeta[i]);
41
- }
42
- }
43
- return;
44
- } catch (er) {
45
- throw new Error(`TUI Meta Error: ${er.message}`);
46
- }
47
- }
48
-
49
- /**
50
- * Creates a new meta tag with the provided meta data.
51
- * Any existing meta tag with any matching attribute key/value pair, excluding 'content' keys, will be removed.
52
- * @param {MetaDataArray} data - The meta data for the site or route.
53
- * @returns {boolean} - Returns boolean indicating the success of the meta update.
54
- */
55
- export function metaUpdateTag(data) {
56
- try {
57
- if (!checkIsObject(data)) {
58
- throw 'Data provided is not an object.'
59
- }
60
- // Remove existing meta tags with matching attributes
61
- const existingMetaTags = document.getElementsByTagName('meta');
62
- for (let i = 0; i < existingMetaTags.length; i++) {
63
- const metaTag = existingMetaTags[i];
64
- let hasMatchingAttribute = false; // Assume no matching attribute initially
65
- // Check if any attribute in 'data' matches (ignore 'content' key)
66
- for (const [key, value] of Object.entries(data)) {
67
- if (key === 'content') continue; // Skip the 'content' key
68
-
69
- if (metaTag.getAttribute(key) === value) {
70
- hasMatchingAttribute = true; // Set to true if any attribute matches
71
- break; // Exit loop if any attribute matches
72
- }
73
- }
74
- // If any attribute matches, remove the meta tag
75
- if (hasMatchingAttribute) {
76
- metaTag.remove();
77
- i--; // Adjust index after removal
78
- }
79
- }
80
-
81
-
82
- let elmMeta = document.createElement('meta');
83
- Object.keys(data).forEach(key => {
84
- elmMeta.setAttribute(key, data[key]);
85
- });
86
- document.head.appendChild(elmMeta);
87
- return true;
88
- } catch (er) {
89
- console.error(`TUI Meta Error: ${er.message}`);
90
- return false;
91
- }
92
- }
93
-