@hkdigital/lib-core 0.5.11 → 0.5.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +148 -13
- package/dist/meta/robots/index.d.ts +37 -0
- package/dist/meta/robots/index.js +83 -0
- package/dist/meta/robots/typedef.d.ts +17 -0
- package/dist/meta/robots/typedef.js +12 -0
- package/dist/meta/robots.d.ts +1 -0
- package/dist/meta/robots.js +5 -0
- package/dist/meta/sitemap/index.d.ts +11 -0
- package/dist/meta/sitemap/index.js +63 -0
- package/dist/meta/sitemap/typedef.d.ts +20 -0
- package/dist/meta/sitemap/typedef.js +14 -0
- package/dist/meta/sitemap.d.ts +1 -0
- package/dist/meta/sitemap.js +5 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -32,6 +32,9 @@ pnpm add @skeletonlabs/skeleton
|
|
|
32
32
|
# UI icons
|
|
33
33
|
pnpm add @steeze-ui/heroicons
|
|
34
34
|
|
|
35
|
+
# CSS processing (Tailwind and PostCSS)
|
|
36
|
+
pnpm add tailwindcss @tailwindcss/postcss postcss autoprefixer
|
|
37
|
+
|
|
35
38
|
# Logging
|
|
36
39
|
pnpm add pino pino-pretty
|
|
37
40
|
|
|
@@ -42,13 +45,13 @@ pnpm add jsonwebtoken
|
|
|
42
45
|
pnpm add @eslint/js eslint-plugin-import
|
|
43
46
|
|
|
44
47
|
# Image processing
|
|
45
|
-
pnpm add vite-imagetools
|
|
48
|
+
pnpm add -D vite-imagetools
|
|
46
49
|
```
|
|
47
50
|
|
|
48
51
|
**For other libraries**, install as dev dependencies and declare as peer dependencies:
|
|
49
52
|
```bash
|
|
50
53
|
# Install as dev dependencies and peer dependencies
|
|
51
|
-
pnpm add -D --save-peer @sveltejs/kit svelte svelte-preprocess runed valibot @skeletonlabs/skeleton @steeze-ui/heroicons pino pino-pretty jsonwebtoken @eslint/js eslint-plugin-import vite-imagetools
|
|
54
|
+
pnpm add -D --save-peer @sveltejs/kit svelte svelte-preprocess runed valibot @skeletonlabs/skeleton @steeze-ui/heroicons tailwindcss @tailwindcss/postcss postcss autoprefixer pino pino-pretty jsonwebtoken @eslint/js eslint-plugin-import vite-imagetools
|
|
52
55
|
```
|
|
53
56
|
|
|
54
57
|
### Design System & Configuration
|
|
@@ -135,7 +138,8 @@ This library includes a complete design system with Tailwind CSS integration. Ba
|
|
|
135
138
|
export default config;
|
|
136
139
|
```
|
|
137
140
|
|
|
138
|
-
5. **
|
|
141
|
+
5. **Image import type definitions** - Add imagetools type support to
|
|
142
|
+
`app.d.ts`:
|
|
139
143
|
```typescript
|
|
140
144
|
// src/app.d.ts
|
|
141
145
|
import '@hkdigital/lib-core/config/imagetools.d.ts';
|
|
@@ -179,6 +183,59 @@ This library includes a complete design system with Tailwind CSS integration. Ba
|
|
|
179
183
|
import heroResponsive from '$lib/assets/hero.jpg?preset=photo&responsive';
|
|
180
184
|
```
|
|
181
185
|
|
|
186
|
+
6. **(meta) folder setup** - Copy and configure PWA/favicon generation:
|
|
187
|
+
|
|
188
|
+
The library includes a complete `(meta)` folder with PWA configuration,
|
|
189
|
+
favicon generation, manifest.json, sitemap.xml, and robots.txt endpoints.
|
|
190
|
+
|
|
191
|
+
**Copy the folder to your project:**
|
|
192
|
+
```bash
|
|
193
|
+
cp -r node_modules/@hkdigital/lib-core/src/routes/\(meta\) src/routes/
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
**Customize for your app:**
|
|
197
|
+
- Replace `src/routes/(meta)/favicon.png` with your 512×512px image
|
|
198
|
+
- Edit `src/routes/(meta)/config.js`:
|
|
199
|
+
```javascript
|
|
200
|
+
export const name = 'Your App Name';
|
|
201
|
+
export const shortName = 'App';
|
|
202
|
+
export const description = 'Your app description';
|
|
203
|
+
export const backgroundAndThemeColor = '#082962';
|
|
204
|
+
|
|
205
|
+
// Add your site routes for sitemap
|
|
206
|
+
export const siteRoutes = ['/', '/about', '/contact'];
|
|
207
|
+
|
|
208
|
+
// Configure robots.txt (prevent test sites from being indexed)
|
|
209
|
+
export const robotsConfig = {
|
|
210
|
+
allowedHosts: ['mysite.com', 'www.mysite.com'],
|
|
211
|
+
disallowedPaths: ['/admin/*'],
|
|
212
|
+
includeSitemap: true
|
|
213
|
+
};
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
**Integrate into root layout:**
|
|
217
|
+
```svelte
|
|
218
|
+
<!-- src/routes/+layout.svelte -->
|
|
219
|
+
<script>
|
|
220
|
+
import { Favicons, PWA } from './(meta)/index.js';
|
|
221
|
+
</script>
|
|
222
|
+
|
|
223
|
+
<Favicons />
|
|
224
|
+
<PWA />
|
|
225
|
+
|
|
226
|
+
{@render children()}
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
**What you get:**
|
|
230
|
+
- Automatic favicon generation (16, 32, 192, 512px)
|
|
231
|
+
- Apple touch icons (120, 152, 167, 180px)
|
|
232
|
+
- Dynamic `/manifest.json` endpoint
|
|
233
|
+
- Dynamic `/sitemap.xml` endpoint
|
|
234
|
+
- Dynamic `/robots.txt` with host filtering
|
|
235
|
+
|
|
236
|
+
See [src/routes/(meta)/README.md](./src/routes/(meta)/README.md) for
|
|
237
|
+
complete documentation.
|
|
238
|
+
|
|
182
239
|
### Logging System
|
|
183
240
|
|
|
184
241
|
The library includes a comprehensive logging system that provides:
|
|
@@ -220,34 +277,112 @@ pnpm run upgrade:all # Update all packages
|
|
|
220
277
|
pnpm run publish:npm # Version bump and publish to npm
|
|
221
278
|
```
|
|
222
279
|
|
|
223
|
-
### Import
|
|
280
|
+
### Import Patterns and Export Structure
|
|
224
281
|
|
|
225
|
-
|
|
282
|
+
**Public exports use domain-specific files matching folder names:**
|
|
226
283
|
|
|
227
|
-
|
|
284
|
+
```js
|
|
285
|
+
// Standard pattern: folder → matching .js export file
|
|
286
|
+
import { httpGet, httpPost } from '@hkdigital/lib-core/network/http.js';
|
|
287
|
+
import { CacheManager } from '@hkdigital/lib-core/network/cache.js';
|
|
288
|
+
import { LCHAR } from '@hkdigital/lib-core/constants/regexp.js';
|
|
289
|
+
import { Button } from '@hkdigital/lib-core/ui/primitives.js';
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
**Pattern:**
|
|
293
|
+
- Folder `$lib/network/http/` → Export file `$lib/network/http.js`
|
|
294
|
+
- Folder `$lib/network/cache/` → Export file `$lib/network/cache.js`
|
|
295
|
+
- Folder `$lib/constants/regexp/` → Export file `$lib/constants/regexp.js`
|
|
296
|
+
|
|
297
|
+
**Rare exception - index.js for aggregated APIs:**
|
|
228
298
|
|
|
229
299
|
```js
|
|
230
|
-
//
|
|
231
|
-
import {
|
|
300
|
+
// Only used for large subsystems with public-facing aggregated APIs
|
|
301
|
+
import { designTokens } from '@hkdigital/lib-core/design/index.js';
|
|
232
302
|
```
|
|
233
303
|
|
|
304
|
+
**TypeDefs for JSDoc:**
|
|
305
|
+
|
|
234
306
|
```js
|
|
235
307
|
/**
|
|
236
|
-
* @param {import('@hkdigital/lib-core/network/typedef.js').
|
|
308
|
+
* @param {import('@hkdigital/lib-core/network/typedef.js').HttpGetOptions}
|
|
309
|
+
* options
|
|
237
310
|
*/
|
|
311
|
+
function fetchData(options) {
|
|
312
|
+
// ...
|
|
313
|
+
}
|
|
238
314
|
```
|
|
239
315
|
|
|
240
|
-
###
|
|
316
|
+
### CSS Architecture (app.css)
|
|
241
317
|
|
|
242
|
-
|
|
318
|
+
**CRITICAL**: Your `src/app.css` must include the complete design system
|
|
319
|
+
architecture. Incomplete imports will cause build failures.
|
|
243
320
|
|
|
244
|
-
|
|
321
|
+
**Required structure:**
|
|
245
322
|
|
|
246
323
|
```css
|
|
247
324
|
/* src/app.css */
|
|
248
|
-
|
|
325
|
+
|
|
326
|
+
/* 1. CSS Layers - Controls style precedence */
|
|
327
|
+
@layer theme, base, utilities, components;
|
|
328
|
+
|
|
329
|
+
/* 2. Tailwind CSS Core */
|
|
330
|
+
@import 'tailwindcss';
|
|
331
|
+
|
|
332
|
+
/* 3. HKdigital Design System Theme (ALL required for colors to work) */
|
|
333
|
+
@import '../node_modules/@hkdigital/lib-core/dist/design/themes/hkdev/theme.css' layer(theme);
|
|
334
|
+
@import '../node_modules/@hkdigital/lib-core/dist/design/themes/hkdev/globals.css';
|
|
335
|
+
@import '../node_modules/@hkdigital/lib-core/dist/design/themes/hkdev/components.css' layer(components);
|
|
336
|
+
@import '../node_modules/@hkdigital/lib-core/dist/design/themes/hkdev/responsive.css';
|
|
337
|
+
|
|
338
|
+
/* 4. Skeleton UI Framework */
|
|
339
|
+
@import '@skeletonlabs/skeleton' source('../node_modules/@skeletonlabs/skeleton-svelte/dist');
|
|
340
|
+
@import '@skeletonlabs/skeleton/optional/presets' source('../node_modules/@skeletonlabs/skeleton-svelte/dist');
|
|
341
|
+
|
|
342
|
+
/* 5. Tailwind Configuration Reference */
|
|
343
|
+
@config "../tailwind.config.js";
|
|
344
|
+
|
|
345
|
+
/* 6. Optional: Additional utilities */
|
|
346
|
+
/*@import '../node_modules/@hkdigital/lib-core/dist/css/utilities.css';*/
|
|
249
347
|
```
|
|
250
348
|
|
|
349
|
+
**Why all theme files are required:**
|
|
350
|
+
- Missing any theme file will cause "Cannot apply unknown utility class"
|
|
351
|
+
errors
|
|
352
|
+
- Classes like `bg-surface-100`, `text-primary-500` won't work without
|
|
353
|
+
complete theme
|
|
354
|
+
- All four theme files (theme.css, globals.css, components.css,
|
|
355
|
+
responsive.css) are needed
|
|
356
|
+
|
|
357
|
+
See [src/lib/design/README.md](./src/lib/design/README.md) for complete
|
|
358
|
+
CSS architecture documentation.
|
|
359
|
+
|
|
360
|
+
### Critical: data-theme Attribute
|
|
361
|
+
|
|
362
|
+
**IMPORTANT**: Add `data-theme="hkdev"` to your `<body>` element in
|
|
363
|
+
`src/app.html`. Without this, theme colors will not work correctly.
|
|
364
|
+
|
|
365
|
+
```html
|
|
366
|
+
<!-- src/app.html -->
|
|
367
|
+
<!doctype html>
|
|
368
|
+
<html lang="en">
|
|
369
|
+
<head>
|
|
370
|
+
<meta charset="utf-8" />
|
|
371
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
372
|
+
%sveltekit.head%
|
|
373
|
+
</head>
|
|
374
|
+
<body data-theme="hkdev" data-sveltekit-preload-data="hover">
|
|
375
|
+
<div>%sveltekit.body%</div>
|
|
376
|
+
</body>
|
|
377
|
+
</html>
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
**Why this is required:**
|
|
381
|
+
- Theme CSS custom properties are scoped to `[data-theme='hkdev']`
|
|
382
|
+
- Without this attribute, colors fall back to browser defaults
|
|
383
|
+
- **Symptom**: Colors like `bg-primary-500` show grey instead of magenta
|
|
384
|
+
- **Solution**: Add `data-theme="hkdev"` to `<body>` element
|
|
385
|
+
|
|
251
386
|
## Building the library
|
|
252
387
|
|
|
253
388
|
To build your library:
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/** @typedef {import('./typedef.js').RobotsConfig} RobotsConfig */
|
|
2
|
+
/**
|
|
3
|
+
* Check if hostname matches allowed hosts pattern
|
|
4
|
+
*
|
|
5
|
+
* @param {string} hostname - Hostname to check (e.g., test.mysite.com)
|
|
6
|
+
* @param {string[] | '*' | undefined} allowedHosts - Allowed host patterns
|
|
7
|
+
*
|
|
8
|
+
* @returns {boolean} True if host is allowed
|
|
9
|
+
*/
|
|
10
|
+
export function isHostAllowed(hostname: string, allowedHosts: string[] | "*" | undefined): boolean;
|
|
11
|
+
/**
|
|
12
|
+
* Generate robots.txt with sitemap reference
|
|
13
|
+
*
|
|
14
|
+
* NOTE: If deployed behind a reverse proxy (nginx, Cloudflare, etc.),
|
|
15
|
+
* ensure your adapter is configured to trust proxy headers for correct
|
|
16
|
+
* origin detection:
|
|
17
|
+
*
|
|
18
|
+
* // svelte.config.js
|
|
19
|
+
* export default {
|
|
20
|
+
* kit: {
|
|
21
|
+
* adapter: adapter({
|
|
22
|
+
* // Trust X-Forwarded-* headers from proxy
|
|
23
|
+
* trustProxy: true
|
|
24
|
+
* })
|
|
25
|
+
* }
|
|
26
|
+
* };
|
|
27
|
+
*
|
|
28
|
+
* Without this, url.origin may be http://localhost instead of your
|
|
29
|
+
* actual domain, and the sitemap directive will be omitted.
|
|
30
|
+
*
|
|
31
|
+
* @param {URL} url - Request URL object
|
|
32
|
+
* @param {RobotsConfig} [config] - Robots configuration object
|
|
33
|
+
*
|
|
34
|
+
* @returns {string} robots.txt content
|
|
35
|
+
*/
|
|
36
|
+
export function generateRobotsTxt(url: URL, config?: RobotsConfig): string;
|
|
37
|
+
export type RobotsConfig = import("./typedef.js").RobotsConfig;
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/** @typedef {import('./typedef.js').RobotsConfig} RobotsConfig */
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Check if hostname matches allowed hosts pattern
|
|
5
|
+
*
|
|
6
|
+
* @param {string} hostname - Hostname to check (e.g., test.mysite.com)
|
|
7
|
+
* @param {string[] | '*' | undefined} allowedHosts - Allowed host patterns
|
|
8
|
+
*
|
|
9
|
+
* @returns {boolean} True if host is allowed
|
|
10
|
+
*/
|
|
11
|
+
export function isHostAllowed(hostname, allowedHosts) {
|
|
12
|
+
// If not configured or set to '*', allow all hosts
|
|
13
|
+
if (!allowedHosts || allowedHosts === '*') {
|
|
14
|
+
return true;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
if (typeof allowedHosts === 'string') {
|
|
18
|
+
allowedHosts = [allowedHosts];
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// Check if hostname matches any allowed pattern
|
|
22
|
+
return allowedHosts.some((pattern) => {
|
|
23
|
+
// Convert wildcard pattern to regex
|
|
24
|
+
// Example: *.mysite.com -> ^.*\.mysite\.com$
|
|
25
|
+
const regexPattern = pattern
|
|
26
|
+
.replace(/\./g, '\\.') // Escape dots
|
|
27
|
+
.replace(/\*/g, '.*'); // * becomes .*
|
|
28
|
+
|
|
29
|
+
const regex = new RegExp(`^${regexPattern}$`, 'i');
|
|
30
|
+
return regex.test(hostname);
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Generate robots.txt with sitemap reference
|
|
36
|
+
*
|
|
37
|
+
* NOTE: If deployed behind a reverse proxy (nginx, Cloudflare, etc.),
|
|
38
|
+
* ensure your adapter is configured to trust proxy headers for correct
|
|
39
|
+
* origin detection:
|
|
40
|
+
*
|
|
41
|
+
* // svelte.config.js
|
|
42
|
+
* export default {
|
|
43
|
+
* kit: {
|
|
44
|
+
* adapter: adapter({
|
|
45
|
+
* // Trust X-Forwarded-* headers from proxy
|
|
46
|
+
* trustProxy: true
|
|
47
|
+
* })
|
|
48
|
+
* }
|
|
49
|
+
* };
|
|
50
|
+
*
|
|
51
|
+
* Without this, url.origin may be http://localhost instead of your
|
|
52
|
+
* actual domain, and the sitemap directive will be omitted.
|
|
53
|
+
*
|
|
54
|
+
* @param {URL} url - Request URL object
|
|
55
|
+
* @param {RobotsConfig} [config] - Robots configuration object
|
|
56
|
+
*
|
|
57
|
+
* @returns {string} robots.txt content
|
|
58
|
+
*/
|
|
59
|
+
export function generateRobotsTxt(url, config = {}) {
|
|
60
|
+
const hostAllowed = isHostAllowed(url.hostname, config.allowedHosts);
|
|
61
|
+
|
|
62
|
+
// Block entire site if host is not allowed
|
|
63
|
+
if (!hostAllowed) {
|
|
64
|
+
return 'User-agent: *\nDisallow: /';
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Allow site, but add specific path blocks
|
|
68
|
+
let content = 'User-agent: *\nAllow: /';
|
|
69
|
+
|
|
70
|
+
// Add disallowed paths
|
|
71
|
+
if (config.disallowedPaths && config.disallowedPaths.length > 0) {
|
|
72
|
+
config.disallowedPaths.forEach((path) => {
|
|
73
|
+
content += `\nDisallow: ${path}`;
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Add sitemap reference if enabled and origin is available
|
|
78
|
+
if (url.origin && config.includeSitemap !== false) {
|
|
79
|
+
content += `\nSitemap: ${url.origin}/sitemap.xml`;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return content;
|
|
83
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
declare const _default: {};
|
|
2
|
+
export default _default;
|
|
3
|
+
export type RobotsConfig = {
|
|
4
|
+
/**
|
|
5
|
+
* Allowed host patterns. Use '*' or omit to allow all hosts.
|
|
6
|
+
* Supports wildcards (e.g., '*.example.com')
|
|
7
|
+
*/
|
|
8
|
+
allowedHosts?: string[] | "*" | undefined;
|
|
9
|
+
/**
|
|
10
|
+
* Paths to block from indexing (e.g., '/admin', '/api/*')
|
|
11
|
+
*/
|
|
12
|
+
disallowedPaths?: string[] | undefined;
|
|
13
|
+
/**
|
|
14
|
+
* Include sitemap reference in robots.txt (default: true)
|
|
15
|
+
*/
|
|
16
|
+
includeSitemap?: boolean | undefined;
|
|
17
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @typedef {Object} RobotsConfig
|
|
3
|
+
* @property {string[] | '*'} [allowedHosts]
|
|
4
|
+
* Allowed host patterns. Use '*' or omit to allow all hosts.
|
|
5
|
+
* Supports wildcards (e.g., '*.example.com')
|
|
6
|
+
* @property {string[]} [disallowedPaths]
|
|
7
|
+
* Paths to block from indexing (e.g., '/admin', '/api/*')
|
|
8
|
+
* @property {boolean} [includeSitemap]
|
|
9
|
+
* Include sitemap reference in robots.txt (default: true)
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
export default {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { generateRobotsTxt, isHostAllowed } from "./robots/index.js";
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generate sitemap XML
|
|
3
|
+
*
|
|
4
|
+
* @param {string} origin - Base URL (e.g., https://example.com)
|
|
5
|
+
* @param {SitemapRoute[]} [routes=[]] - Array of routes
|
|
6
|
+
*
|
|
7
|
+
* @returns {string} XML sitemap
|
|
8
|
+
*/
|
|
9
|
+
export function generateSitemap(origin: string, routes?: SitemapRoute[]): string;
|
|
10
|
+
export type SitemapRoute = import("./typedef.js").SitemapRoute;
|
|
11
|
+
export type SitemapRouteObject = import("./typedef.js").SitemapRouteObject;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
// @see https://www.sitemaps.org/protocol.html
|
|
2
|
+
|
|
3
|
+
/** @typedef {import('./typedef.js').SitemapRoute} SitemapRoute */
|
|
4
|
+
/** @typedef {import('./typedef.js').SitemapRouteObject} SitemapRouteObject */
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Normalize route to full route object with defaults
|
|
8
|
+
*
|
|
9
|
+
* @param {import('./typedef.js').SitemapRoute} route - Route path string or route object
|
|
10
|
+
*
|
|
11
|
+
* @returns {SitemapRouteObject} Normalized route object
|
|
12
|
+
*/
|
|
13
|
+
function normalizeRoute(route) {
|
|
14
|
+
// Handle simple string format
|
|
15
|
+
if (typeof route === 'string') {
|
|
16
|
+
return {
|
|
17
|
+
path: route,
|
|
18
|
+
priority: route === '/' ? 1.0 : 0.8,
|
|
19
|
+
changefreq: route === '/' ? 'daily' : 'weekly'
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// Handle object format with defaults
|
|
24
|
+
return {
|
|
25
|
+
priority: 0.8,
|
|
26
|
+
changefreq: 'weekly',
|
|
27
|
+
...route
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Generate sitemap XML
|
|
33
|
+
*
|
|
34
|
+
* @param {string} origin - Base URL (e.g., https://example.com)
|
|
35
|
+
* @param {SitemapRoute[]} [routes=[]] - Array of routes
|
|
36
|
+
*
|
|
37
|
+
* @returns {string} XML sitemap
|
|
38
|
+
*/
|
|
39
|
+
export function generateSitemap(origin, routes = []) {
|
|
40
|
+
// Ensure root path is always included (failsafe)
|
|
41
|
+
const hasRoot = routes.some((route) => {
|
|
42
|
+
const path = typeof route === 'string' ? route : route.path;
|
|
43
|
+
return path === '/';
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
const normalizedRoutes = hasRoot ? routes : ['/', ...routes];
|
|
47
|
+
|
|
48
|
+
const urls = normalizedRoutes
|
|
49
|
+
.map(normalizeRoute)
|
|
50
|
+
.map(
|
|
51
|
+
(route) => `
|
|
52
|
+
<url>
|
|
53
|
+
<loc>${origin}${route.path}</loc>
|
|
54
|
+
<changefreq>${route.changefreq}</changefreq>
|
|
55
|
+
<priority>${route.priority}</priority>
|
|
56
|
+
</url>`
|
|
57
|
+
)
|
|
58
|
+
.join('');
|
|
59
|
+
|
|
60
|
+
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
61
|
+
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">${urls}
|
|
62
|
+
</urlset>`;
|
|
63
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
declare const _default: {};
|
|
2
|
+
export default _default;
|
|
3
|
+
export type SitemapRouteObject = {
|
|
4
|
+
/**
|
|
5
|
+
* - Route path (e.g., '/about')
|
|
6
|
+
*/
|
|
7
|
+
path: string;
|
|
8
|
+
/**
|
|
9
|
+
* - Priority (0.0 to 1.0)
|
|
10
|
+
*/
|
|
11
|
+
priority?: number | undefined;
|
|
12
|
+
/**
|
|
13
|
+
* - Change frequency
|
|
14
|
+
*/
|
|
15
|
+
changefreq?: "hourly" | "daily" | "weekly" | "always" | "monthly" | "yearly" | "never" | undefined;
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Route can be a simple string path or an object with details
|
|
19
|
+
*/
|
|
20
|
+
export type SitemapRoute = string | SitemapRouteObject;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @typedef {Object} SitemapRouteObject
|
|
3
|
+
* @property {string} path - Route path (e.g., '/about')
|
|
4
|
+
* @property {number} [priority] - Priority (0.0 to 1.0)
|
|
5
|
+
* @property {'always'|'hourly'|'daily'|'weekly'|'monthly'|'yearly'|'never'}
|
|
6
|
+
* [changefreq] - Change frequency
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* @typedef {string | SitemapRouteObject} SitemapRoute
|
|
11
|
+
* Route can be a simple string path or an object with details
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
export default {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { generateSitemap } from "./sitemap/index.js";
|