Skip to content
Source
Sign inSign up
Open History to see the last commit

Input.ts

94 lines3.2 KB

1import type { Config } from "effect/Config";
2import type { Effect } from "effect/Effect";
3import type * as S from "effect/Schema";
4import type { Primitive } from ".//Util/data.ts";
5import type { Output } from "./Output.ts";
6​
7export type Function = (...args: any[]) => any;
8export type Constructor = new (...args: any[]) => any;
9type PolicyLike = { kind: "alchemy/Policy" };
10​
11export type Input<T> =
12 | T
13 | Output<T>
14 | Config<T>
15 // TODO(sam): extract Requirements in Resource
16 | Effect<T, any, any>
17 | (T extends S.Schema<any>
18 ? never
19 :
20 | Output<T, any>
21 | (T extends Primitive
22 ? never
23 : T extends any[]
24 ? number extends T["length"]
25 ? Input<T[number]>[]
26 : Inputs<T>
27 : T extends object
28 ? { [K in keyof T]: Input<T[K]> }
29 : never));
30​
31export type InputProps<T extends Record<string, any>, Static extends keyof T = never> = {
32 [K in keyof T]: K extends Static ? T[K] : Input<T[K]>;
33};
34​
35/**
36 * Distributes {@link Input} over each member of a (possibly union) Props
37 * type. A resource whose Props form a discriminated union (e.g. Access
38 * IdentityProvider's `type` ↔ `config` pairing) must keep the correlation
39 * between the discriminant and its payload — a non-distributive mapped
40 * type over the union collapses `keyof` to the common keys and severs
41 * that link, silently accepting a `config` from the wrong variant.
42 */
43export type PropsInput<P> = P extends object
44 ? { [K in keyof P]: Input<P[K]> }
45 : P extends undefined
46 ? {}
47 : never;
48​
49export declare namespace Input {
50 export type Resolve<T> = T extends {
51 Type: string;
52 Attributes: infer Attributes;
53 }
54 ? {
55 [K in keyof Attributes]: Resolve<Attributes[K]>;
56 }
57 : T extends Output<infer U>
58 ? U
59 : T extends Primitive | Constructor | Function | S.Schema<any> | PolicyLike
60 ? T
61 : T extends any[]
62 ? ResolveArray<T>
63 : T extends Record<string, any>
64 ? {
65 [k in keyof T]: Input.Resolve<T[k]>;
66 }
67 : never;
68​
69 export type ResolveArray<T extends any[]> = number extends T["length"]
70 ? Resolve<T[number]>[]
71 : ResolveTuple<T>;
72​
73 export type ResolveTuple<
74 T extends any[],
75 // TODO(sam): I added the accumulator because it resolved infinite type instantiation
76 Accum extends any[] = [],
77 > = T extends [infer H, ...infer Tail] ? ResolveTuple<Tail, [...Accum, Input.Resolve<H>]> : Accum;
78​
79 export type ResolveProps<Props extends Record<string, any>> = {
80 [k in keyof Props]: Input.Resolve<Props[k]>;
81 };
82​
83 export type ResolveOpaque<T> =
84 // use true extends IsOut to avoid distribution in the case where we have an Out<T>
85 // because T is a clean type, e.g. Input<SubnetProps> should just be SubnetProps (don't bother resolving the recursive input type variants)
86 true extends IsOut<T> ? ResolveOut<T> : Resolve<T>;
87 export type IsOut<T> = T extends Output<infer _U> ? true : never;
88​
89 export type ResolveOut<T> = T extends Output<infer U> ? U : never;
91​
92export type Inputs<T extends any[], Out extends any[] = []> = T extends [infer H, ...infer T]
93 ? Inputs<T, [...Out, Input<H>]>
94 : Out;