@wp-typia/rest 0.3.6 → 0.3.7
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 +37 -16
- package/dist/client.js +4 -3
- package/dist/errors.d.ts +14 -0
- package/dist/errors.js +25 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/react.js +2 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -15,26 +15,40 @@ It does not include any WordPress PHP bridge logic. Generated PHP route code sta
|
|
|
15
15
|
If you need a backend-neutral consumer instead of WordPress-specific route
|
|
16
16
|
resolution, use `@wp-typia/api-client`.
|
|
17
17
|
|
|
18
|
+
## Export contract
|
|
19
|
+
|
|
20
|
+
- `@wp-typia/rest`
|
|
21
|
+
Canonical convenience surface for transport helpers plus HTTP decoder helpers.
|
|
22
|
+
- `@wp-typia/rest/client`
|
|
23
|
+
Backward-compatible alias of the root surface. It is not a distinct semantic
|
|
24
|
+
contract and may be removed in a future major once downstream imports settle.
|
|
25
|
+
- `@wp-typia/rest/http`
|
|
26
|
+
Backward-compatible alias of the root surface. It remains publishable for
|
|
27
|
+
existing imports, but it is not a distinct decoder-only contract in the
|
|
28
|
+
current major line.
|
|
29
|
+
- `@wp-typia/rest/react`
|
|
30
|
+
React-only cache and hook layer.
|
|
31
|
+
|
|
18
32
|
The root `@wp-typia/rest` entry stays transport-oriented. If you want query and
|
|
19
33
|
mutation hooks on top of those WordPress helpers, use the React-only subpath:
|
|
20
34
|
|
|
21
35
|
```ts
|
|
22
|
-
import { useEndpointMutation, useEndpointQuery } from
|
|
36
|
+
import { useEndpointMutation, useEndpointQuery } from '@wp-typia/rest/react';
|
|
23
37
|
```
|
|
24
38
|
|
|
25
39
|
Typical usage:
|
|
26
40
|
|
|
27
41
|
```ts
|
|
28
|
-
import { callEndpoint, createEndpoint } from
|
|
42
|
+
import { callEndpoint, createEndpoint } from '@wp-typia/rest';
|
|
29
43
|
|
|
30
44
|
const endpoint = createEndpoint<MyRequest, MyResponse>({
|
|
31
|
-
method:
|
|
32
|
-
path:
|
|
45
|
+
method: 'POST',
|
|
46
|
+
path: '/my-namespace/v1/demo',
|
|
33
47
|
validateRequest: validators.request,
|
|
34
48
|
validateResponse: validators.response,
|
|
35
49
|
});
|
|
36
50
|
|
|
37
|
-
const result = await callEndpoint(endpoint, { title:
|
|
51
|
+
const result = await callEndpoint(endpoint, { title: 'Hello' });
|
|
38
52
|
```
|
|
39
53
|
|
|
40
54
|
`callEndpoint(...)` returns `EndpointValidationResult<Req, Res>`. If request
|
|
@@ -42,22 +56,32 @@ validation fails before transport execution, the result keeps
|
|
|
42
56
|
`validationTarget: "request"`. Response validation runs after transport and uses
|
|
43
57
|
`validationTarget: "response"`.
|
|
44
58
|
|
|
59
|
+
Invalid request/response payloads stay in that result union. Thrown exceptions
|
|
60
|
+
are reserved for public runtime misconfiguration or assertion APIs:
|
|
61
|
+
|
|
62
|
+
- `RestConfigurationError`
|
|
63
|
+
- `RestRootResolutionError`
|
|
64
|
+
- `RestQueryHookUsageError`
|
|
65
|
+
- `RestValidationAssertionError`
|
|
66
|
+
- shared base classes re-exported from `@wp-typia/api-client`:
|
|
67
|
+
`WpTypiaContractError` and `WpTypiaValidationAssertionError`
|
|
68
|
+
|
|
45
69
|
If you need a canonical REST URL for a route path, use:
|
|
46
70
|
|
|
47
71
|
```ts
|
|
48
|
-
import { resolveRestRouteUrl } from
|
|
72
|
+
import { resolveRestRouteUrl } from '@wp-typia/rest';
|
|
49
73
|
|
|
50
|
-
const url = resolveRestRouteUrl(
|
|
74
|
+
const url = resolveRestRouteUrl('/my-namespace/v1/demo');
|
|
51
75
|
```
|
|
52
76
|
|
|
53
77
|
If you want Typia-powered HTTP decoding, compile the decoder in the consumer project and pass it in:
|
|
54
78
|
|
|
55
79
|
```ts
|
|
56
|
-
import typia from
|
|
57
|
-
import { createQueryDecoder } from
|
|
80
|
+
import typia from 'typia';
|
|
81
|
+
import { createQueryDecoder } from '@wp-typia/rest';
|
|
58
82
|
|
|
59
83
|
const decodeQuery = createQueryDecoder(
|
|
60
|
-
typia.http.createValidateQuery<MyQuery>()
|
|
84
|
+
typia.http.createValidateQuery<MyQuery>(),
|
|
61
85
|
);
|
|
62
86
|
```
|
|
63
87
|
|
|
@@ -76,17 +100,14 @@ The `./react` subpath adds a small cache client and React hook layer on top of
|
|
|
76
100
|
non-query calls go through `useEndpointMutation(...)`.
|
|
77
101
|
|
|
78
102
|
```tsx
|
|
79
|
-
import {
|
|
80
|
-
useEndpointMutation,
|
|
81
|
-
useEndpointQuery,
|
|
82
|
-
} from "@wp-typia/rest/react";
|
|
103
|
+
import { useEndpointMutation, useEndpointQuery } from '@wp-typia/rest/react';
|
|
83
104
|
|
|
84
105
|
const query = useEndpointQuery(stateEndpoint, request, {
|
|
85
106
|
staleTime: 30_000,
|
|
86
107
|
resolveCallOptions: () => ({
|
|
87
108
|
requestOptions: {
|
|
88
109
|
headers: {
|
|
89
|
-
|
|
110
|
+
'X-WP-Nonce': resolveRestNonce(),
|
|
90
111
|
},
|
|
91
112
|
},
|
|
92
113
|
}),
|
|
@@ -97,7 +118,7 @@ const mutation = useEndpointMutation(writeStateEndpoint, {
|
|
|
97
118
|
resolveCallOptions: () => ({
|
|
98
119
|
requestOptions: {
|
|
99
120
|
headers: {
|
|
100
|
-
|
|
121
|
+
'X-WP-Nonce': resolveRestNonce(),
|
|
101
122
|
},
|
|
102
123
|
},
|
|
103
124
|
}),
|
package/dist/client.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { encodeGetLikeRequest, joinPathWithQuery, joinUrlWithQuery, mergeHeaderInputs, parseResponsePayload, } from "@wp-typia/api-client/client-utils";
|
|
2
2
|
import { isFormDataLike, toValidationResult, } from "./internal/runtime-primitives.js";
|
|
3
|
+
import { RestConfigurationError, RestRootResolutionError, RestValidationAssertionError, } from "./errors.js";
|
|
3
4
|
export { isValidationResult, normalizeValidationError, toValidationResult } from "./internal/runtime-primitives.js";
|
|
4
5
|
function getDefaultRestRoot() {
|
|
5
6
|
if (typeof window !== "undefined") {
|
|
@@ -15,7 +16,7 @@ function getDefaultRestRoot() {
|
|
|
15
16
|
}
|
|
16
17
|
}
|
|
17
18
|
}
|
|
18
|
-
throw new
|
|
19
|
+
throw new RestRootResolutionError("Unable to resolve the WordPress REST root automatically. Provide wpApiSettings.root, an api.w.org discovery link, or an explicit url.");
|
|
19
20
|
}
|
|
20
21
|
export function resolveRestRouteUrl(routePath, root = getDefaultRestRoot()) {
|
|
21
22
|
const [pathWithQuery, hash = ""] = routePath.split("#", 2);
|
|
@@ -50,7 +51,7 @@ function resolveFetchUrl(options) {
|
|
|
50
51
|
if (typeof options.path === "string" && options.path.length > 0) {
|
|
51
52
|
return resolveRestRouteUrl(options.path);
|
|
52
53
|
}
|
|
53
|
-
throw new
|
|
54
|
+
throw new RestConfigurationError("API fetch options must include either a path or a url.");
|
|
54
55
|
}
|
|
55
56
|
async function defaultFetch(options) {
|
|
56
57
|
const response = await fetch(resolveFetchUrl(options), {
|
|
@@ -154,7 +155,7 @@ export function createValidatedFetch(validator, fetchFn = defaultFetch) {
|
|
|
154
155
|
async assertFetch(options) {
|
|
155
156
|
const result = await this.fetch(options);
|
|
156
157
|
if (!result.isValid) {
|
|
157
|
-
throw new
|
|
158
|
+
throw new RestValidationAssertionError(result, result.errors[0]
|
|
158
159
|
? `${result.errors[0].path}: ${result.errors[0].expected}`
|
|
159
160
|
: "REST response validation failed.");
|
|
160
161
|
}
|
package/dist/errors.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { WpTypiaContractError, WpTypiaValidationAssertionError, type ValidationResult } from "@wp-typia/api-client";
|
|
2
|
+
export { ApiClientConfigurationError, WpTypiaContractError, WpTypiaValidationAssertionError, } from "@wp-typia/api-client";
|
|
3
|
+
export declare class RestConfigurationError extends WpTypiaContractError {
|
|
4
|
+
constructor(message: string);
|
|
5
|
+
}
|
|
6
|
+
export declare class RestRootResolutionError extends RestConfigurationError {
|
|
7
|
+
constructor(message: string);
|
|
8
|
+
}
|
|
9
|
+
export declare class RestQueryHookUsageError extends RestConfigurationError {
|
|
10
|
+
constructor(message: string);
|
|
11
|
+
}
|
|
12
|
+
export declare class RestValidationAssertionError<T = unknown> extends WpTypiaValidationAssertionError<T> {
|
|
13
|
+
constructor(validation: ValidationResult<T>, message: string);
|
|
14
|
+
}
|
package/dist/errors.js
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { WpTypiaContractError, WpTypiaValidationAssertionError, } from "@wp-typia/api-client";
|
|
2
|
+
export { ApiClientConfigurationError, WpTypiaContractError, WpTypiaValidationAssertionError, } from "@wp-typia/api-client";
|
|
3
|
+
export class RestConfigurationError extends WpTypiaContractError {
|
|
4
|
+
constructor(message) {
|
|
5
|
+
super(message, "REST_CONFIGURATION_ERROR");
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
export class RestRootResolutionError extends RestConfigurationError {
|
|
9
|
+
constructor(message) {
|
|
10
|
+
super(message);
|
|
11
|
+
this.name = new.target.name;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
export class RestQueryHookUsageError extends RestConfigurationError {
|
|
15
|
+
constructor(message) {
|
|
16
|
+
super(message);
|
|
17
|
+
this.name = new.target.name;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
export class RestValidationAssertionError extends WpTypiaValidationAssertionError {
|
|
21
|
+
constructor(validation, message) {
|
|
22
|
+
super(validation, message);
|
|
23
|
+
this.name = new.target.name;
|
|
24
|
+
}
|
|
25
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,2 +1,3 @@
|
|
|
1
1
|
export { createEndpoint, createValidatedFetch, callEndpoint, isValidationResult, normalizeValidationError, resolveRestRouteUrl, toValidationResult, type ApiEndpoint, type EndpointCallOptions, type EndpointRequestValidationResult, type EndpointResponseValidationResult, type EndpointValidationResult, type EndpointValidationTarget, type ValidatedFetch, type ValidationResult, type ValidationError, type ValidationLike, } from "./client.js";
|
|
2
|
+
export { ApiClientConfigurationError, RestConfigurationError, RestQueryHookUsageError, RestRootResolutionError, RestValidationAssertionError, WpTypiaContractError, WpTypiaValidationAssertionError, } from "./errors.js";
|
|
2
3
|
export { createHeadersDecoder, createParameterDecoder, createQueryDecoder, } from "./http.js";
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,3 @@
|
|
|
1
1
|
export { createEndpoint, createValidatedFetch, callEndpoint, isValidationResult, normalizeValidationError, resolveRestRouteUrl, toValidationResult, } from "./client.js";
|
|
2
|
+
export { ApiClientConfigurationError, RestConfigurationError, RestQueryHookUsageError, RestRootResolutionError, RestValidationAssertionError, WpTypiaContractError, WpTypiaValidationAssertionError, } from "./errors.js";
|
|
2
3
|
export { createHeadersDecoder, createParameterDecoder, createQueryDecoder, } from "./http.js";
|
package/dist/react.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { createContext, createElement, useContext, useEffect, useMemo, useRef, useState, useSyncExternalStore, } from "@wordpress/element";
|
|
2
2
|
import { callEndpoint, } from "./client.js";
|
|
3
|
+
import { RestQueryHookUsageError } from "./errors.js";
|
|
3
4
|
import { isPlainObject } from "./internal/runtime-primitives.js";
|
|
4
5
|
const EMPTY_SNAPSHOT = {
|
|
5
6
|
data: undefined,
|
|
@@ -325,7 +326,7 @@ export function useEndpointDataClient() {
|
|
|
325
326
|
}
|
|
326
327
|
export function useEndpointQuery(endpoint, request, options = {}) {
|
|
327
328
|
if (endpoint.method !== "GET") {
|
|
328
|
-
throw new
|
|
329
|
+
throw new RestQueryHookUsageError("useEndpointQuery only supports GET endpoints in v1.");
|
|
329
330
|
}
|
|
330
331
|
const defaultClient = useEndpointDataClient();
|
|
331
332
|
const client = asInternalClient(options.client ?? defaultClient);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wp-typia/rest",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.7",
|
|
4
4
|
"description": "Typed WordPress REST helpers powered by Typia validation",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -62,7 +62,7 @@
|
|
|
62
62
|
"bun": ">=1.3.11"
|
|
63
63
|
},
|
|
64
64
|
"dependencies": {
|
|
65
|
-
"@wp-typia/api-client": "^0.4.
|
|
65
|
+
"@wp-typia/api-client": "^0.4.4",
|
|
66
66
|
"@typia/interface": "^12.0.1",
|
|
67
67
|
"@wordpress/api-fetch": "^7.42.0"
|
|
68
68
|
},
|