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<
32 T extends Record<string, any>,
33 Static extends keyof T = never,
34> = {
35 [K in keyof T]: K extends Static ? T[K] : Input<T[K]>;
36};
37
38/**
39 * Distributes {@link Input} over each member of a (possibly union) Props
40 * type. A resource whose Props form a discriminated union (e.g. Access
41 * IdentityProvider's `type` ↔ `config` pairing) must keep the correlation
42 * between the discriminant and its payload — a non-distributive mapped
43 * type over the union collapses `keyof` to the common keys and severs
44 * that link, silently accepting a `config` from the wrong variant.
45 */
46export type PropsInput<P> = P extends object
47 ? { [K in keyof P]: Input<P[K]> }
48 : P extends undefined
49 ? {}
50 : never;
51
52export declare namespace Input {
53 export type Resolve<T> = T extends {
54 Type: string;
55 Attributes: infer Attributes;
56 }
57 ? {
58 [K in keyof Attributes]: Resolve<Attributes[K]>;
59 }
60 : T extends Output<infer U>
61 ? U
62 : T extends
63 | Primitive
64 | Constructor
65 | Function
66 | S.Schema<any>
67 | PolicyLike
68 ? T
69 : T extends any[]
70 ? ResolveArray<T>
71 : T extends Record<string, any>
72 ? {
73 [k in keyof T]: Input.Resolve<T[k]>;
74 }
75 : never;
76
77 export type ResolveArray<T extends any[]> = number extends T["length"]
78 ? Resolve<T[number]>[]
79 : ResolveTuple<T>;
80
81 export type ResolveTuple<
82 T extends any[],
83 // TODO(sam): I added the accumulator because it resolved infinite type instantiation
84 Accum extends any[] = [],
85 > = T extends [infer H, ...infer Tail]
86 ? ResolveTuple<Tail, [...Accum, Input.Resolve<H>]>
87 : Accum;
88
89 export type ResolveProps<Props extends Record<string, any>> = {
90 [k in keyof Props]: Input.Resolve<Props[k]>;
91 };
92
93 export type ResolveOpaque<T> =
94 // use true extends IsOut to avoid distribution in the case where we have an Out<T>
95 // because T is a clean type, e.g. Input<SubnetProps> should just be SubnetProps (don't bother resolving the recursive input type variants)
96 true extends IsOut<T> ? ResolveOut<T> : Resolve<T>;
97 export type IsOut<T> = T extends Output<infer _U> ? true : never;
98
99 export type ResolveOut<T> = T extends Output<infer U> ? U : never;
100}
101
102export type Inputs<T extends any[], Out extends any[] = []> = T extends [
103 infer H,
104 ...infer T,
105]
106 ? Inputs<T, [...Out, Input<H>]>
107 : Out;