@terraforge/core 0.0.1 → 0.0.3

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/README.md CHANGED
@@ -7,15 +7,12 @@ The core of Terraforge lives in `@terraforge/core`, with the Terraform bridge in
7
7
 
8
8
  The most used IaC solutions are slow & don't effectively leverage diffing to speed up their deployments.
9
9
 
10
- ## Todo's
11
- - When a resource is being deleted inside a deployment we need to make sure that resources that depends on our deleted resource will be updated first.
12
-
13
10
  ## Setup
14
11
 
15
12
  Install with (NPM):
16
13
 
17
14
  ```
18
- npm i @terraforge/core @terraforge/terraform
15
+ npm i @terraforge/core @terraforge/aws
19
16
  ```
20
17
 
21
18
  ## Example
@@ -33,13 +30,7 @@ In this example, we will use a local file lock & state provider.
33
30
 
34
31
  ```ts
35
32
  import { App, FileStateBackend, FileLockBackend, Stack, WorkSpace } from '@terraforge/core'
36
- import { Terraform, $ } from '@terraforge/terraform'
37
-
38
- const terraform = new Terraform({
39
- providerLocation: './providers'
40
- })
41
-
42
- const aws = await terraform.install('hashicorp', 'aws', '5.93.0')
33
+ import { aws } from '@terraforge/aws'
43
34
 
44
35
  const workspace = new WorkSpace({
45
36
  providers: [
@@ -61,10 +52,10 @@ This example illustrates how simple it is to define multi-stack resources withou
61
52
  ```ts
62
53
  const app = new App('todo-app')
63
54
  const storage = new Stack(app, 'storage')
64
- const list = new $.aws.s3.Bucket(storage, 'list', {})
55
+ const list = new aws.s3.Bucket(storage, 'list', {})
65
56
 
66
57
  const items = new Stack(app, 'items')
67
- const todo = new $.aws.s3.BucketObject(items, 'item', {
58
+ const todo = new aws.s3.BucketObject(items, 'item', {
68
59
  bucket: list.bucket,
69
60
  key: 'item-1',
70
61
  content: JSON.stringify({
@@ -0,0 +1,333 @@
1
+ declare class Future<T = unknown> {
2
+ protected callback: (resolve: (data: T) => void, reject: (error: unknown) => void) => void;
3
+ protected listeners;
4
+ protected status: 0 | 1 | 2 | 3;
5
+ protected data?: T;
6
+ protected error?: unknown;
7
+ constructor(callback: (resolve: (data: T) => void, reject: (error: unknown) => void) => void);
8
+ get [Symbol.toStringTag]();
9
+ pipe<N>(cb: (value: T) => N);
10
+ then(resolve: (data: T) => void, reject?: (error: unknown) => void);
11
+ }
12
+ type Input<T = unknown> = T | Output<T> | Future<T> | Promise<T>;
13
+ type OptionalInput<T = unknown> = Input<T> | Input<T | undefined> | Input<undefined>;
14
+ declare const findInputDeps: unknown;
15
+ declare const resolveInputs: <T>(inputs: T) => Promise<T>;
16
+ type OptionalOutput<T = unknown> = Output<T | undefined>;
17
+ declare class Output<T = unknown> extends Future<T> {
18
+ readonly dependencies: Set<Meta>;
19
+ constructor(dependencies: Set<Meta>, callback: (resolve: (data: T) => void, reject: (error: unknown) => void) => void);
20
+ pipe<N>(cb: (value: T) => N);
21
+ }
22
+ declare const deferredOutput: unknown;
23
+ declare const output: unknown;
24
+ declare const nodeMetaSymbol: unknown;
25
+ type Node<
26
+ T extends Tag = Tag,
27
+ I extends State = State,
28
+ O extends State = any,
29
+ C extends Config = Config
30
+ > = {
31
+ [nodeMetaSymbol]: Meta<T, I, O, C>;
32
+ } & O;
33
+ declare const isNode: (obj: object) => obj is {
34
+ [nodeMetaSymbol]: Meta;
35
+ };
36
+ declare function getMeta(node: Resource): ResourceMeta;
37
+ declare function getMeta(node: DataSource): DataSourceMeta;
38
+ declare function getMeta(node: Node): Meta;
39
+ declare const isResource: (obj: object) => obj is Resource;
40
+ declare const isDataSource: (obj: object) => obj is DataSource;
41
+ type ResourceConfig = Config & {
42
+ /** Import an existing resource instead of creating a new resource. */
43
+ import?: string;
44
+ /** If true the resource will be retained in the backing cloud provider during a Pulumi delete operation. */
45
+ retainOnDelete?: boolean;
46
+ /** Override the default create-after-delete behavior when replacing a resource. */
47
+ /** If set, the provider’s Delete method will not be called for this resource if the specified resource is being deleted as well. */
48
+ /** Declare that changes to certain properties should be treated as forcing a replacement. */
49
+ replaceOnChanges?: string[];
50
+ };
51
+ type ResourceMeta<
52
+ I extends State = State,
53
+ O extends State = State
54
+ > = Meta<"resource", I, O, ResourceConfig>;
55
+ type Resource<
56
+ I extends State = State,
57
+ O extends State = State
58
+ > = O & {
59
+ readonly [nodeMetaSymbol]: ResourceMeta<I, O>;
60
+ };
61
+ type ResourceClass<
62
+ I extends State = State,
63
+ O extends State = State
64
+ > = {
65
+ new (parent: Group, id: string, props: I, config?: ResourceConfig): Resource<I, O>;
66
+ get(parent: Group, id: string, physicalId: string): DataSource<I, O>;
67
+ };
68
+ declare class Stack extends Group {
69
+ readonly app: App;
70
+ readonly dependencies;
71
+ constructor(app: App, name: string);
72
+ dependsOn(...stacks: Stack[]);
73
+ }
74
+ type URN = `urn:${string}`;
75
+ type Tag = "resource" | "data";
76
+ type State = Record<string, unknown>;
77
+ type Config = {
78
+ /** Specify additional explicit dependencies in addition to the ones in the dependency graph. */
79
+ dependsOn?: Resource<any, any>[];
80
+ /** Pass an ID of an explicitly configured provider, instead of using the default provider. */
81
+ provider?: string;
82
+ };
83
+ type Meta<
84
+ T extends Tag = Tag,
85
+ I extends State = State,
86
+ O extends State = State,
87
+ C extends Config = Config
88
+ > = {
89
+ readonly tag: T;
90
+ readonly urn: URN;
91
+ readonly logicalId: string;
92
+ readonly type: string;
93
+ readonly stack: Stack;
94
+ readonly provider: string;
95
+ readonly input: I;
96
+ readonly config?: C;
97
+ readonly dependencies: Set<URN>;
98
+ readonly resolve: (data: O) => void;
99
+ readonly output: <O>(cb: (data: State) => O) => Output<O>;
100
+ };
101
+ declare const createMeta: <
102
+ T extends Tag = Tag,
103
+ I extends State = State,
104
+ O extends State = State,
105
+ C extends Config = Config
106
+ >(tag: T, provider: string, parent: Group, type: string, logicalId: string, input: I, config?: C) => Meta<T, I, O, C>;
107
+ type DataSourceMeta<
108
+ I extends State = State,
109
+ O extends State = State
110
+ > = Meta<"data", I, O>;
111
+ type DataSource<
112
+ I extends State = State,
113
+ O extends State = State
114
+ > = {
115
+ readonly [nodeMetaSymbol]: DataSourceMeta<I, O>;
116
+ } & O;
117
+ type DataSourceFunction<
118
+ I extends State = State,
119
+ O extends State = State
120
+ > = (parent: Group, id: string, input: I, config?: Config) => DataSource<I, O>;
121
+ declare class Group {
122
+ readonly parent: Group | undefined;
123
+ readonly type: string;
124
+ readonly name: string;
125
+ protected children: Array<Group | Node>;
126
+ constructor(parent: Group | undefined, type: string, name: string);
127
+ get urn(): URN;
128
+ protected addChild(child: Group | Node);
129
+ add(...children: Array<Group | Node>);
130
+ get nodes(): Node[];
131
+ get resources(): Resource[];
132
+ get dataSources(): DataSource[];
133
+ }
134
+ declare class App extends Group {
135
+ readonly name: string;
136
+ constructor(name: string);
137
+ get stacks(): Stack[];
138
+ }
139
+ declare const enableDebug: unknown;
140
+ declare const createDebugger: (group: string) => unknown;
141
+ import { UUID as UUID2 } from "node:crypto";
142
+ interface LockBackend {
143
+ insecureReleaseLock(urn: URN): Promise<void>;
144
+ locked(urn: URN): Promise<boolean>;
145
+ lock(urn: URN): Promise<() => Promise<void>>;
146
+ }
147
+ import { UUID } from "node:crypto";
148
+ type AppState = {
149
+ name: string;
150
+ version?: number;
151
+ idempotentToken?: UUID;
152
+ stacks: Record<URN, StackState>;
153
+ };
154
+ type StackState = {
155
+ name: string;
156
+ nodes: Record<URN, NodeState>;
157
+ };
158
+ type NodeState = {
159
+ tag: "resource" | "data";
160
+ type: string;
161
+ version?: number;
162
+ provider: string;
163
+ input: State;
164
+ output: State;
165
+ dependencies: URN[];
166
+ lifecycle?: {
167
+ retainOnDelete?: boolean;
168
+ deleteAfterCreate?: boolean;
169
+ };
170
+ };
171
+ type StateBackend = {
172
+ get(urn: URN): Promise<AppState | undefined>;
173
+ update(urn: URN, state: AppState): Promise<void>;
174
+ delete(urn: URN): Promise<void>;
175
+ };
176
+ type CreateProps<T = State> = {
177
+ type: string;
178
+ state: T;
179
+ idempotantToken?: string;
180
+ };
181
+ type UpdateProps<T = State> = {
182
+ type: string;
183
+ priorState: T;
184
+ proposedState: T;
185
+ idempotantToken?: string;
186
+ };
187
+ type DeleteProps<T = State> = {
188
+ type: string;
189
+ state: T;
190
+ idempotantToken?: string;
191
+ };
192
+ type GetProps<T = State> = {
193
+ type: string;
194
+ state: T;
195
+ };
196
+ type GetDataProps<T = State> = {
197
+ type: string;
198
+ state: T;
199
+ };
200
+ interface Provider {
201
+ ownResource(id: string): boolean;
202
+ getResource(props: GetProps): Promise<{
203
+ version: number;
204
+ state: State;
205
+ }>;
206
+ createResource(props: CreateProps): Promise<{
207
+ version: number;
208
+ state: State;
209
+ }>;
210
+ updateResource(props: UpdateProps): Promise<{
211
+ version: number;
212
+ state: State;
213
+ }>;
214
+ deleteResource(props: DeleteProps): Promise<void>;
215
+ getData?(props: GetDataProps): Promise<{
216
+ state: State;
217
+ }>;
218
+ destroy?(): Promise<void>;
219
+ }
220
+ type ProcedureOptions = {
221
+ filters?: string[];
222
+ idempotentToken?: UUID2;
223
+ };
224
+ type WorkSpaceOptions = {
225
+ providers: Provider[];
226
+ concurrency?: number;
227
+ backend: {
228
+ state: StateBackend;
229
+ lock: LockBackend;
230
+ };
231
+ };
232
+ declare class WorkSpace {
233
+ protected props: WorkSpaceOptions;
234
+ constructor(props: WorkSpaceOptions);
235
+ deploy(app: App, options?: ProcedureOptions);
236
+ delete(app: App, options?: ProcedureOptions);
237
+ hydrate(app: App);
238
+ protected destroyProviders();
239
+ }
240
+ type ResourceOperation = "create" | "update" | "delete" | "replace" | "import" | "resolve" | "get";
241
+ declare class ResourceError extends Error {
242
+ readonly urn: URN;
243
+ readonly type: string;
244
+ readonly operation: ResourceOperation;
245
+ static wrap(urn: URN, type: string, operation: ResourceOperation, error: unknown);
246
+ constructor(urn: URN, type: string, operation: ResourceOperation, message: string);
247
+ }
248
+ declare class AppError extends Error {
249
+ readonly app: string;
250
+ readonly issues: (ResourceError | Error)[];
251
+ constructor(app: string, issues: (ResourceError | Error)[], message: string);
252
+ }
253
+ declare class ResourceNotFound extends Error {}
254
+ declare class ResourceAlreadyExists extends Error {}
255
+ declare class MemoryStateBackend implements StateBackend {
256
+ protected states;
257
+ get(urn: URN);
258
+ update(urn: URN, state: AppState);
259
+ delete(urn: URN);
260
+ clear();
261
+ }
262
+ declare class MemoryLockBackend implements LockBackend {
263
+ protected locks;
264
+ insecureReleaseLock(urn: URN);
265
+ locked(urn: URN);
266
+ lock(urn: URN);
267
+ clear();
268
+ }
269
+ declare class FileStateBackend implements StateBackend {
270
+ private props;
271
+ constructor(props: {
272
+ dir: string;
273
+ });
274
+ private stateFile;
275
+ private mkdir;
276
+ get(urn: URN);
277
+ update(urn: URN, state: AppState);
278
+ delete(urn: URN);
279
+ }
280
+ declare class FileLockBackend implements LockBackend {
281
+ private props;
282
+ constructor(props: {
283
+ dir: string;
284
+ });
285
+ private lockFile;
286
+ private mkdir;
287
+ insecureReleaseLock(urn: URN);
288
+ locked(urn: URN);
289
+ lock(urn: URN);
290
+ }
291
+ import { AwsCredentialIdentity, AwsCredentialIdentityProvider } from "@aws-sdk/types";
292
+ import { S3Client } from "@aws-sdk/client-s3";
293
+ type Props = {
294
+ credentials: AwsCredentialIdentity | AwsCredentialIdentityProvider;
295
+ region: string;
296
+ bucket: string;
297
+ };
298
+ declare class S3StateBackend implements StateBackend {
299
+ private props;
300
+ protected client: S3Client;
301
+ constructor(props: Props);
302
+ get(urn: URN);
303
+ update(urn: URN, state: AppState);
304
+ delete(urn: URN);
305
+ }
306
+ import { DynamoDB } from "@aws-sdk/client-dynamodb";
307
+ import { AwsCredentialIdentity as AwsCredentialIdentity2, AwsCredentialIdentityProvider as AwsCredentialIdentityProvider2 } from "@aws-sdk/types";
308
+ type Props2 = {
309
+ credentials: AwsCredentialIdentity2 | AwsCredentialIdentityProvider2;
310
+ region: string;
311
+ tableName: string;
312
+ };
313
+ declare class DynamoLockBackend implements LockBackend {
314
+ private props;
315
+ protected client: DynamoDB;
316
+ constructor(props: Props2);
317
+ insecureReleaseLock(urn: URN);
318
+ locked(urn: URN);
319
+ lock(urn: URN);
320
+ }
321
+ declare const createCustomResourceClass: <
322
+ I extends State,
323
+ O extends State
324
+ >(providerId: string, resourceType: string) => ResourceClass<I, O>;
325
+ type CustomResourceProvider = Partial<{
326
+ getResource?(props: Omit<GetProps, "type">): Promise<State>;
327
+ updateResource?(props: Omit<UpdateProps, "type">): Promise<State>;
328
+ createResource?(props: Omit<CreateProps, "type">): Promise<State>;
329
+ deleteResource?(props: Omit<DeleteProps, "type">): Promise<void>;
330
+ getData?(props: Omit<GetDataProps, "type">): Promise<State>;
331
+ }>;
332
+ declare const createCustomProvider: (providerId: string, resourceProviders: Record<string, CustomResourceProvider>) => Provider;
333
+ export { resolveInputs, output, nodeMetaSymbol, isResource, isNode, isDataSource, getMeta, findInputDeps, enableDebug, deferredOutput, createMeta, createDebugger, createCustomResourceClass, createCustomProvider, WorkSpaceOptions, WorkSpace, UpdateProps, URN, Tag, StateBackend, State, Stack, S3StateBackend, ResourceNotFound, ResourceMeta, ResourceError, ResourceConfig, ResourceClass, ResourceAlreadyExists, Resource, Provider, ProcedureOptions, Output, OptionalOutput, OptionalInput, Node, Meta, MemoryStateBackend, MemoryLockBackend, LockBackend, Input, Group, GetProps, GetDataProps, Future, FileStateBackend, FileLockBackend, DynamoLockBackend, DeleteProps, DataSourceMeta, DataSourceFunction, DataSource, CustomResourceProvider, CreateProps, Config, AppError, App };