1import type {
2 Apply,
3 Create,
4 Delete,
5 NoopUpdate,
6 Plan,
7 Replace,
8 Update,
9} from "@/Plan.ts";
10import type { ProviderService } from "@/Provider.ts";
11import type { ResourceLike } from "@/Resource.ts";
12import type { CreatedResourceState } from "@/State/index.ts";
13import * as Effect from "effect/Effect";
14
15const provider: ProviderService<ResourceLike> = {
16 list: () => Effect.succeed([]),
17 reconcile: () => Effect.succeed({}),
18 delete: () => Effect.void,
19};
20
21const resource = (id: string, props: object): ResourceLike => ({
22 Namespace: undefined,
23 FQN: id,
24 Type: "Test.Resource",
25 LogicalId: id,
26 Props: props,
27 RemovalPolicy: "destroy",
28 Adopt: undefined,
29 Mode: undefined,
30 RequiresImplementation: undefined,
31 FormerFqns: undefined,
32 Attributes: {},
33 Binding: undefined,
34 Providers: undefined,
35});
36
37const state = (id: string, props: object): CreatedResourceState => ({
38 resourceType: "Test.Resource",
39 namespace: undefined,
40 fqn: id,
41 logicalId: id,
42 instanceId: `test-${id}`,
43 providerVersion: 0,
44 status: "created",
45 downstream: [],
46 bindings: [],
47 props,
48 attr: {},
49 removalPolicy: "destroy",
50});
51
52const baseNode = (id: string, props: object) => ({
53 resource: resource(id, props),
54 provider,
55 mode: undefined,
56 downstream: [],
57 bindings: [],
58});
59
60export const updateNode = (
61 olds: object,
62 news: object,
63 id = "Worker",
64): Update => ({
65 ...baseNode(id, news),
66 action: "update",
67 props: news,
68 state: state(id, olds),
69});
70
71export const createNode = (props: object, id = "Worker"): Create => ({
72 ...baseNode(id, props),
73 action: "create",
74 props,
75 state: undefined,
76});
77
78export const noopNode = (props: object, id = "Worker"): NoopUpdate => ({
79 ...baseNode(id, props),
80 action: "noop",
81 state: state(id, props),
82});
83
84export const replaceNode = (
85 olds: object,
86 news: object,
87 id = "Worker",
88): Replace => ({
89 ...baseNode(id, news),
90 action: "replace",
91 props: news,
92 state: state(id, olds),
93 deleteFirst: false,
94});
95
96export const deleteNode = (props: object, id = "Worker"): Delete => ({
97 ...baseNode(id, props),
98 action: "delete",
99 state: state(id, props),
100});
101
102export const planWith = (
103 resources: Apply[] = [],
104 deletions: Delete[] = [],
105): Plan<undefined> => ({
106 resources: Object.fromEntries(
107 resources.map((node) => [node.resource.FQN, node]),
108 ),
109 deletions: Object.fromEntries(
110 deletions.map((node) => [node.resource.FQN, node]),
111 ),
112 actions: {},
113 actionDeletions: {},
114 output: undefined,
115 cycleMembers: new Set<string>(),
116});