@terraforge/terraform 0.0.5 → 0.0.6
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.d.ts +74 -56
- package/dist/index.js +177 -103
- package/package.json +3 -3
package/dist/index.d.ts
CHANGED
|
@@ -1,74 +1,92 @@
|
|
|
1
|
-
|
|
1
|
+
import { Provider, State as State$1, GetProps, CreateProps, UpdateProps, DeleteProps, GetDataProps } from '@terraforge/core';
|
|
2
|
+
|
|
3
|
+
type Version = `${number}.${number}.${number}` | 'latest';
|
|
4
|
+
|
|
2
5
|
type TerraformProviderConfig = {
|
|
3
|
-
|
|
4
|
-
|
|
6
|
+
id?: string;
|
|
7
|
+
location?: string;
|
|
5
8
|
};
|
|
6
9
|
type InstallProps = {
|
|
7
|
-
|
|
10
|
+
location?: string;
|
|
8
11
|
};
|
|
9
12
|
declare const createTerraformAPI: <T>(props: {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
namespace: string;
|
|
14
|
+
provider: {
|
|
15
|
+
org: string;
|
|
16
|
+
type: string;
|
|
17
|
+
version: Version;
|
|
18
|
+
};
|
|
16
19
|
}) => T;
|
|
20
|
+
|
|
17
21
|
type Property = {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
22
|
+
description?: string;
|
|
23
|
+
required?: boolean;
|
|
24
|
+
optional?: boolean;
|
|
25
|
+
/** The computed field means that it could be computed by the server. */
|
|
26
|
+
computed?: boolean;
|
|
27
|
+
deprecated?: boolean;
|
|
28
|
+
sensitive?: boolean;
|
|
25
29
|
} & ({
|
|
26
|
-
|
|
30
|
+
type: 'string' | 'number' | 'boolean';
|
|
27
31
|
} | {
|
|
28
|
-
|
|
29
|
-
|
|
32
|
+
type: 'array' | 'record';
|
|
33
|
+
item: Property;
|
|
30
34
|
} | {
|
|
31
|
-
|
|
32
|
-
|
|
35
|
+
type: 'object' | 'array-object';
|
|
36
|
+
properties: Record<string, Property>;
|
|
33
37
|
} | {
|
|
34
|
-
|
|
38
|
+
type: 'unknown';
|
|
35
39
|
});
|
|
40
|
+
|
|
36
41
|
declare const generateTypes: (providers: Record<string, Property>, resources: Record<string, Property>, dataSources: Record<string, Property>) => string;
|
|
37
|
-
|
|
42
|
+
|
|
38
43
|
type State = Record<string, unknown>;
|
|
39
44
|
type Plugin = Readonly<{
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
45
|
+
schema: () => {
|
|
46
|
+
provider: Property;
|
|
47
|
+
resources: Record<string, Property>;
|
|
48
|
+
dataSources: Record<string, Property>;
|
|
49
|
+
};
|
|
50
|
+
stop: () => Promise<void>;
|
|
51
|
+
configure: (config: State) => Promise<void>;
|
|
52
|
+
readResource: (type: string, state: State) => Promise<State>;
|
|
53
|
+
readDataSource: (type: string, state: State) => Promise<State>;
|
|
54
|
+
validateResource: (type: string, state: State) => Promise<void>;
|
|
55
|
+
planResourceChange: (type: string, priorState: State | null, proposedNewState: State | null) => Promise<{
|
|
56
|
+
requiresReplace: Array<string | number>[];
|
|
57
|
+
plannedState: State;
|
|
58
|
+
}>;
|
|
59
|
+
applyResourceChange: (type: string, priorState: State | null, proposedNewState: State | null) => Promise<State>;
|
|
55
60
|
}>;
|
|
61
|
+
|
|
56
62
|
declare class TerraformProvider implements Provider {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
63
|
+
private type;
|
|
64
|
+
private id;
|
|
65
|
+
private createPlugin;
|
|
66
|
+
private config;
|
|
67
|
+
private configured?;
|
|
68
|
+
private plugin?;
|
|
69
|
+
constructor(type: string, id: string, createPlugin: () => Promise<Plugin>, config: State$1);
|
|
70
|
+
private configure;
|
|
71
|
+
private prepare;
|
|
72
|
+
destroy(): Promise<void>;
|
|
73
|
+
ownResource(id: string): boolean;
|
|
74
|
+
getResource({ type, state }: GetProps): Promise<{
|
|
75
|
+
version: number;
|
|
76
|
+
state: State;
|
|
77
|
+
}>;
|
|
78
|
+
createResource({ type, state }: CreateProps): Promise<{
|
|
79
|
+
version: number;
|
|
80
|
+
state: State;
|
|
81
|
+
}>;
|
|
82
|
+
updateResource({ type, priorState, proposedState }: UpdateProps): Promise<{
|
|
83
|
+
version: number;
|
|
84
|
+
state: State;
|
|
85
|
+
}>;
|
|
86
|
+
deleteResource({ type, state }: DeleteProps): Promise<void>;
|
|
87
|
+
getData({ type, state }: GetDataProps): Promise<{
|
|
88
|
+
state: State;
|
|
89
|
+
}>;
|
|
73
90
|
}
|
|
74
|
-
|
|
91
|
+
|
|
92
|
+
export { type InstallProps, TerraformProvider, type TerraformProviderConfig, createTerraformAPI, generateTypes };
|
package/dist/index.js
CHANGED
|
@@ -4,13 +4,13 @@ import { fromJSON } from "@grpc/proto-loader";
|
|
|
4
4
|
import { createDebugger } from "@terraforge/core";
|
|
5
5
|
|
|
6
6
|
// src/plugin/diagnostic.ts
|
|
7
|
-
|
|
7
|
+
var DiagnosticsError = class extends Error {
|
|
8
8
|
diagnostics;
|
|
9
9
|
constructor(diagnostics) {
|
|
10
10
|
super(diagnostics[0]?.summary ?? "Diagnostic error");
|
|
11
11
|
this.diagnostics = diagnostics;
|
|
12
12
|
}
|
|
13
|
-
}
|
|
13
|
+
};
|
|
14
14
|
var throwDiagnosticError = (response) => {
|
|
15
15
|
const diagnostics = response.diagnostics.map((item) => ({
|
|
16
16
|
severity: item.severity === 1 ? "error" : "warning",
|
|
@@ -686,15 +686,19 @@ var createPluginClient = async (props) => {
|
|
|
686
686
|
if (!proto) {
|
|
687
687
|
throw new Error(`We don't have support for the ${props.protocol} protocol`);
|
|
688
688
|
}
|
|
689
|
-
const
|
|
690
|
-
const grpc = loadPackageDefinition(
|
|
691
|
-
const client = new grpc["tfplugin" + props.version].Provider(
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
689
|
+
const pack2 = fromJSON(proto);
|
|
690
|
+
const grpc = loadPackageDefinition(pack2);
|
|
691
|
+
const client = new grpc["tfplugin" + props.version].Provider(
|
|
692
|
+
`unix://${props.endpoint}`,
|
|
693
|
+
credentials.createInsecure(),
|
|
694
|
+
{
|
|
695
|
+
"grpc.max_receive_message_length": 100 * 1024 * 1024,
|
|
696
|
+
"grpc.max_send_message_length": 100 * 1024 * 1024
|
|
697
|
+
}
|
|
698
|
+
);
|
|
695
699
|
debug("init", props.protocol);
|
|
696
700
|
await new Promise((resolve, reject) => {
|
|
697
|
-
const deadline = new Date;
|
|
701
|
+
const deadline = /* @__PURE__ */ new Date();
|
|
698
702
|
deadline.setSeconds(deadline.getSeconds() + 10);
|
|
699
703
|
client.waitForReady(deadline, (error) => {
|
|
700
704
|
if (error) {
|
|
@@ -733,12 +737,12 @@ var createPluginClient = async (props) => {
|
|
|
733
737
|
// src/plugin/download.ts
|
|
734
738
|
import { createDebugger as createDebugger2 } from "@terraforge/core";
|
|
735
739
|
import jszip from "jszip";
|
|
736
|
-
import { mkdir, stat, writeFile } from "
|
|
737
|
-
import { homedir } from "
|
|
738
|
-
import { join } from "
|
|
740
|
+
import { mkdir, stat, writeFile } from "fs/promises";
|
|
741
|
+
import { homedir } from "os";
|
|
742
|
+
import { join } from "path";
|
|
739
743
|
|
|
740
744
|
// src/plugin/registry.ts
|
|
741
|
-
import { arch, platform } from "
|
|
745
|
+
import { arch, platform } from "os";
|
|
742
746
|
import { compare } from "semver";
|
|
743
747
|
var baseUrl = "https://registry.terraform.io/v1/providers";
|
|
744
748
|
var getProviderVersions = async (org, type) => {
|
|
@@ -763,6 +767,7 @@ var getProviderVersions = async (org, type) => {
|
|
|
763
767
|
};
|
|
764
768
|
var getProviderDownloadUrl = async (org, type, version) => {
|
|
765
769
|
const url = [
|
|
770
|
+
//
|
|
766
771
|
baseUrl,
|
|
767
772
|
org,
|
|
768
773
|
type,
|
|
@@ -856,7 +861,7 @@ var downloadPlugin = async (props) => {
|
|
|
856
861
|
|
|
857
862
|
// src/plugin/server.ts
|
|
858
863
|
import { createDebugger as createDebugger3 } from "@terraforge/core";
|
|
859
|
-
import { spawn } from "
|
|
864
|
+
import { spawn } from "child_process";
|
|
860
865
|
var debug3 = createDebugger3("Server");
|
|
861
866
|
var createPluginServer = (props) => {
|
|
862
867
|
return new Promise((resolve, reject) => {
|
|
@@ -893,7 +898,8 @@ var createPluginServer = (props) => {
|
|
|
893
898
|
return;
|
|
894
899
|
}
|
|
895
900
|
}
|
|
896
|
-
} catch (error) {
|
|
901
|
+
} catch (error) {
|
|
902
|
+
}
|
|
897
903
|
debug3("failed");
|
|
898
904
|
reject(new Error("Failed to start the plugin"));
|
|
899
905
|
});
|
|
@@ -947,6 +953,7 @@ var parseBlock = (block) => {
|
|
|
947
953
|
type: "object",
|
|
948
954
|
version: block.version,
|
|
949
955
|
description: block.description,
|
|
956
|
+
// deprecated: block.deprecated,
|
|
950
957
|
properties
|
|
951
958
|
};
|
|
952
959
|
};
|
|
@@ -1018,6 +1025,7 @@ var parseAttribute = (attr) => {
|
|
|
1018
1025
|
return {
|
|
1019
1026
|
...prop,
|
|
1020
1027
|
...parseBlock(attr.nestedType)
|
|
1028
|
+
// properties: parseBlock(attr.nestedType).properties,
|
|
1021
1029
|
};
|
|
1022
1030
|
}
|
|
1023
1031
|
throw new Error("Empty attr");
|
|
@@ -1122,12 +1130,11 @@ var formatAttributePath = (state) => {
|
|
|
1122
1130
|
});
|
|
1123
1131
|
});
|
|
1124
1132
|
};
|
|
1125
|
-
|
|
1126
|
-
class IncorrectType extends TypeError {
|
|
1133
|
+
var IncorrectType = class extends TypeError {
|
|
1127
1134
|
constructor(type, path) {
|
|
1128
1135
|
super(`${path.join(".")} should be a ${type}`);
|
|
1129
1136
|
}
|
|
1130
|
-
}
|
|
1137
|
+
};
|
|
1131
1138
|
var formatInputState = (schema, state, includeSchemaFields = true, path = []) => {
|
|
1132
1139
|
if (state === null) {
|
|
1133
1140
|
return null;
|
|
@@ -1199,7 +1206,7 @@ var formatInputState = (schema, state, includeSchemaFields = true, path = []) =>
|
|
|
1199
1206
|
};
|
|
1200
1207
|
var formatOutputState = (schema, state, path = []) => {
|
|
1201
1208
|
if (state === null) {
|
|
1202
|
-
return;
|
|
1209
|
+
return void 0;
|
|
1203
1210
|
}
|
|
1204
1211
|
if (schema.type === "array") {
|
|
1205
1212
|
if (Array.isArray(state)) {
|
|
@@ -1238,7 +1245,7 @@ var formatOutputState = (schema, state, path = []) => {
|
|
|
1238
1245
|
}
|
|
1239
1246
|
return object;
|
|
1240
1247
|
} else {
|
|
1241
|
-
return;
|
|
1248
|
+
return void 0;
|
|
1242
1249
|
}
|
|
1243
1250
|
}
|
|
1244
1251
|
throw new IncorrectType(schema.type, path);
|
|
@@ -1411,6 +1418,29 @@ var createPlugin6 = async ({
|
|
|
1411
1418
|
});
|
|
1412
1419
|
return formatOutputState(schema2, decodeDynamicValue(apply.newState));
|
|
1413
1420
|
}
|
|
1421
|
+
// async applyResourceChange(
|
|
1422
|
+
// type: string,
|
|
1423
|
+
// priorState: Record<string, unknown> | null,
|
|
1424
|
+
// proposedState: Record<string, unknown> | null
|
|
1425
|
+
// ) {
|
|
1426
|
+
// const schema = getResourceSchema(resources, type)
|
|
1427
|
+
// const preparedPriorState = formatInputState(schema, priorState)
|
|
1428
|
+
// const preparedProposedState = formatInputState(schema, proposedState)
|
|
1429
|
+
// const plan = await client.call('PlanResourceChange', {
|
|
1430
|
+
// typeName: type,
|
|
1431
|
+
// priorState: encodeDynamicValue(preparedPriorState),
|
|
1432
|
+
// proposedNewState: encodeDynamicValue(preparedProposedState),
|
|
1433
|
+
// config: encodeDynamicValue(preparedProposedState),
|
|
1434
|
+
// })
|
|
1435
|
+
// const plannedState = decodeDynamicValue(plan.plannedState)
|
|
1436
|
+
// const apply = await client.call('ApplyResourceChange', {
|
|
1437
|
+
// typeName: type,
|
|
1438
|
+
// priorState: encodeDynamicValue(preparedPriorState),
|
|
1439
|
+
// plannedState: encodeDynamicValue(plannedState),
|
|
1440
|
+
// config: encodeDynamicValue(plannedState),
|
|
1441
|
+
// })
|
|
1442
|
+
// return formatOutputState(schema, decodeDynamicValue(apply.newState))
|
|
1443
|
+
// },
|
|
1414
1444
|
};
|
|
1415
1445
|
};
|
|
1416
1446
|
|
|
@@ -1448,20 +1478,15 @@ var retry = async (tries, cb) => {
|
|
|
1448
1478
|
import {
|
|
1449
1479
|
ResourceNotFound
|
|
1450
1480
|
} from "@terraforge/core";
|
|
1451
|
-
|
|
1452
|
-
class TerraformProvider {
|
|
1453
|
-
type;
|
|
1454
|
-
id;
|
|
1455
|
-
createPlugin;
|
|
1456
|
-
config;
|
|
1457
|
-
configured;
|
|
1458
|
-
plugin;
|
|
1481
|
+
var TerraformProvider = class {
|
|
1459
1482
|
constructor(type, id, createPlugin, config) {
|
|
1460
1483
|
this.type = type;
|
|
1461
1484
|
this.id = id;
|
|
1462
1485
|
this.createPlugin = createPlugin;
|
|
1463
1486
|
this.config = config;
|
|
1464
1487
|
}
|
|
1488
|
+
configured;
|
|
1489
|
+
plugin;
|
|
1465
1490
|
async configure() {
|
|
1466
1491
|
const plugin = await this.prepare();
|
|
1467
1492
|
if (!this.configured) {
|
|
@@ -1480,8 +1505,8 @@ class TerraformProvider {
|
|
|
1480
1505
|
if (this.plugin) {
|
|
1481
1506
|
const plugin = await this.plugin;
|
|
1482
1507
|
plugin.stop();
|
|
1483
|
-
this.plugin =
|
|
1484
|
-
this.configured =
|
|
1508
|
+
this.plugin = void 0;
|
|
1509
|
+
this.configured = void 0;
|
|
1485
1510
|
}
|
|
1486
1511
|
}
|
|
1487
1512
|
ownResource(id) {
|
|
@@ -1491,7 +1516,7 @@ class TerraformProvider {
|
|
|
1491
1516
|
const plugin = await this.configure();
|
|
1492
1517
|
const newState = await plugin.readResource(type, state);
|
|
1493
1518
|
if (!newState) {
|
|
1494
|
-
throw new ResourceNotFound;
|
|
1519
|
+
throw new ResourceNotFound();
|
|
1495
1520
|
}
|
|
1496
1521
|
return {
|
|
1497
1522
|
version: 0,
|
|
@@ -1511,7 +1536,9 @@ class TerraformProvider {
|
|
|
1511
1536
|
const { requiresReplace } = await plugin.planResourceChange(type, priorState, proposedState);
|
|
1512
1537
|
if (requiresReplace.length > 0) {
|
|
1513
1538
|
const formattedAttrs = requiresReplace.map((p) => p.join(".")).join('", "');
|
|
1514
|
-
throw new Error(
|
|
1539
|
+
throw new Error(
|
|
1540
|
+
`Updating the "${formattedAttrs}" properties for the "${type}" resource will require the resource to be replaced.`
|
|
1541
|
+
);
|
|
1515
1542
|
}
|
|
1516
1543
|
const newState = await plugin.applyResourceChange(type, priorState, proposedState);
|
|
1517
1544
|
return {
|
|
@@ -1527,9 +1554,10 @@ class TerraformProvider {
|
|
|
1527
1554
|
try {
|
|
1528
1555
|
const newState = await plugin.readResource(type, state);
|
|
1529
1556
|
if (!newState) {
|
|
1530
|
-
throw new ResourceNotFound;
|
|
1557
|
+
throw new ResourceNotFound();
|
|
1531
1558
|
}
|
|
1532
|
-
} catch (_) {
|
|
1559
|
+
} catch (_) {
|
|
1560
|
+
}
|
|
1533
1561
|
throw error;
|
|
1534
1562
|
}
|
|
1535
1563
|
}
|
|
@@ -1543,28 +1571,45 @@ class TerraformProvider {
|
|
|
1543
1571
|
state: data
|
|
1544
1572
|
};
|
|
1545
1573
|
}
|
|
1546
|
-
|
|
1574
|
+
// async generateTypes(dir: string) {
|
|
1575
|
+
// const plugin = await this.prepare()
|
|
1576
|
+
// const schema = plugin.schema()
|
|
1577
|
+
// const types = generateTypes(
|
|
1578
|
+
// {
|
|
1579
|
+
// [`${this.type}_provider`]: schema.provider,
|
|
1580
|
+
// },
|
|
1581
|
+
// schema.resources,
|
|
1582
|
+
// schema.dataSources
|
|
1583
|
+
// )
|
|
1584
|
+
// await mkdir(dir, { recursive: true })
|
|
1585
|
+
// await writeFile(join(dir, `${this.type}.d.ts`), types)
|
|
1586
|
+
// await this.destroy()
|
|
1587
|
+
// }
|
|
1588
|
+
};
|
|
1547
1589
|
|
|
1548
1590
|
// src/resource.ts
|
|
1549
1591
|
import { createMeta, nodeMetaSymbol } from "@terraforge/core";
|
|
1550
1592
|
import { snakeCase as snakeCase2 } from "change-case";
|
|
1551
1593
|
var createNamespaceProxy = (cb, scb) => {
|
|
1552
|
-
const cache = new Map;
|
|
1553
|
-
return new Proxy(
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
cache.
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1594
|
+
const cache = /* @__PURE__ */ new Map();
|
|
1595
|
+
return new Proxy(
|
|
1596
|
+
{},
|
|
1597
|
+
{
|
|
1598
|
+
get(_, key) {
|
|
1599
|
+
if (!cache.has(key)) {
|
|
1600
|
+
const value = typeof key === "symbol" ? scb?.(key) : cb(key);
|
|
1601
|
+
cache.set(key, value);
|
|
1602
|
+
}
|
|
1603
|
+
return cache.get(key);
|
|
1604
|
+
},
|
|
1605
|
+
set(_, key) {
|
|
1606
|
+
if (typeof key === "string") {
|
|
1607
|
+
throw new Error(`Cannot set property ${key} on read-only object.`);
|
|
1608
|
+
}
|
|
1609
|
+
throw new Error(`This object is read-only.`);
|
|
1564
1610
|
}
|
|
1565
|
-
throw new Error(`This object is read-only.`);
|
|
1566
1611
|
}
|
|
1567
|
-
|
|
1612
|
+
);
|
|
1568
1613
|
};
|
|
1569
1614
|
var createClassProxy = (construct, get) => {
|
|
1570
1615
|
return new Proxy(class {
|
|
@@ -1596,11 +1641,14 @@ var createRecursiveProxy = ({
|
|
|
1596
1641
|
return dataSource([...names, name.substring(3)], ...args);
|
|
1597
1642
|
};
|
|
1598
1643
|
} else {
|
|
1599
|
-
return createClassProxy(
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1644
|
+
return createClassProxy(
|
|
1645
|
+
(...args) => {
|
|
1646
|
+
return resource(ns, ...args);
|
|
1647
|
+
},
|
|
1648
|
+
(...args) => {
|
|
1649
|
+
return dataSource(ns, ...args);
|
|
1650
|
+
}
|
|
1651
|
+
);
|
|
1604
1652
|
}
|
|
1605
1653
|
});
|
|
1606
1654
|
};
|
|
@@ -1612,29 +1660,52 @@ var createResourceProxy = (name) => {
|
|
|
1612
1660
|
const type = snakeCase2(name + "_" + ns.join("_"));
|
|
1613
1661
|
const provider = `terraform:${name}:${config?.provider ?? "default"}`;
|
|
1614
1662
|
const meta = createMeta("resource", provider, parent, type, id, input, config);
|
|
1615
|
-
const resource = createNamespaceProxy(
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1663
|
+
const resource = createNamespaceProxy(
|
|
1664
|
+
(key) => {
|
|
1665
|
+
return meta.output((data) => data[key]);
|
|
1666
|
+
},
|
|
1667
|
+
(key) => {
|
|
1668
|
+
if (key === nodeMetaSymbol) {
|
|
1669
|
+
return meta;
|
|
1670
|
+
}
|
|
1671
|
+
return;
|
|
1620
1672
|
}
|
|
1621
|
-
|
|
1622
|
-
});
|
|
1673
|
+
);
|
|
1623
1674
|
parent.add(resource);
|
|
1624
1675
|
return resource;
|
|
1625
1676
|
},
|
|
1677
|
+
// external: (ns: string[], id: string, input: State, config?: ResourceConfig) => {
|
|
1678
|
+
// const type = snakeCase(ns.join('_'))
|
|
1679
|
+
// const provider = `terraform:${ns[0]}:${config?.provider ?? 'default'}`
|
|
1680
|
+
// const $ = createResourceMeta(provider, type, id, input, config)
|
|
1681
|
+
// const resource = createNamespaceProxy(
|
|
1682
|
+
// key => {
|
|
1683
|
+
// if (key === '$') {
|
|
1684
|
+
// return $
|
|
1685
|
+
// }
|
|
1686
|
+
// return $.output(data => data[key])
|
|
1687
|
+
// },
|
|
1688
|
+
// { $ }
|
|
1689
|
+
// ) as Resource
|
|
1690
|
+
// parent.add(resource)
|
|
1691
|
+
// return resource
|
|
1692
|
+
// },
|
|
1693
|
+
// (ns: string[], parent: Group, id: string, input: State, config?: ResourceConfig)
|
|
1626
1694
|
dataSource: (ns, parent, id, input, config) => {
|
|
1627
1695
|
const type = snakeCase2(name + "_" + ns.join("_"));
|
|
1628
1696
|
const provider = `terraform:${name}:${config?.provider ?? "default"}`;
|
|
1629
1697
|
const meta = createMeta("data", provider, parent, type, id, input, config);
|
|
1630
|
-
const dataSource = createNamespaceProxy(
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1698
|
+
const dataSource = createNamespaceProxy(
|
|
1699
|
+
(key) => {
|
|
1700
|
+
return meta.output((data) => data[key]);
|
|
1701
|
+
},
|
|
1702
|
+
(key) => {
|
|
1703
|
+
if (key === nodeMetaSymbol) {
|
|
1704
|
+
return meta;
|
|
1705
|
+
}
|
|
1706
|
+
return;
|
|
1635
1707
|
}
|
|
1636
|
-
|
|
1637
|
-
});
|
|
1708
|
+
);
|
|
1638
1709
|
parent.add(dataSource);
|
|
1639
1710
|
return dataSource;
|
|
1640
1711
|
}
|
|
@@ -1650,9 +1721,15 @@ var createTerraformAPI = (props) => {
|
|
|
1650
1721
|
const createPlugin = (pluginProps) => {
|
|
1651
1722
|
return createLazyPlugin({ ...props.provider, ...pluginProps });
|
|
1652
1723
|
};
|
|
1653
|
-
return new Proxy(() => {
|
|
1724
|
+
return new Proxy(() => {
|
|
1725
|
+
}, {
|
|
1654
1726
|
apply(_, _this, [input, config]) {
|
|
1655
|
-
return new TerraformProvider(
|
|
1727
|
+
return new TerraformProvider(
|
|
1728
|
+
props.namespace,
|
|
1729
|
+
config?.id ?? "default",
|
|
1730
|
+
createPlugin({ location: config?.location }),
|
|
1731
|
+
input
|
|
1732
|
+
);
|
|
1656
1733
|
},
|
|
1657
1734
|
get(_, prop) {
|
|
1658
1735
|
if (prop === "install") {
|
|
@@ -1662,10 +1739,11 @@ var createTerraformAPI = (props) => {
|
|
|
1662
1739
|
}
|
|
1663
1740
|
});
|
|
1664
1741
|
};
|
|
1742
|
+
|
|
1665
1743
|
// src/type-gen.ts
|
|
1666
1744
|
import { camelCase as camelCase2, pascalCase } from "change-case";
|
|
1667
1745
|
var tab = (indent) => {
|
|
1668
|
-
return "
|
|
1746
|
+
return " ".repeat(indent);
|
|
1669
1747
|
};
|
|
1670
1748
|
var generateTypes = (providers, resources, dataSources) => {
|
|
1671
1749
|
return [
|
|
@@ -1680,6 +1758,9 @@ var generateTypes = (providers, resources, dataSources) => {
|
|
|
1680
1758
|
generateNamespace(resources, (name, prop, indent) => {
|
|
1681
1759
|
const typeName = pascalCase(name);
|
|
1682
1760
|
return [
|
|
1761
|
+
// `${tab(indent)}export type ${typeName}Input = ${generatePropertyInputType(prop, indent)}`,
|
|
1762
|
+
// `${tab(indent)}export type ${typeName}Output = ${generatePropertyOutputType(prop, indent)}`,
|
|
1763
|
+
// `${tab(indent)}export declare const ${typeName}: ResourceClass<${typeName}Input, ${typeName}Output>`,
|
|
1683
1764
|
`${tab(indent)}export type ${typeName}Input = ${generatePropertyInputType(prop, indent)}`,
|
|
1684
1765
|
`${tab(indent)}export type ${typeName}Output = ${generatePropertyOutputType(prop, indent)}`,
|
|
1685
1766
|
`${tab(indent)}export class ${typeName} {`,
|
|
@@ -1687,9 +1768,7 @@ var generateTypes = (providers, resources, dataSources) => {
|
|
|
1687
1768
|
`${tab(indent + 1)}readonly $: c.ResourceMeta<${typeName}Input, ${typeName}Output>`,
|
|
1688
1769
|
generateClassProperties(prop, indent + 1),
|
|
1689
1770
|
`${tab(indent)}}`
|
|
1690
|
-
].join(
|
|
1691
|
-
|
|
1692
|
-
`);
|
|
1771
|
+
].join("\n\n");
|
|
1693
1772
|
}),
|
|
1694
1773
|
generateNamespace(dataSources, (name, prop, indent) => {
|
|
1695
1774
|
const typeName = pascalCase(name);
|
|
@@ -1697,13 +1776,9 @@ var generateTypes = (providers, resources, dataSources) => {
|
|
|
1697
1776
|
`${tab(indent)}export type Get${typeName}Input = ${generatePropertyInputType(prop, indent)}`,
|
|
1698
1777
|
`${tab(indent)}export type Get${typeName}Output = ${generatePropertyOutputType(prop, indent)}`,
|
|
1699
1778
|
`${tab(indent)}export const get${typeName}:c.DataSourceFunction<Get${typeName}Input, Get${typeName}Output>`
|
|
1700
|
-
].join(
|
|
1701
|
-
|
|
1702
|
-
`);
|
|
1779
|
+
].join("\n\n");
|
|
1703
1780
|
})
|
|
1704
|
-
].join(
|
|
1705
|
-
|
|
1706
|
-
`);
|
|
1781
|
+
].join("\n\n");
|
|
1707
1782
|
};
|
|
1708
1783
|
var generateImport = (name, from) => {
|
|
1709
1784
|
return `import * as ${name} from '${from}'`;
|
|
@@ -1743,6 +1818,7 @@ var generatePropertyOutputType = (prop, indent) => {
|
|
|
1743
1818
|
wrap: (v, p, ctx) => ctx.depth === 1 ? p.optional && !p.computed ? `c.OptionalOutput<${v}>` : `c.Output<${v}>` : v,
|
|
1744
1819
|
filter: () => true,
|
|
1745
1820
|
readonly: true,
|
|
1821
|
+
// required: true,
|
|
1746
1822
|
optional: (p, ctx) => ctx.depth > 1 && p.optional && !p.computed || false
|
|
1747
1823
|
});
|
|
1748
1824
|
};
|
|
@@ -1753,11 +1829,11 @@ var generateClassProperties = (prop, indent) => {
|
|
|
1753
1829
|
return Object.entries(prop.properties).map(([name, prop2]) => {
|
|
1754
1830
|
return [
|
|
1755
1831
|
prop2.description ? [`
|
|
1756
|
-
`, ` `.repeat(indent), `/** `, prop2.description.trim(), " */",
|
|
1757
|
-
`].join("") : "",
|
|
1832
|
+
`, ` `.repeat(indent), `/** `, prop2.description.trim(), " */", "\n"].join("") : "",
|
|
1758
1833
|
` `.repeat(indent),
|
|
1759
1834
|
"readonly ",
|
|
1760
1835
|
camelCase2(name),
|
|
1836
|
+
// ctx.optional(prop, ctx) ? '?' : '',
|
|
1761
1837
|
": ",
|
|
1762
1838
|
generateValue(prop2, {
|
|
1763
1839
|
readonly: true,
|
|
@@ -1766,12 +1842,12 @@ var generateClassProperties = (prop, indent) => {
|
|
|
1766
1842
|
wrap: (v, p, ctx) => {
|
|
1767
1843
|
return ctx.depth === 1 ? p.optional && !p.computed ? `c.OptionalOutput<${v}>` : `c.Output<${v}>` : v;
|
|
1768
1844
|
},
|
|
1845
|
+
// ctx.depth === 1 ? `c.Output<${p.optional && !p.computed ? `${v} | undefined` : v}>` : v,
|
|
1769
1846
|
indent: indent + 1,
|
|
1770
1847
|
depth: 1
|
|
1771
1848
|
})
|
|
1772
1849
|
].join("");
|
|
1773
|
-
}).join(
|
|
1774
|
-
`);
|
|
1850
|
+
}).join("\n");
|
|
1775
1851
|
};
|
|
1776
1852
|
var groupByNamespace = (resources, minLevel, maxLevel) => {
|
|
1777
1853
|
const grouped = {};
|
|
@@ -1809,11 +1885,9 @@ var generateNamespace = (resources, render) => {
|
|
|
1809
1885
|
} else {
|
|
1810
1886
|
return render(name2, resources[entry], indent + 1);
|
|
1811
1887
|
}
|
|
1812
|
-
}).join(
|
|
1813
|
-
`),
|
|
1888
|
+
}).join("\n"),
|
|
1814
1889
|
`${tab(indent)}}`
|
|
1815
|
-
].join(
|
|
1816
|
-
`);
|
|
1890
|
+
].join("\n");
|
|
1817
1891
|
};
|
|
1818
1892
|
return renderNamespace("root", grouped, 0);
|
|
1819
1893
|
};
|
|
@@ -1834,27 +1908,27 @@ var generateValue = (prop, ctx) => {
|
|
|
1834
1908
|
if (prop.type === "object" || prop.type === "array-object") {
|
|
1835
1909
|
const type = [
|
|
1836
1910
|
"{",
|
|
1837
|
-
Object.entries(prop.properties).filter(([_, p]) => ctx.filter(p)).map(
|
|
1838
|
-
prop2
|
|
1839
|
-
|
|
1840
|
-
`].join("") : "",
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1911
|
+
Object.entries(prop.properties).filter(([_, p]) => ctx.filter(p)).map(
|
|
1912
|
+
([name, prop2]) => [
|
|
1913
|
+
prop2.description ? [`
|
|
1914
|
+
`, ` `.repeat(ctx.indent), `/** `, prop2.description.trim(), " */", "\n"].join("") : "",
|
|
1915
|
+
` `.repeat(ctx.indent),
|
|
1916
|
+
// ctx.readonly ? "readonly " : "",
|
|
1917
|
+
camelCase2(name),
|
|
1918
|
+
ctx.optional(prop2, ctx) ? "?" : "",
|
|
1919
|
+
": ",
|
|
1920
|
+
generateValue(prop2, { ...ctx, indent: ctx.indent + 1, depth: ctx.depth + 1 })
|
|
1921
|
+
].join("")
|
|
1922
|
+
).join("\n"),
|
|
1848
1923
|
`${` `.repeat(ctx.indent - 1)}}`
|
|
1849
|
-
].join(
|
|
1850
|
-
`);
|
|
1924
|
+
].join("\n");
|
|
1851
1925
|
const object = ctx.readonly ? `Readonly<${type}>` : type;
|
|
1852
1926
|
return ctx.wrap(object, prop, ctx);
|
|
1853
1927
|
}
|
|
1854
1928
|
throw new Error(`Unknown property type: ${prop.type}`);
|
|
1855
1929
|
};
|
|
1856
1930
|
export {
|
|
1857
|
-
|
|
1931
|
+
TerraformProvider,
|
|
1858
1932
|
createTerraformAPI,
|
|
1859
|
-
|
|
1933
|
+
generateTypes
|
|
1860
1934
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@terraforge/terraform",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.6",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"module": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -14,12 +14,12 @@
|
|
|
14
14
|
}
|
|
15
15
|
},
|
|
16
16
|
"scripts": {
|
|
17
|
-
"build": "
|
|
17
|
+
"build": "tsup src/index.ts --format esm --dts --clean --out-dir ./dist",
|
|
18
18
|
"prepublishOnly": "bun run build",
|
|
19
19
|
"test": "bun test"
|
|
20
20
|
},
|
|
21
21
|
"peerDependencies": {
|
|
22
|
-
"@terraforge/core": "
|
|
22
|
+
"@terraforge/core": "0.0.4"
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
25
|
"@grpc/grpc-js": "1.12.6",
|