@nxgt/httpyz-query 0.2.0 → 0.2.2
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 +2 -2
- package/dist/chunks/index-hecx9b0s.js +54 -0
- package/dist/chunks/index-hecx9b0s.js.map +10 -0
- package/dist/index.js +7 -53
- package/dist/index.js.map +4 -5
- package/dist/openapi.js +7 -53
- package/dist/openapi.js.map +4 -5
- package/package.json +6 -6
package/README.md
CHANGED
|
@@ -55,7 +55,7 @@ fails with the client's `ReplyStatusError` on any other:
|
|
|
55
55
|
```ts
|
|
56
56
|
import { useQuery } from '@tanstack/react-query';
|
|
57
57
|
import { z } from 'zod';
|
|
58
|
-
import { queries } from './queries
|
|
58
|
+
import { queries } from './queries';
|
|
59
59
|
|
|
60
60
|
const Employee = z.object({ id: z.int(), name: z.string() });
|
|
61
61
|
const Problem = z.object({ title: z.string() });
|
|
@@ -156,7 +156,7 @@ an optional peer. It takes the bound client, and reads the spec from the
|
|
|
156
156
|
|
|
157
157
|
```ts
|
|
158
158
|
import { createOpenApiQueries } from '@nxgt/httpyz-query/openapi';
|
|
159
|
-
import { api } from './api
|
|
159
|
+
import { api } from './api'; // createOpenApiClient(http, operations)
|
|
160
160
|
|
|
161
161
|
export const queries = createOpenApiQueries(api);
|
|
162
162
|
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
// src/key/key.ts
|
|
2
|
+
var joined = (given, query) => given ? AbortSignal.any([given, query]) : query;
|
|
3
|
+
var hashable = (value) => value instanceof URLSearchParams || typeof FormData !== "undefined" && value instanceof FormData ? [...value.entries()] : value;
|
|
4
|
+
var PARTS = [
|
|
5
|
+
"param",
|
|
6
|
+
"query",
|
|
7
|
+
"header",
|
|
8
|
+
"json",
|
|
9
|
+
"form",
|
|
10
|
+
"text",
|
|
11
|
+
"body"
|
|
12
|
+
];
|
|
13
|
+
function keyed(input) {
|
|
14
|
+
if (!input)
|
|
15
|
+
return;
|
|
16
|
+
const given = input;
|
|
17
|
+
const key = {};
|
|
18
|
+
for (const part of PARTS) {
|
|
19
|
+
if (given[part] !== undefined)
|
|
20
|
+
key[part] = hashable(given[part]);
|
|
21
|
+
}
|
|
22
|
+
if (given.decode === false)
|
|
23
|
+
key.decode = false;
|
|
24
|
+
return Object.keys(key).length > 0 ? key : undefined;
|
|
25
|
+
}
|
|
26
|
+
function keyOf(scope, method, path, input) {
|
|
27
|
+
const key = scope === undefined ? [method] : [scope, method];
|
|
28
|
+
if (path !== undefined)
|
|
29
|
+
key.push(path);
|
|
30
|
+
const rest = keyed(input);
|
|
31
|
+
if (rest !== undefined)
|
|
32
|
+
key.push(rest);
|
|
33
|
+
return key;
|
|
34
|
+
}
|
|
35
|
+
function paged(input, name, pageParam) {
|
|
36
|
+
const given = input?.query;
|
|
37
|
+
if (given instanceof URLSearchParams) {
|
|
38
|
+
const query = new URLSearchParams(given);
|
|
39
|
+
if (pageParam === null || pageParam === undefined)
|
|
40
|
+
query.delete(name);
|
|
41
|
+
else
|
|
42
|
+
query.set(name, String(pageParam));
|
|
43
|
+
return { ...input, query };
|
|
44
|
+
}
|
|
45
|
+
return {
|
|
46
|
+
...input,
|
|
47
|
+
query: { ...given, [name]: pageParam }
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export { joined, keyOf, paged };
|
|
52
|
+
|
|
53
|
+
//# debugId=96A550186B7F86F464756E2164756E21
|
|
54
|
+
//# sourceMappingURL=index-hecx9b0s.js.map
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/key/key.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"/** What the keys and calls of both entry points share. */\n\n/** Both signals: the call ends on either. */\nexport const joined = (\n\tgiven: AbortSignal | null | undefined,\n\tquery: AbortSignal,\n): AbortSignal => (given ? AbortSignal.any([given, query]) : query);\n\n/** A value TanStack hashes as it is: a `URLSearchParams` or `FormData` as its entries. */\nconst hashable = (value: unknown): unknown =>\n\tvalue instanceof URLSearchParams ||\n\t(typeof FormData !== 'undefined' && value instanceof FormData)\n\t\t? [...value.entries()]\n\t\t: value;\n\n/** The parts of an input that tell two calls to one path apart. */\nconst PARTS = [\n\t'param',\n\t'query',\n\t'header',\n\t'json',\n\t'form',\n\t'text',\n\t'body',\n] as const;\n\n/** What tells two calls to one path apart: what they send, and `decode: false`. */\nfunction keyed(input: object | undefined): object | undefined {\n\tif (!input) return undefined;\n\tconst given = input as { readonly [part: string]: unknown };\n\tconst key: Record<string, unknown> = {};\n\tfor (const part of PARTS) {\n\t\tif (given[part] !== undefined) key[part] = hashable(given[part]);\n\t}\n\tif (given.decode === false) key.decode = false;\n\treturn Object.keys(key).length > 0 ? key : undefined;\n}\n\n/** A key, or the start of one: `[scope?, method, path?, input?]`. */\nexport function keyOf(\n\tscope: string | undefined,\n\tmethod: string,\n\tpath?: string,\n\tinput?: object,\n): unknown[] {\n\tconst key: unknown[] = scope === undefined ? [method] : [scope, method];\n\tif (path !== undefined) key.push(path);\n\tconst rest = keyed(input);\n\tif (rest !== undefined) key.push(rest);\n\treturn key;\n}\n\n/** `input` with `pageParam` as its query parameter `name`: left out when `null`. */\nexport function paged<Input extends { readonly query?: unknown }>(\n\tinput: Input | undefined,\n\tname: string,\n\tpageParam: unknown,\n): Input {\n\tconst given = input?.query;\n\tif (given instanceof URLSearchParams) {\n\t\tconst query = new URLSearchParams(given);\n\t\tif (pageParam === null || pageParam === undefined) query.delete(name);\n\t\telse query.set(name, String(pageParam));\n\t\treturn { ...input, query } as Input;\n\t}\n\treturn {\n\t\t...input,\n\t\tquery: { ...(given as object | undefined), [name]: pageParam },\n\t} as Input;\n}\n"
|
|
6
|
+
],
|
|
7
|
+
"mappings": ";AAGO,IAAM,SAAS,CACrB,OACA,UACkB,QAAQ,YAAY,IAAI,CAAC,OAAO,KAAK,CAAC,IAAI;AAG7D,IAAM,WAAW,CAAC,UACjB,iBAAiB,mBAChB,OAAO,aAAa,eAAe,iBAAiB,WAClD,CAAC,GAAG,MAAM,QAAQ,CAAC,IACnB;AAGJ,IAAM,QAAQ;AAAA,EACb;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACD;AAGA,SAAS,KAAK,CAAC,OAA+C;AAAA,EAC7D,IAAI,CAAC;AAAA,IAAO;AAAA,EACZ,MAAM,QAAQ;AAAA,EACd,MAAM,MAA+B,CAAC;AAAA,EACtC,WAAW,QAAQ,OAAO;AAAA,IACzB,IAAI,MAAM,UAAU;AAAA,MAAW,IAAI,QAAQ,SAAS,MAAM,KAAK;AAAA,EAChE;AAAA,EACA,IAAI,MAAM,WAAW;AAAA,IAAO,IAAI,SAAS;AAAA,EACzC,OAAO,OAAO,KAAK,GAAG,EAAE,SAAS,IAAI,MAAM;AAAA;AAIrC,SAAS,KAAK,CACpB,OACA,QACA,MACA,OACY;AAAA,EACZ,MAAM,MAAiB,UAAU,YAAY,CAAC,MAAM,IAAI,CAAC,OAAO,MAAM;AAAA,EACtE,IAAI,SAAS;AAAA,IAAW,IAAI,KAAK,IAAI;AAAA,EACrC,MAAM,OAAO,MAAM,KAAK;AAAA,EACxB,IAAI,SAAS;AAAA,IAAW,IAAI,KAAK,IAAI;AAAA,EACrC,OAAO;AAAA;AAID,SAAS,KAAiD,CAChE,OACA,MACA,WACQ;AAAA,EACR,MAAM,QAAQ,OAAO;AAAA,EACrB,IAAI,iBAAiB,iBAAiB;AAAA,IACrC,MAAM,QAAQ,IAAI,gBAAgB,KAAK;AAAA,IACvC,IAAI,cAAc,QAAQ,cAAc;AAAA,MAAW,MAAM,OAAO,IAAI;AAAA,IAC/D;AAAA,YAAM,IAAI,MAAM,OAAO,SAAS,CAAC;AAAA,IACtC,OAAO,KAAK,OAAO,MAAM;AAAA,EAC1B;AAAA,EACA,OAAO;AAAA,OACH;AAAA,IACH,OAAO,KAAM,QAA+B,OAAO,UAAU;AAAA,EAC9D;AAAA;",
|
|
8
|
+
"debugId": "96A550186B7F86F464756E2164756E21",
|
|
9
|
+
"names": []
|
|
10
|
+
}
|
package/dist/index.js
CHANGED
|
@@ -1,57 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
var hashable = (value) => value instanceof URLSearchParams || typeof FormData !== "undefined" && value instanceof FormData ? [...value.entries()] : value;
|
|
7
|
-
var PARTS = [
|
|
8
|
-
"param",
|
|
9
|
-
"query",
|
|
10
|
-
"header",
|
|
11
|
-
"json",
|
|
12
|
-
"form",
|
|
13
|
-
"text",
|
|
14
|
-
"body"
|
|
15
|
-
];
|
|
16
|
-
function keyed(input) {
|
|
17
|
-
if (!input)
|
|
18
|
-
return;
|
|
19
|
-
const given = input;
|
|
20
|
-
const key = {};
|
|
21
|
-
for (const part of PARTS) {
|
|
22
|
-
if (given[part] !== undefined)
|
|
23
|
-
key[part] = hashable(given[part]);
|
|
24
|
-
}
|
|
25
|
-
if (given.decode === false)
|
|
26
|
-
key.decode = false;
|
|
27
|
-
return Object.keys(key).length > 0 ? key : undefined;
|
|
28
|
-
}
|
|
29
|
-
function keyOf(scope, method, path, input) {
|
|
30
|
-
const key = scope === undefined ? [method] : [scope, method];
|
|
31
|
-
if (path !== undefined)
|
|
32
|
-
key.push(path);
|
|
33
|
-
const rest = keyed(input);
|
|
34
|
-
if (rest !== undefined)
|
|
35
|
-
key.push(rest);
|
|
36
|
-
return key;
|
|
37
|
-
}
|
|
38
|
-
function paged(input, name, pageParam) {
|
|
39
|
-
const given = input?.query;
|
|
40
|
-
if (given instanceof URLSearchParams) {
|
|
41
|
-
const query = new URLSearchParams(given);
|
|
42
|
-
if (pageParam === null || pageParam === undefined)
|
|
43
|
-
query.delete(name);
|
|
44
|
-
else
|
|
45
|
-
query.set(name, String(pageParam));
|
|
46
|
-
return { ...input, query };
|
|
47
|
-
}
|
|
48
|
-
return {
|
|
49
|
-
...input,
|
|
50
|
-
query: { ...given, [name]: pageParam }
|
|
51
|
-
};
|
|
52
|
-
}
|
|
1
|
+
import {
|
|
2
|
+
joined,
|
|
3
|
+
keyOf,
|
|
4
|
+
paged
|
|
5
|
+
} from "./chunks/index-hecx9b0s.js";
|
|
53
6
|
|
|
54
7
|
// src/queries/create-queries.ts
|
|
8
|
+
import { ok } from "@nxgt/httpyz";
|
|
55
9
|
function createQueries(http, { scope } = {}) {
|
|
56
10
|
const send = http.request;
|
|
57
11
|
const queryKey = (method, path, input) => keyOf(scope, method, path, input);
|
|
@@ -83,5 +37,5 @@ export {
|
|
|
83
37
|
createQueries
|
|
84
38
|
};
|
|
85
39
|
|
|
86
|
-
//# debugId=
|
|
40
|
+
//# debugId=144A38071D25A1FA64756E2164756E21
|
|
87
41
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../src/queries/create-queries.ts"
|
|
3
|
+
"sources": ["../src/queries/create-queries.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"/**\n * `createQueries`: TanStack Query options for the calls of a client of\n * `createHttpClient`. It adds no runtime of TanStack's: each function returns\n * a plain object, whose `queryFn` sends the call with the query's `signal`.\n */\nimport { type HttpClient, type Method, ok } from '@nxgt/httpyz';\nimport { joined, keyOf, paged } from '../key/key';\nimport type { HttpQueries, KeyInput, Paging, QueriesOptions } from './types';\n\ntype Send = (\n\tmethod: Method,\n\tpath: string,\n\toptions: object,\n) => Promise<{ readonly status: number; readonly data: unknown }>;\n\ntype Options = KeyInput & { readonly signal?: AbortSignal | null };\n\n/**\n * TanStack Query options for the calls of `http`.\n *\n * ```ts\n * const queries = createQueries(http);\n * const { data } = useQuery(\n * queries.queryOptions('get', '/items/{id}', { param: { id }, responses: { 200: Item } }),\n * );\n * ```\n */\nexport function createQueries(\n\thttp: HttpClient,\n\t{ scope }: QueriesOptions = {},\n): HttpQueries {\n\tconst send = http.request as unknown as Send;\n\tconst queryKey = (method: Method, path?: string, input?: KeyInput) =>\n\t\tkeyOf(scope, method, path, input);\n\tconst call = (\n\t\tmethod: Method,\n\t\tpath: string,\n\t\toptions: Options | undefined,\n\t\tsignal: AbortSignal,\n\t) =>\n\t\tsend(method, path, {\n\t\t\t...options,\n\t\t\tsignal: joined(options?.signal, signal),\n\t\t}).then(ok);\n\n\treturn {\n\t\tqueryKey,\n\t\tqueryOptions: (method: Method, path: string, options?: Options) => ({\n\t\t\tqueryKey: queryKey(method, path, options),\n\t\t\tqueryFn: ({ signal }: { signal: AbortSignal }) =>\n\t\t\t\tcall(method, path, options, signal),\n\t\t}),\n\t\tinfiniteQueryOptions: (\n\t\t\tmethod: Method,\n\t\t\tpath: string,\n\t\t\toptions: Options,\n\t\t\t{ pageParamName, ...paging }: Paging<unknown, unknown>,\n\t\t) => ({\n\t\t\t...paging,\n\t\t\t// Apart from the query of the same call, whose data is one page, not all of them.\n\t\t\tqueryKey: [...queryKey(method, path, options), 'infinite'],\n\t\t\tqueryFn: ({\n\t\t\t\tsignal,\n\t\t\t\tpageParam,\n\t\t\t}: {\n\t\t\t\tsignal: AbortSignal;\n\t\t\t\tpageParam: unknown;\n\t\t\t}) =>\n\t\t\t\tcall(method, path, paged(options, pageParamName, pageParam), signal),\n\t\t}),\n\t\tmutationOptions: (method: Method, path: string, options?: object) => ({\n\t\t\tmutationKey: queryKey(method, path),\n\t\t\tmutationFn: (variables: object | undefined) =>\n\t\t\t\tsend(method, path, { ...options, ...(variables || {}) }).then(ok),\n\t\t}),\n\t} as unknown as HttpQueries;\n}\n"
|
|
6
|
-
"/** What the keys and calls of both entry points share. */\n\n/** Both signals: the call ends on either. */\nexport const joined = (\n\tgiven: AbortSignal | null | undefined,\n\tquery: AbortSignal,\n): AbortSignal => (given ? AbortSignal.any([given, query]) : query);\n\n/** A value TanStack hashes as it is: a `URLSearchParams` or `FormData` as its entries. */\nconst hashable = (value: unknown): unknown =>\n\tvalue instanceof URLSearchParams ||\n\t(typeof FormData !== 'undefined' && value instanceof FormData)\n\t\t? [...value.entries()]\n\t\t: value;\n\n/** The parts of an input that tell two calls to one path apart. */\nconst PARTS = [\n\t'param',\n\t'query',\n\t'header',\n\t'json',\n\t'form',\n\t'text',\n\t'body',\n] as const;\n\n/** What tells two calls to one path apart: what they send, and `decode: false`. */\nfunction keyed(input: object | undefined): object | undefined {\n\tif (!input) return undefined;\n\tconst given = input as { readonly [part: string]: unknown };\n\tconst key: Record<string, unknown> = {};\n\tfor (const part of PARTS) {\n\t\tif (given[part] !== undefined) key[part] = hashable(given[part]);\n\t}\n\tif (given.decode === false) key.decode = false;\n\treturn Object.keys(key).length > 0 ? key : undefined;\n}\n\n/** A key, or the start of one: `[scope?, method, path?, input?]`. */\nexport function keyOf(\n\tscope: string | undefined,\n\tmethod: string,\n\tpath?: string,\n\tinput?: object,\n): unknown[] {\n\tconst key: unknown[] = scope === undefined ? [method] : [scope, method];\n\tif (path !== undefined) key.push(path);\n\tconst rest = keyed(input);\n\tif (rest !== undefined) key.push(rest);\n\treturn key;\n}\n\n/** `input` with `pageParam` as its query parameter `name`: left out when `null`. */\nexport function paged<Input extends { readonly query?: unknown }>(\n\tinput: Input | undefined,\n\tname: string,\n\tpageParam: unknown,\n): Input {\n\tconst given = input?.query;\n\tif (given instanceof URLSearchParams) {\n\t\tconst query = new URLSearchParams(given);\n\t\tif (pageParam === null || pageParam === undefined) query.delete(name);\n\t\telse query.set(name, String(pageParam));\n\t\treturn { ...input, query } as Input;\n\t}\n\treturn {\n\t\t...input,\n\t\tquery: { ...(given as object | undefined), [name]: pageParam },\n\t} as Input;\n}\n"
|
|
5
|
+
"/**\n * `createQueries`: TanStack Query options for the calls of a client of\n * `createHttpClient`. It adds no runtime of TanStack's: each function returns\n * a plain object, whose `queryFn` sends the call with the query's `signal`.\n */\nimport { type HttpClient, type Method, ok } from '@nxgt/httpyz';\nimport { joined, keyOf, paged } from '../key/key';\nimport type { HttpQueries, KeyInput, Paging, QueriesOptions } from './types';\n\ntype Send = (\n\tmethod: Method,\n\tpath: string,\n\toptions: object,\n) => Promise<{ readonly status: number; readonly data: unknown }>;\n\ntype Options = KeyInput & { readonly signal?: AbortSignal | null };\n\n/**\n * TanStack Query options for the calls of `http`.\n *\n * ```ts\n * const queries = createQueries(http);\n * const { data } = useQuery(\n * queries.queryOptions('get', '/items/{id}', { param: { id }, responses: { 200: Item } }),\n * );\n * ```\n */\nexport function createQueries(\n\thttp: HttpClient,\n\t{ scope }: QueriesOptions = {},\n): HttpQueries {\n\tconst send = http.request as unknown as Send;\n\tconst queryKey = (method: Method, path?: string, input?: KeyInput) =>\n\t\tkeyOf(scope, method, path, input);\n\tconst call = (\n\t\tmethod: Method,\n\t\tpath: string,\n\t\toptions: Options | undefined,\n\t\tsignal: AbortSignal,\n\t) =>\n\t\tsend(method, path, {\n\t\t\t...options,\n\t\t\tsignal: joined(options?.signal, signal),\n\t\t}).then(ok);\n\n\treturn {\n\t\tqueryKey,\n\t\tqueryOptions: (method: Method, path: string, options?: Options) => ({\n\t\t\tqueryKey: queryKey(method, path, options),\n\t\t\tqueryFn: ({ signal }: { signal: AbortSignal }) =>\n\t\t\t\tcall(method, path, options, signal),\n\t\t}),\n\t\tinfiniteQueryOptions: (\n\t\t\tmethod: Method,\n\t\t\tpath: string,\n\t\t\toptions: Options,\n\t\t\t{ pageParamName, ...paging }: Paging<unknown, unknown>,\n\t\t) => ({\n\t\t\t...paging,\n\t\t\t// Apart from the query of the same call, whose data is one page, not all of them.\n\t\t\tqueryKey: [...queryKey(method, path, options), 'infinite'],\n\t\t\tqueryFn: ({\n\t\t\t\tsignal,\n\t\t\t\tpageParam,\n\t\t\t}: {\n\t\t\t\tsignal: AbortSignal;\n\t\t\t\tpageParam: unknown;\n\t\t\t}) =>\n\t\t\t\tcall(method, path, paged(options, pageParamName, pageParam), signal),\n\t\t}),\n\t\tmutationOptions: (method: Method, path: string, options?: object) => ({\n\t\t\tmutationKey: queryKey(method, path),\n\t\t\tmutationFn: (variables: object | undefined) =>\n\t\t\t\tsend(method, path, { ...options, ...(variables || {}) }).then(ok),\n\t\t}),\n\t} as unknown as HttpQueries;\n}\n"
|
|
7
6
|
],
|
|
8
|
-
"mappings": "
|
|
9
|
-
"debugId": "
|
|
7
|
+
"mappings": ";;;;;;;AAKA;AAsBO,SAAS,aAAa,CAC5B,QACE,UAA0B,CAAC,GACf;AAAA,EACd,MAAM,OAAO,KAAK;AAAA,EAClB,MAAM,WAAW,CAAC,QAAgB,MAAe,UAChD,MAAM,OAAO,QAAQ,MAAM,KAAK;AAAA,EACjC,MAAM,OAAO,CACZ,QACA,MACA,SACA,WAEA,KAAK,QAAQ,MAAM;AAAA,OACf;AAAA,IACH,QAAQ,OAAO,SAAS,QAAQ,MAAM;AAAA,EACvC,CAAC,EAAE,KAAK,EAAE;AAAA,EAEX,OAAO;AAAA,IACN;AAAA,IACA,cAAc,CAAC,QAAgB,MAAc,aAAuB;AAAA,MACnE,UAAU,SAAS,QAAQ,MAAM,OAAO;AAAA,MACxC,SAAS,GAAG,aACX,KAAK,QAAQ,MAAM,SAAS,MAAM;AAAA,IACpC;AAAA,IACA,sBAAsB,CACrB,QACA,MACA,WACE,kBAAkB,cACf;AAAA,SACF;AAAA,MAEH,UAAU,CAAC,GAAG,SAAS,QAAQ,MAAM,OAAO,GAAG,UAAU;AAAA,MACzD,SAAS;AAAA,QACR;AAAA,QACA;AAAA,YAKA,KAAK,QAAQ,MAAM,MAAM,SAAS,eAAe,SAAS,GAAG,MAAM;AAAA,IACrE;AAAA,IACA,iBAAiB,CAAC,QAAgB,MAAc,aAAsB;AAAA,MACrE,aAAa,SAAS,QAAQ,IAAI;AAAA,MAClC,YAAY,CAAC,cACZ,KAAK,QAAQ,MAAM,KAAK,YAAa,aAAa,CAAC,EAAG,CAAC,EAAE,KAAK,EAAE;AAAA,IAClE;AAAA,EACD;AAAA;",
|
|
8
|
+
"debugId": "144A38071D25A1FA64756E2164756E21",
|
|
10
9
|
"names": []
|
|
11
10
|
}
|
package/dist/openapi.js
CHANGED
|
@@ -1,57 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
var hashable = (value) => value instanceof URLSearchParams || typeof FormData !== "undefined" && value instanceof FormData ? [...value.entries()] : value;
|
|
7
|
-
var PARTS = [
|
|
8
|
-
"param",
|
|
9
|
-
"query",
|
|
10
|
-
"header",
|
|
11
|
-
"json",
|
|
12
|
-
"form",
|
|
13
|
-
"text",
|
|
14
|
-
"body"
|
|
15
|
-
];
|
|
16
|
-
function keyed(input) {
|
|
17
|
-
if (!input)
|
|
18
|
-
return;
|
|
19
|
-
const given = input;
|
|
20
|
-
const key = {};
|
|
21
|
-
for (const part of PARTS) {
|
|
22
|
-
if (given[part] !== undefined)
|
|
23
|
-
key[part] = hashable(given[part]);
|
|
24
|
-
}
|
|
25
|
-
if (given.decode === false)
|
|
26
|
-
key.decode = false;
|
|
27
|
-
return Object.keys(key).length > 0 ? key : undefined;
|
|
28
|
-
}
|
|
29
|
-
function keyOf(scope, method, path, input) {
|
|
30
|
-
const key = scope === undefined ? [method] : [scope, method];
|
|
31
|
-
if (path !== undefined)
|
|
32
|
-
key.push(path);
|
|
33
|
-
const rest = keyed(input);
|
|
34
|
-
if (rest !== undefined)
|
|
35
|
-
key.push(rest);
|
|
36
|
-
return key;
|
|
37
|
-
}
|
|
38
|
-
function paged(input, name, pageParam) {
|
|
39
|
-
const given = input?.query;
|
|
40
|
-
if (given instanceof URLSearchParams) {
|
|
41
|
-
const query = new URLSearchParams(given);
|
|
42
|
-
if (pageParam === null || pageParam === undefined)
|
|
43
|
-
query.delete(name);
|
|
44
|
-
else
|
|
45
|
-
query.set(name, String(pageParam));
|
|
46
|
-
return { ...input, query };
|
|
47
|
-
}
|
|
48
|
-
return {
|
|
49
|
-
...input,
|
|
50
|
-
query: { ...given, [name]: pageParam }
|
|
51
|
-
};
|
|
52
|
-
}
|
|
1
|
+
import {
|
|
2
|
+
joined,
|
|
3
|
+
keyOf,
|
|
4
|
+
paged
|
|
5
|
+
} from "./chunks/index-hecx9b0s.js";
|
|
53
6
|
|
|
54
7
|
// src/openapi/create-openapi-queries.ts
|
|
8
|
+
import { ok } from "@nxgt/httpyz";
|
|
55
9
|
function createOpenApiQueries(api, { scope } = {}) {
|
|
56
10
|
const takes = new Map;
|
|
57
11
|
for (const operation of Object.values(api.operations)) {
|
|
@@ -107,5 +61,5 @@ export {
|
|
|
107
61
|
createOpenApiQueries
|
|
108
62
|
};
|
|
109
63
|
|
|
110
|
-
//# debugId=
|
|
64
|
+
//# debugId=97FD1D3B94B61A7A64756E2164756E21
|
|
111
65
|
//# sourceMappingURL=openapi.js.map
|
package/dist/openapi.js.map
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../src/openapi/create-openapi-queries.ts"
|
|
3
|
+
"sources": ["../src/openapi/create-openapi-queries.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"/**\n * `createOpenApiQueries`: TanStack Query options for the operations of a\n * client bound to a generated spec by `@nxgt/openapi-httpyz`. It imports that\n * package's types only: the calls are the bound client's own.\n */\nimport { type Method, ok } from '@nxgt/httpyz';\nimport type {\n\tOpenApiClient,\n\tOperationInit,\n\tOperationsShape,\n\tRuntimeOperation,\n} from '@nxgt/openapi-httpyz';\nimport { joined, keyOf, paged } from '../key/key';\nimport type { KeyInput, Paging, QueriesOptions } from '../queries/types';\nimport type { MutationInit, OpenApiQueries } from './types';\n\ntype Call = (\n\tpath: string,\n\t...args: unknown[]\n) => Promise<{ readonly status: number; readonly data: unknown }>;\n\n/**\n * TanStack Query options for the operations of `api`. The client's own\n * `operations` tell an operation's input from its init, as they do for its\n * calls: one that takes nothing is called with its init alone.\n *\n * ```ts\n * const queries = createOpenApiQueries(api);\n * const { data } = useQuery(queries.queryOptions('get', '/employees/{id}', { param: { id } }));\n * ```\n */\nexport function createOpenApiQueries<\n\tOps extends OperationsShape<Ops>,\n\tRoutes,\n\tDecoded extends boolean,\n>(\n\tapi: OpenApiClient<Ops, Routes, Decoded>,\n\t{ scope }: QueriesOptions = {},\n): OpenApiQueries<Ops, Routes, Decoded> {\n\t// As the bound client reads its arguments: an operation that takes nothing has no input.\n\tconst takes = new Map<string, boolean>();\n\tfor (const operation of Object.values<RuntimeOperation>(\n\t\tapi.operations as unknown as { readonly [id: string]: RuntimeOperation },\n\t)) {\n\t\ttakes.set(\n\t\t\t`${operation.method} ${operation.path}`,\n\t\t\toperation.parameters.length > 0 ||\n\t\t\t\tObject.keys(operation.body?.content ?? {}).length > 0,\n\t\t);\n\t}\n\tconst takesInput = (method: Method, path: string): boolean => {\n\t\tconst found = takes.get(`${method} ${path}`);\n\t\tif (found === undefined) {\n\t\t\tthrow new Error(\n\t\t\t\t`The spec has no ${method.toUpperCase()} ${path} operation`,\n\t\t\t);\n\t\t}\n\t\treturn found;\n\t};\n\t/** The input and the init of a call's arguments. */\n\tconst split = (method: Method, path: string, args: readonly unknown[]) =>\n\t\ttakesInput(method, path)\n\t\t\t? { input: args[0] as object | undefined, init: args[1] as OperationInit }\n\t\t\t: { input: undefined, init: args[0] as OperationInit };\n\tconst call = (\n\t\tmethod: Method,\n\t\tpath: string,\n\t\tinput: object | undefined,\n\t\tinit: OperationInit | undefined,\n\t\tsignal?: AbortSignal,\n\t) => {\n\t\tconst sent = signal\n\t\t\t? { ...init, signal: joined(init?.signal, signal) }\n\t\t\t: init;\n\t\tconst at = (api as unknown as Record<Method, Call>)[method];\n\t\treturn (\n\t\t\ttakesInput(method, path) ? at(path, input, sent) : at(path, sent)\n\t\t).then(ok);\n\t};\n\tconst queryKey = (method: Method, path?: string, input?: KeyInput) =>\n\t\tkeyOf(scope, method, path, input);\n\n\treturn {\n\t\tqueryKey,\n\t\tqueryOptions: (method: Method, path: string, ...args: unknown[]) => {\n\t\t\tconst { input, init } = split(method, path, args);\n\t\t\treturn {\n\t\t\t\tqueryKey: queryKey(method, path, input),\n\t\t\t\tqueryFn: ({ signal }: { signal: AbortSignal }) =>\n\t\t\t\t\tcall(method, path, input, init, signal),\n\t\t\t};\n\t\t},\n\t\tinfiniteQueryOptions: (\n\t\t\tmethod: Method,\n\t\t\tpath: string,\n\t\t\tinput: object | undefined,\n\t\t\t{ pageParamName, ...paging }: Paging<unknown, unknown>,\n\t\t\tinit?: OperationInit,\n\t\t) => {\n\t\t\ttakesInput(method, path);\n\t\t\treturn {\n\t\t\t\t...paging,\n\t\t\t\t// Apart from the query of the same call, whose data is one page, not all of them.\n\t\t\t\tqueryKey: [...queryKey(method, path, input), 'infinite'],\n\t\t\t\tqueryFn: ({\n\t\t\t\t\tsignal,\n\t\t\t\t\tpageParam,\n\t\t\t\t}: {\n\t\t\t\t\tsignal: AbortSignal;\n\t\t\t\t\tpageParam: unknown;\n\t\t\t\t}) =>\n\t\t\t\t\tcall(\n\t\t\t\t\t\tmethod,\n\t\t\t\t\t\tpath,\n\t\t\t\t\t\tpaged(input, pageParamName, pageParam),\n\t\t\t\t\t\tinit,\n\t\t\t\t\t\tsignal,\n\t\t\t\t\t),\n\t\t\t};\n\t\t},\n\t\tmutationOptions: (\n\t\t\tmethod: Method,\n\t\t\tpath: string,\n\t\t\tinit?: MutationInit<object | undefined>,\n\t\t) => {\n\t\t\ttakesInput(method, path);\n\t\t\treturn {\n\t\t\t\tmutationKey: queryKey(method, path),\n\t\t\t\tmutationFn: (variables: object | undefined) => {\n\t\t\t\t\tconst input = variables || undefined;\n\t\t\t\t\treturn call(\n\t\t\t\t\t\tmethod,\n\t\t\t\t\t\tpath,\n\t\t\t\t\t\tinput,\n\t\t\t\t\t\ttypeof init === 'function' ? init(input) : init,\n\t\t\t\t\t);\n\t\t\t\t},\n\t\t\t};\n\t\t},\n\t} as unknown as OpenApiQueries<Ops, Routes, Decoded>;\n}\n"
|
|
6
|
-
"/** What the keys and calls of both entry points share. */\n\n/** Both signals: the call ends on either. */\nexport const joined = (\n\tgiven: AbortSignal | null | undefined,\n\tquery: AbortSignal,\n): AbortSignal => (given ? AbortSignal.any([given, query]) : query);\n\n/** A value TanStack hashes as it is: a `URLSearchParams` or `FormData` as its entries. */\nconst hashable = (value: unknown): unknown =>\n\tvalue instanceof URLSearchParams ||\n\t(typeof FormData !== 'undefined' && value instanceof FormData)\n\t\t? [...value.entries()]\n\t\t: value;\n\n/** The parts of an input that tell two calls to one path apart. */\nconst PARTS = [\n\t'param',\n\t'query',\n\t'header',\n\t'json',\n\t'form',\n\t'text',\n\t'body',\n] as const;\n\n/** What tells two calls to one path apart: what they send, and `decode: false`. */\nfunction keyed(input: object | undefined): object | undefined {\n\tif (!input) return undefined;\n\tconst given = input as { readonly [part: string]: unknown };\n\tconst key: Record<string, unknown> = {};\n\tfor (const part of PARTS) {\n\t\tif (given[part] !== undefined) key[part] = hashable(given[part]);\n\t}\n\tif (given.decode === false) key.decode = false;\n\treturn Object.keys(key).length > 0 ? key : undefined;\n}\n\n/** A key, or the start of one: `[scope?, method, path?, input?]`. */\nexport function keyOf(\n\tscope: string | undefined,\n\tmethod: string,\n\tpath?: string,\n\tinput?: object,\n): unknown[] {\n\tconst key: unknown[] = scope === undefined ? [method] : [scope, method];\n\tif (path !== undefined) key.push(path);\n\tconst rest = keyed(input);\n\tif (rest !== undefined) key.push(rest);\n\treturn key;\n}\n\n/** `input` with `pageParam` as its query parameter `name`: left out when `null`. */\nexport function paged<Input extends { readonly query?: unknown }>(\n\tinput: Input | undefined,\n\tname: string,\n\tpageParam: unknown,\n): Input {\n\tconst given = input?.query;\n\tif (given instanceof URLSearchParams) {\n\t\tconst query = new URLSearchParams(given);\n\t\tif (pageParam === null || pageParam === undefined) query.delete(name);\n\t\telse query.set(name, String(pageParam));\n\t\treturn { ...input, query } as Input;\n\t}\n\treturn {\n\t\t...input,\n\t\tquery: { ...(given as object | undefined), [name]: pageParam },\n\t} as Input;\n}\n"
|
|
5
|
+
"/**\n * `createOpenApiQueries`: TanStack Query options for the operations of a\n * client bound to a generated spec by `@nxgt/openapi-httpyz`. It imports that\n * package's types only: the calls are the bound client's own.\n */\nimport { type Method, ok } from '@nxgt/httpyz';\nimport type {\n\tOpenApiClient,\n\tOperationInit,\n\tOperationsShape,\n\tRuntimeOperation,\n} from '@nxgt/openapi-httpyz';\nimport { joined, keyOf, paged } from '../key/key';\nimport type { KeyInput, Paging, QueriesOptions } from '../queries/types';\nimport type { MutationInit, OpenApiQueries } from './types';\n\ntype Call = (\n\tpath: string,\n\t...args: unknown[]\n) => Promise<{ readonly status: number; readonly data: unknown }>;\n\n/**\n * TanStack Query options for the operations of `api`. The client's own\n * `operations` tell an operation's input from its init, as they do for its\n * calls: one that takes nothing is called with its init alone.\n *\n * ```ts\n * const queries = createOpenApiQueries(api);\n * const { data } = useQuery(queries.queryOptions('get', '/employees/{id}', { param: { id } }));\n * ```\n */\nexport function createOpenApiQueries<\n\tOps extends OperationsShape<Ops>,\n\tRoutes,\n\tDecoded extends boolean,\n>(\n\tapi: OpenApiClient<Ops, Routes, Decoded>,\n\t{ scope }: QueriesOptions = {},\n): OpenApiQueries<Ops, Routes, Decoded> {\n\t// As the bound client reads its arguments: an operation that takes nothing has no input.\n\tconst takes = new Map<string, boolean>();\n\tfor (const operation of Object.values<RuntimeOperation>(\n\t\tapi.operations as unknown as { readonly [id: string]: RuntimeOperation },\n\t)) {\n\t\ttakes.set(\n\t\t\t`${operation.method} ${operation.path}`,\n\t\t\toperation.parameters.length > 0 ||\n\t\t\t\tObject.keys(operation.body?.content ?? {}).length > 0,\n\t\t);\n\t}\n\tconst takesInput = (method: Method, path: string): boolean => {\n\t\tconst found = takes.get(`${method} ${path}`);\n\t\tif (found === undefined) {\n\t\t\tthrow new Error(\n\t\t\t\t`The spec has no ${method.toUpperCase()} ${path} operation`,\n\t\t\t);\n\t\t}\n\t\treturn found;\n\t};\n\t/** The input and the init of a call's arguments. */\n\tconst split = (method: Method, path: string, args: readonly unknown[]) =>\n\t\ttakesInput(method, path)\n\t\t\t? { input: args[0] as object | undefined, init: args[1] as OperationInit }\n\t\t\t: { input: undefined, init: args[0] as OperationInit };\n\tconst call = (\n\t\tmethod: Method,\n\t\tpath: string,\n\t\tinput: object | undefined,\n\t\tinit: OperationInit | undefined,\n\t\tsignal?: AbortSignal,\n\t) => {\n\t\tconst sent = signal\n\t\t\t? { ...init, signal: joined(init?.signal, signal) }\n\t\t\t: init;\n\t\tconst at = (api as unknown as Record<Method, Call>)[method];\n\t\treturn (\n\t\t\ttakesInput(method, path) ? at(path, input, sent) : at(path, sent)\n\t\t).then(ok);\n\t};\n\tconst queryKey = (method: Method, path?: string, input?: KeyInput) =>\n\t\tkeyOf(scope, method, path, input);\n\n\treturn {\n\t\tqueryKey,\n\t\tqueryOptions: (method: Method, path: string, ...args: unknown[]) => {\n\t\t\tconst { input, init } = split(method, path, args);\n\t\t\treturn {\n\t\t\t\tqueryKey: queryKey(method, path, input),\n\t\t\t\tqueryFn: ({ signal }: { signal: AbortSignal }) =>\n\t\t\t\t\tcall(method, path, input, init, signal),\n\t\t\t};\n\t\t},\n\t\tinfiniteQueryOptions: (\n\t\t\tmethod: Method,\n\t\t\tpath: string,\n\t\t\tinput: object | undefined,\n\t\t\t{ pageParamName, ...paging }: Paging<unknown, unknown>,\n\t\t\tinit?: OperationInit,\n\t\t) => {\n\t\t\ttakesInput(method, path);\n\t\t\treturn {\n\t\t\t\t...paging,\n\t\t\t\t// Apart from the query of the same call, whose data is one page, not all of them.\n\t\t\t\tqueryKey: [...queryKey(method, path, input), 'infinite'],\n\t\t\t\tqueryFn: ({\n\t\t\t\t\tsignal,\n\t\t\t\t\tpageParam,\n\t\t\t\t}: {\n\t\t\t\t\tsignal: AbortSignal;\n\t\t\t\t\tpageParam: unknown;\n\t\t\t\t}) =>\n\t\t\t\t\tcall(\n\t\t\t\t\t\tmethod,\n\t\t\t\t\t\tpath,\n\t\t\t\t\t\tpaged(input, pageParamName, pageParam),\n\t\t\t\t\t\tinit,\n\t\t\t\t\t\tsignal,\n\t\t\t\t\t),\n\t\t\t};\n\t\t},\n\t\tmutationOptions: (\n\t\t\tmethod: Method,\n\t\t\tpath: string,\n\t\t\tinit?: MutationInit<object | undefined>,\n\t\t) => {\n\t\t\ttakesInput(method, path);\n\t\t\treturn {\n\t\t\t\tmutationKey: queryKey(method, path),\n\t\t\t\tmutationFn: (variables: object | undefined) => {\n\t\t\t\t\tconst input = variables || undefined;\n\t\t\t\t\treturn call(\n\t\t\t\t\t\tmethod,\n\t\t\t\t\t\tpath,\n\t\t\t\t\t\tinput,\n\t\t\t\t\t\ttypeof init === 'function' ? init(input) : init,\n\t\t\t\t\t);\n\t\t\t\t},\n\t\t\t};\n\t\t},\n\t} as unknown as OpenApiQueries<Ops, Routes, Decoded>;\n}\n"
|
|
7
6
|
],
|
|
8
|
-
"mappings": "
|
|
9
|
-
"debugId": "
|
|
7
|
+
"mappings": ";;;;;;;AAKA;AA0BO,SAAS,oBAIf,CACA,OACE,UAA0B,CAAC,GACU;AAAA,EAEvC,MAAM,QAAQ,IAAI;AAAA,EAClB,WAAW,aAAa,OAAO,OAC9B,IAAI,UACL,GAAG;AAAA,IACF,MAAM,IACL,GAAG,UAAU,UAAU,UAAU,QACjC,UAAU,WAAW,SAAS,KAC7B,OAAO,KAAK,UAAU,MAAM,WAAW,CAAC,CAAC,EAAE,SAAS,CACtD;AAAA,EACD;AAAA,EACA,MAAM,aAAa,CAAC,QAAgB,SAA0B;AAAA,IAC7D,MAAM,QAAQ,MAAM,IAAI,GAAG,UAAU,MAAM;AAAA,IAC3C,IAAI,UAAU,WAAW;AAAA,MACxB,MAAM,IAAI,MACT,mBAAmB,OAAO,YAAY,KAAK,gBAC5C;AAAA,IACD;AAAA,IACA,OAAO;AAAA;AAAA,EAGR,MAAM,QAAQ,CAAC,QAAgB,MAAc,SAC5C,WAAW,QAAQ,IAAI,IACpB,EAAE,OAAO,KAAK,IAA0B,MAAM,KAAK,GAAoB,IACvE,EAAE,OAAO,WAAW,MAAM,KAAK,GAAoB;AAAA,EACvD,MAAM,OAAO,CACZ,QACA,MACA,OACA,MACA,WACI;AAAA,IACJ,MAAM,OAAO,SACV,KAAK,MAAM,QAAQ,OAAO,MAAM,QAAQ,MAAM,EAAE,IAChD;AAAA,IACH,MAAM,KAAM,IAAwC;AAAA,IACpD,QACC,WAAW,QAAQ,IAAI,IAAI,GAAG,MAAM,OAAO,IAAI,IAAI,GAAG,MAAM,IAAI,GAC/D,KAAK,EAAE;AAAA;AAAA,EAEV,MAAM,WAAW,CAAC,QAAgB,MAAe,UAChD,MAAM,OAAO,QAAQ,MAAM,KAAK;AAAA,EAEjC,OAAO;AAAA,IACN;AAAA,IACA,cAAc,CAAC,QAAgB,SAAiB,SAAoB;AAAA,MACnE,QAAQ,OAAO,SAAS,MAAM,QAAQ,MAAM,IAAI;AAAA,MAChD,OAAO;AAAA,QACN,UAAU,SAAS,QAAQ,MAAM,KAAK;AAAA,QACtC,SAAS,GAAG,aACX,KAAK,QAAQ,MAAM,OAAO,MAAM,MAAM;AAAA,MACxC;AAAA;AAAA,IAED,sBAAsB,CACrB,QACA,MACA,SACE,kBAAkB,UACpB,SACI;AAAA,MACJ,WAAW,QAAQ,IAAI;AAAA,MACvB,OAAO;AAAA,WACH;AAAA,QAEH,UAAU,CAAC,GAAG,SAAS,QAAQ,MAAM,KAAK,GAAG,UAAU;AAAA,QACvD,SAAS;AAAA,UACR;AAAA,UACA;AAAA,cAKA,KACC,QACA,MACA,MAAM,OAAO,eAAe,SAAS,GACrC,MACA,MACD;AAAA,MACF;AAAA;AAAA,IAED,iBAAiB,CAChB,QACA,MACA,SACI;AAAA,MACJ,WAAW,QAAQ,IAAI;AAAA,MACvB,OAAO;AAAA,QACN,aAAa,SAAS,QAAQ,IAAI;AAAA,QAClC,YAAY,CAAC,cAAkC;AAAA,UAC9C,MAAM,QAAQ,aAAa;AAAA,UAC3B,OAAO,KACN,QACA,MACA,OACA,OAAO,SAAS,aAAa,KAAK,KAAK,IAAI,IAC5C;AAAA;AAAA,MAEF;AAAA;AAAA,EAEF;AAAA;",
|
|
8
|
+
"debugId": "97FD1D3B94B61A7A64756E2164756E21",
|
|
10
9
|
"names": []
|
|
11
10
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nxgt/httpyz-query",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.2",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -46,16 +46,16 @@
|
|
|
46
46
|
"typecheck": "bun run fixtures && tsc --noEmit"
|
|
47
47
|
},
|
|
48
48
|
"devDependencies": {
|
|
49
|
-
"@nxgt/httpyz": "^0.1
|
|
50
|
-
"@nxgt/openapi-codegen": "^0.
|
|
51
|
-
"@nxgt/openapi-httpyz": "^0.
|
|
49
|
+
"@nxgt/httpyz": "^0.3.1",
|
|
50
|
+
"@nxgt/openapi-codegen": "^0.4.1",
|
|
51
|
+
"@nxgt/openapi-httpyz": "^0.3.0",
|
|
52
52
|
"@tanstack/query-core": "^5.102.8",
|
|
53
53
|
"@types/bun": "^1.4.0",
|
|
54
54
|
"zod": "^4.5.4"
|
|
55
55
|
},
|
|
56
56
|
"peerDependencies": {
|
|
57
|
-
"@nxgt/httpyz": "^0.1
|
|
58
|
-
"@nxgt/openapi-httpyz": "^0.
|
|
57
|
+
"@nxgt/httpyz": "^0.3.1",
|
|
58
|
+
"@nxgt/openapi-httpyz": "^0.3.0",
|
|
59
59
|
"@tanstack/query-core": "^5.90.0",
|
|
60
60
|
"typescript": "^6.0.3"
|
|
61
61
|
},
|