@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 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 "@wp-typia/rest/react";
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 "@wp-typia/rest";
42
+ import { callEndpoint, createEndpoint } from '@wp-typia/rest';
29
43
 
30
44
  const endpoint = createEndpoint<MyRequest, MyResponse>({
31
- method: "POST",
32
- path: "/my-namespace/v1/demo",
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: "Hello" });
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 "@wp-typia/rest";
72
+ import { resolveRestRouteUrl } from '@wp-typia/rest';
49
73
 
50
- const url = resolveRestRouteUrl("/my-namespace/v1/demo");
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 "typia";
57
- import { createQueryDecoder } from "@wp-typia/rest";
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
- "X-WP-Nonce": resolveRestNonce(),
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
- "X-WP-Nonce": resolveRestNonce(),
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 Error("Unable to resolve the WordPress REST root automatically. Provide wpApiSettings.root, an api.w.org discovery link, or an explicit url.");
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 Error("API fetch options must include either a path or a url.");
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 Error(result.errors[0]
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
  }
@@ -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 Error("useEndpointQuery only supports GET endpoints in v1.");
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.6",
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.3",
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
  },