katanakit-js 2.2.1 → 2.12.9
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 +72 -437
- package/dist/adapters/astro/astro.service.d.ts +103 -15
- package/dist/adapters/astro/astro.service.d.ts.map +1 -1
- package/dist/adapters/astro/astro.service.js +145 -75
- package/dist/adapters/astro/astro.service.js.map +1 -1
- package/dist/adapters/astro/index.d.ts +1 -1
- package/dist/adapters/astro/index.d.ts.map +1 -1
- package/dist/adapters/astro/index.js +1 -1
- package/dist/adapters/astro/index.js.map +1 -1
- package/dist/adapters/astro/rss.service.d.ts +85 -105
- package/dist/adapters/astro/rss.service.d.ts.map +1 -1
- package/dist/adapters/astro/rss.service.js +172 -168
- package/dist/adapters/astro/rss.service.js.map +1 -1
- package/dist/adapters/astro/seo.service.d.ts +10 -0
- package/dist/adapters/astro/seo.service.d.ts.map +1 -0
- package/dist/adapters/astro/seo.service.js +3 -0
- package/dist/adapters/astro/seo.service.js.map +1 -0
- package/dist/adapters/express/app.d.ts +30 -1
- package/dist/adapters/express/app.d.ts.map +1 -1
- package/dist/adapters/express/app.js +31 -3
- package/dist/adapters/express/app.js.map +1 -1
- package/dist/adapters/express/index.d.ts +2 -2
- package/dist/adapters/express/index.d.ts.map +1 -1
- package/dist/adapters/express/index.js +2 -2
- package/dist/adapters/express/index.js.map +1 -1
- package/dist/adapters/express/main.js +2 -2
- package/dist/adapters/express/main.js.map +1 -1
- package/dist/adapters/express/products.controller.d.ts +67 -8
- package/dist/adapters/express/products.controller.d.ts.map +1 -1
- package/dist/adapters/express/products.controller.js +105 -49
- package/dist/adapters/express/products.controller.js.map +1 -1
- package/dist/adapters/express/server.d.ts +37 -13
- package/dist/adapters/express/server.d.ts.map +1 -1
- package/dist/adapters/express/server.js +118 -53
- package/dist/adapters/express/server.js.map +1 -1
- package/dist/adapters/nuxt/nuxt.service.d.ts +8 -6
- package/dist/adapters/nuxt/nuxt.service.d.ts.map +1 -1
- package/dist/adapters/nuxt/nuxt.service.js +34 -10
- package/dist/adapters/nuxt/nuxt.service.js.map +1 -1
- package/dist/adapters/vue/vue.service.d.ts +5 -2
- package/dist/adapters/vue/vue.service.d.ts.map +1 -1
- package/dist/adapters/vue/vue.service.js +41 -7
- package/dist/adapters/vue/vue.service.js.map +1 -1
- package/dist/config/index.d.ts +2 -1
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +1 -1
- package/dist/config/index.js.map +1 -1
- package/dist/config/seo-meta.types.d.ts +177 -0
- package/dist/config/seo-meta.types.d.ts.map +1 -0
- package/dist/config/seo-meta.types.js +11 -0
- package/dist/config/seo-meta.types.js.map +1 -0
- package/dist/config/seo.service.d.ts +41 -58
- package/dist/config/seo.service.d.ts.map +1 -1
- package/dist/config/seo.service.js +468 -136
- package/dist/config/seo.service.js.map +1 -1
- package/dist/config/site.config.d.ts +10 -50
- package/dist/config/site.config.d.ts.map +1 -1
- package/dist/config/site.config.js +8 -36
- package/dist/config/site.config.js.map +1 -1
- package/dist/core/index.d.ts +1 -3
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +1 -3
- package/dist/core/index.js.map +1 -1
- package/dist/core/services/dates.service.d.ts +149 -22
- package/dist/core/services/dates.service.d.ts.map +1 -1
- package/dist/core/services/dates.service.js +201 -54
- package/dist/core/services/dates.service.js.map +1 -1
- package/dist/core/services/error.service.d.ts +32 -20
- package/dist/core/services/error.service.d.ts.map +1 -1
- package/dist/core/services/error.service.js +44 -32
- package/dist/core/services/error.service.js.map +1 -1
- package/dist/core/services/formatter.service.d.ts +245 -35
- package/dist/core/services/formatter.service.d.ts.map +1 -1
- package/dist/core/services/formatter.service.js +281 -57
- package/dist/core/services/formatter.service.js.map +1 -1
- package/dist/core/services/generator.service.d.ts +115 -26
- package/dist/core/services/generator.service.d.ts.map +1 -1
- package/dist/core/services/generator.service.js +191 -56
- package/dist/core/services/generator.service.js.map +1 -1
- package/dist/core/services/geometry.service.d.ts +369 -39
- package/dist/core/services/geometry.service.d.ts.map +1 -1
- package/dist/core/services/geometry.service.js +424 -66
- package/dist/core/services/geometry.service.js.map +1 -1
- package/dist/core/services/http.service.d.ts +244 -21
- package/dist/core/services/http.service.d.ts.map +1 -1
- package/dist/core/services/http.service.js +419 -98
- package/dist/core/services/http.service.js.map +1 -1
- package/dist/core/services/logger.service.d.ts +95 -29
- package/dist/core/services/logger.service.d.ts.map +1 -1
- package/dist/core/services/logger.service.js +167 -41
- package/dist/core/services/logger.service.js.map +1 -1
- package/dist/core/services/reactive.service.d.ts +146 -19
- package/dist/core/services/reactive.service.d.ts.map +1 -1
- package/dist/core/services/reactive.service.js +278 -137
- package/dist/core/services/reactive.service.js.map +1 -1
- package/dist/core/services/timing.service.d.ts +142 -20
- package/dist/core/services/timing.service.d.ts.map +1 -1
- package/dist/core/services/timing.service.js +324 -185
- package/dist/core/services/timing.service.js.map +1 -1
- package/dist/core/services/utils.service.d.ts +228 -43
- package/dist/core/services/utils.service.d.ts.map +1 -1
- package/dist/core/services/utils.service.js +305 -125
- package/dist/core/services/utils.service.js.map +1 -1
- package/dist/infrastructure/dom/dom.service.d.ts +307 -44
- package/dist/infrastructure/dom/dom.service.d.ts.map +1 -1
- package/dist/infrastructure/dom/dom.service.js +408 -129
- package/dist/infrastructure/dom/dom.service.js.map +1 -1
- package/dist/infrastructure/index.d.ts +0 -3
- package/dist/infrastructure/index.d.ts.map +1 -1
- package/dist/infrastructure/index.js +0 -3
- package/dist/infrastructure/index.js.map +1 -1
- package/dist/infrastructure/observer/observer.service.d.ts +124 -31
- package/dist/infrastructure/observer/observer.service.d.ts.map +1 -1
- package/dist/infrastructure/observer/observer.service.js +227 -131
- package/dist/infrastructure/observer/observer.service.js.map +1 -1
- package/dist/infrastructure/sensors/sensors.service.d.ts +154 -22
- package/dist/infrastructure/sensors/sensors.service.d.ts.map +1 -1
- package/dist/infrastructure/sensors/sensors.service.js +264 -112
- package/dist/infrastructure/sensors/sensors.service.js.map +1 -1
- package/dist/infrastructure/storage/storage.service.d.ts +123 -45
- package/dist/infrastructure/storage/storage.service.d.ts.map +1 -1
- package/dist/infrastructure/storage/storage.service.js +236 -66
- package/dist/infrastructure/storage/storage.service.js.map +1 -1
- package/dist/infrastructure/theme/theme.service.d.ts +93 -29
- package/dist/infrastructure/theme/theme.service.d.ts.map +1 -1
- package/dist/infrastructure/theme/theme.service.js +198 -96
- package/dist/infrastructure/theme/theme.service.js.map +1 -1
- package/dist/infrastructure/viewport/viewport.service.d.ts +233 -35
- package/dist/infrastructure/viewport/viewport.service.d.ts.map +1 -1
- package/dist/infrastructure/viewport/viewport.service.js +358 -139
- package/dist/infrastructure/viewport/viewport.service.js.map +1 -1
- package/dist/infrastructure/worker/worker.service.d.ts +84 -38
- package/dist/infrastructure/worker/worker.service.d.ts.map +1 -1
- package/dist/infrastructure/worker/worker.service.js +234 -133
- package/dist/infrastructure/worker/worker.service.js.map +1 -1
- package/dist/prisma/index.d.ts +2 -0
- package/dist/prisma/index.d.ts.map +1 -0
- package/dist/prisma/index.js +2 -0
- package/dist/prisma/index.js.map +1 -0
- package/dist/prisma/schema.json +11 -33
- package/dist/prisma/use-prisma.d.ts +68 -0
- package/dist/prisma/use-prisma.d.ts.map +1 -0
- package/dist/prisma/use-prisma.js +82 -0
- package/dist/prisma/use-prisma.js.map +1 -0
- package/dist/types/index.d.ts +20 -12
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +124 -125
- package/CHANGELOG.md +0 -101
|
@@ -1,7 +1,24 @@
|
|
|
1
|
+
import { createRequire } from "node:module";
|
|
2
|
+
let cachedCreateError;
|
|
3
|
+
function tryLoadH3CreateError() {
|
|
4
|
+
if (cachedCreateError !== undefined)
|
|
5
|
+
return cachedCreateError;
|
|
6
|
+
try {
|
|
7
|
+
const require = createRequire(import.meta.url);
|
|
8
|
+
const h3 = require("h3");
|
|
9
|
+
cachedCreateError = typeof h3.createError === "function" ? h3.createError : null;
|
|
10
|
+
}
|
|
11
|
+
catch {
|
|
12
|
+
cachedCreateError = null;
|
|
13
|
+
}
|
|
14
|
+
return cachedCreateError;
|
|
15
|
+
}
|
|
1
16
|
/**
|
|
2
17
|
* Unwraps a KatanaKit Safe Result, throwing an H3-compatible error on failure.
|
|
3
18
|
* Returns the data directly on success.
|
|
4
19
|
*
|
|
20
|
+
* Prefers `h3.createError` when available so Nuxt/H3 status codes work correctly.
|
|
21
|
+
*
|
|
5
22
|
* @param result - The Safe Result from `useFetch`, `useGet`, `usePost`, etc.
|
|
6
23
|
* @param context - Optional context prefix for the error message.
|
|
7
24
|
* @returns The data from the result.
|
|
@@ -10,12 +27,12 @@
|
|
|
10
27
|
* @example
|
|
11
28
|
* ```ts
|
|
12
29
|
* // server/api/pokemon/[id].ts
|
|
13
|
-
* import {
|
|
30
|
+
* import { useGetApi } from "katanakit-js";
|
|
14
31
|
* import { useUnwrap } from "katanakit-js/adapters/nuxt";
|
|
15
32
|
*
|
|
16
33
|
* export default defineEventHandler(async (event) => {
|
|
17
34
|
* const id = getRouterParam(event, "id");
|
|
18
|
-
* const result = await
|
|
35
|
+
* const result = await useGetApi("pokeapi", "pokemonById", { params: { id } });
|
|
19
36
|
* return useUnwrap(result, `Pokemon ${id}`);
|
|
20
37
|
* });
|
|
21
38
|
* ```
|
|
@@ -26,8 +43,6 @@ export function useUnwrap(result, context) {
|
|
|
26
43
|
}
|
|
27
44
|
const message = context ? `${context}: ${result.error.message}` : result.error.message;
|
|
28
45
|
const statusCode = result.error.status || 500;
|
|
29
|
-
// Dynamic import to avoid hard dependency on h3.
|
|
30
|
-
// Consumers must have h3 installed (it comes with Nuxt).
|
|
31
46
|
throw createH3Error(statusCode, message);
|
|
32
47
|
}
|
|
33
48
|
/**
|
|
@@ -41,11 +56,11 @@ export function useUnwrap(result, context) {
|
|
|
41
56
|
* @example
|
|
42
57
|
* ```ts
|
|
43
58
|
* // server/api/users.ts
|
|
44
|
-
* import {
|
|
59
|
+
* import { useGetApi } from "katanakit-js";
|
|
45
60
|
* import { useSafeResponse } from "katanakit-js/adapters/nuxt";
|
|
46
61
|
*
|
|
47
62
|
* export default defineEventHandler(async () => {
|
|
48
|
-
* const result = await
|
|
63
|
+
* const result = await useGetApi("api", "users");
|
|
49
64
|
* return useSafeResponse(result);
|
|
50
65
|
* });
|
|
51
66
|
* ```
|
|
@@ -74,11 +89,11 @@ export function useSafeResponse(result) {
|
|
|
74
89
|
* @example
|
|
75
90
|
* ```ts
|
|
76
91
|
* // server/api/products.ts
|
|
77
|
-
* import {
|
|
92
|
+
* import { useFetchApi } from "katanakit-js";
|
|
78
93
|
* import { useEventResponse } from "katanakit-js/adapters/nuxt";
|
|
79
94
|
*
|
|
80
95
|
* export default defineEventHandler(async (event) => {
|
|
81
|
-
* const result = await
|
|
96
|
+
* const result = await useFetchApi("shop", "products");
|
|
82
97
|
* return useEventResponse(event, result);
|
|
83
98
|
* });
|
|
84
99
|
* ```
|
|
@@ -94,11 +109,20 @@ export function useEventResponse(event, result) {
|
|
|
94
109
|
status: result.error.status,
|
|
95
110
|
};
|
|
96
111
|
}
|
|
97
|
-
|
|
98
|
-
|
|
112
|
+
/**
|
|
113
|
+
* Creates an error that H3/Nuxt recognize (statusCode / statusMessage).
|
|
114
|
+
* Uses `h3.createError` when the peer is installed; otherwise brands a plain Error.
|
|
115
|
+
*/
|
|
99
116
|
function createH3Error(statusCode, message) {
|
|
117
|
+
const createError = tryLoadH3CreateError();
|
|
118
|
+
if (createError) {
|
|
119
|
+
return createError({ statusCode, statusMessage: message, message });
|
|
120
|
+
}
|
|
100
121
|
const error = new Error(message);
|
|
101
122
|
error.statusCode = statusCode;
|
|
123
|
+
error.status = statusCode;
|
|
124
|
+
error.statusMessage = message;
|
|
125
|
+
error.name = "H3Error";
|
|
102
126
|
return error;
|
|
103
127
|
}
|
|
104
128
|
//# sourceMappingURL=nuxt.service.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nuxt.service.js","sourceRoot":"","sources":["../../../src/adapters/nuxt/nuxt.service.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"nuxt.service.js","sourceRoot":"","sources":["../../../src/adapters/nuxt/nuxt.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -14,14 +14,17 @@ export interface KatanaFetchState<T> {
|
|
|
14
14
|
refetch: () => Promise<void>;
|
|
15
15
|
}
|
|
16
16
|
/**
|
|
17
|
-
* Vue 3 composable that wraps KatanaKit's
|
|
17
|
+
* Vue 3 composable that wraps KatanaKit's HTTP GET with the reactivity system.
|
|
18
18
|
* It bridges the Safe Result pattern to idiomatic Vue state (`data`, `error`,
|
|
19
19
|
* `loading`) and never throws on HTTP errors.
|
|
20
20
|
*
|
|
21
|
+
* Stale responses are ignored via a request version counter and AbortController.
|
|
22
|
+
* In-flight requests are aborted on unmount when `onUnmounted` is available.
|
|
23
|
+
*
|
|
21
24
|
* When `options` is a Vue `Ref`, the request re-runs automatically whenever the
|
|
22
25
|
* ref changes (deep watch), so URL params or query params can drive refetching.
|
|
23
26
|
*
|
|
24
|
-
* @param apiName - Name of the registered API (see `
|
|
27
|
+
* @param apiName - Name of the registered API (see `useInitApis`).
|
|
25
28
|
* @param endpointName - Name of the endpoint inside that API.
|
|
26
29
|
* @param options - Optional `UrlOptions` (path/query params), plain or reactive.
|
|
27
30
|
* @returns Reactive `{ data, error, loading, refetch }`.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vue.service.d.ts","sourceRoot":"","sources":["../../../src/adapters/vue/vue.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,KAAK,QAAQ,
|
|
1
|
+
{"version":3,"file":"vue.service.d.ts","sourceRoot":"","sources":["../../../src/adapters/vue/vue.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,KAAK,QAAQ,EAAe,KAAK,GAAG,EAAiC,MAAM,KAAK,CAAC;AAGjG,OAAO,KAAK,EAAE,QAAQ,EAAe,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAE9E;;GAEG;AACH,MAAM,WAAW,gBAAgB,CAAC,CAAC;IAClC,sDAAsD;IACtD,IAAI,EAAE,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IACpB,0DAA0D;IAC1D,KAAK,EAAE,GAAG,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAC;IAC5B,sCAAsC;IACtC,OAAO,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;IACtB,oCAAoC;IACpC,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC7B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAC/B,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,MAAM,EACpB,OAAO,CAAC,EAAE,QAAQ,CAAC,UAAU,CAAC,GAC5B,gBAAgB,CAAC,CAAC,CAAC,CAmErB"}
|
|
@@ -1,14 +1,17 @@
|
|
|
1
|
-
import { isRef, ref, shallowRef, unref, watch } from "vue";
|
|
2
|
-
import {
|
|
1
|
+
import { isRef, onUnmounted, ref, shallowRef, unref, watch } from "vue";
|
|
2
|
+
import { useFetch } from "../../core/services/http.service.js";
|
|
3
3
|
/**
|
|
4
|
-
* Vue 3 composable that wraps KatanaKit's
|
|
4
|
+
* Vue 3 composable that wraps KatanaKit's HTTP GET with the reactivity system.
|
|
5
5
|
* It bridges the Safe Result pattern to idiomatic Vue state (`data`, `error`,
|
|
6
6
|
* `loading`) and never throws on HTTP errors.
|
|
7
7
|
*
|
|
8
|
+
* Stale responses are ignored via a request version counter and AbortController.
|
|
9
|
+
* In-flight requests are aborted on unmount when `onUnmounted` is available.
|
|
10
|
+
*
|
|
8
11
|
* When `options` is a Vue `Ref`, the request re-runs automatically whenever the
|
|
9
12
|
* ref changes (deep watch), so URL params or query params can drive refetching.
|
|
10
13
|
*
|
|
11
|
-
* @param apiName - Name of the registered API (see `
|
|
14
|
+
* @param apiName - Name of the registered API (see `useInitApis`).
|
|
12
15
|
* @param endpointName - Name of the endpoint inside that API.
|
|
13
16
|
* @param options - Optional `UrlOptions` (path/query params), plain or reactive.
|
|
14
17
|
* @returns Reactive `{ data, error, loading, refetch }`.
|
|
@@ -28,21 +31,52 @@ export function useKatanaFetch(apiName, endpointName, options) {
|
|
|
28
31
|
const data = shallowRef(null);
|
|
29
32
|
const error = ref(null);
|
|
30
33
|
const loading = ref(true);
|
|
34
|
+
let requestVersion = 0;
|
|
35
|
+
let activeController = null;
|
|
36
|
+
let disposed = false;
|
|
31
37
|
const refetch = async () => {
|
|
38
|
+
const version = ++requestVersion;
|
|
39
|
+
activeController?.abort();
|
|
40
|
+
const controller = new AbortController();
|
|
41
|
+
activeController = controller;
|
|
32
42
|
loading.value = true;
|
|
33
43
|
error.value = null;
|
|
34
|
-
const result = await
|
|
44
|
+
const result = await useFetch(apiName, endpointName, {
|
|
45
|
+
method: "GET",
|
|
46
|
+
urlOptions: unref(options),
|
|
47
|
+
signal: controller.signal,
|
|
48
|
+
});
|
|
49
|
+
if (disposed || version !== requestVersion) {
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
35
52
|
if (result.ok) {
|
|
36
53
|
data.value = result.data;
|
|
54
|
+
error.value = null;
|
|
37
55
|
}
|
|
38
56
|
else {
|
|
39
|
-
|
|
57
|
+
// Ignore abort errors from superseded / unmounted requests.
|
|
58
|
+
const aborted = controller.signal.aborted || /abort/i.test(result.error.message);
|
|
59
|
+
if (!aborted) {
|
|
60
|
+
error.value = result.error;
|
|
61
|
+
}
|
|
40
62
|
}
|
|
41
63
|
loading.value = false;
|
|
42
64
|
};
|
|
43
65
|
// Refetch automatically when a reactive options ref changes.
|
|
44
66
|
if (isRef(options)) {
|
|
45
|
-
watch(options,
|
|
67
|
+
watch(options, () => {
|
|
68
|
+
void refetch();
|
|
69
|
+
}, { deep: true });
|
|
70
|
+
}
|
|
71
|
+
// Dispose on unmount when running inside a component setup.
|
|
72
|
+
try {
|
|
73
|
+
onUnmounted(() => {
|
|
74
|
+
disposed = true;
|
|
75
|
+
activeController?.abort();
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
catch {
|
|
79
|
+
// Outside of a component setup context — skip lifecycle hook.
|
|
46
80
|
}
|
|
47
81
|
// Initial fetch on setup.
|
|
48
82
|
void refetch();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vue.service.js","sourceRoot":"","sources":["../../../src/adapters/vue/vue.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,
|
|
1
|
+
{"version":3,"file":"vue.service.js","sourceRoot":"","sources":["../../../src/adapters/vue/vue.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAiB,WAAW,EAAY,GAAG,EAAE,UAAU,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,KAAK,CAAC;AAEjG,OAAO,EAAE,QAAQ,EAAE,MAAM,qCAAqC,CAAC;AAiB/D;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,MAAM,UAAU,cAAc,CAC7B,OAAe,EACf,YAAoB,EACpB,OAA8B;IAE9B,MAAM,IAAI,GAAG,UAAU,CAAW,IAAI,CAAC,CAAC;IACxC,MAAM,KAAK,GAAG,GAAG,CAAkB,IAAI,CAAC,CAAC;IACzC,MAAM,OAAO,GAAG,GAAG,CAAC,IAAI,CAAC,CAAC;IAE1B,IAAI,cAAc,GAAG,CAAC,CAAC;IACvB,IAAI,gBAAgB,GAA2B,IAAI,CAAC;IACpD,IAAI,QAAQ,GAAG,KAAK,CAAC;IAErB,MAAM,OAAO,GAAG,KAAK,IAAmB,EAAE;QACzC,MAAM,OAAO,GAAG,EAAE,cAAc,CAAC;QACjC,gBAAgB,EAAE,KAAK,EAAE,CAAC;QAC1B,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;QACzC,gBAAgB,GAAG,UAAU,CAAC;QAE9B,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC;QACrB,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC;QAEnB,MAAM,MAAM,GAAmB,MAAM,QAAQ,CAAI,OAAO,EAAE,YAAY,EAAE;YACvE,MAAM,EAAE,KAAK;YACb,UAAU,EAAE,KAAK,CAAC,OAAO,CAAC;YAC1B,MAAM,EAAE,UAAU,CAAC,MAAM;SACzB,CAAC,CAAC;QAEH,IAAI,QAAQ,IAAI,OAAO,KAAK,cAAc,EAAE,CAAC;YAC5C,OAAO;QACR,CAAC;QAED,IAAI,MAAM,CAAC,EAAE,EAAE,CAAC;YACf,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC;YACzB,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC;QACpB,CAAC;aAAM,CAAC;YACP,4DAA4D;YAC5D,MAAM,OAAO,GAAG,UAAU,CAAC,MAAM,CAAC,OAAO,IAAI,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YACjF,IAAI,CAAC,OAAO,EAAE,CAAC;gBACd,KAAK,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;YAC5B,CAAC;QACF,CAAC;QAED,OAAO,CAAC,KAAK,GAAG,KAAK,CAAC;IACvB,CAAC,CAAC;IAEF,6DAA6D;IAC7D,IAAI,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC;QACpB,KAAK,CACJ,OAAO,EACP,GAAG,EAAE;YACJ,KAAK,OAAO,EAAE,CAAC;QAChB,CAAC,EACD,EAAE,IAAI,EAAE,IAAI,EAAE,CACd,CAAC;IACH,CAAC;IAED,4DAA4D;IAC5D,IAAI,CAAC;QACJ,WAAW,CAAC,GAAG,EAAE;YAChB,QAAQ,GAAG,IAAI,CAAC;YAChB,gBAAgB,EAAE,KAAK,EAAE,CAAC;QAC3B,CAAC,CAAC,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACR,8DAA8D;IAC/D,CAAC;IAED,0BAA0B;IAC1B,KAAK,OAAO,EAAE,CAAC;IAEf,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC;AAC1C,CAAC"}
|
package/dist/config/index.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export type { SeoArrayable, SeoBooleanable, SeoMeta, SeoMetaArticle, SeoMetaFlat, SeoMetaInput, SeoOgImageObject, SeoRobotsObject, SeoTagNode, SeoTagResult, SeoTagsResult, UseSeoMetaBase, UseSeoMetaOptions, } from "./seo.service.js";
|
|
2
|
+
export { useApplySeoTag, useGenerateMetaTags, useHeadTags, useRssHeadLink, useSeoMeta, useSeoTag, useSeoTags, useTitle, } from "./seo.service.js";
|
|
2
3
|
export { type SiteConfig, siteConfig } from "./site.config.js";
|
|
3
4
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACX,YAAY,EACZ,cAAc,EACd,OAAO,EACP,cAAc,EACd,WAAW,EACX,YAAY,EACZ,gBAAgB,EAChB,eAAe,EACf,UAAU,EACV,YAAY,EACZ,aAAa,EACb,cAAc,EACd,iBAAiB,GACjB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACN,cAAc,EACd,mBAAmB,EACnB,WAAW,EACX,cAAc,EACd,UAAU,EACV,SAAS,EACT,UAAU,EACV,QAAQ,GACR,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,KAAK,UAAU,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC"}
|
package/dist/config/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { useGenerateMetaTags, useHeadTags, useRssHeadLink, useTitle, } from "./seo.service.js";
|
|
1
|
+
export { useApplySeoTag, useGenerateMetaTags, useHeadTags, useRssHeadLink, useSeoMeta, useSeoTag, useSeoTags, useTitle, } from "./seo.service.js";
|
|
2
2
|
export { siteConfig } from "./site.config.js";
|
|
3
3
|
//# sourceMappingURL=index.js.map
|
package/dist/config/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"AAeA,OAAO,EACN,cAAc,EACd,mBAAmB,EACnB,WAAW,EACX,cAAc,EACd,UAAU,EACV,SAAS,EACT,UAAU,EACV,QAAQ,GACR,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAmB,UAAU,EAAE,MAAM,kBAAkB,CAAC"}
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Slim SEO types: typical HTML meta + Open Graph (Facebook) only.
|
|
3
|
+
* CamelCase keys map to `<title>` / `<meta>` / `<link rel="canonical">`.
|
|
4
|
+
*
|
|
5
|
+
* Naming cheat-sheet for {@link UseSeoMetaOptions}:
|
|
6
|
+
* - `site` = base URL (`https://example.com`)
|
|
7
|
+
* - `siteTitle` = brand / site name (`"My Site"`)
|
|
8
|
+
* - `title` = **page** document title (`"Blog Post"` → often `"Blog Post | My Site"`)
|
|
9
|
+
*/
|
|
10
|
+
export type SeoBooleanable = boolean | "true" | "false" | "" | 0 | 1;
|
|
11
|
+
export type SeoArrayable<T> = T | readonly T[];
|
|
12
|
+
/** Open Graph image (string URL or object). */
|
|
13
|
+
export interface SeoOgImageObject {
|
|
14
|
+
url?: string;
|
|
15
|
+
secureUrl?: string;
|
|
16
|
+
type?: "image/jpeg" | "image/gif" | "image/png" | "image/webp" | "image/avif" | string;
|
|
17
|
+
width?: string | number;
|
|
18
|
+
height?: string | number;
|
|
19
|
+
alt?: string;
|
|
20
|
+
}
|
|
21
|
+
/** Robots as string or simple object. */
|
|
22
|
+
export interface SeoRobotsObject {
|
|
23
|
+
index?: SeoBooleanable;
|
|
24
|
+
follow?: SeoBooleanable;
|
|
25
|
+
noindex?: SeoBooleanable;
|
|
26
|
+
nofollow?: SeoBooleanable;
|
|
27
|
+
none?: SeoBooleanable;
|
|
28
|
+
noarchive?: SeoBooleanable;
|
|
29
|
+
nosnippet?: SeoBooleanable;
|
|
30
|
+
}
|
|
31
|
+
/** Article Open Graph extensions (`og:type=article`). */
|
|
32
|
+
export interface SeoMetaArticle {
|
|
33
|
+
articleAuthor?: readonly string[];
|
|
34
|
+
articleModifiedTime?: string;
|
|
35
|
+
articlePublishedTime?: string;
|
|
36
|
+
articleSection?: string;
|
|
37
|
+
articleTag?: readonly string[];
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Flat meta: HTML head essentials + Facebook Open Graph.
|
|
41
|
+
*/
|
|
42
|
+
export interface SeoMetaFlat extends SeoMetaArticle {
|
|
43
|
+
/**
|
|
44
|
+
* Page document title → `<title>`.
|
|
45
|
+
* Not the site brand (`siteTitle`). When both differ, the helper usually
|
|
46
|
+
* renders `"Page | Brand"`.
|
|
47
|
+
*/
|
|
48
|
+
title?: string;
|
|
49
|
+
/**
|
|
50
|
+
* Page summary → `<meta name="description">`.
|
|
51
|
+
* Prefer this for the page; use `ogDescription` only to override the share preview.
|
|
52
|
+
*/
|
|
53
|
+
description?: string;
|
|
54
|
+
/** Meta keywords (legacy; optional). */
|
|
55
|
+
keywords?: string;
|
|
56
|
+
/** Meta author. */
|
|
57
|
+
author?: string;
|
|
58
|
+
/**
|
|
59
|
+
* Explicit canonical URL → `<link rel="canonical">`.
|
|
60
|
+
* Prefer this over `url` when you know the preferred address.
|
|
61
|
+
*/
|
|
62
|
+
canonical?: string;
|
|
63
|
+
/**
|
|
64
|
+
* Absolute page URL. Fallback for canonical / `og:url` when those are omitted
|
|
65
|
+
* (resolution order: `ogUrl` → `canonical` → `url` → `site`).
|
|
66
|
+
*/
|
|
67
|
+
url?: string;
|
|
68
|
+
charset?: "utf-8" | string;
|
|
69
|
+
viewport?: string | Record<string, string | number | undefined>;
|
|
70
|
+
robots?: "noindex, nofollow" | "index, follow" | string | SeoRobotsObject;
|
|
71
|
+
/**
|
|
72
|
+
* Open Graph page URL (`og:url`).
|
|
73
|
+
* Falls back to `canonical` → `url` → `site`.
|
|
74
|
+
*/
|
|
75
|
+
ogUrl?: string;
|
|
76
|
+
/**
|
|
77
|
+
* Open Graph title (`og:title`). Defaults to the resolved page `title` when omitted.
|
|
78
|
+
*/
|
|
79
|
+
ogTitle?: string;
|
|
80
|
+
/**
|
|
81
|
+
* Open Graph description (`og:description`). Defaults to `description` when omitted.
|
|
82
|
+
*/
|
|
83
|
+
ogDescription?: string;
|
|
84
|
+
ogType?: "website" | "article" | "profile" | string;
|
|
85
|
+
ogLocale?: string;
|
|
86
|
+
/**
|
|
87
|
+
* Open Graph site name (`og:site_name`). Defaults to `siteTitle` when omitted.
|
|
88
|
+
*/
|
|
89
|
+
ogSiteName?: string;
|
|
90
|
+
ogImage?: string | SeoArrayable<SeoOgImageObject>;
|
|
91
|
+
ogImageUrl?: string;
|
|
92
|
+
ogImageSecureUrl?: string;
|
|
93
|
+
ogImageType?: string;
|
|
94
|
+
ogImageWidth?: string | number;
|
|
95
|
+
ogImageHeight?: string | number;
|
|
96
|
+
ogImageAlt?: string;
|
|
97
|
+
}
|
|
98
|
+
/** Flat meta input (all keys optional / nullable). */
|
|
99
|
+
export type SeoMetaInput = {
|
|
100
|
+
[K in keyof SeoMetaFlat]?: SeoMetaFlat[K] | null;
|
|
101
|
+
};
|
|
102
|
+
/** Site + HTML + OG fields in one object (before Omit). */
|
|
103
|
+
export type UseSeoMetaBase = SeoMetaInput & {
|
|
104
|
+
/**
|
|
105
|
+
* Site origin / base URL (no trailing slash), e.g. `"https://example.com"`.
|
|
106
|
+
* Not a title — used for canonical, OG, RSS, and JSON-LD defaults.
|
|
107
|
+
*/
|
|
108
|
+
site?: string;
|
|
109
|
+
/**
|
|
110
|
+
* Site brand / product name (e.g. `"KatanaKit"`).
|
|
111
|
+
* Distinct from page {@link SeoMetaFlat.title}.
|
|
112
|
+
* Used as `<title>` suffix (`"Page | Brand"`), `og:site_name`, and RSS feed name.
|
|
113
|
+
*/
|
|
114
|
+
siteTitle?: string;
|
|
115
|
+
/** Language code (e.g. `"en"`, `"es-ES"`). */
|
|
116
|
+
lang?: string;
|
|
117
|
+
rss?: Partial<{
|
|
118
|
+
enabled: boolean;
|
|
119
|
+
path: string;
|
|
120
|
+
title?: string;
|
|
121
|
+
description?: string;
|
|
122
|
+
limit: number;
|
|
123
|
+
}>;
|
|
124
|
+
seo?: Partial<{
|
|
125
|
+
noindex: boolean;
|
|
126
|
+
canonical: boolean;
|
|
127
|
+
openGraph: boolean;
|
|
128
|
+
jsonLd: boolean;
|
|
129
|
+
}>;
|
|
130
|
+
nav?: Array<{
|
|
131
|
+
label: string;
|
|
132
|
+
href: string;
|
|
133
|
+
external?: boolean;
|
|
134
|
+
}>;
|
|
135
|
+
};
|
|
136
|
+
/**
|
|
137
|
+
* Public options for {@link useSeoMeta}.
|
|
138
|
+
* Only HTML + Open Graph (+ site fields). Omit keys you do not want in the type.
|
|
139
|
+
*
|
|
140
|
+
* @example
|
|
141
|
+
* ```ts
|
|
142
|
+
* // site = URL, siteTitle = brand, title = this page
|
|
143
|
+
* useSeoMeta({
|
|
144
|
+
* site: "https://katanakit.dev",
|
|
145
|
+
* siteTitle: "KatanaKit",
|
|
146
|
+
* title: "Getting started", // → <title>Getting started | KatanaKit</title>
|
|
147
|
+
* description: "…",
|
|
148
|
+
* ogImage: "/og.png",
|
|
149
|
+
* } satisfies UseSeoMetaOptions);
|
|
150
|
+
*
|
|
151
|
+
* useSeoMeta({ title: "Home" } as UseSeoMetaOptions<"rss" | "nav">);
|
|
152
|
+
* ```
|
|
153
|
+
*/
|
|
154
|
+
export type UseSeoMetaOptions<OmitKeys extends keyof UseSeoMetaBase = never> = Omit<UseSeoMetaBase, OmitKeys>;
|
|
155
|
+
/**
|
|
156
|
+
* Legacy page meta. Prefer {@link UseSeoMetaOptions}.
|
|
157
|
+
* @deprecated
|
|
158
|
+
*/
|
|
159
|
+
export interface SeoMeta {
|
|
160
|
+
title: string;
|
|
161
|
+
description?: string;
|
|
162
|
+
canonical?: string;
|
|
163
|
+
url?: string;
|
|
164
|
+
ogImage?: string;
|
|
165
|
+
ogType?: "website" | "article" | "profile";
|
|
166
|
+
publishedTime?: string;
|
|
167
|
+
modifiedTime?: string;
|
|
168
|
+
author?: string;
|
|
169
|
+
tags?: string[];
|
|
170
|
+
noindex?: boolean;
|
|
171
|
+
}
|
|
172
|
+
export interface SeoTagNode {
|
|
173
|
+
tag: "title" | "meta" | "link" | "script";
|
|
174
|
+
attrs?: Record<string, string>;
|
|
175
|
+
text?: string;
|
|
176
|
+
}
|
|
177
|
+
//# sourceMappingURL=seo-meta.types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"seo-meta.types.d.ts","sourceRoot":"","sources":["../../src/config/seo-meta.types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Slim SEO types: typical HTML meta + Open Graph (Facebook) only.
|
|
3
|
+
* CamelCase keys map to `<title>` / `<meta>` / `<link rel="canonical">`.
|
|
4
|
+
*
|
|
5
|
+
* Naming cheat-sheet for {@link UseSeoMetaOptions}:
|
|
6
|
+
* - `site` = base URL (`https://example.com`)
|
|
7
|
+
* - `siteTitle` = brand / site name (`"My Site"`)
|
|
8
|
+
* - `title` = **page** document title (`"Blog Post"` → often `"Blog Post | My Site"`)
|
|
9
|
+
*/
|
|
10
|
+
export {};
|
|
11
|
+
//# sourceMappingURL=seo-meta.types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"seo-meta.types.js","sourceRoot":"","sources":["../../src/config/seo-meta.types.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG"}
|
|
@@ -1,72 +1,55 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { SeoMeta, SeoMetaInput, SeoTagNode, UseSeoMetaBase, UseSeoMetaOptions } from "./seo-meta.types.js";
|
|
2
|
+
import { type SiteConfig } from "./site.config.js";
|
|
3
|
+
export type { SeoArrayable, SeoBooleanable, SeoMeta, SeoMetaArticle, SeoMetaFlat, SeoMetaInput, SeoOgImageObject, SeoRobotsObject, SeoTagNode, UseSeoMetaBase, UseSeoMetaOptions, } from "./seo-meta.types.js";
|
|
2
4
|
/**
|
|
3
|
-
*
|
|
5
|
+
* Result of {@link useSeoMeta}: `html` / `tags` for the head, plus **one**
|
|
6
|
+
* flat object of resolved fields (site + HTML + OG). No duplicate
|
|
7
|
+
* `title` / `meta.title` / `config.title`.
|
|
8
|
+
*
|
|
9
|
+
* - `title` = document title (page)
|
|
10
|
+
* - `siteTitle` = brand / site name
|
|
11
|
+
* - `html` / `tags` = what you inject into `<head>`
|
|
4
12
|
*/
|
|
5
|
-
export
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
/** Page URL (absolute, e.g. "https://example.com/blog/post/"). */
|
|
13
|
-
url?: string;
|
|
14
|
-
/** OG image URL (absolute). Falls back to site config. */
|
|
15
|
-
ogImage?: string;
|
|
16
|
-
/** Content type: "website" | "article" | "profile" (default: "website"). */
|
|
17
|
-
ogType?: "website" | "article" | "profile";
|
|
18
|
-
/** Article published date (ISO string, for og:type=article). */
|
|
19
|
-
publishedTime?: string;
|
|
20
|
-
/** Article modified date (ISO string, for og:type=article). */
|
|
21
|
-
modifiedTime?: string;
|
|
22
|
-
/** Article author (for og:type=article). */
|
|
23
|
-
author?: string;
|
|
24
|
-
/** Article tags (for og:type=article). */
|
|
25
|
-
tags?: string[];
|
|
26
|
-
/** Whether to add noindex (default: false). */
|
|
27
|
-
noindex?: boolean;
|
|
28
|
-
}
|
|
13
|
+
export type SeoTagResult = UseSeoMetaOptions & {
|
|
14
|
+
html: string;
|
|
15
|
+
tags: SeoTagNode[];
|
|
16
|
+
jsonLd?: Record<string, unknown>;
|
|
17
|
+
};
|
|
18
|
+
/** @deprecated Use {@link SeoTagResult}. */
|
|
19
|
+
export type SeoTagsResult = SeoTagResult;
|
|
29
20
|
/**
|
|
30
|
-
*
|
|
31
|
-
* canonical URL, and JSON-LD structured data.
|
|
32
|
-
*
|
|
33
|
-
* @param config - Site-wide configuration.
|
|
34
|
-
* @param meta - Page-specific meta.
|
|
35
|
-
* @returns HTML string of meta tags to inject in `<head>`.
|
|
21
|
+
* SEO helper: one flat object in → one flat object out (+ html/tags).
|
|
36
22
|
*
|
|
37
23
|
* @example
|
|
38
|
-
* ```
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
* description: "A great post about TypeScript",
|
|
46
|
-
* url: "https://example.com/blog/my-post/",
|
|
47
|
-
* ogType: "article",
|
|
48
|
-
* publishedTime: "2024-01-15T00:00:00Z",
|
|
24
|
+
* ```ts
|
|
25
|
+
* const seo = useSeoMeta({
|
|
26
|
+
* site: "https://example.com",
|
|
27
|
+
* siteTitle: "My Site",
|
|
28
|
+
* title: "Home",
|
|
29
|
+
* description: "…",
|
|
30
|
+
* ogImage: "https://example.com/image.png",
|
|
49
31
|
* });
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
* <Fragment set:html={metaTags} />
|
|
53
|
-
* </head>
|
|
32
|
+
* // seo.title, seo.site, seo.ogImage — once each
|
|
33
|
+
* // seo.html / seo.tags — head injection
|
|
54
34
|
* ```
|
|
55
35
|
*/
|
|
56
|
-
export declare function
|
|
36
|
+
export declare function useSeoMeta<OmitKeys extends keyof UseSeoMetaBase = never>(opts: UseSeoMetaOptions<OmitKeys>, defaults?: SiteConfig): SeoTagResult;
|
|
57
37
|
/**
|
|
58
|
-
*
|
|
38
|
+
* @deprecated Prefer {@link useSeoMeta} with a unified flat object.
|
|
39
|
+
* Legacy: `useSeoTag(siteConfig, { title, description, ... })`.
|
|
59
40
|
*/
|
|
60
|
-
export declare function
|
|
41
|
+
export declare function useSeoTag(config: SiteConfig, meta: SeoMeta): SeoTagResult;
|
|
42
|
+
/** @deprecated Prefer {@link useSeoMeta}. */
|
|
43
|
+
export declare const useSeoTags: typeof useSeoTag;
|
|
61
44
|
/**
|
|
62
|
-
*
|
|
45
|
+
* Applies tags from a {@link SeoTagResult} into `document.head` (Vanilla / SPA).
|
|
46
|
+
* No-op when `document` is unavailable (SSR).
|
|
63
47
|
*/
|
|
48
|
+
export declare function useApplySeoTag(seo: SeoTagResult, head?: ParentNode | null): void;
|
|
49
|
+
/** HTML string of meta tags (no RSS). Prefer {@link useSeoMeta}. */
|
|
50
|
+
export declare function useGenerateMetaTags(config: SiteConfig, meta: SeoMeta): string;
|
|
51
|
+
export declare function useTitle(config: SiteConfig, pageTitle?: string): string;
|
|
64
52
|
export declare function useRssHeadLink(config: SiteConfig): string;
|
|
65
|
-
/**
|
|
66
|
-
|
|
67
|
-
* canonical, OG, Twitter, JSON-LD, RSS link).
|
|
68
|
-
*
|
|
69
|
-
* Convenience wrapper around `useGenerateMetaTags` + `useRssHeadLink`.
|
|
70
|
-
*/
|
|
71
|
-
export declare function useHeadTags(config: SiteConfig, meta: SeoMeta): string;
|
|
53
|
+
/** Full `<head>` HTML (meta + RSS). Accepts legacy {@link SeoMeta} or flat {@link SeoMetaInput}. */
|
|
54
|
+
export declare function useHeadTags(config: SiteConfig, meta: SeoMeta | SeoMetaInput): string;
|
|
72
55
|
//# sourceMappingURL=seo.service.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"seo.service.d.ts","sourceRoot":"","sources":["../../src/config/seo.service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"seo.service.d.ts","sourceRoot":"","sources":["../../src/config/seo.service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACX,OAAO,EACP,YAAY,EAGZ,UAAU,EACV,cAAc,EACd,iBAAiB,EACjB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAmC,KAAK,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEpF,YAAY,EACX,YAAY,EACZ,cAAc,EACd,OAAO,EACP,cAAc,EACd,WAAW,EACX,YAAY,EACZ,gBAAgB,EAChB,eAAe,EACf,UAAU,EACV,cAAc,EACd,iBAAiB,GACjB,MAAM,qBAAqB,CAAC;AAE7B;;;;;;;;GAQG;AACH,MAAM,MAAM,YAAY,GAAG,iBAAiB,GAAG;IAC9C,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,UAAU,EAAE,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACjC,CAAC;AAEF,4CAA4C;AAC5C,MAAM,MAAM,aAAa,GAAG,YAAY,CAAC;AAEzC;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,UAAU,CAAC,QAAQ,SAAS,MAAM,cAAc,GAAG,KAAK,EACvE,IAAI,EAAE,iBAAiB,CAAC,QAAQ,CAAC,EACjC,QAAQ,GAAE,UAA8B,GACtC,YAAY,CA6Cd;AAED;;;GAGG;AACH,wBAAgB,SAAS,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,GAAG,YAAY,CAEzE;AAED,6CAA6C;AAC7C,eAAO,MAAM,UAAU,kBAAY,CAAC;AAgEpC;;;GAGG;AACH,wBAAgB,cAAc,CAC7B,GAAG,EAAE,YAAY,EACjB,IAAI,GAAE,UAAU,GAAG,IAA6D,GAC9E,IAAI,CAoBN;AAED,oEAAoE;AACpE,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,GAAG,MAAM,CAM7E;AAED,wBAAgB,QAAQ,CAAC,MAAM,EAAE,UAAU,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAKvE;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CAGzD;AAED,oGAAoG;AACpG,wBAAgB,WAAW,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,GAAG,YAAY,GAAG,MAAM,CAKpF"}
|