@sapporta/rest-core 3.52.1
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/.babelrc +10 -0
- package/.eslintrc.json +21 -0
- package/CHANGELOG.md +3 -0
- package/LICENCE +21 -0
- package/README.md +19 -0
- package/jest.config.ts +16 -0
- package/package.json +33 -0
- package/project.json +51 -0
- package/src/index.ts +15 -0
- package/src/lib/client.spec.ts +1330 -0
- package/src/lib/client.ts +481 -0
- package/src/lib/dsl.spec.ts +1308 -0
- package/src/lib/dsl.ts +472 -0
- package/src/lib/fetch.spec.ts +102 -0
- package/src/lib/infer-types.spec.ts +935 -0
- package/src/lib/infer-types.ts +282 -0
- package/src/lib/paths.spec.ts +138 -0
- package/src/lib/paths.ts +61 -0
- package/src/lib/query.spec.ts +329 -0
- package/src/lib/query.ts +114 -0
- package/src/lib/response-error.spec.ts +67 -0
- package/src/lib/response-error.ts +61 -0
- package/src/lib/response-validation-error.ts +24 -0
- package/src/lib/server.spec.ts +163 -0
- package/src/lib/server.ts +83 -0
- package/src/lib/standard-schema-utils.spec.ts +218 -0
- package/src/lib/standard-schema-utils.ts +280 -0
- package/src/lib/standard-schema.ts +71 -0
- package/src/lib/status-codes.ts +75 -0
- package/src/lib/test-helpers.ts +7 -0
- package/src/lib/type-guards.spec.ts +355 -0
- package/src/lib/type-guards.ts +99 -0
- package/src/lib/type-utils.spec.ts +59 -0
- package/src/lib/type-utils.ts +234 -0
- package/src/lib/unknown-status-error.ts +15 -0
- package/src/lib/validation-error.ts +36 -0
- package/tsconfig.json +22 -0
- package/tsconfig.lib.json +10 -0
- package/tsconfig.spec.json +9 -0
- package/typedoc.json +5 -0
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
import type { z } from 'zod';
|
|
2
|
+
import { ContractNoBodyType, ContractNullType, ContractPlainType } from './dsl';
|
|
3
|
+
import { StandardSchemaV1 } from './standard-schema';
|
|
4
|
+
|
|
5
|
+
type GetIndexedField<T, K> = K extends keyof T
|
|
6
|
+
? T[K]
|
|
7
|
+
: K extends `${number}`
|
|
8
|
+
? '0' extends keyof T
|
|
9
|
+
? undefined
|
|
10
|
+
: number extends keyof T
|
|
11
|
+
? T[number]
|
|
12
|
+
: undefined
|
|
13
|
+
: undefined;
|
|
14
|
+
|
|
15
|
+
type FieldWithPossiblyUndefined<T, Key> =
|
|
16
|
+
| GetFieldType<Exclude<T, undefined>, Key>
|
|
17
|
+
| Extract<T, undefined>;
|
|
18
|
+
|
|
19
|
+
type IndexedFieldWithPossiblyUndefined<T, Key> =
|
|
20
|
+
| GetIndexedField<Exclude<T, undefined>, Key>
|
|
21
|
+
| Extract<T, undefined>;
|
|
22
|
+
|
|
23
|
+
export type GetFieldType<T, P> = P extends `${infer Left}.${infer Right}`
|
|
24
|
+
? Left extends keyof T
|
|
25
|
+
? FieldWithPossiblyUndefined<T[Left], Right>
|
|
26
|
+
: Left extends `${infer FieldKey}[${infer IndexKey}]`
|
|
27
|
+
? FieldKey extends keyof T
|
|
28
|
+
? FieldWithPossiblyUndefined<
|
|
29
|
+
IndexedFieldWithPossiblyUndefined<T[FieldKey], IndexKey>,
|
|
30
|
+
Right
|
|
31
|
+
>
|
|
32
|
+
: undefined
|
|
33
|
+
: undefined
|
|
34
|
+
: P extends keyof T
|
|
35
|
+
? T[P]
|
|
36
|
+
: P extends `${infer FieldKey}[${infer IndexKey}]`
|
|
37
|
+
? FieldKey extends keyof T
|
|
38
|
+
? IndexedFieldWithPossiblyUndefined<T[FieldKey], IndexKey>
|
|
39
|
+
: undefined
|
|
40
|
+
: undefined;
|
|
41
|
+
|
|
42
|
+
// https://stackoverflow.com/questions/63447660/typescript-remove-all-properties-with-particular-type
|
|
43
|
+
// Nested solution also available ^
|
|
44
|
+
type ExcludeKeysWithTypeOf<T, V> = {
|
|
45
|
+
[K in keyof T]-?: [Exclude<T[K], undefined>] extends [V] ? never : K;
|
|
46
|
+
}[keyof T];
|
|
47
|
+
|
|
48
|
+
type ExcludeKeysWithoutTypeOf<T, V> = {
|
|
49
|
+
[K in keyof T]-?: [Exclude<T[K], undefined>] extends [V] ? K : never;
|
|
50
|
+
}[keyof T];
|
|
51
|
+
|
|
52
|
+
export type Without<T, V> = Pick<T, ExcludeKeysWithTypeOf<T, V>>;
|
|
53
|
+
export type With<T, V> = Pick<T, ExcludeKeysWithoutTypeOf<T, V>>;
|
|
54
|
+
|
|
55
|
+
export type SchemaOutputOrType<T> = T extends ContractNullType
|
|
56
|
+
? null
|
|
57
|
+
: T extends ContractNoBodyType
|
|
58
|
+
? undefined
|
|
59
|
+
: T extends ContractPlainType<infer U>
|
|
60
|
+
? U
|
|
61
|
+
: // @deprecated - remove in next major version when zod (standard schema) is required
|
|
62
|
+
T extends z.ZodTypeAny
|
|
63
|
+
? z.output<T>
|
|
64
|
+
: T extends StandardSchemaV1
|
|
65
|
+
? StandardSchemaV1.InferOutput<T>
|
|
66
|
+
: T;
|
|
67
|
+
|
|
68
|
+
// TODO: remove in next major version
|
|
69
|
+
/** @deprecated use SchemaOutputOrType */
|
|
70
|
+
export type ZodInferOrType<T> = SchemaOutputOrType<T>;
|
|
71
|
+
|
|
72
|
+
export type SchemaInputOrType<T> = T extends ContractNullType
|
|
73
|
+
? null
|
|
74
|
+
: T extends ContractNoBodyType
|
|
75
|
+
? undefined
|
|
76
|
+
: T extends ContractPlainType<infer U>
|
|
77
|
+
? U
|
|
78
|
+
: // @deprecated - remove in next major version when zod (standard schema) is required
|
|
79
|
+
T extends z.ZodTypeAny
|
|
80
|
+
? z.input<T>
|
|
81
|
+
: T extends StandardSchemaV1
|
|
82
|
+
? StandardSchemaV1.InferInput<T>
|
|
83
|
+
: T;
|
|
84
|
+
|
|
85
|
+
// TODO: remove in next major version
|
|
86
|
+
/** @deprecated use SchemaInputOrType */
|
|
87
|
+
export type ZodInputOrType<T> = SchemaInputOrType<T>;
|
|
88
|
+
|
|
89
|
+
export type Merge<T, U> = Omit<T, keyof U> & U;
|
|
90
|
+
|
|
91
|
+
type Try<A, B, C> = A extends B ? A : C;
|
|
92
|
+
|
|
93
|
+
type NarrowRaw<T> =
|
|
94
|
+
// eslint-disable-next-line @typescript-eslint/ban-types
|
|
95
|
+
| (T extends Function ? T : never)
|
|
96
|
+
| (T extends string | number | bigint | boolean ? T : never)
|
|
97
|
+
| (T extends [] ? [] : never)
|
|
98
|
+
| {
|
|
99
|
+
[K in keyof T]: K extends 'description' ? T[K] : NarrowNotSchema<T[K]>;
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
type NarrowNotSchema<T> = Try<T, StandardSchemaV1, NarrowRaw<T>>;
|
|
103
|
+
|
|
104
|
+
export type Narrow<T> = Try<T, [], NarrowNotSchema<T>>;
|
|
105
|
+
|
|
106
|
+
export type PartialBy<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Makes the properties of `T` specified by `K` optional, where `K` can be any type (not necessarily keys of `T`).
|
|
110
|
+
* If `K` is not a key of `T`, it is ignored.
|
|
111
|
+
*
|
|
112
|
+
* @template T - The base object type.
|
|
113
|
+
* @template K - The keys to make optional (can be any type, only keys of `T` are used).
|
|
114
|
+
*/
|
|
115
|
+
export type PartialByLooseKeys<T, K> = Omit<T, K extends keyof T ? K : never> &
|
|
116
|
+
Partial<Pick<T, K extends keyof T ? K : never>>;
|
|
117
|
+
|
|
118
|
+
// https://github.com/ts-essentials/ts-essentials/blob/4c451652ba7c20b0e0b965e0b7755fd4d7844127/lib/types.ts#L228
|
|
119
|
+
type OptionalKeys<T> = T extends unknown
|
|
120
|
+
? {
|
|
121
|
+
[K in keyof T]-?: undefined extends { [K2 in keyof T]: K2 }[K]
|
|
122
|
+
? K
|
|
123
|
+
: never;
|
|
124
|
+
}[keyof T]
|
|
125
|
+
: never;
|
|
126
|
+
|
|
127
|
+
// TODO: Replace all usages of this with IfAllPropertiesOptional
|
|
128
|
+
export type AreAllPropertiesOptional<T> = T extends Record<string, unknown>
|
|
129
|
+
? Exclude<keyof T, OptionalKeys<T>> extends never
|
|
130
|
+
? true
|
|
131
|
+
: false
|
|
132
|
+
: false;
|
|
133
|
+
|
|
134
|
+
export type IfAllPropertiesOptional<T, TIf, TElse> = T extends Record<
|
|
135
|
+
string,
|
|
136
|
+
unknown
|
|
137
|
+
>
|
|
138
|
+
? Exclude<keyof T, OptionalKeys<T>> extends never
|
|
139
|
+
? TIf
|
|
140
|
+
: TElse
|
|
141
|
+
: TElse;
|
|
142
|
+
|
|
143
|
+
export type OptionalIfAllOptional<
|
|
144
|
+
T,
|
|
145
|
+
Select extends keyof T = keyof T,
|
|
146
|
+
> = PartialBy<
|
|
147
|
+
T,
|
|
148
|
+
Select &
|
|
149
|
+
{
|
|
150
|
+
[K in keyof T]: AreAllPropertiesOptional<T[K]> extends true ? K : never;
|
|
151
|
+
}[keyof T]
|
|
152
|
+
>;
|
|
153
|
+
|
|
154
|
+
export type Prettify<T> = {
|
|
155
|
+
[K in keyof T]: T[K];
|
|
156
|
+
} & {};
|
|
157
|
+
|
|
158
|
+
export type DefinedOrEmpty<
|
|
159
|
+
T,
|
|
160
|
+
K extends keyof NonNullable<T>,
|
|
161
|
+
> = undefined extends T ? {} : NonNullable<T>[K];
|
|
162
|
+
|
|
163
|
+
declare const tag: unique symbol;
|
|
164
|
+
|
|
165
|
+
declare type Tagged<Token> = {
|
|
166
|
+
readonly [tag]: Token;
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
export type Opaque<Type, Token = unknown> = Type & Tagged<Token>;
|
|
170
|
+
|
|
171
|
+
export type UnwrapOpaque<OpaqueType extends Tagged<unknown>> =
|
|
172
|
+
OpaqueType extends Opaque<infer Type, OpaqueType[typeof tag]>
|
|
173
|
+
? Type
|
|
174
|
+
: OpaqueType;
|
|
175
|
+
|
|
176
|
+
export type WithoutUnknown<T> = Pick<
|
|
177
|
+
T,
|
|
178
|
+
{
|
|
179
|
+
[K in keyof T]: unknown extends Exclude<T[K], undefined> ? never : K;
|
|
180
|
+
}[keyof T]
|
|
181
|
+
>;
|
|
182
|
+
|
|
183
|
+
export type LowercaseKeys<T> = Prettify<{
|
|
184
|
+
[K in keyof T as K extends string ? Lowercase<K> : K]: T[K];
|
|
185
|
+
}>;
|
|
186
|
+
|
|
187
|
+
export type Extends<T, U> = T extends U ? true : false;
|
|
188
|
+
|
|
189
|
+
export type And<B1 extends boolean, B2 extends boolean> = {
|
|
190
|
+
false: {
|
|
191
|
+
false: false;
|
|
192
|
+
true: false;
|
|
193
|
+
};
|
|
194
|
+
true: {
|
|
195
|
+
false: false;
|
|
196
|
+
true: true;
|
|
197
|
+
};
|
|
198
|
+
}[`${B1}`][`${B2}`];
|
|
199
|
+
|
|
200
|
+
export type Or<B1 extends boolean, B2 extends boolean> = {
|
|
201
|
+
false: {
|
|
202
|
+
false: false;
|
|
203
|
+
true: true;
|
|
204
|
+
};
|
|
205
|
+
true: {
|
|
206
|
+
false: true;
|
|
207
|
+
true: true;
|
|
208
|
+
};
|
|
209
|
+
}[`${B1}`][`${B2}`];
|
|
210
|
+
|
|
211
|
+
export type Not<B extends boolean> = {
|
|
212
|
+
false: true;
|
|
213
|
+
true: false;
|
|
214
|
+
}[`${B}`];
|
|
215
|
+
|
|
216
|
+
type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (
|
|
217
|
+
k: infer I,
|
|
218
|
+
) => void
|
|
219
|
+
? I
|
|
220
|
+
: never;
|
|
221
|
+
|
|
222
|
+
type CommonKeys<T, R = {}> = R extends T
|
|
223
|
+
? keyof T & CommonKeys<Exclude<T, R>>
|
|
224
|
+
: keyof T;
|
|
225
|
+
|
|
226
|
+
type Common<T> = Pick<T, CommonKeys<T>>;
|
|
227
|
+
|
|
228
|
+
type RemoveUnionProperties<T> = {
|
|
229
|
+
[TKey in keyof T as [T[TKey]] extends [UnionToIntersection<T[TKey]>]
|
|
230
|
+
? TKey
|
|
231
|
+
: never]: T[TKey];
|
|
232
|
+
};
|
|
233
|
+
|
|
234
|
+
export type CommonAndEqual<T> = RemoveUnionProperties<Common<T>>;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export class UnknownStatusError extends Error {
|
|
2
|
+
response: { status: number; body: unknown };
|
|
3
|
+
|
|
4
|
+
constructor(
|
|
5
|
+
response: { status: number; body: unknown },
|
|
6
|
+
knownResponseStatuses: string[],
|
|
7
|
+
) {
|
|
8
|
+
const expectedStatuses = knownResponseStatuses.join(',');
|
|
9
|
+
super(
|
|
10
|
+
`Server returned unexpected response. Expected one of: ${expectedStatuses} got: ${response.status}`,
|
|
11
|
+
);
|
|
12
|
+
|
|
13
|
+
this.response = response;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { StandardSchemaV1 } from './standard-schema';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* The error class for standard schema validation errors.
|
|
5
|
+
*
|
|
6
|
+
* @see {@link StandardSchemaV1.FailureResult}
|
|
7
|
+
*/
|
|
8
|
+
export class StandardSchemaError
|
|
9
|
+
extends Error
|
|
10
|
+
implements StandardSchemaV1.FailureResult
|
|
11
|
+
{
|
|
12
|
+
public readonly issues: readonly StandardSchemaV1.Issue[];
|
|
13
|
+
|
|
14
|
+
constructor(issues: ReadonlyArray<StandardSchemaV1.Issue>) {
|
|
15
|
+
/**
|
|
16
|
+
* Similar pattern to ZodError regarding bigints.
|
|
17
|
+
*/
|
|
18
|
+
const message = JSON.stringify(
|
|
19
|
+
issues,
|
|
20
|
+
(_, value) => (typeof value === 'bigint' ? value.toString() : value),
|
|
21
|
+
2,
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
super(message);
|
|
25
|
+
this.name = 'ValidationError';
|
|
26
|
+
this.issues = issues;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/*
|
|
30
|
+
ZodError overrides the toString method to return the serialised message.
|
|
31
|
+
The Next.js implementation relies on this behaviour.
|
|
32
|
+
*/
|
|
33
|
+
override toString() {
|
|
34
|
+
return this.message;
|
|
35
|
+
}
|
|
36
|
+
}
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"extends": "../../../tsconfig.base.json",
|
|
3
|
+
"compilerOptions": {
|
|
4
|
+
"module": "commonjs",
|
|
5
|
+
"forceConsistentCasingInFileNames": true,
|
|
6
|
+
"strict": true,
|
|
7
|
+
"noImplicitOverride": true,
|
|
8
|
+
"noPropertyAccessFromIndexSignature": true,
|
|
9
|
+
"noImplicitReturns": true,
|
|
10
|
+
"noFallthroughCasesInSwitch": true
|
|
11
|
+
},
|
|
12
|
+
"files": [],
|
|
13
|
+
"include": [],
|
|
14
|
+
"references": [
|
|
15
|
+
{
|
|
16
|
+
"path": "./tsconfig.lib.json"
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"path": "./tsconfig.spec.json"
|
|
20
|
+
}
|
|
21
|
+
]
|
|
22
|
+
}
|