kizlo 0.2.1 → 0.3.0
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 +7 -11
- package/dist/adapters/captcha.js +13 -5
- package/dist/cli/commands/dev.js +1 -1
- package/dist/cli/commands/init.js +51 -36
- package/dist/cli/commands/test.js +4 -1
- package/dist/cli/presets/base.js +17 -9
- package/dist/cli/presets/nextjs.js +61 -14
- package/dist/cli/wp/dev.js +1 -1
- package/dist/cli/wp/phpunit.js +104 -0
- package/dist/context.js +2 -2
- package/dist/index.d.ts +6 -4
- package/dist/index.js +4 -3
- package/dist/integrations/nextjs/kizlo.server.d.ts +5 -6
- package/dist/integrations/nextjs/kizlo.server.js +7 -5
- package/dist/integrations/nextjs/revalidate.d.ts +28 -0
- package/dist/integrations/nextjs/revalidate.js +49 -0
- package/dist/integrations/nextjs/robots.d.ts +7 -0
- package/dist/integrations/nextjs/robots.js +23 -0
- package/dist/integrations/nextjs/seo.d.ts +7 -0
- package/dist/integrations/nextjs/seo.js +41 -0
- package/dist/integrations/nextjs/sitemap.d.ts +33 -0
- package/dist/integrations/nextjs/sitemap.js +31 -0
- package/dist/nextjs/server.d.ts +3 -1
- package/dist/nextjs/server.js +3 -1
- package/dist/nextjs.d.ts +2 -1
- package/dist/nextjs.js +2 -1
- package/dist/package.js +1 -1
- package/dist/post/index.js +2 -2
- package/dist/router.d.ts +71 -13
- package/dist/seo/index.js +71 -6
- package/dist/seo/robots.js +18 -0
- package/dist/seo/schema.d.ts +15 -1
- package/dist/seo/schema.js +5 -1
- package/dist/seo/sitemap.d.ts +39 -0
- package/dist/seo/sitemap.js +64 -0
- package/dist/seo/types.d.ts +5 -1
- package/dist/seo/utils.d.ts +6 -0
- package/dist/seo/utils.js +33 -1
- package/dist/settings/service.interface.d.ts +1 -0
- package/dist/shared/crypto.d.ts +11 -8
- package/dist/shared/crypto.js +26 -9
- package/dist/shared/error.d.ts +3 -3
- package/dist/shared/procedure.d.ts +10 -10
- package/dist/webhook/schema.d.ts +2 -9
- package/dist/webhook/schema.js +5 -16
- package/dist/wordpress/service.js +4 -1
- package/package.json +2 -2
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { parseSitemapSlug, renderSitemapIndex, renderUrlSet, xmlResponse } from "./utils.js";
|
|
2
|
+
|
|
3
|
+
//#region src/seo/sitemap.ts
|
|
4
|
+
/**
|
|
5
|
+
* Every generated sitemap is served from `/sitemaps`: the index at `/sitemaps/index.xml`
|
|
6
|
+
* and each collection page at `/sitemaps/{key}.xml` (later pages `-{n}`). The base is fixed
|
|
7
|
+
* because the index `<loc>` entries (built by `sitemapEntryPath`) point at it, so the route
|
|
8
|
+
* must be mounted there for the links to resolve. How the route is mounted is a
|
|
9
|
+
* framework concern; this handler only cares about the trailing slug.
|
|
10
|
+
*/
|
|
11
|
+
const SITEMAP_BASE = "/sitemaps";
|
|
12
|
+
/** Slug that serves the sitemap index (`/sitemaps/index.xml`) rather than a collection. */
|
|
13
|
+
const SITEMAP_INDEX_SLUG = "index.xml";
|
|
14
|
+
/**
|
|
15
|
+
* Builds a Web `Request` -> `Response` handler that serves the sitemap index
|
|
16
|
+
* (`/sitemaps/index.xml`) and every collection page, merging any `extra` sitemaps in.
|
|
17
|
+
* Framework-agnostic: the slug is the last path segment of the request URL, so this runs
|
|
18
|
+
* as-is on any web-standard server (Hono, a plain fetch handler, a Next route handler).
|
|
19
|
+
* Mounting it at the right path is the caller's job; framework wrappers (e.g. the Next
|
|
20
|
+
* integration) add mount assertions on top.
|
|
21
|
+
*/
|
|
22
|
+
function createSitemapRoute(client, options) {
|
|
23
|
+
const extra = options?.extra ?? [];
|
|
24
|
+
return async function GET(request) {
|
|
25
|
+
const url = new URL(request.url);
|
|
26
|
+
const slug = lastPathSegment(url);
|
|
27
|
+
if (!slug) return notFound();
|
|
28
|
+
if (slug === SITEMAP_INDEX_SLUG) {
|
|
29
|
+
const { data: data$1 } = await client.seo.sitemaps.index();
|
|
30
|
+
return xmlResponse(renderSitemapIndex([...data$1?.sitemaps ?? [], ...extra.map((item) => item.entry)], data$1?.origin ?? url.origin));
|
|
31
|
+
}
|
|
32
|
+
const parsed = parseSitemapSlug(slug);
|
|
33
|
+
if (!parsed) return notFound();
|
|
34
|
+
const custom = extra.find((item) => item.entry.key === parsed.key);
|
|
35
|
+
if (custom) {
|
|
36
|
+
if (parsed.page > custom.entry.pages) return notFound();
|
|
37
|
+
const { data: data$1 } = await client.seo.sitemaps.index();
|
|
38
|
+
return xmlResponse(renderUrlSet(await custom.urls(data$1?.origin ?? url.origin, parsed.page)));
|
|
39
|
+
}
|
|
40
|
+
const { data: sitemaps } = await client.seo.sitemaps.list();
|
|
41
|
+
if (!sitemaps) return notFound();
|
|
42
|
+
const entry = sitemaps.find((item) => item.key === parsed.key);
|
|
43
|
+
if (!entry || parsed.page > entry.pages) return notFound();
|
|
44
|
+
const { data } = await client.seo.urls(entry.type === "author" ? {
|
|
45
|
+
type: "author",
|
|
46
|
+
page: parsed.page
|
|
47
|
+
} : {
|
|
48
|
+
type: entry.type,
|
|
49
|
+
key: entry.key,
|
|
50
|
+
page: parsed.page
|
|
51
|
+
});
|
|
52
|
+
if (!data) return notFound();
|
|
53
|
+
return xmlResponse(renderUrlSet(data));
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
function lastPathSegment(url) {
|
|
57
|
+
return decodeURIComponent(url.pathname.split("/").filter(Boolean).pop() ?? "");
|
|
58
|
+
}
|
|
59
|
+
function notFound() {
|
|
60
|
+
return new Response("Not Found", { status: 404 });
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
//#endregion
|
|
64
|
+
export { SITEMAP_BASE, SITEMAP_INDEX_SLUG, createSitemapRoute };
|
package/dist/seo/types.d.ts
CHANGED
|
@@ -62,6 +62,10 @@ interface WPK_Sitemap {
|
|
|
62
62
|
pages: number;
|
|
63
63
|
lastmod: string;
|
|
64
64
|
}
|
|
65
|
+
interface WPK_SitemapIndex {
|
|
66
|
+
origin: string;
|
|
67
|
+
sitemaps: WPK_Sitemap[];
|
|
68
|
+
}
|
|
65
69
|
interface WPK_SitemapUrlImage {
|
|
66
70
|
loc: string;
|
|
67
71
|
title: string;
|
|
@@ -77,4 +81,4 @@ interface WPK_ListSitemapUrlInput {
|
|
|
77
81
|
page?: number;
|
|
78
82
|
}
|
|
79
83
|
//#endregion
|
|
80
|
-
export { WPK_ListSitemapUrlInput, WPK_RobotRule, WPK_Robots, WPK_Seo, WPK_Sitemap, WPK_SitemapContentType, WPK_SitemapUrl, WPK_SitemapUrlImage };
|
|
84
|
+
export { WPK_ListSitemapUrlInput, WPK_RobotRule, WPK_Robots, WPK_Seo, WPK_Sitemap, WPK_SitemapContentType, WPK_SitemapIndex, WPK_SitemapUrl, WPK_SitemapUrlImage };
|
package/dist/seo/utils.js
CHANGED
|
@@ -39,6 +39,38 @@ function deserializeSeo(data) {
|
|
|
39
39
|
schema: data.schema
|
|
40
40
|
};
|
|
41
41
|
}
|
|
42
|
+
function sitemapEntryPath(key, page) {
|
|
43
|
+
return `/sitemaps/${key}${page > 1 ? `-${page}` : ""}.xml`;
|
|
44
|
+
}
|
|
45
|
+
function parseSitemapSlug(slug) {
|
|
46
|
+
const match = /^(.+?)(?:-(\d+))?\.xml$/.exec(slug);
|
|
47
|
+
if (!match) return null;
|
|
48
|
+
const [, key, rawPage] = match;
|
|
49
|
+
const page = rawPage ? Number(rawPage) : 1;
|
|
50
|
+
if (!key || !Number.isInteger(page) || page < 1) return null;
|
|
51
|
+
return {
|
|
52
|
+
key,
|
|
53
|
+
page
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
function escapeXml(value) {
|
|
57
|
+
return value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
58
|
+
}
|
|
59
|
+
function renderSitemapIndex(sitemaps, origin) {
|
|
60
|
+
return `<?xml version="1.0" encoding="UTF-8"?>\n<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">\n${sitemaps.flatMap((sitemap) => Array.from({ length: sitemap.pages }, (_, index) => {
|
|
61
|
+
return `\t<sitemap>\n\t\t<loc>${escapeXml(`${origin}${sitemapEntryPath(sitemap.key, index + 1)}`)}</loc>\n\t\t<lastmod>${escapeXml(sitemap.lastmod)}</lastmod>\n\t</sitemap>`;
|
|
62
|
+
})).join("\n")}\n</sitemapindex>\n`;
|
|
63
|
+
}
|
|
64
|
+
function renderUrlSet(urls) {
|
|
65
|
+
return `<?xml version="1.0" encoding="UTF-8"?>\n<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:image="http://www.google.com/schemas/sitemap-image/1.1">\n${urls.map((url) => {
|
|
66
|
+
const images = url.images.map((image) => `\t\t<image:image>\n\t\t\t<image:loc>${escapeXml(image.loc)}</image:loc>\n\t\t</image:image>`).join("\n");
|
|
67
|
+
const imageBlock = images ? `\n${images}` : "";
|
|
68
|
+
return `\t<url>\n\t\t<loc>${escapeXml(url.loc)}</loc>\n\t\t<lastmod>${escapeXml(url.lastmod)}</lastmod>${imageBlock}\n\t</url>`;
|
|
69
|
+
}).join("\n")}\n</urlset>\n`;
|
|
70
|
+
}
|
|
71
|
+
function xmlResponse(body) {
|
|
72
|
+
return new Response(body, { headers: { "Content-Type": "application/xml; charset=utf-8" } });
|
|
73
|
+
}
|
|
42
74
|
|
|
43
75
|
//#endregion
|
|
44
|
-
export { deserializeSeo };
|
|
76
|
+
export { deserializeSeo, parseSitemapSlug, renderSitemapIndex, renderUrlSet, xmlResponse };
|
package/dist/shared/crypto.d.ts
CHANGED
|
@@ -1,15 +1,18 @@
|
|
|
1
|
-
import { BinaryLike } from "node:crypto";
|
|
2
|
-
|
|
3
1
|
//#region src/shared/crypto.d.ts
|
|
4
|
-
|
|
2
|
+
/** SHA family accepted by the Web Crypto API. */
|
|
3
|
+
type ShaAlgorithm = "SHA-256" | "SHA-384" | "SHA-512";
|
|
5
4
|
/**
|
|
6
5
|
* Compares two strings in a timing-safe manner to prevent timing attacks.
|
|
7
6
|
*
|
|
7
|
+
* Both inputs are hashed to fixed-length digests before comparison, so the
|
|
8
|
+
* check is constant-time regardless of input length and never throws on a
|
|
9
|
+
* length mismatch.
|
|
10
|
+
*
|
|
8
11
|
* @param a - The first string to compare.
|
|
9
12
|
* @param b - The second string to compare.
|
|
10
13
|
* @returns `true` if the strings match, `false` otherwise.
|
|
11
14
|
*/
|
|
12
|
-
declare function compare(a: string, b: string): boolean
|
|
15
|
+
declare function compare(a: string, b: string): Promise<boolean>;
|
|
13
16
|
/**
|
|
14
17
|
* Hashes a secret API key with SHA-256 for secure database storage.
|
|
15
18
|
* Safe to use in place of bcrypt/argon2 because API keys are high-entropy
|
|
@@ -19,10 +22,10 @@ declare function compare(a: string, b: string): boolean;
|
|
|
19
22
|
* @param key - The raw secret API key to hash.
|
|
20
23
|
* @returns A SHA-256 hex string suitable for database storage.
|
|
21
24
|
*/
|
|
22
|
-
declare function hash(key: string): string
|
|
25
|
+
declare function hash(key: string, algorithm?: ShaAlgorithm): Promise<string>;
|
|
23
26
|
/**
|
|
24
|
-
* Create
|
|
27
|
+
* Create an HMAC hex digest using the Web Crypto API. Defaults to SHA-256.
|
|
25
28
|
*/
|
|
26
|
-
declare function hmac(key: string, value:
|
|
29
|
+
declare function hmac(key: string, value: string, algorithm?: ShaAlgorithm): Promise<string>;
|
|
27
30
|
//#endregion
|
|
28
|
-
export { compare, hash, hmac };
|
|
31
|
+
export { ShaAlgorithm, compare, hash, hmac };
|
package/dist/shared/crypto.js
CHANGED
|
@@ -1,15 +1,28 @@
|
|
|
1
|
-
import { createHash, createHmac, timingSafeEqual } from "node:crypto";
|
|
2
|
-
|
|
3
1
|
//#region src/shared/crypto.ts
|
|
2
|
+
const encoder = new TextEncoder();
|
|
3
|
+
function toHex(buffer) {
|
|
4
|
+
let hex = "";
|
|
5
|
+
for (const byte of new Uint8Array(buffer)) hex += byte.toString(16).padStart(2, "0");
|
|
6
|
+
return hex;
|
|
7
|
+
}
|
|
4
8
|
/**
|
|
5
9
|
* Compares two strings in a timing-safe manner to prevent timing attacks.
|
|
6
10
|
*
|
|
11
|
+
* Both inputs are hashed to fixed-length digests before comparison, so the
|
|
12
|
+
* check is constant-time regardless of input length and never throws on a
|
|
13
|
+
* length mismatch.
|
|
14
|
+
*
|
|
7
15
|
* @param a - The first string to compare.
|
|
8
16
|
* @param b - The second string to compare.
|
|
9
17
|
* @returns `true` if the strings match, `false` otherwise.
|
|
10
18
|
*/
|
|
11
|
-
function compare(a, b) {
|
|
12
|
-
|
|
19
|
+
async function compare(a, b) {
|
|
20
|
+
const [ha, hb] = await Promise.all([crypto.subtle.digest("SHA-256", encoder.encode(a)), crypto.subtle.digest("SHA-256", encoder.encode(b))]);
|
|
21
|
+
const va = new Uint8Array(ha);
|
|
22
|
+
const vb = new Uint8Array(hb);
|
|
23
|
+
let diff = 0;
|
|
24
|
+
for (let i = 0; i < va.length; i++) diff |= (va[i] ?? 0) ^ (vb[i] ?? 0);
|
|
25
|
+
return diff === 0;
|
|
13
26
|
}
|
|
14
27
|
/**
|
|
15
28
|
* Hashes a secret API key with SHA-256 for secure database storage.
|
|
@@ -20,14 +33,18 @@ function compare(a, b) {
|
|
|
20
33
|
* @param key - The raw secret API key to hash.
|
|
21
34
|
* @returns A SHA-256 hex string suitable for database storage.
|
|
22
35
|
*/
|
|
23
|
-
function hash(key) {
|
|
24
|
-
return
|
|
36
|
+
async function hash(key, algorithm = "SHA-256") {
|
|
37
|
+
return toHex(await crypto.subtle.digest(algorithm, encoder.encode(key)));
|
|
25
38
|
}
|
|
26
39
|
/**
|
|
27
|
-
* Create
|
|
40
|
+
* Create an HMAC hex digest using the Web Crypto API. Defaults to SHA-256.
|
|
28
41
|
*/
|
|
29
|
-
function hmac(key, value) {
|
|
30
|
-
|
|
42
|
+
async function hmac(key, value, algorithm = "SHA-256") {
|
|
43
|
+
const cryptoKey = await crypto.subtle.importKey("raw", encoder.encode(key), {
|
|
44
|
+
name: "HMAC",
|
|
45
|
+
hash: algorithm
|
|
46
|
+
}, false, ["sign"]);
|
|
47
|
+
return toHex(await crypto.subtle.sign("HMAC", cryptoKey, encoder.encode(value)));
|
|
31
48
|
}
|
|
32
49
|
|
|
33
50
|
//#endregion
|
package/dist/shared/error.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { LiteralUnion, Metadata, Schema, SchemaInput, SchemaOutput } from "@kizlo/shared";
|
|
2
2
|
|
|
3
3
|
//#region src/shared/error.d.ts
|
|
4
4
|
declare const COMMON_ERRORS: {
|
|
@@ -116,11 +116,11 @@ type ErrorDefinition = {
|
|
|
116
116
|
/** Human-readable message. Overridable per throw via `errors.CODE({ message })`. */
|
|
117
117
|
message?: string;
|
|
118
118
|
/** Standard Schema for the error's `data` payload — validated and typed when you throw `errors.CODE({ data })`. */
|
|
119
|
-
data?:
|
|
119
|
+
data?: Schema;
|
|
120
120
|
};
|
|
121
121
|
declare function defineErrorMap<const T extends Partial<Record<CommonErrorLiteral, ErrorDefinition>>>(map: T): T;
|
|
122
122
|
type DefinedErrorMapLike = Record<string, ErrorDefinition>;
|
|
123
|
-
type ThrowableErrorFn<TCode extends string, T extends ErrorDefinition> = T["data"] extends
|
|
123
|
+
type ThrowableErrorFn<TCode extends string, T extends ErrorDefinition> = T["data"] extends Schema ? undefined extends SchemaInput<T["data"]> ? (options?: {
|
|
124
124
|
status?: number;
|
|
125
125
|
message?: string;
|
|
126
126
|
data?: SchemaInput<T["data"]>;
|
|
@@ -2,7 +2,7 @@ import { DefinedErrorMapLike, ThrowableErrorMap, WithCommonErrorMap } from "./er
|
|
|
2
2
|
import { ServerContext } from "../context.js";
|
|
3
3
|
import { AnyMiddleware, InferUses, Middleware } from "./middleware.js";
|
|
4
4
|
import * as _orpc_contract0 from "@orpc/contract";
|
|
5
|
-
import {
|
|
5
|
+
import { DeepMerge, Pathname, Prettify, Promisify, Schema, SchemaInput, SchemaOutput } from "@kizlo/shared";
|
|
6
6
|
import * as _orpc_server0 from "@orpc/server";
|
|
7
7
|
import { HTTPMethod } from "@orpc/server";
|
|
8
8
|
import { JsonifiedValue } from "@orpc/openapi-client";
|
|
@@ -33,25 +33,25 @@ interface Procedure<TScope extends InvocationScope, TInput, TOutput, TError exte
|
|
|
33
33
|
options: {
|
|
34
34
|
scope: TScope;
|
|
35
35
|
errors?: TError;
|
|
36
|
-
output:
|
|
36
|
+
output: Schema;
|
|
37
37
|
inputValidation?: boolean;
|
|
38
38
|
outputValidation?: boolean;
|
|
39
39
|
middlewares?: AnyMiddleware[];
|
|
40
40
|
} & ({
|
|
41
41
|
scope: "internal";
|
|
42
|
-
input?:
|
|
42
|
+
input?: Schema;
|
|
43
43
|
} | {
|
|
44
44
|
scope: "remote";
|
|
45
|
-
input?:
|
|
45
|
+
input?: Schema;
|
|
46
46
|
method?: HTTPMethod;
|
|
47
47
|
} | {
|
|
48
48
|
scope: "api";
|
|
49
49
|
method?: HTTPMethod;
|
|
50
50
|
path?: Pathname;
|
|
51
|
-
body?:
|
|
52
|
-
query?:
|
|
53
|
-
params?:
|
|
54
|
-
headers?:
|
|
51
|
+
body?: Schema;
|
|
52
|
+
query?: Schema;
|
|
53
|
+
params?: Schema;
|
|
54
|
+
headers?: Schema;
|
|
55
55
|
});
|
|
56
56
|
};
|
|
57
57
|
}
|
|
@@ -112,9 +112,9 @@ type ProcedureOptions<TScope extends InvocationScope, TPathname extends Pathname
|
|
|
112
112
|
input?: TInput;
|
|
113
113
|
});
|
|
114
114
|
declare function createProcedure<TScope extends InvocationScope, TPathname extends Pathname, TInput extends Schema | undefined = undefined, TBody extends Schema | undefined = undefined, TParams extends Schema | undefined = undefined, TQuery extends Schema | undefined = undefined, THeaders extends Schema | undefined = undefined, TOutput extends Schema = Schema, TError extends DefinedErrorMapLike = DefinedErrorMapLike, TMiddlewares extends Middleware<ResolvedSchemaOutput<TScope, TPathname, TInput, TBody, TParams, TQuery, THeaders>, SchemaOutput<TOutput>, TError>[] = Middleware<ResolvedSchemaOutput<TScope, TPathname, TInput, TBody, TParams, TQuery, THeaders>, SchemaOutput<TOutput>, TError>[], TContext extends ProcedureContext<TMiddlewares> = ProcedureContext<TMiddlewares>>(options: ProcedureOptions<TScope, TPathname, TInput, TBody, TParams, TQuery, THeaders, TOutput, TError, TMiddlewares>, handler: ProcedureHandler<ResolvedSchemaOutput<TScope, TPathname, TInput, TBody, TParams, TQuery, THeaders>, SchemaOutput<TOutput>, TError, TContext>): Procedure<TScope, ResolvedSchemaInput<TScope, TPathname, TInput, TBody, TParams, TQuery, THeaders>, TScope extends "api" ? JsonifiedValue<SchemaOutput<TOutput>> : SchemaOutput<TOutput>, TError>;
|
|
115
|
-
declare function schemaType<TInput, TOutput = TInput>(schema?:
|
|
115
|
+
declare function schemaType<TInput, TOutput = TInput>(schema?: Schema): Schema<TInput, TOutput>;
|
|
116
116
|
declare function buildProcedure(procedure: AnyProcedure): _orpc_server0.DecoratedProcedure<_orpc_server0.Context & Record<never, never>, _orpc_server0.Context, _orpc_contract0.Schema<unknown, unknown>, _orpc_contract0.Schema<any, any>, Record<never, never>, Record<never, never>>;
|
|
117
117
|
declare function handleUnexpectedError(error: unknown, errors?: DefinedErrorMapLike): never;
|
|
118
|
-
declare function combineDetailed(parts: Record<string,
|
|
118
|
+
declare function combineDetailed(parts: Record<string, Schema>): Schema;
|
|
119
119
|
//#endregion
|
|
120
120
|
export { AnyProcedure, AnyProcedureRouter, BaseHandlerOptions, ExtractParams, ExtractProcedureByScope, InvocationScope, OpenapiPart, Procedure, ProcedureContext, ProcedureErrors, ProcedureHandler, ProcedureOptions, ResolveParamsPart, ResolvedSchemaInput, ResolvedSchemaOutput, RouterDepthTuple, SchemaIO, buildProcedure, combineDetailed, createProcedure, handleUnexpectedError, schemaType };
|
package/dist/webhook/schema.d.ts
CHANGED
|
@@ -12,6 +12,7 @@ declare const KizloEvent: z.ZodUnion<readonly [z.ZodObject<{
|
|
|
12
12
|
data: z.ZodObject<{
|
|
13
13
|
post_id: z.ZodNumber;
|
|
14
14
|
post_type: z.ZodString;
|
|
15
|
+
url: z.ZodOptional<z.ZodString>;
|
|
15
16
|
}, z.core.$strip>;
|
|
16
17
|
}, z.core.$strip>, z.ZodObject<{
|
|
17
18
|
type: z.ZodEnum<{
|
|
@@ -24,15 +25,7 @@ declare const KizloEvent: z.ZodUnion<readonly [z.ZodObject<{
|
|
|
24
25
|
taxonomy: z.ZodString;
|
|
25
26
|
post_types: z.ZodArray<z.ZodString>;
|
|
26
27
|
count: z.ZodNumber;
|
|
27
|
-
|
|
28
|
-
}, z.core.$strip>, z.ZodObject<{
|
|
29
|
-
type: z.ZodEnum<{
|
|
30
|
-
"payment.status_requested": "payment.status_requested";
|
|
31
|
-
}>;
|
|
32
|
-
data: z.ZodObject<{
|
|
33
|
-
transaction_id: z.ZodNullable<z.ZodString>;
|
|
34
|
-
payment_method_id: z.ZodString;
|
|
35
|
-
payment_session_id: z.ZodString;
|
|
28
|
+
url: z.ZodOptional<z.ZodString>;
|
|
36
29
|
}, z.core.$strip>;
|
|
37
30
|
}, z.core.$strip>, z.ZodObject<{
|
|
38
31
|
type: z.ZodEnum<{
|
package/dist/webhook/schema.js
CHANGED
|
@@ -14,20 +14,18 @@ const POST_EVENT_TYPES = [
|
|
|
14
14
|
"post.deleted"
|
|
15
15
|
];
|
|
16
16
|
const PostEventType = z.enum(POST_EVENT_TYPES);
|
|
17
|
-
const PAYMENT_EVENT_TYPES = ["payment.status_requested"];
|
|
18
|
-
const PaymentEventType = z.enum(PAYMENT_EVENT_TYPES);
|
|
19
17
|
const SETTINGS_EVENT_TYPES = ["settings.saved"];
|
|
20
18
|
const SettingsEventType = z.enum(SETTINGS_EVENT_TYPES);
|
|
21
19
|
const EVENT_TYPES = [
|
|
22
20
|
...TERM_EVENT_TYPES,
|
|
23
21
|
...POST_EVENT_TYPES,
|
|
24
|
-
...PAYMENT_EVENT_TYPES,
|
|
25
22
|
...SETTINGS_EVENT_TYPES
|
|
26
23
|
];
|
|
27
24
|
const EventType = z.enum(EVENT_TYPES);
|
|
28
25
|
const PostEventData = z.object({
|
|
29
26
|
post_id: z.number(),
|
|
30
|
-
post_type: z.string()
|
|
27
|
+
post_type: z.string(),
|
|
28
|
+
url: z.string().optional()
|
|
31
29
|
});
|
|
32
30
|
const PostEvent = z.object({
|
|
33
31
|
type: PostEventType,
|
|
@@ -37,21 +35,13 @@ const TermEventData = z.object({
|
|
|
37
35
|
term_id: z.number(),
|
|
38
36
|
taxonomy: z.string(),
|
|
39
37
|
post_types: z.array(z.string()),
|
|
40
|
-
count: z.number().nonnegative()
|
|
38
|
+
count: z.number().nonnegative(),
|
|
39
|
+
url: z.string().optional()
|
|
41
40
|
});
|
|
42
41
|
const TermEvent = z.object({
|
|
43
42
|
type: TermEventType,
|
|
44
43
|
data: TermEventData
|
|
45
44
|
});
|
|
46
|
-
const PaymentEventData = z.object({
|
|
47
|
-
transaction_id: z.nullable(z.string()),
|
|
48
|
-
payment_method_id: z.string(),
|
|
49
|
-
payment_session_id: z.string()
|
|
50
|
-
});
|
|
51
|
-
const PaymentEvent = z.object({
|
|
52
|
-
type: PaymentEventType,
|
|
53
|
-
data: PaymentEventData
|
|
54
|
-
});
|
|
55
45
|
const SettingsEventData = z.null();
|
|
56
46
|
const SettingsEvent = z.object({
|
|
57
47
|
type: SettingsEventType,
|
|
@@ -60,7 +50,6 @@ const SettingsEvent = z.object({
|
|
|
60
50
|
const KizloEvent = z.union([
|
|
61
51
|
PostEvent,
|
|
62
52
|
TermEvent,
|
|
63
|
-
PaymentEvent,
|
|
64
53
|
SettingsEvent
|
|
65
54
|
]);
|
|
66
55
|
const AnyEvent = z.object({
|
|
@@ -69,4 +58,4 @@ const AnyEvent = z.object({
|
|
|
69
58
|
});
|
|
70
59
|
|
|
71
60
|
//#endregion
|
|
72
|
-
export { AnyEvent, KizloEvent };
|
|
61
|
+
export { AnyEvent, KizloEvent, POST_EVENT_TYPES, TERM_EVENT_TYPES };
|
|
@@ -17,7 +17,10 @@ var WordPressService = class {
|
|
|
17
17
|
authHeader;
|
|
18
18
|
defaultTimeout;
|
|
19
19
|
constructor(context) {
|
|
20
|
-
|
|
20
|
+
const credentialBytes = new TextEncoder().encode(`${context.credentials.username}:${context.credentials.password}`);
|
|
21
|
+
let binary = "";
|
|
22
|
+
for (const byte of credentialBytes) binary += String.fromCharCode(byte);
|
|
23
|
+
this.authHeader = `${WP_AUTH_TYPE} ${btoa(binary)}`;
|
|
21
24
|
this.siteBase = context.credentials.url.endsWith("/") ? context.credentials.url : `${context.credentials.url}/`;
|
|
22
25
|
this.defaultTimeout = context.timeout ?? SAFE_REQUEST_TIMEOUT;
|
|
23
26
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "kizlo",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "A headless WordPress toolkit for TypeScript.",
|
|
6
6
|
"keywords": [
|
|
@@ -76,7 +76,7 @@
|
|
|
76
76
|
},
|
|
77
77
|
"dependencies": {
|
|
78
78
|
"@clack/prompts": "^1.5.1",
|
|
79
|
-
"@kizlo/shared": "0.1.
|
|
79
|
+
"@kizlo/shared": "0.1.2",
|
|
80
80
|
"@orpc/client": "^1.14.3",
|
|
81
81
|
"@orpc/contract": "^1.14.3",
|
|
82
82
|
"@orpc/openapi": "^1.14.3",
|