@terraforge/terraform 0.0.9 → 0.0.11

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/dist/index.js DELETED
@@ -1,1986 +0,0 @@
1
- // src/type-gen.ts
2
- import { camelCase, pascalCase } from "change-case";
3
- var tab = (indent) => {
4
- return " ".repeat(indent);
5
- };
6
- var generateTypes = (providers, resources, dataSources) => {
7
- return [
8
- generateImport("c", "@terraforge/core"),
9
- generateImport("t", "@terraforge/terraform"),
10
- "type _Record<T> = Record<string, T>",
11
- generateInstallHelperFunctions(providers),
12
- generateNamespace(providers, (name, prop, indent) => {
13
- const typeName = name.toLowerCase();
14
- return `${tab(indent)}export declare function ${typeName}(props: ${generatePropertyInputConst(prop, indent)}, config?: t.TerraformProviderConfig): t.TerraformProvider`;
15
- }),
16
- generateNamespace(resources, (name, prop, indent) => {
17
- const typeName = pascalCase(name);
18
- return [
19
- // `${tab(indent)}export type ${typeName}Input = ${generatePropertyInputType(prop, indent)}`,
20
- // `${tab(indent)}export type ${typeName}Output = ${generatePropertyOutputType(prop, indent)}`,
21
- // `${tab(indent)}export declare const ${typeName}: ResourceClass<${typeName}Input, ${typeName}Output>`,
22
- `${tab(indent)}export type ${typeName}Input = ${generatePropertyInputType(prop, indent)}`,
23
- `${tab(indent)}export type ${typeName}Output = ${generatePropertyOutputType(prop, indent)}`,
24
- `${tab(indent)}export class ${typeName} {`,
25
- `${tab(indent + 1)}constructor(parent: c.Group, id: string, props: ${typeName}Input, config?:c.ResourceConfig)`,
26
- // `${tab(indent + 1)}readonly $: c.ResourceMeta<${typeName}Input, ${typeName}Output>`,
27
- generateClassProperties(prop, indent + 1),
28
- `${tab(indent)}}`
29
- ].join("\n\n");
30
- }),
31
- generateNamespace(dataSources, (name, prop, indent) => {
32
- const typeName = pascalCase(name);
33
- return [
34
- `${tab(indent)}export type Get${typeName}Input = ${generatePropertyInputType(prop, indent)}`,
35
- `${tab(indent)}export type Get${typeName}Output = ${generatePropertyOutputType(prop, indent)}`,
36
- `${tab(indent)}export const get${typeName}:c.DataSourceFunction<Get${typeName}Input, Get${typeName}Output>`
37
- ].join("\n\n");
38
- })
39
- ].join("\n\n");
40
- };
41
- var generateImport = (name, from) => {
42
- return `import * as ${name} from '${from}'`;
43
- };
44
- var generateInstallHelperFunctions = (resources) => {
45
- return generateNamespace(resources, (name, _prop, indent) => {
46
- const typeName = name.toLowerCase();
47
- return [
48
- `${tab(indent)}export declare namespace ${typeName} {`,
49
- `${tab(indent + 1)}export function install(props?: t.InstallProps): Promise<void>`,
50
- `${tab(indent + 1)}export function uninstall(props?: t.InstallProps): Promise<void>`,
51
- `${tab(indent + 1)}export function isInstalled(props?: t.InstallProps): Promise<boolean>`,
52
- `${tab(indent)}}`
53
- ].join("\n");
54
- });
55
- };
56
- var generatePropertyInputConst = (prop, indent) => {
57
- return generateValue(prop, {
58
- depth: 0,
59
- indent: indent + 1,
60
- wrap: (v, _, ctx) => {
61
- return `${v}${ctx.depth === 1 ? "," : ""}`;
62
- },
63
- filter: () => true,
64
- optional: (p) => p.optional ?? false
65
- });
66
- };
67
- var generatePropertyInputType = (prop, indent) => {
68
- return generateValue(prop, {
69
- depth: 0,
70
- indent: indent + 1,
71
- wrap: (v, p, ctx) => {
72
- return ctx.depth > 0 ? p.optional ? `c.OptionalInput<${v}>` : `c.Input<${v}>` : v;
73
- },
74
- filter: (prop2) => !(prop2.computed && typeof prop2.optional === "undefined" && typeof prop2.required === "undefined"),
75
- optional: (p) => p.optional ?? false
76
- });
77
- };
78
- var generatePropertyOutputType = (prop, indent) => {
79
- return generateValue(prop, {
80
- depth: 0,
81
- indent: indent + 1,
82
- wrap: (v, p, ctx) => ctx.depth === 1 ? p.optional && !p.computed ? `c.OptionalOutput<${v}>` : `c.Output<${v}>` : v,
83
- filter: () => true,
84
- readonly: true,
85
- // required: true,
86
- optional: (p, ctx) => ctx.depth > 1 && p.optional && !p.computed || false
87
- });
88
- };
89
- var generateClassProperties = (prop, indent) => {
90
- if (prop.type !== "object") {
91
- return "";
92
- }
93
- return Object.entries(prop.properties).map(([name, prop2]) => {
94
- return [
95
- prop2.description ? [`
96
- `, ` `.repeat(indent), `/** `, prop2.description.trim(), " */", "\n"].join("") : "",
97
- ` `.repeat(indent),
98
- "readonly ",
99
- camelCase(name),
100
- // ctx.optional(prop, ctx) ? '?' : '',
101
- ": ",
102
- generateValue(prop2, {
103
- readonly: true,
104
- filter: () => true,
105
- optional: (p, ctx) => ctx.depth > 1 && p.optional && !p.computed || false,
106
- wrap: (v, p, ctx) => {
107
- return ctx.depth === 1 ? p.optional && !p.computed ? `c.OptionalOutput<${v}>` : `c.Output<${v}>` : v;
108
- },
109
- // ctx.depth === 1 ? `c.Output<${p.optional && !p.computed ? `${v} | undefined` : v}>` : v,
110
- indent: indent + 1,
111
- depth: 1
112
- })
113
- ].join("");
114
- }).join("\n");
115
- };
116
- var groupByNamespace = (resources, minLevel, maxLevel) => {
117
- const grouped = {};
118
- const types = Object.keys(resources).sort();
119
- for (const type of types) {
120
- const names = type.split("_");
121
- if (names.length < minLevel) {
122
- throw new Error(`Resource not properly namespaced: ${type}`);
123
- }
124
- let current = grouped;
125
- let count = Math.min(maxLevel, names.length - 1);
126
- while (count--) {
127
- const ns = camelCase(names.shift());
128
- if (!current[ns]) {
129
- current[ns] = {};
130
- }
131
- current = current[ns];
132
- }
133
- const name = pascalCase(names.join("_"));
134
- current[name] = type;
135
- }
136
- return grouped;
137
- };
138
- var generateNamespace = (resources, render) => {
139
- const grouped = groupByNamespace(resources, 1, 2);
140
- const renderNamespace = (name, group, indent) => {
141
- if (name === "default") {
142
- name = "$default";
143
- }
144
- if (typeof group === "string") {
145
- return render(name, resources[group], indent);
146
- }
147
- return [
148
- `${tab(indent)}export ${indent === 0 ? "declare " : ""}namespace ${name.toLowerCase()} {`,
149
- Object.entries(group).map(([name2, entry]) => {
150
- if (typeof entry !== "string") {
151
- return renderNamespace(name2, entry, indent + 1);
152
- } else {
153
- return render(name2, resources[entry], indent + 1);
154
- }
155
- }).join("\n"),
156
- `${tab(indent)}}`
157
- ].join("\n");
158
- };
159
- return Object.entries(grouped).map(([name, entry]) => {
160
- return renderNamespace(name, entry, 0);
161
- });
162
- };
163
- var generateValue = (prop, ctx) => {
164
- if (["string", "number", "boolean", "unknown"].includes(prop.type)) {
165
- return ctx.wrap(prop.type, prop, ctx);
166
- }
167
- if (prop.type === "array") {
168
- const type = generateValue(prop.item, { ...ctx, depth: ctx.depth + 1 });
169
- const array = ctx.readonly ? `ReadonlyArray<${type}>` : `Array<${type}>`;
170
- return ctx.wrap(array, prop, ctx);
171
- }
172
- if (prop.type === "record") {
173
- const type = generateValue(prop.item, { ...ctx, depth: ctx.depth + 1 });
174
- const record = ctx.readonly ? `Readonly<_Record<${type}>>` : `_Record<${type}>`;
175
- return ctx.wrap(record, prop, ctx);
176
- }
177
- if (prop.type === "object" || prop.type === "array-object") {
178
- const type = [
179
- "{",
180
- Object.entries(prop.properties).filter(([_, p]) => ctx.filter(p)).map(
181
- ([name, prop2]) => [
182
- prop2.description ? [`
183
- `, ` `.repeat(ctx.indent), `/** `, prop2.description.trim(), " */", "\n"].join("") : "",
184
- ` `.repeat(ctx.indent),
185
- // ctx.readonly ? "readonly " : "",
186
- camelCase(name),
187
- ctx.optional(prop2, ctx) ? "?" : "",
188
- ": ",
189
- generateValue(prop2, { ...ctx, indent: ctx.indent + 1, depth: ctx.depth + 1 })
190
- ].join("")
191
- ).join("\n"),
192
- `${` `.repeat(ctx.indent - 1)}}`
193
- ].join("\n");
194
- const object = ctx.readonly ? `Readonly<${type}>` : type;
195
- return ctx.wrap(object, prop, ctx);
196
- }
197
- throw new Error(`Unknown property type: ${prop.type}`);
198
- };
199
-
200
- // src/provider.ts
201
- import {
202
- ResourceNotFound
203
- } from "@terraforge/core";
204
- var TerraformProvider = class {
205
- constructor(type, id, createPlugin, config) {
206
- this.type = type;
207
- this.id = id;
208
- this.createPlugin = createPlugin;
209
- this.config = config;
210
- }
211
- configured;
212
- plugin;
213
- async configure() {
214
- const plugin = await this.prepare();
215
- if (!this.configured) {
216
- this.configured = plugin.configure(this.config);
217
- }
218
- await this.configured;
219
- return plugin;
220
- }
221
- prepare() {
222
- if (!this.plugin) {
223
- this.plugin = this.createPlugin();
224
- }
225
- return this.plugin;
226
- }
227
- async destroy() {
228
- if (this.plugin) {
229
- const plugin = await this.plugin;
230
- plugin.stop();
231
- this.plugin = void 0;
232
- this.configured = void 0;
233
- }
234
- }
235
- ownResource(id) {
236
- return `terraform:${this.type}:${this.id}` === id;
237
- }
238
- async getResource({ type, state }) {
239
- const plugin = await this.configure();
240
- const newState = await plugin.readResource(type, state);
241
- if (!newState) {
242
- throw new ResourceNotFound();
243
- }
244
- return {
245
- version: 0,
246
- state: newState
247
- };
248
- }
249
- async createResource({ type, state }) {
250
- const plugin = await this.configure();
251
- const newState = await plugin.applyResourceChange(type, null, state);
252
- return {
253
- version: 0,
254
- state: newState
255
- };
256
- }
257
- async updateResource({ type, priorState, proposedState }) {
258
- const plugin = await this.configure();
259
- const { requiresReplace } = await plugin.planResourceChange(type, priorState, proposedState);
260
- if (requiresReplace.length > 0) {
261
- const formattedAttrs = requiresReplace.map((p) => p.join(".")).join('", "');
262
- throw new Error(
263
- `Updating the "${formattedAttrs}" properties for the "${type}" resource will require the resource to be replaced.`
264
- );
265
- }
266
- const newState = await plugin.applyResourceChange(type, priorState, proposedState);
267
- return {
268
- version: 0,
269
- state: newState
270
- };
271
- }
272
- async deleteResource({ type, state }) {
273
- const plugin = await this.configure();
274
- try {
275
- await plugin.applyResourceChange(type, state, null);
276
- } catch (error) {
277
- try {
278
- const newState = await plugin.readResource(type, state);
279
- if (!newState) {
280
- throw new ResourceNotFound();
281
- }
282
- } catch (_) {
283
- }
284
- throw error;
285
- }
286
- }
287
- async getData({ type, state }) {
288
- const plugin = await this.configure();
289
- const data = await plugin.readDataSource(type, state);
290
- if (!data) {
291
- throw new Error(`Data source not found ${type}`);
292
- }
293
- return {
294
- state: data
295
- };
296
- }
297
- // async generateTypes(dir: string) {
298
- // const plugin = await this.prepare()
299
- // const schema = plugin.schema()
300
- // const types = generateTypes(
301
- // {
302
- // [`${this.type}_provider`]: schema.provider,
303
- // },
304
- // schema.resources,
305
- // schema.dataSources
306
- // )
307
- // await mkdir(dir, { recursive: true })
308
- // await writeFile(join(dir, `${this.type}.d.ts`), types)
309
- // await this.destroy()
310
- // }
311
- };
312
-
313
- // src/proxy.ts
314
- import { createMeta, nodeMetaSymbol } from "@terraforge/core";
315
- import { snakeCase as snakeCase2 } from "change-case";
316
-
317
- // src/plugin/client.ts
318
- import { credentials, loadPackageDefinition } from "@grpc/grpc-js";
319
- import { fromJSON } from "@grpc/proto-loader";
320
- import { createDebugger } from "@terraforge/core";
321
-
322
- // src/plugin/diagnostic.ts
323
- var DiagnosticsError = class extends Error {
324
- diagnostics;
325
- constructor(diagnostics) {
326
- super(diagnostics[0]?.summary ?? "Diagnostic error");
327
- this.diagnostics = diagnostics;
328
- }
329
- };
330
- var throwDiagnosticError = (response) => {
331
- const diagnostics = response.diagnostics.map((item) => ({
332
- severity: item.severity === 1 ? "error" : "warning",
333
- summary: item.summary,
334
- detail: item.detail,
335
- path: item.attribute?.steps.map((step) => step.attributeName)
336
- }));
337
- return new DiagnosticsError(diagnostics);
338
- };
339
-
340
- // src/plugin/protocol/tfplugin5.ts
341
- var tfplugin5_default = {
342
- options: { syntax: "proto3" },
343
- nested: {
344
- tfplugin5: {
345
- nested: {
346
- DynamicValue: { fields: { msgpack: { type: "bytes", id: 1 }, json: { type: "bytes", id: 2 } } },
347
- Diagnostic: {
348
- fields: {
349
- severity: { type: "Severity", id: 1 },
350
- summary: { type: "string", id: 2 },
351
- detail: { type: "string", id: 3 },
352
- attribute: { type: "AttributePath", id: 4 }
353
- },
354
- nested: { Severity: { values: { INVALID: 0, ERROR: 1, WARNING: 2 } } }
355
- },
356
- AttributePath: {
357
- fields: { steps: { rule: "repeated", type: "Step", id: 1 } },
358
- nested: {
359
- Step: {
360
- oneofs: { selector: { oneof: ["attributeName", "elementKeyString", "elementKeyInt"] } },
361
- fields: {
362
- attributeName: { type: "string", id: 1 },
363
- elementKeyString: { type: "string", id: 2 },
364
- elementKeyInt: { type: "int64", id: 3 }
365
- }
366
- }
367
- }
368
- },
369
- Stop: {
370
- fields: {},
371
- nested: { Request: { fields: {} }, Response: { fields: { Error: { type: "string", id: 1 } } } }
372
- },
373
- RawState: {
374
- fields: { json: { type: "bytes", id: 1 }, flatmap: { keyType: "string", type: "string", id: 2 } }
375
- },
376
- Schema: {
377
- fields: { version: { type: "int64", id: 1 }, block: { type: "Block", id: 2 } },
378
- nested: {
379
- Block: {
380
- fields: {
381
- version: { type: "int64", id: 1 },
382
- attributes: { rule: "repeated", type: "Attribute", id: 2 },
383
- blockTypes: { rule: "repeated", type: "NestedBlock", id: 3 }
384
- }
385
- },
386
- Attribute: {
387
- fields: {
388
- name: { type: "string", id: 1 },
389
- type: { type: "bytes", id: 2 },
390
- description: { type: "string", id: 3 },
391
- required: { type: "bool", id: 4 },
392
- optional: { type: "bool", id: 5 },
393
- computed: { type: "bool", id: 6 },
394
- sensitive: { type: "bool", id: 7 }
395
- }
396
- },
397
- NestedBlock: {
398
- fields: {
399
- typeName: { type: "string", id: 1 },
400
- block: { type: "Block", id: 2 },
401
- nesting: { type: "NestingMode", id: 3 },
402
- minItems: { type: "int64", id: 4 },
403
- maxItems: { type: "int64", id: 5 }
404
- },
405
- nested: {
406
- NestingMode: { values: { INVALID: 0, SINGLE: 1, LIST: 2, SET: 3, MAP: 4, GROUP: 5 } }
407
- }
408
- }
409
- }
410
- },
411
- Provider: {
412
- methods: {
413
- GetSchema: {
414
- requestType: "GetProviderSchema.Request",
415
- responseType: "GetProviderSchema.Response"
416
- },
417
- PrepareProviderConfig: {
418
- requestType: "PrepareProviderConfig.Request",
419
- responseType: "PrepareProviderConfig.Response"
420
- },
421
- ValidateResourceTypeConfig: {
422
- requestType: "ValidateResourceTypeConfig.Request",
423
- responseType: "ValidateResourceTypeConfig.Response"
424
- },
425
- ValidateDataSourceConfig: {
426
- requestType: "ValidateDataSourceConfig.Request",
427
- responseType: "ValidateDataSourceConfig.Response"
428
- },
429
- UpgradeResourceState: {
430
- requestType: "UpgradeResourceState.Request",
431
- responseType: "UpgradeResourceState.Response"
432
- },
433
- Configure: { requestType: "Configure.Request", responseType: "Configure.Response" },
434
- ReadResource: { requestType: "ReadResource.Request", responseType: "ReadResource.Response" },
435
- PlanResourceChange: {
436
- requestType: "PlanResourceChange.Request",
437
- responseType: "PlanResourceChange.Response"
438
- },
439
- ApplyResourceChange: {
440
- requestType: "ApplyResourceChange.Request",
441
- responseType: "ApplyResourceChange.Response"
442
- },
443
- ImportResourceState: {
444
- requestType: "ImportResourceState.Request",
445
- responseType: "ImportResourceState.Response"
446
- },
447
- ReadDataSource: {
448
- requestType: "ReadDataSource.Request",
449
- responseType: "ReadDataSource.Response"
450
- },
451
- Stop: { requestType: "Stop.Request", responseType: "Stop.Response" }
452
- }
453
- },
454
- GetProviderSchema: {
455
- fields: {},
456
- nested: {
457
- Request: { fields: {} },
458
- Response: {
459
- fields: {
460
- provider: { type: "Schema", id: 1 },
461
- resourceSchemas: { keyType: "string", type: "Schema", id: 2 },
462
- dataSourceSchemas: { keyType: "string", type: "Schema", id: 3 },
463
- diagnostics: { rule: "repeated", type: "Diagnostic", id: 4 }
464
- }
465
- }
466
- }
467
- },
468
- PrepareProviderConfig: {
469
- fields: {},
470
- nested: {
471
- Request: { fields: { config: { type: "DynamicValue", id: 1 } } },
472
- Response: {
473
- fields: {
474
- preparedConfig: { type: "DynamicValue", id: 1 },
475
- diagnostics: { rule: "repeated", type: "Diagnostic", id: 2 }
476
- }
477
- }
478
- }
479
- },
480
- UpgradeResourceState: {
481
- fields: {},
482
- nested: {
483
- Request: {
484
- fields: {
485
- typeName: { type: "string", id: 1 },
486
- version: { type: "int64", id: 2 },
487
- rawState: { type: "RawState", id: 3 }
488
- }
489
- },
490
- Response: {
491
- fields: {
492
- upgradedState: { type: "DynamicValue", id: 1 },
493
- diagnostics: { rule: "repeated", type: "Diagnostic", id: 2 }
494
- }
495
- }
496
- }
497
- },
498
- ValidateResourceTypeConfig: {
499
- fields: {},
500
- nested: {
501
- Request: {
502
- fields: { typeName: { type: "string", id: 1 }, config: { type: "DynamicValue", id: 2 } }
503
- },
504
- Response: { fields: { diagnostics: { rule: "repeated", type: "Diagnostic", id: 1 } } }
505
- }
506
- },
507
- ValidateDataSourceConfig: {
508
- fields: {},
509
- nested: {
510
- Request: {
511
- fields: { typeName: { type: "string", id: 1 }, config: { type: "DynamicValue", id: 2 } }
512
- },
513
- Response: { fields: { diagnostics: { rule: "repeated", type: "Diagnostic", id: 1 } } }
514
- }
515
- },
516
- Configure: {
517
- fields: {},
518
- nested: {
519
- Request: {
520
- fields: {
521
- terraformVersion: { type: "string", id: 1 },
522
- config: { type: "DynamicValue", id: 2 }
523
- }
524
- },
525
- Response: { fields: { diagnostics: { rule: "repeated", type: "Diagnostic", id: 1 } } }
526
- }
527
- },
528
- ReadResource: {
529
- fields: {},
530
- nested: {
531
- Request: {
532
- fields: {
533
- typeName: { type: "string", id: 1 },
534
- currentState: { type: "DynamicValue", id: 2 },
535
- private: { type: "bytes", id: 3 }
536
- }
537
- },
538
- Response: {
539
- fields: {
540
- newState: { type: "DynamicValue", id: 1 },
541
- diagnostics: { rule: "repeated", type: "Diagnostic", id: 2 },
542
- private: { type: "bytes", id: 3 }
543
- }
544
- }
545
- }
546
- },
547
- PlanResourceChange: {
548
- fields: {},
549
- nested: {
550
- Request: {
551
- fields: {
552
- typeName: { type: "string", id: 1 },
553
- priorState: { type: "DynamicValue", id: 2 },
554
- proposedNewState: { type: "DynamicValue", id: 3 },
555
- config: { type: "DynamicValue", id: 4 },
556
- priorPrivate: { type: "bytes", id: 5 }
557
- }
558
- },
559
- Response: {
560
- fields: {
561
- plannedState: { type: "DynamicValue", id: 1 },
562
- requiresReplace: { rule: "repeated", type: "AttributePath", id: 2 },
563
- plannedPrivate: { type: "bytes", id: 3 },
564
- diagnostics: { rule: "repeated", type: "Diagnostic", id: 4 },
565
- legacyTypeSystem: { type: "bool", id: 5 }
566
- }
567
- }
568
- }
569
- },
570
- ApplyResourceChange: {
571
- fields: {},
572
- nested: {
573
- Request: {
574
- fields: {
575
- typeName: { type: "string", id: 1 },
576
- priorState: { type: "DynamicValue", id: 2 },
577
- plannedState: { type: "DynamicValue", id: 3 },
578
- config: { type: "DynamicValue", id: 4 },
579
- plannedPrivate: { type: "bytes", id: 5 }
580
- }
581
- },
582
- Response: {
583
- fields: {
584
- newState: { type: "DynamicValue", id: 1 },
585
- private: { type: "bytes", id: 2 },
586
- diagnostics: { rule: "repeated", type: "Diagnostic", id: 3 },
587
- legacyTypeSystem: { type: "bool", id: 4 }
588
- }
589
- }
590
- }
591
- },
592
- ImportResourceState: {
593
- fields: {},
594
- nested: {
595
- Request: { fields: { typeName: { type: "string", id: 1 }, id: { type: "string", id: 2 } } },
596
- ImportedResource: {
597
- fields: {
598
- typeName: { type: "string", id: 1 },
599
- state: { type: "DynamicValue", id: 2 },
600
- private: { type: "bytes", id: 3 }
601
- }
602
- },
603
- Response: {
604
- fields: {
605
- importedResources: { rule: "repeated", type: "ImportedResource", id: 1 },
606
- diagnostics: { rule: "repeated", type: "Diagnostic", id: 2 }
607
- }
608
- }
609
- }
610
- },
611
- ReadDataSource: {
612
- fields: {},
613
- nested: {
614
- Request: {
615
- fields: { typeName: { type: "string", id: 1 }, config: { type: "DynamicValue", id: 2 } }
616
- },
617
- Response: {
618
- fields: {
619
- state: { type: "DynamicValue", id: 1 },
620
- diagnostics: { rule: "repeated", type: "Diagnostic", id: 2 }
621
- }
622
- }
623
- }
624
- },
625
- Provisioner: {
626
- methods: {
627
- GetSchema: {
628
- requestType: "GetProvisionerSchema.Request",
629
- responseType: "GetProvisionerSchema.Response"
630
- },
631
- ValidateProvisionerConfig: {
632
- requestType: "ValidateProvisionerConfig.Request",
633
- responseType: "ValidateProvisionerConfig.Response"
634
- },
635
- ProvisionResource: {
636
- requestType: "ProvisionResource.Request",
637
- responseType: "ProvisionResource.Response",
638
- responseStream: true
639
- },
640
- Stop: { requestType: "Stop.Request", responseType: "Stop.Response" }
641
- }
642
- },
643
- GetProvisionerSchema: {
644
- fields: {},
645
- nested: {
646
- Request: { fields: {} },
647
- Response: {
648
- fields: {
649
- provisioner: { type: "Schema", id: 1 },
650
- diagnostics: { rule: "repeated", type: "Diagnostic", id: 2 }
651
- }
652
- }
653
- }
654
- },
655
- ValidateProvisionerConfig: {
656
- fields: {},
657
- nested: {
658
- Request: { fields: { config: { type: "DynamicValue", id: 1 } } },
659
- Response: { fields: { diagnostics: { rule: "repeated", type: "Diagnostic", id: 1 } } }
660
- }
661
- },
662
- ProvisionResource: {
663
- fields: {},
664
- nested: {
665
- Request: {
666
- fields: {
667
- config: { type: "DynamicValue", id: 1 },
668
- connection: { type: "DynamicValue", id: 2 }
669
- }
670
- },
671
- Response: {
672
- fields: {
673
- output: { type: "string", id: 1 },
674
- diagnostics: { rule: "repeated", type: "Diagnostic", id: 2 }
675
- }
676
- }
677
- }
678
- }
679
- }
680
- }
681
- }
682
- };
683
-
684
- // src/plugin/protocol/tfplugin6.ts
685
- var tfplugin6_default = {
686
- options: { syntax: "proto3", go_package: "github.com/hashicorp/terraform/internal/tfplugin6" },
687
- nested: {
688
- tfplugin6: {
689
- nested: {
690
- DynamicValue: { fields: { msgpack: { type: "bytes", id: 1 }, json: { type: "bytes", id: 2 } } },
691
- Diagnostic: {
692
- fields: {
693
- severity: { type: "Severity", id: 1 },
694
- summary: { type: "string", id: 2 },
695
- detail: { type: "string", id: 3 },
696
- attribute: { type: "AttributePath", id: 4 }
697
- },
698
- nested: { Severity: { values: { INVALID: 0, ERROR: 1, WARNING: 2 } } }
699
- },
700
- AttributePath: {
701
- fields: { steps: { rule: "repeated", type: "Step", id: 1 } },
702
- nested: {
703
- Step: {
704
- oneofs: { selector: { oneof: ["attributeName", "elementKeyString", "elementKeyInt"] } },
705
- fields: {
706
- attributeName: { type: "string", id: 1 },
707
- elementKeyString: { type: "string", id: 2 },
708
- elementKeyInt: { type: "int64", id: 3 }
709
- }
710
- }
711
- }
712
- },
713
- StopProvider: {
714
- fields: {},
715
- nested: { Request: { fields: {} }, Response: { fields: { Error: { type: "string", id: 1 } } } }
716
- },
717
- RawState: {
718
- fields: { json: { type: "bytes", id: 1 }, flatmap: { keyType: "string", type: "string", id: 2 } }
719
- },
720
- StringKind: { values: { PLAIN: 0, MARKDOWN: 1 } },
721
- Schema: {
722
- fields: { version: { type: "int64", id: 1 }, block: { type: "Block", id: 2 } },
723
- nested: {
724
- Block: {
725
- fields: {
726
- version: { type: "int64", id: 1 },
727
- attributes: { rule: "repeated", type: "Attribute", id: 2 },
728
- blockTypes: { rule: "repeated", type: "NestedBlock", id: 3 },
729
- description: { type: "string", id: 4 },
730
- descriptionKind: { type: "StringKind", id: 5 },
731
- deprecated: { type: "bool", id: 6 }
732
- }
733
- },
734
- Attribute: {
735
- fields: {
736
- name: { type: "string", id: 1 },
737
- type: { type: "bytes", id: 2 },
738
- nestedType: { type: "Object", id: 10 },
739
- description: { type: "string", id: 3 },
740
- required: { type: "bool", id: 4 },
741
- optional: { type: "bool", id: 5 },
742
- computed: { type: "bool", id: 6 },
743
- sensitive: { type: "bool", id: 7 },
744
- descriptionKind: { type: "StringKind", id: 8 },
745
- deprecated: { type: "bool", id: 9 }
746
- }
747
- },
748
- NestedBlock: {
749
- fields: {
750
- typeName: { type: "string", id: 1 },
751
- block: { type: "Block", id: 2 },
752
- nesting: { type: "NestingMode", id: 3 },
753
- minItems: { type: "int64", id: 4 },
754
- maxItems: { type: "int64", id: 5 }
755
- },
756
- nested: {
757
- NestingMode: { values: { INVALID: 0, SINGLE: 1, LIST: 2, SET: 3, MAP: 4, GROUP: 5 } }
758
- }
759
- },
760
- Object: {
761
- fields: {
762
- attributes: { rule: "repeated", type: "Attribute", id: 1 },
763
- nesting: { type: "NestingMode", id: 3 },
764
- minItems: { type: "int64", id: 4 },
765
- maxItems: { type: "int64", id: 5 }
766
- },
767
- nested: { NestingMode: { values: { INVALID: 0, SINGLE: 1, LIST: 2, SET: 3, MAP: 4 } } }
768
- }
769
- }
770
- },
771
- Provider: {
772
- methods: {
773
- GetProviderSchema: {
774
- requestType: "GetProviderSchema.Request",
775
- responseType: "GetProviderSchema.Response"
776
- },
777
- ValidateProviderConfig: {
778
- requestType: "ValidateProviderConfig.Request",
779
- responseType: "ValidateProviderConfig.Response"
780
- },
781
- ValidateResourceConfig: {
782
- requestType: "ValidateResourceConfig.Request",
783
- responseType: "ValidateResourceConfig.Response"
784
- },
785
- ValidateDataResourceConfig: {
786
- requestType: "ValidateDataResourceConfig.Request",
787
- responseType: "ValidateDataResourceConfig.Response"
788
- },
789
- UpgradeResourceState: {
790
- requestType: "UpgradeResourceState.Request",
791
- responseType: "UpgradeResourceState.Response"
792
- },
793
- ConfigureProvider: {
794
- requestType: "ConfigureProvider.Request",
795
- responseType: "ConfigureProvider.Response"
796
- },
797
- ReadResource: { requestType: "ReadResource.Request", responseType: "ReadResource.Response" },
798
- PlanResourceChange: {
799
- requestType: "PlanResourceChange.Request",
800
- responseType: "PlanResourceChange.Response"
801
- },
802
- ApplyResourceChange: {
803
- requestType: "ApplyResourceChange.Request",
804
- responseType: "ApplyResourceChange.Response"
805
- },
806
- ImportResourceState: {
807
- requestType: "ImportResourceState.Request",
808
- responseType: "ImportResourceState.Response"
809
- },
810
- ReadDataSource: {
811
- requestType: "ReadDataSource.Request",
812
- responseType: "ReadDataSource.Response"
813
- },
814
- StopProvider: { requestType: "StopProvider.Request", responseType: "StopProvider.Response" }
815
- }
816
- },
817
- GetProviderSchema: {
818
- fields: {},
819
- nested: {
820
- Request: { fields: {} },
821
- Response: {
822
- fields: {
823
- provider: { type: "Schema", id: 1 },
824
- resourceSchemas: { keyType: "string", type: "Schema", id: 2 },
825
- dataSourceSchemas: { keyType: "string", type: "Schema", id: 3 },
826
- diagnostics: { rule: "repeated", type: "Diagnostic", id: 4 },
827
- providerMeta: { type: "Schema", id: 5 }
828
- }
829
- }
830
- }
831
- },
832
- ValidateProviderConfig: {
833
- fields: {},
834
- nested: {
835
- Request: { fields: { config: { type: "DynamicValue", id: 1 } } },
836
- Response: { fields: { diagnostics: { rule: "repeated", type: "Diagnostic", id: 2 } } }
837
- }
838
- },
839
- UpgradeResourceState: {
840
- fields: {},
841
- nested: {
842
- Request: {
843
- fields: {
844
- typeName: { type: "string", id: 1 },
845
- version: { type: "int64", id: 2 },
846
- rawState: { type: "RawState", id: 3 }
847
- }
848
- },
849
- Response: {
850
- fields: {
851
- upgradedState: { type: "DynamicValue", id: 1 },
852
- diagnostics: { rule: "repeated", type: "Diagnostic", id: 2 }
853
- }
854
- }
855
- }
856
- },
857
- ValidateResourceConfig: {
858
- fields: {},
859
- nested: {
860
- Request: {
861
- fields: { typeName: { type: "string", id: 1 }, config: { type: "DynamicValue", id: 2 } }
862
- },
863
- Response: { fields: { diagnostics: { rule: "repeated", type: "Diagnostic", id: 1 } } }
864
- }
865
- },
866
- ValidateDataResourceConfig: {
867
- fields: {},
868
- nested: {
869
- Request: {
870
- fields: { typeName: { type: "string", id: 1 }, config: { type: "DynamicValue", id: 2 } }
871
- },
872
- Response: { fields: { diagnostics: { rule: "repeated", type: "Diagnostic", id: 1 } } }
873
- }
874
- },
875
- ConfigureProvider: {
876
- fields: {},
877
- nested: {
878
- Request: {
879
- fields: {
880
- terraformVersion: { type: "string", id: 1 },
881
- config: { type: "DynamicValue", id: 2 }
882
- }
883
- },
884
- Response: { fields: { diagnostics: { rule: "repeated", type: "Diagnostic", id: 1 } } }
885
- }
886
- },
887
- ReadResource: {
888
- fields: {},
889
- nested: {
890
- Request: {
891
- fields: {
892
- typeName: { type: "string", id: 1 },
893
- currentState: { type: "DynamicValue", id: 2 },
894
- private: { type: "bytes", id: 3 },
895
- providerMeta: { type: "DynamicValue", id: 4 }
896
- }
897
- },
898
- Response: {
899
- fields: {
900
- newState: { type: "DynamicValue", id: 1 },
901
- diagnostics: { rule: "repeated", type: "Diagnostic", id: 2 },
902
- private: { type: "bytes", id: 3 }
903
- }
904
- }
905
- }
906
- },
907
- PlanResourceChange: {
908
- fields: {},
909
- nested: {
910
- Request: {
911
- fields: {
912
- typeName: { type: "string", id: 1 },
913
- priorState: { type: "DynamicValue", id: 2 },
914
- proposedNewState: { type: "DynamicValue", id: 3 },
915
- config: { type: "DynamicValue", id: 4 },
916
- priorPrivate: { type: "bytes", id: 5 },
917
- providerMeta: { type: "DynamicValue", id: 6 }
918
- }
919
- },
920
- Response: {
921
- fields: {
922
- plannedState: { type: "DynamicValue", id: 1 },
923
- requiresReplace: { rule: "repeated", type: "AttributePath", id: 2 },
924
- plannedPrivate: { type: "bytes", id: 3 },
925
- diagnostics: { rule: "repeated", type: "Diagnostic", id: 4 }
926
- }
927
- }
928
- }
929
- },
930
- ApplyResourceChange: {
931
- fields: {},
932
- nested: {
933
- Request: {
934
- fields: {
935
- typeName: { type: "string", id: 1 },
936
- priorState: { type: "DynamicValue", id: 2 },
937
- plannedState: { type: "DynamicValue", id: 3 },
938
- config: { type: "DynamicValue", id: 4 },
939
- plannedPrivate: { type: "bytes", id: 5 },
940
- providerMeta: { type: "DynamicValue", id: 6 }
941
- }
942
- },
943
- Response: {
944
- fields: {
945
- newState: { type: "DynamicValue", id: 1 },
946
- private: { type: "bytes", id: 2 },
947
- diagnostics: { rule: "repeated", type: "Diagnostic", id: 3 }
948
- }
949
- }
950
- }
951
- },
952
- ImportResourceState: {
953
- fields: {},
954
- nested: {
955
- Request: { fields: { typeName: { type: "string", id: 1 }, id: { type: "string", id: 2 } } },
956
- ImportedResource: {
957
- fields: {
958
- typeName: { type: "string", id: 1 },
959
- state: { type: "DynamicValue", id: 2 },
960
- private: { type: "bytes", id: 3 }
961
- }
962
- },
963
- Response: {
964
- fields: {
965
- importedResources: { rule: "repeated", type: "ImportedResource", id: 1 },
966
- diagnostics: { rule: "repeated", type: "Diagnostic", id: 2 }
967
- }
968
- }
969
- }
970
- },
971
- ReadDataSource: {
972
- fields: {},
973
- nested: {
974
- Request: {
975
- fields: {
976
- typeName: { type: "string", id: 1 },
977
- config: { type: "DynamicValue", id: 2 },
978
- providerMeta: { type: "DynamicValue", id: 3 }
979
- }
980
- },
981
- Response: {
982
- fields: {
983
- state: { type: "DynamicValue", id: 1 },
984
- diagnostics: { rule: "repeated", type: "Diagnostic", id: 2 }
985
- }
986
- }
987
- }
988
- }
989
- }
990
- }
991
- }
992
- };
993
-
994
- // src/plugin/client.ts
995
- var debug = createDebugger("Client");
996
- var protocols = {
997
- tfplugin5: tfplugin5_default,
998
- tfplugin6: tfplugin6_default
999
- };
1000
- var createPluginClient = async (props) => {
1001
- const proto = protocols[props.protocol.split(".").at(0) ?? ""];
1002
- if (!proto) {
1003
- throw new Error(`We don't have support for the ${props.protocol} protocol`);
1004
- }
1005
- const pack2 = fromJSON(proto);
1006
- const grpc = loadPackageDefinition(pack2);
1007
- const client = new grpc["tfplugin" + props.version].Provider(
1008
- `unix://${props.endpoint}`,
1009
- credentials.createInsecure(),
1010
- {
1011
- "grpc.max_receive_message_length": 100 * 1024 * 1024,
1012
- "grpc.max_send_message_length": 100 * 1024 * 1024
1013
- }
1014
- );
1015
- debug("init", props.protocol);
1016
- await new Promise((resolve, reject) => {
1017
- const deadline = /* @__PURE__ */ new Date();
1018
- deadline.setSeconds(deadline.getSeconds() + 10);
1019
- client.waitForReady(deadline, (error) => {
1020
- if (error) {
1021
- reject(error);
1022
- } else {
1023
- resolve();
1024
- }
1025
- });
1026
- });
1027
- debug("connected");
1028
- return {
1029
- call(method, payload) {
1030
- return new Promise((resolve, reject) => {
1031
- const fn = client[method];
1032
- debug("call", method);
1033
- if (!fn) {
1034
- reject(new Error(`Unknown method call: ${method}`));
1035
- return;
1036
- }
1037
- fn.call(client, payload, (error, response) => {
1038
- if (error) {
1039
- debug("failed", error);
1040
- reject(error);
1041
- } else if (response.diagnostics) {
1042
- debug("failed", response.diagnostics);
1043
- reject(throwDiagnosticError(response));
1044
- } else {
1045
- resolve(response);
1046
- }
1047
- });
1048
- });
1049
- }
1050
- };
1051
- };
1052
-
1053
- // src/plugin/download.ts
1054
- import { createDebugger as createDebugger2 } from "@terraforge/core";
1055
- import jszip from "jszip";
1056
- import { mkdir, rm, stat, writeFile } from "fs/promises";
1057
- import { homedir } from "os";
1058
- import { dirname, join } from "path";
1059
-
1060
- // src/plugin/registry.ts
1061
- import { arch, platform } from "os";
1062
- import { compare } from "semver";
1063
- var baseUrl = "https://registry.terraform.io/v1/providers";
1064
- var getProviderVersions = async (org, type) => {
1065
- const resp = await fetch(`${baseUrl}/${org}/${type}/versions`);
1066
- const data = await resp.json();
1067
- const versions = data.versions;
1068
- const os = getOS();
1069
- const ar = getArchitecture();
1070
- const supported = versions.filter((v) => {
1071
- return !!v.platforms.find((p) => p.os === os && p.arch === ar);
1072
- });
1073
- const sorted = supported.sort((a, b) => compare(a.version, b.version));
1074
- const latest = sorted.at(-1);
1075
- if (!latest) {
1076
- throw new Error("Version is unsupported for your platform.");
1077
- }
1078
- return {
1079
- versions,
1080
- supported,
1081
- latest: latest.version
1082
- };
1083
- };
1084
- var getProviderDownloadUrl = async (org, type, version) => {
1085
- const url = [
1086
- //
1087
- baseUrl,
1088
- org,
1089
- type,
1090
- version,
1091
- "download",
1092
- getOS(),
1093
- getArchitecture()
1094
- ].join("/");
1095
- const response = await fetch(url);
1096
- const result = await response.json();
1097
- return {
1098
- url: result.download_url,
1099
- shasum: result.shasum,
1100
- protocols: result.protocols
1101
- };
1102
- };
1103
- var getOS = () => {
1104
- const os = platform();
1105
- switch (os) {
1106
- case "linux":
1107
- return "linux";
1108
- case "win32":
1109
- return "windows";
1110
- case "darwin":
1111
- return "darwin";
1112
- case "freebsd":
1113
- return "freebsd";
1114
- case "openbsd":
1115
- return "openbsd";
1116
- }
1117
- throw new Error(`Unsupported OS platform: ${os}`);
1118
- };
1119
- var getArchitecture = () => {
1120
- const ar = arch();
1121
- switch (ar) {
1122
- case "arm":
1123
- return "arm";
1124
- case "arm64":
1125
- return "arm64";
1126
- case "x64":
1127
- return "amd64";
1128
- case "ia32":
1129
- return "386";
1130
- }
1131
- throw new Error(`Unsupported architecture: ${ar}`);
1132
- };
1133
-
1134
- // src/plugin/download.ts
1135
- var exists = async (file) => {
1136
- try {
1137
- await stat(file);
1138
- } catch (error) {
1139
- return false;
1140
- }
1141
- return true;
1142
- };
1143
- var debug2 = createDebugger2("Downloader");
1144
- var installPath = join(homedir(), ".terraforge", "plugins");
1145
- var getInstallPath = (props) => {
1146
- const dir = props.location ?? installPath;
1147
- const file = join(dir, `${props.org}-${props.type}-${props.version}`);
1148
- return file;
1149
- };
1150
- var isPluginInstalled = (props) => {
1151
- return exists(getInstallPath(props));
1152
- };
1153
- var deletePlugin = async (props) => {
1154
- const file = getInstallPath(props);
1155
- const isAlreadyInstalled = await isPluginInstalled(props);
1156
- if (isAlreadyInstalled) {
1157
- debug2(props.type, "deleting...");
1158
- await rm(file);
1159
- debug2(props.type, "deleted");
1160
- } else {
1161
- debug2(props.type, "not installed");
1162
- }
1163
- };
1164
- var downloadPlugin = async (props) => {
1165
- if (props.version === "latest") {
1166
- const { latest } = await getProviderVersions(props.org, props.type);
1167
- props.version = latest;
1168
- }
1169
- const file = getInstallPath(props);
1170
- const isAlreadyInstalled = await isPluginInstalled(props);
1171
- if (!isAlreadyInstalled) {
1172
- debug2(props.type, "downloading...");
1173
- const info = await getProviderDownloadUrl(props.org, props.type, props.version);
1174
- const res = await fetch(info.url);
1175
- const buf = await res.bytes();
1176
- const zip = await jszip.loadAsync(buf);
1177
- const zipped = zip.filter((file2) => file2.startsWith("terraform-provider")).at(0);
1178
- if (!zipped) {
1179
- throw new Error(`Can't find the provider inside the downloaded zip file.`);
1180
- }
1181
- const binary = await zipped.async("nodebuffer");
1182
- debug2(props.type, "done");
1183
- await mkdir(dirname(file), { recursive: true });
1184
- await writeFile(file, binary, {
1185
- mode: 509
1186
- });
1187
- } else {
1188
- debug2(props.type, "already downloaded");
1189
- }
1190
- return {
1191
- file,
1192
- version: props.version
1193
- };
1194
- };
1195
-
1196
- // src/plugin/server.ts
1197
- import { createDebugger as createDebugger3 } from "@terraforge/core";
1198
- import { spawn } from "child_process";
1199
- var debug3 = createDebugger3("Server");
1200
- var createPluginServer = (props) => {
1201
- return new Promise((resolve, reject) => {
1202
- debug3("init");
1203
- const process = spawn(`${props.file}`, ["-debug"]);
1204
- process.stderr.on("data", (data) => {
1205
- if (props.debug) {
1206
- const message = data.toString("utf8");
1207
- console.log(message);
1208
- }
1209
- });
1210
- process.stdout.once("data", (data) => {
1211
- try {
1212
- const message = data.toString("utf8");
1213
- const matches = message.match(/TF_REATTACH_PROVIDERS\=\'(.*)\'/);
1214
- if (matches && matches.length > 0) {
1215
- const match = matches[0];
1216
- const json = match.slice(23, -1);
1217
- const data2 = JSON.parse(json);
1218
- const entries = Object.values(data2);
1219
- if (entries.length > 0) {
1220
- const entry = entries[0];
1221
- const version = entry.ProtocolVersion;
1222
- const endpoint = entry.Addr.String;
1223
- debug3("started", endpoint);
1224
- resolve({
1225
- kill() {
1226
- process.kill();
1227
- },
1228
- protocol: "tfplugin" + version.toFixed(1),
1229
- version,
1230
- endpoint
1231
- });
1232
- return;
1233
- }
1234
- }
1235
- } catch (error) {
1236
- }
1237
- debug3("failed");
1238
- reject(new Error("Failed to start the plugin"));
1239
- });
1240
- });
1241
- };
1242
-
1243
- // src/plugin/schema.ts
1244
- var NestingMode = {
1245
- INVALID: 0,
1246
- SINGLE: 1,
1247
- LIST: 2,
1248
- SET: 3,
1249
- MAP: 4,
1250
- GROUP: 5
1251
- };
1252
- var parseResourceSchema = (schemas) => {
1253
- const props = {};
1254
- for (const [name, schema] of Object.entries(schemas)) {
1255
- if (schema.block) {
1256
- const block = parseBlock(schema.block);
1257
- props[name] = {
1258
- ...block,
1259
- version: block.version ?? schema.version
1260
- };
1261
- }
1262
- }
1263
- return props;
1264
- };
1265
- var parseProviderSchema = (schema) => {
1266
- if (schema.block) {
1267
- const block = parseBlock(schema.block);
1268
- return {
1269
- ...block,
1270
- version: block.version ?? schema.version
1271
- };
1272
- }
1273
- throw new Error("Invalid block");
1274
- };
1275
- var parseBlock = (block) => {
1276
- const properties = {};
1277
- for (const entry of block.attributes ?? []) {
1278
- properties[entry.name] = parseAttribute(entry);
1279
- }
1280
- for (const entry of block.blockTypes ?? []) {
1281
- properties[entry.typeName] = parseNestedBlock(entry);
1282
- }
1283
- if (block.deprecated) {
1284
- console.warn("Deprecated block");
1285
- }
1286
- return {
1287
- type: "object",
1288
- version: block.version,
1289
- description: block.description,
1290
- // deprecated: block.deprecated,
1291
- properties
1292
- };
1293
- };
1294
- var parseNestedBlock = (block) => {
1295
- const type = parseNestedBlockType(block);
1296
- const item = parseBlock(block.block);
1297
- const prop = {
1298
- optional: true,
1299
- required: false,
1300
- computed: false
1301
- };
1302
- if (type === "array" || type === "record") {
1303
- return {
1304
- ...prop,
1305
- type,
1306
- item
1307
- };
1308
- }
1309
- if (type === "array-object") {
1310
- return {
1311
- ...prop,
1312
- ...item,
1313
- type
1314
- };
1315
- }
1316
- return {
1317
- ...prop,
1318
- ...item
1319
- };
1320
- };
1321
- var parseNestedBlockType = (block) => {
1322
- if (block.nesting === NestingMode.SET) {
1323
- return "array";
1324
- }
1325
- if (block.nesting === NestingMode.LIST) {
1326
- if (block.maxItems?.eq(1)) {
1327
- return "array-object";
1328
- }
1329
- return "array";
1330
- }
1331
- if (block.nesting === NestingMode.MAP) {
1332
- return "record";
1333
- }
1334
- if (block.nesting === NestingMode.GROUP) {
1335
- return "object";
1336
- }
1337
- if (block.nesting === NestingMode.SINGLE) {
1338
- return "object";
1339
- }
1340
- throw new Error(`Invalid nested block type ${block.nesting}`);
1341
- };
1342
- var parseAttribute = (attr) => {
1343
- const prop = {
1344
- description: attr.description,
1345
- required: attr.required,
1346
- optional: attr.optional,
1347
- computed: attr.computed,
1348
- deprecated: attr.deprecated,
1349
- sensitive: attr.sensitive
1350
- };
1351
- if (attr.type) {
1352
- const json = JSON.parse(attr.type.toString("utf8"));
1353
- return {
1354
- ...prop,
1355
- ...parseAttributeType(json)
1356
- };
1357
- }
1358
- if (attr.nestedType) {
1359
- return {
1360
- ...prop,
1361
- ...parseBlock(attr.nestedType)
1362
- // properties: parseBlock(attr.nestedType).properties,
1363
- };
1364
- }
1365
- throw new Error("Empty attr");
1366
- };
1367
- var parseAttributeType = (item) => {
1368
- if (Array.isArray(item)) {
1369
- const type2 = parseType(item[0]);
1370
- if (type2 === "array" || type2 === "record" && item) {
1371
- const record = item[1];
1372
- return {
1373
- type: type2,
1374
- item: parseAttributeType(record)
1375
- };
1376
- }
1377
- if (type2 === "object") {
1378
- const object = item[1];
1379
- const properties = {};
1380
- for (const [name, prop] of Object.entries(object)) {
1381
- properties[name] = parseAttributeType(prop);
1382
- }
1383
- return {
1384
- type: type2,
1385
- properties
1386
- };
1387
- }
1388
- throw new Error("Invalid attribute type");
1389
- }
1390
- const type = parseType(item);
1391
- if (isLeafType(type)) {
1392
- return {
1393
- type
1394
- };
1395
- }
1396
- throw new Error(`Invalid attribute type`);
1397
- };
1398
- var isLeafType = (type) => {
1399
- return ["string", "number", "boolean", "unknown"].includes(type);
1400
- };
1401
- var parseType = (type) => {
1402
- if (type === "string") {
1403
- return "string";
1404
- }
1405
- if (type === "number") {
1406
- return "number";
1407
- }
1408
- if (type === "bool") {
1409
- return "boolean";
1410
- }
1411
- if (["set", "list"].includes(type)) {
1412
- return "array";
1413
- }
1414
- if (type === "object") {
1415
- return "object";
1416
- }
1417
- if (type === "map") {
1418
- return "record";
1419
- }
1420
- if (type === "dynamic") {
1421
- return "unknown";
1422
- }
1423
- throw new Error(`Invalid type: ${type}`);
1424
- };
1425
-
1426
- // src/plugin/version/util.ts
1427
- import { camelCase as camelCase2, snakeCase } from "change-case";
1428
- import { pack, unpack } from "msgpackr";
1429
- var encodeDynamicValue = (value) => {
1430
- return {
1431
- msgpack: pack(value),
1432
- json: value
1433
- };
1434
- };
1435
- var decodeDynamicValue = (value) => {
1436
- return unpack(value.msgpack);
1437
- };
1438
- var getResourceSchema = (resources, type) => {
1439
- const resource = resources[type];
1440
- if (!resource) {
1441
- throw new Error(`Unknown resource type: ${type}`);
1442
- }
1443
- return resource;
1444
- };
1445
- var formatAttributePath = (state) => {
1446
- if (!state) {
1447
- return [];
1448
- }
1449
- return state.map((item) => {
1450
- if (!item.steps) {
1451
- throw new Error("AttributePath should always have steps");
1452
- }
1453
- return item.steps.map((attr) => {
1454
- if ("attributeName" in attr) {
1455
- return attr.attributeName;
1456
- }
1457
- if ("elementKeyString" in attr) {
1458
- return attr.elementKeyString;
1459
- }
1460
- if ("elementKeyInt" in attr) {
1461
- return attr.elementKeyInt;
1462
- }
1463
- throw new Error("AttributePath step should always have an element");
1464
- });
1465
- });
1466
- };
1467
- var IncorrectType = class extends TypeError {
1468
- constructor(type, path) {
1469
- super(`${path.join(".")} should be a ${type}`);
1470
- }
1471
- };
1472
- var formatInputState = (schema, state, includeSchemaFields = true, path = []) => {
1473
- if (state === null) {
1474
- return null;
1475
- }
1476
- if (typeof state === "undefined") {
1477
- return null;
1478
- }
1479
- if (schema.type === "unknown") {
1480
- return state;
1481
- }
1482
- if (schema.type === "string") {
1483
- if (typeof state === "string") {
1484
- return state;
1485
- }
1486
- throw new IncorrectType(schema.type, path);
1487
- }
1488
- if (schema.type === "number") {
1489
- if (typeof state === "number") {
1490
- return state;
1491
- }
1492
- throw new IncorrectType(schema.type, path);
1493
- }
1494
- if (schema.type === "boolean") {
1495
- if (typeof state === "boolean") {
1496
- return state;
1497
- }
1498
- throw new IncorrectType(schema.type, path);
1499
- }
1500
- if (schema.type === "array") {
1501
- if (Array.isArray(state)) {
1502
- return state.map((item, i) => formatInputState(schema.item, item, includeSchemaFields, [...path, i]));
1503
- }
1504
- throw new IncorrectType(schema.type, path);
1505
- }
1506
- if (schema.type === "record") {
1507
- if (typeof state === "object" && state !== null) {
1508
- const record = {};
1509
- for (const [key, value] of Object.entries(state)) {
1510
- record[key] = formatInputState(schema.item, value, includeSchemaFields, [...path, key]);
1511
- }
1512
- return record;
1513
- }
1514
- throw new IncorrectType(schema.type, path);
1515
- }
1516
- if (schema.type === "object" || schema.type === "array-object") {
1517
- if (typeof state === "object" && state !== null) {
1518
- const object = {};
1519
- if (includeSchemaFields) {
1520
- for (const [key, prop] of Object.entries(schema.properties)) {
1521
- const value = state[camelCase2(key)];
1522
- object[key] = formatInputState(prop, value, true, [...path, key]);
1523
- }
1524
- } else {
1525
- for (const [key, value] of Object.entries(state)) {
1526
- const prop = schema.properties[snakeCase(key)];
1527
- if (prop) {
1528
- object[key] = formatInputState(prop, value, false, [...path, key]);
1529
- }
1530
- }
1531
- }
1532
- if (schema.type === "array-object") {
1533
- return [object];
1534
- }
1535
- return object;
1536
- }
1537
- throw new IncorrectType(schema.type, path);
1538
- }
1539
- throw new Error(`Unknown schema type: ${schema.type}`);
1540
- };
1541
- var formatOutputState = (schema, state, path = []) => {
1542
- if (state === null) {
1543
- return void 0;
1544
- }
1545
- if (schema.type === "array") {
1546
- if (Array.isArray(state)) {
1547
- return state.map((item, i) => formatOutputState(schema.item, item, [...path, i]));
1548
- }
1549
- throw new IncorrectType(schema.type, path);
1550
- }
1551
- if (schema.type === "record") {
1552
- if (typeof state === "object" && state !== null) {
1553
- const record = {};
1554
- for (const [key, value] of Object.entries(state)) {
1555
- record[key] = formatOutputState(schema.item, value, [...path, key]);
1556
- }
1557
- return record;
1558
- }
1559
- throw new IncorrectType(schema.type, path);
1560
- }
1561
- if (schema.type === "object") {
1562
- if (typeof state === "object" && state !== null) {
1563
- const object = {};
1564
- for (const [key, prop] of Object.entries(schema.properties)) {
1565
- const value = state[key];
1566
- object[camelCase2(key)] = formatOutputState(prop, value, [...path, key]);
1567
- }
1568
- return object;
1569
- }
1570
- throw new IncorrectType(schema.type, path);
1571
- }
1572
- if (schema.type === "array-object") {
1573
- if (Array.isArray(state)) {
1574
- if (state.length === 1) {
1575
- const object = {};
1576
- for (const [key, prop] of Object.entries(schema.properties)) {
1577
- const value = state[0][key];
1578
- object[camelCase2(key)] = formatOutputState(prop, value, [...path, key]);
1579
- }
1580
- return object;
1581
- } else {
1582
- return void 0;
1583
- }
1584
- }
1585
- throw new IncorrectType(schema.type, path);
1586
- }
1587
- return state;
1588
- };
1589
-
1590
- // src/plugin/version/5.ts
1591
- var createPlugin5 = async ({
1592
- server,
1593
- client
1594
- }) => {
1595
- const schema = await client.call("GetSchema");
1596
- const provider = parseProviderSchema(schema.provider);
1597
- const resources = parseResourceSchema(schema.resourceSchemas);
1598
- const dataSources = parseResourceSchema(schema.dataSourceSchemas);
1599
- return {
1600
- schema() {
1601
- return {
1602
- provider,
1603
- resources,
1604
- dataSources
1605
- };
1606
- },
1607
- async stop() {
1608
- await client.call("Stop");
1609
- server.kill();
1610
- },
1611
- async configure(config) {
1612
- const prepared = await client.call("PrepareProviderConfig", {
1613
- config: encodeDynamicValue(formatInputState(provider, config))
1614
- });
1615
- await client.call("Configure", {
1616
- config: prepared.preparedConfig
1617
- });
1618
- },
1619
- async readResource(type, state) {
1620
- const schema2 = getResourceSchema(resources, type);
1621
- const read = await client.call("ReadResource", {
1622
- typeName: type,
1623
- currentState: encodeDynamicValue(formatInputState(schema2, state))
1624
- });
1625
- return formatOutputState(schema2, decodeDynamicValue(read.newState));
1626
- },
1627
- async readDataSource(type, state) {
1628
- const schema2 = getResourceSchema(dataSources, type);
1629
- const read = await client.call("ReadDataSource", {
1630
- typeName: type,
1631
- config: encodeDynamicValue(formatInputState(schema2, state))
1632
- });
1633
- return formatOutputState(schema2, decodeDynamicValue(read.state));
1634
- },
1635
- async validateResource(type, state) {
1636
- const schema2 = getResourceSchema(resources, type);
1637
- await client.call("ValidateResourceTypeConfig", {
1638
- typeName: type,
1639
- config: encodeDynamicValue(formatInputState(schema2, state))
1640
- });
1641
- },
1642
- async planResourceChange(type, priorState, proposedState) {
1643
- const schema2 = getResourceSchema(resources, type);
1644
- const preparedPriorState = formatInputState(schema2, priorState);
1645
- const preparedProposedState = formatInputState(schema2, proposedState);
1646
- const plan = await client.call("PlanResourceChange", {
1647
- typeName: type,
1648
- priorState: encodeDynamicValue(preparedPriorState),
1649
- proposedNewState: encodeDynamicValue(preparedProposedState),
1650
- config: encodeDynamicValue(preparedProposedState)
1651
- });
1652
- const plannedState = decodeDynamicValue(plan.plannedState);
1653
- const requiresReplace = formatAttributePath(plan.requiresReplace);
1654
- return {
1655
- requiresReplace,
1656
- plannedState
1657
- };
1658
- },
1659
- async applyResourceChange(type, priorState, proposedState) {
1660
- const schema2 = getResourceSchema(resources, type);
1661
- const preparedPriorState = formatInputState(schema2, priorState);
1662
- const preparedProposedState = formatInputState(schema2, proposedState);
1663
- const apply = await client.call("ApplyResourceChange", {
1664
- typeName: type,
1665
- priorState: encodeDynamicValue(preparedPriorState),
1666
- plannedState: encodeDynamicValue(preparedProposedState),
1667
- config: encodeDynamicValue(preparedProposedState)
1668
- });
1669
- return formatOutputState(schema2, decodeDynamicValue(apply.newState));
1670
- }
1671
- };
1672
- };
1673
-
1674
- // src/plugin/version/6.ts
1675
- var createPlugin6 = async ({
1676
- server,
1677
- client
1678
- }) => {
1679
- const schema = await client.call("GetProviderSchema");
1680
- const provider = parseProviderSchema(schema.provider);
1681
- const resources = parseResourceSchema(schema.resourceSchemas);
1682
- const dataSources = parseResourceSchema(schema.dataSourceSchemas);
1683
- return {
1684
- schema() {
1685
- return {
1686
- provider,
1687
- resources,
1688
- dataSources
1689
- };
1690
- },
1691
- async stop() {
1692
- await client.call("StopProvider");
1693
- server.kill();
1694
- },
1695
- async configure(config) {
1696
- const prepared = await client.call("ValidateProviderConfig", {
1697
- config: encodeDynamicValue(formatInputState(provider, config))
1698
- });
1699
- await client.call("ConfigureProvider", {
1700
- config: prepared.preparedConfig
1701
- });
1702
- },
1703
- async readResource(type, state) {
1704
- const schema2 = getResourceSchema(resources, type);
1705
- const read = await client.call("ReadResource", {
1706
- typeName: type,
1707
- currentState: encodeDynamicValue(formatInputState(schema2, state))
1708
- });
1709
- return formatOutputState(schema2, decodeDynamicValue(read.newState));
1710
- },
1711
- async readDataSource(type, state) {
1712
- const schema2 = getResourceSchema(dataSources, type);
1713
- const read = await client.call("ReadDataSource", {
1714
- typeName: type,
1715
- config: encodeDynamicValue(formatInputState(schema2, state))
1716
- });
1717
- return formatOutputState(schema2, decodeDynamicValue(read.state));
1718
- },
1719
- async validateResource(type, state) {
1720
- const schema2 = getResourceSchema(resources, type);
1721
- await client.call("ValidateResourceConfig", {
1722
- typeName: type,
1723
- config: encodeDynamicValue(formatInputState(schema2, state))
1724
- });
1725
- },
1726
- async planResourceChange(type, priorState, proposedState) {
1727
- const schema2 = getResourceSchema(resources, type);
1728
- const preparedPriorState = formatInputState(schema2, priorState);
1729
- const preparedProposedState = formatInputState(schema2, proposedState);
1730
- const plan = await client.call("PlanResourceChange", {
1731
- typeName: type,
1732
- priorState: encodeDynamicValue(preparedPriorState),
1733
- proposedNewState: encodeDynamicValue(preparedProposedState),
1734
- config: encodeDynamicValue(preparedProposedState)
1735
- });
1736
- const plannedState = decodeDynamicValue(plan.plannedState);
1737
- const requiresReplace = formatAttributePath(plan.requiresReplace);
1738
- return {
1739
- requiresReplace,
1740
- plannedState
1741
- };
1742
- },
1743
- async applyResourceChange(type, priorState, proposedState) {
1744
- const schema2 = getResourceSchema(resources, type);
1745
- const preparedPriorState = formatInputState(schema2, priorState);
1746
- const preparedProposedState = formatInputState(schema2, proposedState);
1747
- const apply = await client.call("ApplyResourceChange", {
1748
- typeName: type,
1749
- priorState: encodeDynamicValue(preparedPriorState),
1750
- plannedState: encodeDynamicValue(preparedProposedState),
1751
- config: encodeDynamicValue(preparedProposedState)
1752
- });
1753
- return formatOutputState(schema2, decodeDynamicValue(apply.newState));
1754
- }
1755
- // async applyResourceChange(
1756
- // type: string,
1757
- // priorState: Record<string, unknown> | null,
1758
- // proposedState: Record<string, unknown> | null
1759
- // ) {
1760
- // const schema = getResourceSchema(resources, type)
1761
- // const preparedPriorState = formatInputState(schema, priorState)
1762
- // const preparedProposedState = formatInputState(schema, proposedState)
1763
- // const plan = await client.call('PlanResourceChange', {
1764
- // typeName: type,
1765
- // priorState: encodeDynamicValue(preparedPriorState),
1766
- // proposedNewState: encodeDynamicValue(preparedProposedState),
1767
- // config: encodeDynamicValue(preparedProposedState),
1768
- // })
1769
- // const plannedState = decodeDynamicValue(plan.plannedState)
1770
- // const apply = await client.call('ApplyResourceChange', {
1771
- // typeName: type,
1772
- // priorState: encodeDynamicValue(preparedPriorState),
1773
- // plannedState: encodeDynamicValue(plannedState),
1774
- // config: encodeDynamicValue(plannedState),
1775
- // })
1776
- // return formatOutputState(schema, decodeDynamicValue(apply.newState))
1777
- // },
1778
- };
1779
- };
1780
-
1781
- // src/lazy-plugin.ts
1782
- var createLazyPlugin = (props) => {
1783
- return async () => {
1784
- const { file } = await downloadPlugin(props);
1785
- const server = await retry(3, () => createPluginServer({ file, debug: false }));
1786
- const client = await retry(3, () => createPluginClient(server));
1787
- const plugins = {
1788
- 5: () => createPlugin5({ server, client }),
1789
- 6: () => createPlugin6({ server, client })
1790
- };
1791
- const plugin = await plugins[server.version]?.();
1792
- if (!plugin) {
1793
- throw new Error(`No plugin client available for protocol version ${server.version}`);
1794
- }
1795
- return plugin;
1796
- };
1797
- };
1798
- var retry = async (tries, cb) => {
1799
- let latestError;
1800
- while (--tries) {
1801
- try {
1802
- const result = await cb();
1803
- return result;
1804
- } catch (error) {
1805
- latestError = error;
1806
- }
1807
- }
1808
- throw latestError;
1809
- };
1810
-
1811
- // src/proxy.ts
1812
- var createResourceProxy = (cb) => {
1813
- return new Proxy(
1814
- {},
1815
- {
1816
- get(_, key) {
1817
- return cb(key);
1818
- },
1819
- set(_, key) {
1820
- if (typeof key === "string") {
1821
- throw new Error(`Cannot set property ${key} on read-only object.`);
1822
- }
1823
- throw new Error(`This object is read-only.`);
1824
- }
1825
- }
1826
- );
1827
- };
1828
- var createNamespaceProxy = (cb) => {
1829
- const cache = /* @__PURE__ */ new Map();
1830
- return new Proxy(
1831
- {},
1832
- {
1833
- get(_, key) {
1834
- if (typeof key === "string") {
1835
- if (!cache.has(key)) {
1836
- const value = cb(key);
1837
- cache.set(key, value);
1838
- }
1839
- return cache.get(key);
1840
- }
1841
- return;
1842
- },
1843
- set(_, key) {
1844
- if (typeof key === "string") {
1845
- throw new Error(`Cannot set property ${key} on read-only object.`);
1846
- }
1847
- throw new Error(`This object is read-only.`);
1848
- }
1849
- }
1850
- );
1851
- };
1852
- var createRootProxy = (apply, get) => {
1853
- const cache = /* @__PURE__ */ new Map();
1854
- return new Proxy(() => {
1855
- }, {
1856
- apply(_, _this, args) {
1857
- return apply(...args);
1858
- },
1859
- get(_, key) {
1860
- if (typeof key === "string") {
1861
- if (!cache.has(key)) {
1862
- const value = get(key);
1863
- cache.set(key, value);
1864
- }
1865
- return cache.get(key);
1866
- }
1867
- return;
1868
- }
1869
- });
1870
- };
1871
- var createClassProxy = (construct, get) => {
1872
- return new Proxy(class {
1873
- }, {
1874
- construct(_, args) {
1875
- return construct(...args);
1876
- },
1877
- get(_, key) {
1878
- if (key === "get") {
1879
- return (...args) => {
1880
- return get(...args);
1881
- };
1882
- }
1883
- return;
1884
- }
1885
- });
1886
- };
1887
- var createRecursiveProxy = ({
1888
- provider,
1889
- install,
1890
- uninstall,
1891
- isInstalled,
1892
- resource,
1893
- dataSource
1894
- }) => {
1895
- const findNextProxy = (ns, name) => {
1896
- if (name === name.toLowerCase()) {
1897
- return createNamespaceProxy((key) => {
1898
- return findNextProxy([...ns, name], key);
1899
- });
1900
- } else if (name.startsWith("get")) {
1901
- return (...args) => {
1902
- return dataSource([...ns, name.substring(3)], ...args);
1903
- };
1904
- } else {
1905
- return createClassProxy(
1906
- (...args) => {
1907
- return resource([...ns, name], ...args);
1908
- },
1909
- (...args) => {
1910
- return dataSource([...ns, name], ...args);
1911
- }
1912
- );
1913
- }
1914
- };
1915
- return createRootProxy(provider, (key) => {
1916
- if (key === "install") {
1917
- return install;
1918
- }
1919
- if (key === "uninstall") {
1920
- return uninstall;
1921
- }
1922
- if (key === "isInstalled") {
1923
- return isInstalled;
1924
- }
1925
- return findNextProxy([], key);
1926
- });
1927
- };
1928
- var createTerraformProxy = (props) => {
1929
- return createRecursiveProxy({
1930
- provider(input, config) {
1931
- return new TerraformProvider(
1932
- props.namespace,
1933
- config?.id ?? "default",
1934
- createLazyPlugin({
1935
- ...props.provider,
1936
- location: config?.location
1937
- }),
1938
- input
1939
- );
1940
- },
1941
- async install(installProps) {
1942
- await downloadPlugin({ ...props.provider, ...installProps });
1943
- },
1944
- async uninstall(installProps) {
1945
- await deletePlugin({ ...props.provider, ...installProps });
1946
- },
1947
- async isInstalled(installProps) {
1948
- return await isPluginInstalled({ ...props.provider, ...installProps });
1949
- },
1950
- resource: (ns, parent, id, input, config) => {
1951
- const type = snakeCase2([props.namespace, ...ns].join("_"));
1952
- const provider = `terraform:${props.namespace}:${config?.provider ?? "default"}`;
1953
- const meta = createMeta("resource", provider, parent, type, id, input, config);
1954
- const resource = createResourceProxy((key) => {
1955
- if (typeof key === "string") {
1956
- return meta.output((data) => data[key]);
1957
- } else if (key === nodeMetaSymbol) {
1958
- return meta;
1959
- }
1960
- return;
1961
- });
1962
- parent.add(resource);
1963
- return resource;
1964
- },
1965
- dataSource: (ns, parent, id, input, config) => {
1966
- const type = snakeCase2([props.namespace, ...ns].join("_"));
1967
- const provider = `terraform:${props.namespace}:${config?.provider ?? "default"}`;
1968
- const meta = createMeta("data", provider, parent, type, id, input, config);
1969
- const dataSource = createResourceProxy((key) => {
1970
- if (typeof key === "string") {
1971
- return meta.output((data) => data[key]);
1972
- } else if (key === nodeMetaSymbol) {
1973
- return meta;
1974
- }
1975
- return;
1976
- });
1977
- parent.add(dataSource);
1978
- return dataSource;
1979
- }
1980
- });
1981
- };
1982
- export {
1983
- TerraformProvider,
1984
- createTerraformProxy,
1985
- generateTypes
1986
- };