@robosystems/client 0.2.25 → 0.2.27

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.
Files changed (93) hide show
  1. package/README.md +7 -6
  2. package/bin/{create-feature → create-feature.sh} +11 -1
  3. package/client/client.gen.js +118 -34
  4. package/client/client.gen.ts +125 -38
  5. package/client/index.d.ts +2 -1
  6. package/client/index.js +3 -1
  7. package/client/index.ts +1 -1
  8. package/client/types.gen.d.ts +11 -16
  9. package/client/types.gen.js +0 -1
  10. package/client/types.gen.ts +44 -64
  11. package/client/utils.gen.d.ts +8 -20
  12. package/client/utils.gen.js +44 -112
  13. package/client/utils.gen.ts +57 -181
  14. package/client.gen.d.ts +3 -3
  15. package/client.gen.js +1 -3
  16. package/client.gen.ts +4 -6
  17. package/core/auth.gen.ts +1 -2
  18. package/core/bodySerializer.gen.d.ts +12 -4
  19. package/core/bodySerializer.gen.js +1 -1
  20. package/core/bodySerializer.gen.ts +17 -25
  21. package/core/params.gen.d.ts +10 -0
  22. package/core/params.gen.js +17 -5
  23. package/core/params.gen.ts +37 -21
  24. package/core/pathSerializer.gen.js +3 -11
  25. package/core/pathSerializer.gen.ts +4 -14
  26. package/core/queryKeySerializer.gen.d.ts +18 -0
  27. package/core/queryKeySerializer.gen.js +98 -0
  28. package/core/queryKeySerializer.gen.ts +117 -0
  29. package/core/serverSentEvents.gen.d.ts +71 -0
  30. package/core/serverSentEvents.gen.js +137 -0
  31. package/core/serverSentEvents.gen.ts +243 -0
  32. package/core/types.gen.d.ts +12 -12
  33. package/core/types.gen.js +0 -1
  34. package/core/types.gen.ts +21 -38
  35. package/core/utils.gen.d.ts +19 -0
  36. package/core/utils.gen.js +93 -0
  37. package/core/utils.gen.ts +140 -0
  38. package/extensions/QueryClient.js +23 -2
  39. package/extensions/QueryClient.test.ts +2 -1
  40. package/extensions/QueryClient.ts +27 -2
  41. package/index.ts +3 -2
  42. package/package.json +9 -7
  43. package/sdk/client/client.gen.js +118 -34
  44. package/sdk/client/client.gen.ts +125 -38
  45. package/sdk/client/index.d.ts +2 -1
  46. package/sdk/client/index.js +3 -1
  47. package/sdk/client/index.ts +1 -1
  48. package/sdk/client/types.gen.d.ts +11 -16
  49. package/sdk/client/types.gen.js +0 -1
  50. package/sdk/client/types.gen.ts +44 -64
  51. package/sdk/client/utils.gen.d.ts +8 -20
  52. package/sdk/client/utils.gen.js +44 -112
  53. package/sdk/client/utils.gen.ts +57 -181
  54. package/sdk/client.gen.d.ts +3 -3
  55. package/sdk/client.gen.js +1 -3
  56. package/sdk/client.gen.ts +4 -6
  57. package/sdk/core/auth.gen.ts +1 -2
  58. package/sdk/core/bodySerializer.gen.d.ts +12 -4
  59. package/sdk/core/bodySerializer.gen.js +1 -1
  60. package/sdk/core/bodySerializer.gen.ts +17 -25
  61. package/sdk/core/params.gen.d.ts +10 -0
  62. package/sdk/core/params.gen.js +17 -5
  63. package/sdk/core/params.gen.ts +37 -21
  64. package/sdk/core/pathSerializer.gen.js +3 -11
  65. package/sdk/core/pathSerializer.gen.ts +4 -14
  66. package/sdk/core/queryKeySerializer.gen.d.ts +18 -0
  67. package/sdk/core/queryKeySerializer.gen.js +98 -0
  68. package/sdk/core/queryKeySerializer.gen.ts +117 -0
  69. package/sdk/core/serverSentEvents.gen.d.ts +71 -0
  70. package/sdk/core/serverSentEvents.gen.js +137 -0
  71. package/sdk/core/serverSentEvents.gen.ts +243 -0
  72. package/sdk/core/types.gen.d.ts +12 -12
  73. package/sdk/core/types.gen.js +0 -1
  74. package/sdk/core/types.gen.ts +21 -38
  75. package/sdk/core/utils.gen.d.ts +19 -0
  76. package/sdk/core/utils.gen.js +93 -0
  77. package/sdk/core/utils.gen.ts +140 -0
  78. package/sdk/index.d.ts +2 -2
  79. package/sdk/index.js +114 -17
  80. package/sdk/index.ts +3 -2
  81. package/sdk/sdk.gen.d.ts +112 -3
  82. package/sdk/sdk.gen.js +778 -1736
  83. package/sdk/sdk.gen.ts +782 -1740
  84. package/sdk/types.gen.d.ts +851 -5
  85. package/sdk/types.gen.ts +852 -6
  86. package/sdk-extensions/QueryClient.js +23 -2
  87. package/sdk-extensions/QueryClient.test.ts +2 -1
  88. package/sdk-extensions/QueryClient.ts +27 -2
  89. package/sdk.gen.d.ts +112 -3
  90. package/sdk.gen.js +778 -1736
  91. package/sdk.gen.ts +782 -1740
  92. package/types.gen.d.ts +851 -5
  93. package/types.gen.ts +852 -6
@@ -1,11 +1,18 @@
1
1
  import type { ArrayStyle, ObjectStyle, SerializerOptions } from './pathSerializer.gen';
2
2
  export type QuerySerializer = (query: Record<string, unknown>) => string;
3
3
  export type BodySerializer = (body: any) => any;
4
- export interface QuerySerializerOptions {
4
+ type QuerySerializerOptionsObject = {
5
5
  allowReserved?: boolean;
6
- array?: SerializerOptions<ArrayStyle>;
7
- object?: SerializerOptions<ObjectStyle>;
8
- }
6
+ array?: Partial<SerializerOptions<ArrayStyle>>;
7
+ object?: Partial<SerializerOptions<ObjectStyle>>;
8
+ };
9
+ export type QuerySerializerOptions = QuerySerializerOptionsObject & {
10
+ /**
11
+ * Per-parameter serialization overrides. When provided, these settings
12
+ * override the global array/object settings for specific parameter names.
13
+ */
14
+ parameters?: Record<string, QuerySerializerOptionsObject>;
15
+ };
9
16
  export declare const formDataBodySerializer: {
10
17
  bodySerializer: <T extends Record<string, any> | Array<Record<string, any>>>(body: T) => FormData;
11
18
  };
@@ -15,3 +22,4 @@ export declare const jsonBodySerializer: {
15
22
  export declare const urlSearchParamsBodySerializer: {
16
23
  bodySerializer: <T extends Record<string, any> | Array<Record<string, any>>>(body: T) => string;
17
24
  };
25
+ export {};
@@ -39,7 +39,7 @@ exports.formDataBodySerializer = {
39
39
  },
40
40
  };
41
41
  exports.jsonBodySerializer = {
42
- bodySerializer: (body) => JSON.stringify(body, (_key, value) => typeof value === 'bigint' ? value.toString() : value),
42
+ bodySerializer: (body) => JSON.stringify(body, (_key, value) => (typeof value === 'bigint' ? value.toString() : value)),
43
43
  };
44
44
  exports.urlSearchParamsBodySerializer = {
45
45
  bodySerializer: (body) => {
@@ -1,26 +1,26 @@
1
1
  // This file is auto-generated by @hey-api/openapi-ts
2
2
 
3
- import type {
4
- ArrayStyle,
5
- ObjectStyle,
6
- SerializerOptions,
7
- } from './pathSerializer.gen';
3
+ import type { ArrayStyle, ObjectStyle, SerializerOptions } from './pathSerializer.gen';
8
4
 
9
5
  export type QuerySerializer = (query: Record<string, unknown>) => string;
10
6
 
11
7
  export type BodySerializer = (body: any) => any;
12
8
 
13
- export interface QuerySerializerOptions {
9
+ type QuerySerializerOptionsObject = {
14
10
  allowReserved?: boolean;
15
- array?: SerializerOptions<ArrayStyle>;
16
- object?: SerializerOptions<ObjectStyle>;
17
- }
11
+ array?: Partial<SerializerOptions<ArrayStyle>>;
12
+ object?: Partial<SerializerOptions<ObjectStyle>>;
13
+ };
14
+
15
+ export type QuerySerializerOptions = QuerySerializerOptionsObject & {
16
+ /**
17
+ * Per-parameter serialization overrides. When provided, these settings
18
+ * override the global array/object settings for specific parameter names.
19
+ */
20
+ parameters?: Record<string, QuerySerializerOptionsObject>;
21
+ };
18
22
 
19
- const serializeFormDataPair = (
20
- data: FormData,
21
- key: string,
22
- value: unknown,
23
- ): void => {
23
+ const serializeFormDataPair = (data: FormData, key: string, value: unknown): void => {
24
24
  if (typeof value === 'string' || value instanceof Blob) {
25
25
  data.append(key, value);
26
26
  } else if (value instanceof Date) {
@@ -30,11 +30,7 @@ const serializeFormDataPair = (
30
30
  }
31
31
  };
32
32
 
33
- const serializeUrlSearchParamsPair = (
34
- data: URLSearchParams,
35
- key: string,
36
- value: unknown,
37
- ): void => {
33
+ const serializeUrlSearchParamsPair = (data: URLSearchParams, key: string, value: unknown): void => {
38
34
  if (typeof value === 'string') {
39
35
  data.append(key, value);
40
36
  } else {
@@ -65,15 +61,11 @@ export const formDataBodySerializer = {
65
61
 
66
62
  export const jsonBodySerializer = {
67
63
  bodySerializer: <T>(body: T): string =>
68
- JSON.stringify(body, (_key, value) =>
69
- typeof value === 'bigint' ? value.toString() : value,
70
- ),
64
+ JSON.stringify(body, (_key, value) => (typeof value === 'bigint' ? value.toString() : value)),
71
65
  };
72
66
 
73
67
  export const urlSearchParamsBodySerializer = {
74
- bodySerializer: <T extends Record<string, any> | Array<Record<string, any>>>(
75
- body: T,
76
- ): string => {
68
+ bodySerializer: <T extends Record<string, any> | Array<Record<string, any>>>(body: T): string => {
77
69
  const data = new URLSearchParams();
78
70
 
79
71
  Object.entries(body).forEach(([key, value]) => {
@@ -17,6 +17,16 @@ export type Field = {
17
17
  */
18
18
  key?: string;
19
19
  map?: string;
20
+ } | {
21
+ /**
22
+ * Field name. This is the name we want the user to see and use.
23
+ */
24
+ key: string;
25
+ /**
26
+ * Field mapped name. This is the name we want to use in the request.
27
+ * If `in` is omitted, `map` aliases `key` to the transport layer.
28
+ */
29
+ map: Slot;
20
30
  };
21
31
  export interface Fields {
22
32
  allowExtra?: Partial<Record<Slot, boolean>>;
@@ -22,6 +22,11 @@ const buildKeyMap = (fields, map) => {
22
22
  });
23
23
  }
24
24
  }
25
+ else if ('key' in config) {
26
+ map.set(config.key, {
27
+ map: config.map,
28
+ });
29
+ }
25
30
  else if (config.args) {
26
31
  buildKeyMap(config.args, map);
27
32
  }
@@ -55,7 +60,9 @@ const buildClientParams = (args, fields) => {
55
60
  if (config.key) {
56
61
  const field = map.get(config.key);
57
62
  const name = field.map || config.key;
58
- params[field.in][name] = arg;
63
+ if (field.in) {
64
+ params[field.in][name] = arg;
65
+ }
59
66
  }
60
67
  else {
61
68
  params.body = arg;
@@ -65,8 +72,13 @@ const buildClientParams = (args, fields) => {
65
72
  for (const [key, value] of Object.entries(arg ?? {})) {
66
73
  const field = map.get(key);
67
74
  if (field) {
68
- const name = field.map || key;
69
- params[field.in][name] = value;
75
+ if (field.in) {
76
+ const name = field.map || key;
77
+ params[field.in][name] = value;
78
+ }
79
+ else {
80
+ params[field.map] = value;
81
+ }
70
82
  }
71
83
  else {
72
84
  const extra = extraPrefixes.find(([prefix]) => key.startsWith(prefix));
@@ -74,8 +86,8 @@ const buildClientParams = (args, fields) => {
74
86
  const [prefix, slot] = extra;
75
87
  params[slot][key.slice(prefix.length)] = value;
76
88
  }
77
- else {
78
- for (const [slot, allowed] of Object.entries(config.allowExtra ?? {})) {
89
+ else if ('allowExtra' in config && config.allowExtra) {
90
+ for (const [slot, allowed] of Object.entries(config.allowExtra)) {
79
91
  if (allowed) {
80
92
  params[slot][key] = value;
81
93
  break;
@@ -22,6 +22,17 @@ export type Field =
22
22
  */
23
23
  key?: string;
24
24
  map?: string;
25
+ }
26
+ | {
27
+ /**
28
+ * Field name. This is the name we want the user to see and use.
29
+ */
30
+ key: string;
31
+ /**
32
+ * Field mapped name. This is the name we want to use in the request.
33
+ * If `in` is omitted, `map` aliases `key` to the transport layer.
34
+ */
35
+ map: Slot;
25
36
  };
26
37
 
27
38
  export interface Fields {
@@ -41,10 +52,14 @@ const extraPrefixes = Object.entries(extraPrefixesMap);
41
52
 
42
53
  type KeyMap = Map<
43
54
  string,
44
- {
45
- in: Slot;
46
- map?: string;
47
- }
55
+ | {
56
+ in: Slot;
57
+ map?: string;
58
+ }
59
+ | {
60
+ in?: never;
61
+ map: Slot;
62
+ }
48
63
  >;
49
64
 
50
65
  const buildKeyMap = (fields: FieldsConfig, map?: KeyMap): KeyMap => {
@@ -60,6 +75,10 @@ const buildKeyMap = (fields: FieldsConfig, map?: KeyMap): KeyMap => {
60
75
  map: config.map,
61
76
  });
62
77
  }
78
+ } else if ('key' in config) {
79
+ map.set(config.key, {
80
+ map: config.map,
81
+ });
63
82
  } else if (config.args) {
64
83
  buildKeyMap(config.args, map);
65
84
  }
@@ -83,10 +102,7 @@ const stripEmptySlots = (params: Params) => {
83
102
  }
84
103
  };
85
104
 
86
- export const buildClientParams = (
87
- args: ReadonlyArray<unknown>,
88
- fields: FieldsConfig,
89
- ) => {
105
+ export const buildClientParams = (args: ReadonlyArray<unknown>, fields: FieldsConfig) => {
90
106
  const params: Params = {
91
107
  body: {},
92
108
  headers: {},
@@ -111,7 +127,9 @@ export const buildClientParams = (
111
127
  if (config.key) {
112
128
  const field = map.get(config.key)!;
113
129
  const name = field.map || config.key;
114
- (params[field.in] as Record<string, unknown>)[name] = arg;
130
+ if (field.in) {
131
+ (params[field.in] as Record<string, unknown>)[name] = arg;
132
+ }
115
133
  } else {
116
134
  params.body = arg;
117
135
  }
@@ -120,22 +138,20 @@ export const buildClientParams = (
120
138
  const field = map.get(key);
121
139
 
122
140
  if (field) {
123
- const name = field.map || key;
124
- (params[field.in] as Record<string, unknown>)[name] = value;
141
+ if (field.in) {
142
+ const name = field.map || key;
143
+ (params[field.in] as Record<string, unknown>)[name] = value;
144
+ } else {
145
+ params[field.map] = value;
146
+ }
125
147
  } else {
126
- const extra = extraPrefixes.find(([prefix]) =>
127
- key.startsWith(prefix),
128
- );
148
+ const extra = extraPrefixes.find(([prefix]) => key.startsWith(prefix));
129
149
 
130
150
  if (extra) {
131
151
  const [prefix, slot] = extra;
132
- (params[slot] as Record<string, unknown>)[
133
- key.slice(prefix.length)
134
- ] = value;
135
- } else {
136
- for (const [slot, allowed] of Object.entries(
137
- config.allowExtra ?? {},
138
- )) {
152
+ (params[slot] as Record<string, unknown>)[key.slice(prefix.length)] = value;
153
+ } else if ('allowExtra' in config && config.allowExtra) {
154
+ for (const [slot, allowed] of Object.entries(config.allowExtra)) {
139
155
  if (allowed) {
140
156
  (params[slot as Slot] as Record<string, unknown>)[key] = value;
141
157
  break;
@@ -68,9 +68,7 @@ const serializeArrayParam = ({ allowReserved, explode, name, style, value, }) =>
68
68
  });
69
69
  })
70
70
  .join(separator);
71
- return style === 'label' || style === 'matrix'
72
- ? separator + joinedValues
73
- : joinedValues;
71
+ return style === 'label' || style === 'matrix' ? separator + joinedValues : joinedValues;
74
72
  };
75
73
  exports.serializeArrayParam = serializeArrayParam;
76
74
  const serializePrimitiveParam = ({ allowReserved, name, value, }) => {
@@ -90,11 +88,7 @@ const serializeObjectParam = ({ allowReserved, explode, name, style, value, valu
90
88
  if (style !== 'deepObject' && !explode) {
91
89
  let values = [];
92
90
  Object.entries(value).forEach(([key, v]) => {
93
- values = [
94
- ...values,
95
- key,
96
- allowReserved ? v : encodeURIComponent(v),
97
- ];
91
+ values = [...values, key, allowReserved ? v : encodeURIComponent(v)];
98
92
  });
99
93
  const joinedValues = values.join(',');
100
94
  switch (style) {
@@ -116,8 +110,6 @@ const serializeObjectParam = ({ allowReserved, explode, name, style, value, valu
116
110
  value: v,
117
111
  }))
118
112
  .join(separator);
119
- return style === 'label' || style === 'matrix'
120
- ? separator + joinedValues
121
- : joinedValues;
113
+ return style === 'label' || style === 'matrix' ? separator + joinedValues : joinedValues;
122
114
  };
123
115
  exports.serializeObjectParam = serializeObjectParam;
@@ -1,8 +1,6 @@
1
1
  // This file is auto-generated by @hey-api/openapi-ts
2
2
 
3
- interface SerializeOptions<T>
4
- extends SerializePrimitiveOptions,
5
- SerializerOptions<T> {}
3
+ interface SerializeOptions<T> extends SerializePrimitiveOptions, SerializerOptions<T> {}
6
4
 
7
5
  interface SerializePrimitiveOptions {
8
6
  allowReserved?: boolean;
@@ -105,9 +103,7 @@ export const serializeArrayParam = ({
105
103
  });
106
104
  })
107
105
  .join(separator);
108
- return style === 'label' || style === 'matrix'
109
- ? separator + joinedValues
110
- : joinedValues;
106
+ return style === 'label' || style === 'matrix' ? separator + joinedValues : joinedValues;
111
107
  };
112
108
 
113
109
  export const serializePrimitiveParam = ({
@@ -146,11 +142,7 @@ export const serializeObjectParam = ({
146
142
  if (style !== 'deepObject' && !explode) {
147
143
  let values: string[] = [];
148
144
  Object.entries(value).forEach(([key, v]) => {
149
- values = [
150
- ...values,
151
- key,
152
- allowReserved ? (v as string) : encodeURIComponent(v as string),
153
- ];
145
+ values = [...values, key, allowReserved ? (v as string) : encodeURIComponent(v as string)];
154
146
  });
155
147
  const joinedValues = values.join(',');
156
148
  switch (style) {
@@ -175,7 +167,5 @@ export const serializeObjectParam = ({
175
167
  }),
176
168
  )
177
169
  .join(separator);
178
- return style === 'label' || style === 'matrix'
179
- ? separator + joinedValues
180
- : joinedValues;
170
+ return style === 'label' || style === 'matrix' ? separator + joinedValues : joinedValues;
181
171
  };
@@ -0,0 +1,18 @@
1
+ /**
2
+ * JSON-friendly union that mirrors what Pinia Colada can hash.
3
+ */
4
+ export type JsonValue = null | string | number | boolean | JsonValue[] | {
5
+ [key: string]: JsonValue;
6
+ };
7
+ /**
8
+ * Replacer that converts non-JSON values (bigint, Date, etc.) to safe substitutes.
9
+ */
10
+ export declare const queryKeyJsonReplacer: (_key: string, value: unknown) => unknown;
11
+ /**
12
+ * Safely stringifies a value and parses it back into a JsonValue.
13
+ */
14
+ export declare const stringifyToJsonValue: (input: unknown) => JsonValue | undefined;
15
+ /**
16
+ * Normalizes any accepted value into a JSON-friendly shape for query keys.
17
+ */
18
+ export declare const serializeQueryKeyValue: (value: unknown) => JsonValue | undefined;
@@ -0,0 +1,98 @@
1
+ "use strict";
2
+ // This file is auto-generated by @hey-api/openapi-ts
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.serializeQueryKeyValue = exports.stringifyToJsonValue = exports.queryKeyJsonReplacer = void 0;
5
+ /**
6
+ * Replacer that converts non-JSON values (bigint, Date, etc.) to safe substitutes.
7
+ */
8
+ const queryKeyJsonReplacer = (_key, value) => {
9
+ if (value === undefined || typeof value === 'function' || typeof value === 'symbol') {
10
+ return undefined;
11
+ }
12
+ if (typeof value === 'bigint') {
13
+ return value.toString();
14
+ }
15
+ if (value instanceof Date) {
16
+ return value.toISOString();
17
+ }
18
+ return value;
19
+ };
20
+ exports.queryKeyJsonReplacer = queryKeyJsonReplacer;
21
+ /**
22
+ * Safely stringifies a value and parses it back into a JsonValue.
23
+ */
24
+ const stringifyToJsonValue = (input) => {
25
+ try {
26
+ const json = JSON.stringify(input, exports.queryKeyJsonReplacer);
27
+ if (json === undefined) {
28
+ return undefined;
29
+ }
30
+ return JSON.parse(json);
31
+ }
32
+ catch {
33
+ return undefined;
34
+ }
35
+ };
36
+ exports.stringifyToJsonValue = stringifyToJsonValue;
37
+ /**
38
+ * Detects plain objects (including objects with a null prototype).
39
+ */
40
+ const isPlainObject = (value) => {
41
+ if (value === null || typeof value !== 'object') {
42
+ return false;
43
+ }
44
+ const prototype = Object.getPrototypeOf(value);
45
+ return prototype === Object.prototype || prototype === null;
46
+ };
47
+ /**
48
+ * Turns URLSearchParams into a sorted JSON object for deterministic keys.
49
+ */
50
+ const serializeSearchParams = (params) => {
51
+ const entries = Array.from(params.entries()).sort(([a], [b]) => a.localeCompare(b));
52
+ const result = {};
53
+ for (const [key, value] of entries) {
54
+ const existing = result[key];
55
+ if (existing === undefined) {
56
+ result[key] = value;
57
+ continue;
58
+ }
59
+ if (Array.isArray(existing)) {
60
+ existing.push(value);
61
+ }
62
+ else {
63
+ result[key] = [existing, value];
64
+ }
65
+ }
66
+ return result;
67
+ };
68
+ /**
69
+ * Normalizes any accepted value into a JSON-friendly shape for query keys.
70
+ */
71
+ const serializeQueryKeyValue = (value) => {
72
+ if (value === null) {
73
+ return null;
74
+ }
75
+ if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {
76
+ return value;
77
+ }
78
+ if (value === undefined || typeof value === 'function' || typeof value === 'symbol') {
79
+ return undefined;
80
+ }
81
+ if (typeof value === 'bigint') {
82
+ return value.toString();
83
+ }
84
+ if (value instanceof Date) {
85
+ return value.toISOString();
86
+ }
87
+ if (Array.isArray(value)) {
88
+ return (0, exports.stringifyToJsonValue)(value);
89
+ }
90
+ if (typeof URLSearchParams !== 'undefined' && value instanceof URLSearchParams) {
91
+ return serializeSearchParams(value);
92
+ }
93
+ if (isPlainObject(value)) {
94
+ return (0, exports.stringifyToJsonValue)(value);
95
+ }
96
+ return undefined;
97
+ };
98
+ exports.serializeQueryKeyValue = serializeQueryKeyValue;
@@ -0,0 +1,117 @@
1
+ // This file is auto-generated by @hey-api/openapi-ts
2
+
3
+ /**
4
+ * JSON-friendly union that mirrors what Pinia Colada can hash.
5
+ */
6
+ export type JsonValue =
7
+ | null
8
+ | string
9
+ | number
10
+ | boolean
11
+ | JsonValue[]
12
+ | { [key: string]: JsonValue };
13
+
14
+ /**
15
+ * Replacer that converts non-JSON values (bigint, Date, etc.) to safe substitutes.
16
+ */
17
+ export const queryKeyJsonReplacer = (_key: string, value: unknown) => {
18
+ if (value === undefined || typeof value === 'function' || typeof value === 'symbol') {
19
+ return undefined;
20
+ }
21
+ if (typeof value === 'bigint') {
22
+ return value.toString();
23
+ }
24
+ if (value instanceof Date) {
25
+ return value.toISOString();
26
+ }
27
+ return value;
28
+ };
29
+
30
+ /**
31
+ * Safely stringifies a value and parses it back into a JsonValue.
32
+ */
33
+ export const stringifyToJsonValue = (input: unknown): JsonValue | undefined => {
34
+ try {
35
+ const json = JSON.stringify(input, queryKeyJsonReplacer);
36
+ if (json === undefined) {
37
+ return undefined;
38
+ }
39
+ return JSON.parse(json) as JsonValue;
40
+ } catch {
41
+ return undefined;
42
+ }
43
+ };
44
+
45
+ /**
46
+ * Detects plain objects (including objects with a null prototype).
47
+ */
48
+ const isPlainObject = (value: unknown): value is Record<string, unknown> => {
49
+ if (value === null || typeof value !== 'object') {
50
+ return false;
51
+ }
52
+ const prototype = Object.getPrototypeOf(value as object);
53
+ return prototype === Object.prototype || prototype === null;
54
+ };
55
+
56
+ /**
57
+ * Turns URLSearchParams into a sorted JSON object for deterministic keys.
58
+ */
59
+ const serializeSearchParams = (params: URLSearchParams): JsonValue => {
60
+ const entries = Array.from(params.entries()).sort(([a], [b]) => a.localeCompare(b));
61
+ const result: Record<string, JsonValue> = {};
62
+
63
+ for (const [key, value] of entries) {
64
+ const existing = result[key];
65
+ if (existing === undefined) {
66
+ result[key] = value;
67
+ continue;
68
+ }
69
+
70
+ if (Array.isArray(existing)) {
71
+ (existing as string[]).push(value);
72
+ } else {
73
+ result[key] = [existing, value];
74
+ }
75
+ }
76
+
77
+ return result;
78
+ };
79
+
80
+ /**
81
+ * Normalizes any accepted value into a JSON-friendly shape for query keys.
82
+ */
83
+ export const serializeQueryKeyValue = (value: unknown): JsonValue | undefined => {
84
+ if (value === null) {
85
+ return null;
86
+ }
87
+
88
+ if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {
89
+ return value;
90
+ }
91
+
92
+ if (value === undefined || typeof value === 'function' || typeof value === 'symbol') {
93
+ return undefined;
94
+ }
95
+
96
+ if (typeof value === 'bigint') {
97
+ return value.toString();
98
+ }
99
+
100
+ if (value instanceof Date) {
101
+ return value.toISOString();
102
+ }
103
+
104
+ if (Array.isArray(value)) {
105
+ return stringifyToJsonValue(value);
106
+ }
107
+
108
+ if (typeof URLSearchParams !== 'undefined' && value instanceof URLSearchParams) {
109
+ return serializeSearchParams(value);
110
+ }
111
+
112
+ if (isPlainObject(value)) {
113
+ return stringifyToJsonValue(value);
114
+ }
115
+
116
+ return undefined;
117
+ };
@@ -0,0 +1,71 @@
1
+ import type { Config } from './types.gen';
2
+ export type ServerSentEventsOptions<TData = unknown> = Omit<RequestInit, 'method'> & Pick<Config, 'method' | 'responseTransformer' | 'responseValidator'> & {
3
+ /**
4
+ * Fetch API implementation. You can use this option to provide a custom
5
+ * fetch instance.
6
+ *
7
+ * @default globalThis.fetch
8
+ */
9
+ fetch?: typeof fetch;
10
+ /**
11
+ * Implementing clients can call request interceptors inside this hook.
12
+ */
13
+ onRequest?: (url: string, init: RequestInit) => Promise<Request>;
14
+ /**
15
+ * Callback invoked when a network or parsing error occurs during streaming.
16
+ *
17
+ * This option applies only if the endpoint returns a stream of events.
18
+ *
19
+ * @param error The error that occurred.
20
+ */
21
+ onSseError?: (error: unknown) => void;
22
+ /**
23
+ * Callback invoked when an event is streamed from the server.
24
+ *
25
+ * This option applies only if the endpoint returns a stream of events.
26
+ *
27
+ * @param event Event streamed from the server.
28
+ * @returns Nothing (void).
29
+ */
30
+ onSseEvent?: (event: StreamEvent<TData>) => void;
31
+ serializedBody?: RequestInit['body'];
32
+ /**
33
+ * Default retry delay in milliseconds.
34
+ *
35
+ * This option applies only if the endpoint returns a stream of events.
36
+ *
37
+ * @default 3000
38
+ */
39
+ sseDefaultRetryDelay?: number;
40
+ /**
41
+ * Maximum number of retry attempts before giving up.
42
+ */
43
+ sseMaxRetryAttempts?: number;
44
+ /**
45
+ * Maximum retry delay in milliseconds.
46
+ *
47
+ * Applies only when exponential backoff is used.
48
+ *
49
+ * This option applies only if the endpoint returns a stream of events.
50
+ *
51
+ * @default 30000
52
+ */
53
+ sseMaxRetryDelay?: number;
54
+ /**
55
+ * Optional sleep function for retry backoff.
56
+ *
57
+ * Defaults to using `setTimeout`.
58
+ */
59
+ sseSleepFn?: (ms: number) => Promise<void>;
60
+ url: string;
61
+ };
62
+ export interface StreamEvent<TData = unknown> {
63
+ data: TData;
64
+ event?: string;
65
+ id?: string;
66
+ retry?: number;
67
+ }
68
+ export type ServerSentEventsResult<TData = unknown, TReturn = void, TNext = unknown> = {
69
+ stream: AsyncGenerator<TData extends Record<string, unknown> ? TData[keyof TData] : TData, TReturn, TNext>;
70
+ };
71
+ export declare const createSseClient: <TData = unknown>({ onRequest, onSseError, onSseEvent, responseTransformer, responseValidator, sseDefaultRetryDelay, sseMaxRetryAttempts, sseMaxRetryDelay, sseSleepFn, url, ...options }: ServerSentEventsOptions) => ServerSentEventsResult<TData>;