@geekmidas/cloud 0.0.2 → 0.2.0
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-DiEIrMTf.d.mts → index-ByEJy40r.d.cts} +2 -1
- package/dist/index-ByEJy40r.d.cts.map +1 -0
- package/dist/{index-QvprWg8v.d.cts → index-DZ0QrJQr.d.mts} +2 -1
- package/dist/index-DZ0QrJQr.d.mts.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.mjs +1 -1
- package/dist/utils/index.cjs +1 -1
- package/dist/utils/index.d.cts +1 -1
- package/dist/utils/index.d.mts +1 -1
- package/dist/utils/index.mjs +1 -1
- package/dist/{utils-CsvKEy-e.mjs → utils-BdKG20_m.mjs} +3 -4
- package/dist/utils-BdKG20_m.mjs.map +1 -0
- package/dist/{utils-BtXDcUV8.cjs → utils-CtMjuIMR.cjs} +4 -5
- package/dist/utils-CtMjuIMR.cjs.map +1 -0
- package/package.json +8 -1
- package/src/__tests__/utils.spec.ts +256 -0
- package/src/utils/index.ts +103 -105
- package/tsconfig.json +9 -0
- package/dist/utils-BtXDcUV8.cjs.map +0 -1
- package/dist/utils-CsvKEy-e.mjs.map +0 -1
|
@@ -50,6 +50,7 @@ type Secret = {
|
|
|
50
50
|
};
|
|
51
51
|
type Resource = ApiGatewayV2 | Postgres | Function | Bucket | Vpc | Secret;
|
|
52
52
|
type ResourceProcessor<K extends Resource> = (name: string, value: K) => Record<string, string | number>;
|
|
53
|
+
//# sourceMappingURL=index.d.ts.map
|
|
53
54
|
//#endregion
|
|
54
55
|
export { ApiGatewayV2, Bucket, Function, Postgres, Resource, ResourceProcessor, ResourceType, Secret, SnsTopic, Vpc, buildResourceEnv, environmentCase, getLocalIpAddress };
|
|
55
|
-
//# sourceMappingURL=index-
|
|
56
|
+
//# sourceMappingURL=index-ByEJy40r.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index-ByEJy40r.d.cts","names":[],"sources":["../src/utils/index.ts"],"sourcesContent":[],"mappings":";iBAGgB,iBAAA,CAAA;AAAA,iBAcA,eAAA,CAdiB,IAAA,EAAA,MAAA,CAAA,EAAA,MAAA;AAcjB,aAOJ,YAAA;EAAA,YAAA,GAAY,sBAAA;EA+DR,QAAA,GAAA,kBAAgB;EAAA,QAAA,GAAA,kBAAA;EAAA,MACR,GAAA,gBAAA;EAAQ,GAAvB,GAAA,aAAA;EAAM,MACZ,GAAA,gBAAA;EAAM,SAAA,GAAA,gBAAA;EAkBG,WAAA,GAAA,kBACL;EAIK,eAAQ,GAAA,sBAKA;EAIR,WAAQ,GAAA,kBAEb;EAGK,SAAM,GAAA,gBAEX;EAGK,QAAA,GAAQ,kBAEb;AAGP;AAKY,iBAtDI,gBAAA,CAuDI,MAAM,EAtDjB,MAsDiB,CAAA,MAAA,EAtDF,QAsDE,GAAA,MAAA,CAAA,CAAA,EArDvB,MAqDuB,CAAA,MAAA,EAAA,MAAA,CAAA;AAId,KAvCA,YAAA,GAuCQ;EAAA,IAAA,EAtCb,YAAA,CAAa,YAsCA;EAAA,GACjB,EAAA,MAAA;CAAY;AAEZ,KArCS,QAAA,GAqCT;EAAQ,QACR,EAAA,MAAA;EAAM,IACN,EAAA,MAAA;EAAG,QACH,EAAA,MAAA;EAAM,IAAA,EAAA,MAAA;EAEG,IAAA,EArCL,YAAA,CAAa,QAqCS;EAAA,QAAA,EAAA,MAAA;CAAA;AAErB,KAnCI,QAAA,GAmCJ;EAAC,IACJ,EAAA,MAAA;EAAM,IAAA,EAlCJ,YAAA,CAAa,QAkCT;;KA/BC,MAAA;;QAEL,YAAA,CAAa;;KAGR,QAAA;;QAEL,YAAA,CAAa;;KAGR,GAAA;;QAEL,YAAA,CAAa;;KAGR,MAAA;QACL,YAAA,CAAa;;;KAIR,QAAA,GACT,eACA,WACA,WACA,SACA,MACA;KAES,4BAA4B,kCAEhC,MACH"}
|
|
@@ -50,6 +50,7 @@ type Secret = {
|
|
|
50
50
|
};
|
|
51
51
|
type Resource = ApiGatewayV2 | Postgres | Function | Bucket | Vpc | Secret;
|
|
52
52
|
type ResourceProcessor<K extends Resource> = (name: string, value: K) => Record<string, string | number>;
|
|
53
|
+
//# sourceMappingURL=index.d.ts.map
|
|
53
54
|
//#endregion
|
|
54
55
|
export { ApiGatewayV2, Bucket, Function, Postgres, Resource, ResourceProcessor, ResourceType, Secret, SnsTopic, Vpc, buildResourceEnv, environmentCase, getLocalIpAddress };
|
|
55
|
-
//# sourceMappingURL=index-
|
|
56
|
+
//# sourceMappingURL=index-DZ0QrJQr.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index-DZ0QrJQr.d.mts","names":[],"sources":["../src/utils/index.ts"],"sourcesContent":[],"mappings":";iBAGgB,iBAAA,CAAA;AAAA,iBAcA,eAAA,CAdiB,IAAA,EAAA,MAAA,CAAA,EAAA,MAAA;AAcjB,aAOJ,YAAA;EAAA,YAAA,GAAY,sBAAA;EA+DR,QAAA,GAAA,kBAAgB;EAAA,QAAA,GAAA,kBAAA;EAAA,MACR,GAAA,gBAAA;EAAQ,GAAvB,GAAA,aAAA;EAAM,MACZ,GAAA,gBAAA;EAAM,SAAA,GAAA,gBAAA;EAkBG,WAAA,GAAA,kBACL;EAIK,eAAQ,GAAA,sBAKA;EAIR,WAAQ,GAAA,kBAEb;EAGK,SAAM,GAAA,gBAEX;EAGK,QAAA,GAAQ,kBAEb;AAGP;AAKY,iBAtDI,gBAAA,CAuDI,MAAM,EAtDjB,MAsDiB,CAAA,MAAA,EAtDF,QAsDE,GAAA,MAAA,CAAA,CAAA,EArDvB,MAqDuB,CAAA,MAAA,EAAA,MAAA,CAAA;AAId,KAvCA,YAAA,GAuCQ;EAAA,IAAA,EAtCb,YAAA,CAAa,YAsCA;EAAA,GACjB,EAAA,MAAA;CAAY;AAEZ,KArCS,QAAA,GAqCT;EAAQ,QACR,EAAA,MAAA;EAAM,IACN,EAAA,MAAA;EAAG,QACH,EAAA,MAAA;EAAM,IAAA,EAAA,MAAA;EAEG,IAAA,EArCL,YAAA,CAAa,QAqCS;EAAA,QAAA,EAAA,MAAA;CAAA;AAErB,KAnCI,QAAA,GAmCJ;EAAC,IACJ,EAAA,MAAA;EAAM,IAAA,EAlCJ,YAAA,CAAa,QAkCT;;KA/BC,MAAA;;QAEL,YAAA,CAAa;;KAGR,QAAA;;QAEL,YAAA,CAAa;;KAGR,GAAA;;QAEL,YAAA,CAAa;;KAGR,MAAA;QACL,YAAA,CAAa;;;KAIR,QAAA,GACT,eACA,WACA,WACA,SACA,MACA;KAES,4BAA4B,kCAEhC,MACH"}
|
package/dist/index.cjs
CHANGED
package/dist/index.d.cts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { buildResourceEnv } from "./index-
|
|
1
|
+
import { buildResourceEnv } from "./index-ByEJy40r.cjs";
|
|
2
2
|
export { buildResourceEnv };
|
package/dist/index.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { buildResourceEnv } from "./index-
|
|
1
|
+
import { buildResourceEnv } from "./index-DZ0QrJQr.mjs";
|
|
2
2
|
export { buildResourceEnv };
|
package/dist/index.mjs
CHANGED
package/dist/utils/index.cjs
CHANGED
package/dist/utils/index.d.cts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { ApiGatewayV2, Bucket, Function, Postgres, Resource, ResourceProcessor, ResourceType, Secret, SnsTopic, Vpc, buildResourceEnv, environmentCase, getLocalIpAddress } from "../index-
|
|
1
|
+
import { ApiGatewayV2, Bucket, Function, Postgres, Resource, ResourceProcessor, ResourceType, Secret, SnsTopic, Vpc, buildResourceEnv, environmentCase, getLocalIpAddress } from "../index-ByEJy40r.cjs";
|
|
2
2
|
export { ApiGatewayV2, Bucket, Function, Postgres, Resource, ResourceProcessor, ResourceType, Secret, SnsTopic, Vpc, buildResourceEnv, environmentCase, getLocalIpAddress };
|
package/dist/utils/index.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { ApiGatewayV2, Bucket, Function, Postgres, Resource, ResourceProcessor, ResourceType, Secret, SnsTopic, Vpc, buildResourceEnv, environmentCase, getLocalIpAddress } from "../index-
|
|
1
|
+
import { ApiGatewayV2, Bucket, Function, Postgres, Resource, ResourceProcessor, ResourceType, Secret, SnsTopic, Vpc, buildResourceEnv, environmentCase, getLocalIpAddress } from "../index-DZ0QrJQr.mjs";
|
|
2
2
|
export { ApiGatewayV2, Bucket, Function, Postgres, Resource, ResourceProcessor, ResourceType, Secret, SnsTopic, Vpc, buildResourceEnv, environmentCase, getLocalIpAddress };
|
package/dist/utils/index.mjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { ResourceType, buildResourceEnv, environmentCase, getLocalIpAddress } from "../utils-
|
|
1
|
+
import { ResourceType, buildResourceEnv, environmentCase, getLocalIpAddress } from "../utils-BdKG20_m.mjs";
|
|
2
2
|
|
|
3
3
|
export { ResourceType, buildResourceEnv, environmentCase, getLocalIpAddress };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import os from "node:os";
|
|
1
2
|
import snakecase from "lodash.snakecase";
|
|
2
|
-
import os from "os";
|
|
3
3
|
|
|
4
4
|
//#region src/utils/index.ts
|
|
5
5
|
function getLocalIpAddress() {
|
|
@@ -50,7 +50,7 @@ const topic = (name, value) => {
|
|
|
50
50
|
const key = `${prefix}_ARN`;
|
|
51
51
|
return { [key]: value.arn };
|
|
52
52
|
};
|
|
53
|
-
const noop = (
|
|
53
|
+
const noop = (_name, _value) => ({});
|
|
54
54
|
const processors = {
|
|
55
55
|
[ResourceType.ApiGatewayV2]: noop,
|
|
56
56
|
[ResourceType.Function]: noop,
|
|
@@ -74,11 +74,10 @@ function buildResourceEnv(record) {
|
|
|
74
74
|
}
|
|
75
75
|
const processor = processors[value.type];
|
|
76
76
|
if (processor) Object.assign(env, processor(k, value));
|
|
77
|
-
else console.warn(`No processor found for resource type: `, { value });
|
|
78
77
|
}
|
|
79
78
|
return env;
|
|
80
79
|
}
|
|
81
80
|
|
|
82
81
|
//#endregion
|
|
83
82
|
export { ResourceType, buildResourceEnv, environmentCase, getLocalIpAddress };
|
|
84
|
-
//# sourceMappingURL=utils-
|
|
83
|
+
//# sourceMappingURL=utils-BdKG20_m.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils-BdKG20_m.mjs","names":["name: string","value: Secret","key: string","value: Postgres","value: Bucket","value: SnsTopic","_name: string","_value: any","processors: Record<ResourceType, ResourceProcessor<any>>","record: Record<string, Resource | string>","env: Record<string, string>"],"sources":["../src/utils/index.ts"],"sourcesContent":["import os from 'node:os';\nimport snakecase from 'lodash.snakecase';\n\nexport function getLocalIpAddress() {\n\tconst networkInterfaces = os.networkInterfaces();\n\tfor (const interfaceName in networkInterfaces) {\n\t\tconst addresses = networkInterfaces[interfaceName] || [];\n\t\tfor (const addressInfo of addresses) {\n\t\t\t// Look for an IPv4 address that is not internal (loopback)\n\t\t\tif (addressInfo.family === 'IPv4' && !addressInfo.internal) {\n\t\t\t\treturn addressInfo.address;\n\t\t\t}\n\t\t}\n\t}\n\treturn null; // No suitable IP address found\n}\n\nexport function environmentCase(name: string) {\n\treturn snakecase(name)\n\t\t.toUpperCase()\n\t\t.replace(/_\\d+/g, (r) => {\n\t\t\treturn r.replace('_', '');\n\t\t});\n}\nexport enum ResourceType {\n\tApiGatewayV2 = 'sst.aws.ApiGatewayV2',\n\tPostgres = 'sst.aws.Postgres',\n\tFunction = 'sst.aws.Function',\n\tBucket = 'sst.aws.Bucket',\n\tVpc = 'sst.aws.Vpc',\n\tSecret = 'sst.sst.Secret',\n\tSSTSecret = 'sst:sst:Secret',\n\tSSTFunction = 'sst:sst:Function',\n\tSSTApiGatewayV2 = 'sst:aws:ApiGatewayV2',\n\tSSTPostgres = 'sst:aws:Postgres',\n\tSSTBucket = 'sst:aws:Bucket',\n\tSnsTopic = 'sst:aws:SnsTopic',\n}\n\nconst secret = (name: string, value: Secret) => ({\n\t[environmentCase(name)]: value.value,\n});\nconst postgres = (key: string, value: Postgres) => {\n\tconst prefix = `${environmentCase(key)}`;\n\treturn {\n\t\t[`${prefix}_NAME`]: value.database,\n\t\t[`${prefix}_HOST`]: value.host,\n\t\t[`${prefix}_PASSWORD`]: value.password,\n\t\t[`${prefix}_PORT`]: value.port,\n\t\t[`${prefix}_USERNAME`]: value.username,\n\t};\n};\n\nconst bucket = (name: string, value: Bucket) => {\n\tconst prefix = `${environmentCase(name)}`;\n\treturn {\n\t\t[`${prefix}_NAME`]: value.name,\n\t};\n};\n\nconst topic = (name: string, value: SnsTopic) => {\n\tconst prefix = `${environmentCase(name)}`;\n\tconst key = `${prefix}_ARN`;\n\n\treturn {\n\t\t[key]: value.arn,\n\t};\n};\n\nconst noop = (_name: string, _value: any) => ({});\n\nconst processors: Record<ResourceType, ResourceProcessor<any>> = {\n\t[ResourceType.ApiGatewayV2]: noop,\n\t[ResourceType.Function]: noop,\n\t[ResourceType.Vpc]: noop,\n\t[ResourceType.Secret]: secret,\n\t[ResourceType.Postgres]: postgres,\n\t[ResourceType.Bucket]: bucket,\n\n\t[ResourceType.SSTSecret]: secret,\n\t[ResourceType.SSTBucket]: bucket,\n\t[ResourceType.SSTFunction]: noop,\n\t[ResourceType.SSTPostgres]: postgres,\n\t[ResourceType.SSTApiGatewayV2]: noop,\n\t[ResourceType.SnsTopic]: topic,\n};\n\nexport function buildResourceEnv(\n\trecord: Record<string, Resource | string>,\n): Record<string, string> {\n\tconst env: Record<string, string> = {};\n\tfor (const [k, value] of Object.entries(record)) {\n\t\tif (typeof value === 'string') {\n\t\t\tenv[environmentCase(k)] = value;\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst processor = processors[value.type];\n\t\tif (processor) {\n\t\t\tObject.assign(env, processor(k, value));\n\t\t} else {\n\t\t}\n\t}\n\n\treturn env;\n}\n\nexport type ApiGatewayV2 = {\n\ttype: ResourceType.ApiGatewayV2;\n\turl: string;\n};\n\nexport type Postgres = {\n\tdatabase: string;\n\thost: string;\n\tpassword: string;\n\tport: number;\n\ttype: ResourceType.Postgres;\n\tusername: string;\n};\n\nexport type Function = {\n\tname: string;\n\ttype: ResourceType.Function;\n};\n\nexport type Bucket = {\n\tname: string;\n\ttype: ResourceType.Bucket;\n};\n\nexport type SnsTopic = {\n\tarn: string;\n\ttype: ResourceType.SnsTopic;\n};\n\nexport type Vpc = {\n\tbastion: string;\n\ttype: ResourceType.Vpc;\n};\n\nexport type Secret = {\n\ttype: ResourceType.Secret;\n\tvalue: string;\n};\n\nexport type Resource =\n\t| ApiGatewayV2\n\t| Postgres\n\t| Function\n\t| Bucket\n\t| Vpc\n\t| Secret;\n\nexport type ResourceProcessor<K extends Resource> = (\n\tname: string,\n\tvalue: K,\n) => Record<string, string | number>;\n"],"mappings":";;;;AAGA,SAAgB,oBAAoB;CACnC,MAAM,oBAAoB,GAAG,mBAAmB;AAChD,MAAK,MAAM,iBAAiB,mBAAmB;EAC9C,MAAM,YAAY,kBAAkB,kBAAkB,CAAE;AACxD,OAAK,MAAM,eAAe,UAEzB,KAAI,YAAY,WAAW,WAAW,YAAY,SACjD,QAAO,YAAY;CAGrB;AACD,QAAO;AACP;AAED,SAAgB,gBAAgBA,MAAc;AAC7C,QAAO,UAAU,KAAK,CACpB,aAAa,CACb,QAAQ,SAAS,CAAC,MAAM;AACxB,SAAO,EAAE,QAAQ,KAAK,GAAG;CACzB,EAAC;AACH;AACD,IAAY,wDAAL;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AACA;AAED,MAAM,SAAS,CAACA,MAAcC,WAAmB,GAC/C,gBAAgB,KAAK,GAAG,MAAM,MAC/B;AACD,MAAM,WAAW,CAACC,KAAaC,UAAoB;CAClD,MAAM,UAAU,EAAE,gBAAgB,IAAI,CAAC;AACvC,QAAO;IACJ,EAAE,OAAO,SAAS,MAAM;IACxB,EAAE,OAAO,SAAS,MAAM;IACxB,EAAE,OAAO,aAAa,MAAM;IAC5B,EAAE,OAAO,SAAS,MAAM;IACxB,EAAE,OAAO,aAAa,MAAM;CAC9B;AACD;AAED,MAAM,SAAS,CAACH,MAAcI,UAAkB;CAC/C,MAAM,UAAU,EAAE,gBAAgB,KAAK,CAAC;AACxC,QAAO,IACJ,EAAE,OAAO,SAAS,MAAM,KAC1B;AACD;AAED,MAAM,QAAQ,CAACJ,MAAcK,UAAoB;CAChD,MAAM,UAAU,EAAE,gBAAgB,KAAK,CAAC;CACxC,MAAM,OAAO,EAAE,OAAO;AAEtB,QAAO,GACL,MAAM,MAAM,IACb;AACD;AAED,MAAM,OAAO,CAACC,OAAeC,YAAiB,CAAE;AAEhD,MAAMC,aAA2D;EAC/D,aAAa,eAAe;EAC5B,aAAa,WAAW;EACxB,aAAa,MAAM;EACnB,aAAa,SAAS;EACtB,aAAa,WAAW;EACxB,aAAa,SAAS;EAEtB,aAAa,YAAY;EACzB,aAAa,YAAY;EACzB,aAAa,cAAc;EAC3B,aAAa,cAAc;EAC3B,aAAa,kBAAkB;EAC/B,aAAa,WAAW;AACzB;AAED,SAAgB,iBACfC,QACyB;CACzB,MAAMC,MAA8B,CAAE;AACtC,MAAK,MAAM,CAAC,GAAG,MAAM,IAAI,OAAO,QAAQ,OAAO,EAAE;AAChD,aAAW,UAAU,UAAU;AAC9B,OAAI,gBAAgB,EAAE,IAAI;AAC1B;EACA;EAED,MAAM,YAAY,WAAW,MAAM;AACnC,MAAI,UACH,QAAO,OAAO,KAAK,UAAU,GAAG,MAAM,CAAC;CAGxC;AAED,QAAO;AACP"}
|
|
@@ -21,12 +21,12 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
21
21
|
}) : target, mod));
|
|
22
22
|
|
|
23
23
|
//#endregion
|
|
24
|
+
const node_os = __toESM(require("node:os"));
|
|
24
25
|
const lodash_snakecase = __toESM(require("lodash.snakecase"));
|
|
25
|
-
const os = __toESM(require("os"));
|
|
26
26
|
|
|
27
27
|
//#region src/utils/index.ts
|
|
28
28
|
function getLocalIpAddress() {
|
|
29
|
-
const networkInterfaces =
|
|
29
|
+
const networkInterfaces = node_os.default.networkInterfaces();
|
|
30
30
|
for (const interfaceName in networkInterfaces) {
|
|
31
31
|
const addresses = networkInterfaces[interfaceName] || [];
|
|
32
32
|
for (const addressInfo of addresses) if (addressInfo.family === "IPv4" && !addressInfo.internal) return addressInfo.address;
|
|
@@ -73,7 +73,7 @@ const topic = (name, value) => {
|
|
|
73
73
|
const key = `${prefix}_ARN`;
|
|
74
74
|
return { [key]: value.arn };
|
|
75
75
|
};
|
|
76
|
-
const noop = (
|
|
76
|
+
const noop = (_name, _value) => ({});
|
|
77
77
|
const processors = {
|
|
78
78
|
[ResourceType.ApiGatewayV2]: noop,
|
|
79
79
|
[ResourceType.Function]: noop,
|
|
@@ -97,7 +97,6 @@ function buildResourceEnv(record) {
|
|
|
97
97
|
}
|
|
98
98
|
const processor = processors[value.type];
|
|
99
99
|
if (processor) Object.assign(env, processor(k, value));
|
|
100
|
-
else console.warn(`No processor found for resource type: `, { value });
|
|
101
100
|
}
|
|
102
101
|
return env;
|
|
103
102
|
}
|
|
@@ -127,4 +126,4 @@ Object.defineProperty(exports, 'getLocalIpAddress', {
|
|
|
127
126
|
return getLocalIpAddress;
|
|
128
127
|
}
|
|
129
128
|
});
|
|
130
|
-
//# sourceMappingURL=utils-
|
|
129
|
+
//# sourceMappingURL=utils-CtMjuIMR.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils-CtMjuIMR.cjs","names":["name: string","value: Secret","key: string","value: Postgres","value: Bucket","value: SnsTopic","_name: string","_value: any","processors: Record<ResourceType, ResourceProcessor<any>>","record: Record<string, Resource | string>","env: Record<string, string>"],"sources":["../src/utils/index.ts"],"sourcesContent":["import os from 'node:os';\nimport snakecase from 'lodash.snakecase';\n\nexport function getLocalIpAddress() {\n\tconst networkInterfaces = os.networkInterfaces();\n\tfor (const interfaceName in networkInterfaces) {\n\t\tconst addresses = networkInterfaces[interfaceName] || [];\n\t\tfor (const addressInfo of addresses) {\n\t\t\t// Look for an IPv4 address that is not internal (loopback)\n\t\t\tif (addressInfo.family === 'IPv4' && !addressInfo.internal) {\n\t\t\t\treturn addressInfo.address;\n\t\t\t}\n\t\t}\n\t}\n\treturn null; // No suitable IP address found\n}\n\nexport function environmentCase(name: string) {\n\treturn snakecase(name)\n\t\t.toUpperCase()\n\t\t.replace(/_\\d+/g, (r) => {\n\t\t\treturn r.replace('_', '');\n\t\t});\n}\nexport enum ResourceType {\n\tApiGatewayV2 = 'sst.aws.ApiGatewayV2',\n\tPostgres = 'sst.aws.Postgres',\n\tFunction = 'sst.aws.Function',\n\tBucket = 'sst.aws.Bucket',\n\tVpc = 'sst.aws.Vpc',\n\tSecret = 'sst.sst.Secret',\n\tSSTSecret = 'sst:sst:Secret',\n\tSSTFunction = 'sst:sst:Function',\n\tSSTApiGatewayV2 = 'sst:aws:ApiGatewayV2',\n\tSSTPostgres = 'sst:aws:Postgres',\n\tSSTBucket = 'sst:aws:Bucket',\n\tSnsTopic = 'sst:aws:SnsTopic',\n}\n\nconst secret = (name: string, value: Secret) => ({\n\t[environmentCase(name)]: value.value,\n});\nconst postgres = (key: string, value: Postgres) => {\n\tconst prefix = `${environmentCase(key)}`;\n\treturn {\n\t\t[`${prefix}_NAME`]: value.database,\n\t\t[`${prefix}_HOST`]: value.host,\n\t\t[`${prefix}_PASSWORD`]: value.password,\n\t\t[`${prefix}_PORT`]: value.port,\n\t\t[`${prefix}_USERNAME`]: value.username,\n\t};\n};\n\nconst bucket = (name: string, value: Bucket) => {\n\tconst prefix = `${environmentCase(name)}`;\n\treturn {\n\t\t[`${prefix}_NAME`]: value.name,\n\t};\n};\n\nconst topic = (name: string, value: SnsTopic) => {\n\tconst prefix = `${environmentCase(name)}`;\n\tconst key = `${prefix}_ARN`;\n\n\treturn {\n\t\t[key]: value.arn,\n\t};\n};\n\nconst noop = (_name: string, _value: any) => ({});\n\nconst processors: Record<ResourceType, ResourceProcessor<any>> = {\n\t[ResourceType.ApiGatewayV2]: noop,\n\t[ResourceType.Function]: noop,\n\t[ResourceType.Vpc]: noop,\n\t[ResourceType.Secret]: secret,\n\t[ResourceType.Postgres]: postgres,\n\t[ResourceType.Bucket]: bucket,\n\n\t[ResourceType.SSTSecret]: secret,\n\t[ResourceType.SSTBucket]: bucket,\n\t[ResourceType.SSTFunction]: noop,\n\t[ResourceType.SSTPostgres]: postgres,\n\t[ResourceType.SSTApiGatewayV2]: noop,\n\t[ResourceType.SnsTopic]: topic,\n};\n\nexport function buildResourceEnv(\n\trecord: Record<string, Resource | string>,\n): Record<string, string> {\n\tconst env: Record<string, string> = {};\n\tfor (const [k, value] of Object.entries(record)) {\n\t\tif (typeof value === 'string') {\n\t\t\tenv[environmentCase(k)] = value;\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst processor = processors[value.type];\n\t\tif (processor) {\n\t\t\tObject.assign(env, processor(k, value));\n\t\t} else {\n\t\t}\n\t}\n\n\treturn env;\n}\n\nexport type ApiGatewayV2 = {\n\ttype: ResourceType.ApiGatewayV2;\n\turl: string;\n};\n\nexport type Postgres = {\n\tdatabase: string;\n\thost: string;\n\tpassword: string;\n\tport: number;\n\ttype: ResourceType.Postgres;\n\tusername: string;\n};\n\nexport type Function = {\n\tname: string;\n\ttype: ResourceType.Function;\n};\n\nexport type Bucket = {\n\tname: string;\n\ttype: ResourceType.Bucket;\n};\n\nexport type SnsTopic = {\n\tarn: string;\n\ttype: ResourceType.SnsTopic;\n};\n\nexport type Vpc = {\n\tbastion: string;\n\ttype: ResourceType.Vpc;\n};\n\nexport type Secret = {\n\ttype: ResourceType.Secret;\n\tvalue: string;\n};\n\nexport type Resource =\n\t| ApiGatewayV2\n\t| Postgres\n\t| Function\n\t| Bucket\n\t| Vpc\n\t| Secret;\n\nexport type ResourceProcessor<K extends Resource> = (\n\tname: string,\n\tvalue: K,\n) => Record<string, string | number>;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AAGA,SAAgB,oBAAoB;CACnC,MAAM,oBAAoB,gBAAG,mBAAmB;AAChD,MAAK,MAAM,iBAAiB,mBAAmB;EAC9C,MAAM,YAAY,kBAAkB,kBAAkB,CAAE;AACxD,OAAK,MAAM,eAAe,UAEzB,KAAI,YAAY,WAAW,WAAW,YAAY,SACjD,QAAO,YAAY;CAGrB;AACD,QAAO;AACP;AAED,SAAgB,gBAAgBA,MAAc;AAC7C,QAAO,8BAAU,KAAK,CACpB,aAAa,CACb,QAAQ,SAAS,CAAC,MAAM;AACxB,SAAO,EAAE,QAAQ,KAAK,GAAG;CACzB,EAAC;AACH;AACD,IAAY,wDAAL;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AACA;AAED,MAAM,SAAS,CAACA,MAAcC,WAAmB,GAC/C,gBAAgB,KAAK,GAAG,MAAM,MAC/B;AACD,MAAM,WAAW,CAACC,KAAaC,UAAoB;CAClD,MAAM,UAAU,EAAE,gBAAgB,IAAI,CAAC;AACvC,QAAO;IACJ,EAAE,OAAO,SAAS,MAAM;IACxB,EAAE,OAAO,SAAS,MAAM;IACxB,EAAE,OAAO,aAAa,MAAM;IAC5B,EAAE,OAAO,SAAS,MAAM;IACxB,EAAE,OAAO,aAAa,MAAM;CAC9B;AACD;AAED,MAAM,SAAS,CAACH,MAAcI,UAAkB;CAC/C,MAAM,UAAU,EAAE,gBAAgB,KAAK,CAAC;AACxC,QAAO,IACJ,EAAE,OAAO,SAAS,MAAM,KAC1B;AACD;AAED,MAAM,QAAQ,CAACJ,MAAcK,UAAoB;CAChD,MAAM,UAAU,EAAE,gBAAgB,KAAK,CAAC;CACxC,MAAM,OAAO,EAAE,OAAO;AAEtB,QAAO,GACL,MAAM,MAAM,IACb;AACD;AAED,MAAM,OAAO,CAACC,OAAeC,YAAiB,CAAE;AAEhD,MAAMC,aAA2D;EAC/D,aAAa,eAAe;EAC5B,aAAa,WAAW;EACxB,aAAa,MAAM;EACnB,aAAa,SAAS;EACtB,aAAa,WAAW;EACxB,aAAa,SAAS;EAEtB,aAAa,YAAY;EACzB,aAAa,YAAY;EACzB,aAAa,cAAc;EAC3B,aAAa,cAAc;EAC3B,aAAa,kBAAkB;EAC/B,aAAa,WAAW;AACzB;AAED,SAAgB,iBACfC,QACyB;CACzB,MAAMC,MAA8B,CAAE;AACtC,MAAK,MAAM,CAAC,GAAG,MAAM,IAAI,OAAO,QAAQ,OAAO,EAAE;AAChD,aAAW,UAAU,UAAU;AAC9B,OAAI,gBAAgB,EAAE,IAAI;AAC1B;EACA;EAED,MAAM,YAAY,WAAW,MAAM;AACnC,MAAI,UACH,QAAO,OAAO,KAAK,UAAU,GAAG,MAAM,CAAC;CAGxC;AAED,QAAO;AACP"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@geekmidas/cloud",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": {
|
|
@@ -14,6 +14,10 @@
|
|
|
14
14
|
"require": "./dist/utils/index.cjs"
|
|
15
15
|
}
|
|
16
16
|
},
|
|
17
|
+
"repository": {
|
|
18
|
+
"type": "git",
|
|
19
|
+
"url": "https://github.com/geekmidas/toolbox"
|
|
20
|
+
},
|
|
17
21
|
"publishConfig": {
|
|
18
22
|
"registry": "https://registry.npmjs.org/",
|
|
19
23
|
"access": "public"
|
|
@@ -25,5 +29,8 @@
|
|
|
25
29
|
"@types/lodash.get": "~4.4.9",
|
|
26
30
|
"@types/lodash.set": "~4.3.9",
|
|
27
31
|
"@types/lodash.snakecase": "~4.1.9"
|
|
32
|
+
},
|
|
33
|
+
"peerDependencies": {
|
|
34
|
+
"sst": "~3.17.23"
|
|
28
35
|
}
|
|
29
36
|
}
|
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import {
|
|
3
|
+
buildResourceEnv,
|
|
4
|
+
environmentCase,
|
|
5
|
+
getLocalIpAddress,
|
|
6
|
+
ResourceType,
|
|
7
|
+
} from '../utils';
|
|
8
|
+
|
|
9
|
+
describe('getLocalIpAddress', () => {
|
|
10
|
+
it('should return a valid IPv4 address or null', () => {
|
|
11
|
+
const ip = getLocalIpAddress();
|
|
12
|
+
|
|
13
|
+
if (ip !== null) {
|
|
14
|
+
// Should be a valid IPv4 format
|
|
15
|
+
const parts = ip.split('.');
|
|
16
|
+
expect(parts).toHaveLength(4);
|
|
17
|
+
for (const part of parts) {
|
|
18
|
+
const num = Number.parseInt(part, 10);
|
|
19
|
+
expect(num).toBeGreaterThanOrEqual(0);
|
|
20
|
+
expect(num).toBeLessThanOrEqual(255);
|
|
21
|
+
}
|
|
22
|
+
} else {
|
|
23
|
+
expect(ip).toBeNull();
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
it('should not return loopback address', () => {
|
|
28
|
+
const ip = getLocalIpAddress();
|
|
29
|
+
|
|
30
|
+
if (ip !== null) {
|
|
31
|
+
expect(ip).not.toBe('127.0.0.1');
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
describe('environmentCase', () => {
|
|
37
|
+
it('should convert camelCase to SNAKE_CASE', () => {
|
|
38
|
+
expect(environmentCase('databaseUrl')).toBe('DATABASE_URL');
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
it('should convert PascalCase to SNAKE_CASE', () => {
|
|
42
|
+
expect(environmentCase('DatabaseUrl')).toBe('DATABASE_URL');
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
it('should convert kebab-case to SNAKE_CASE', () => {
|
|
46
|
+
expect(environmentCase('database-url')).toBe('DATABASE_URL');
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
it('should handle single word', () => {
|
|
50
|
+
expect(environmentCase('database')).toBe('DATABASE');
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
it('should handle numbers without underscore prefix', () => {
|
|
54
|
+
expect(environmentCase('api2Endpoint')).toBe('API2_ENDPOINT');
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
it('should handle multiple numbers', () => {
|
|
58
|
+
expect(environmentCase('value1And2')).toBe('VALUE1_AND2');
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
it('should handle already uppercase', () => {
|
|
62
|
+
expect(environmentCase('DATABASE')).toBe('DATABASE');
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
describe('buildResourceEnv', () => {
|
|
67
|
+
it('should handle string values', () => {
|
|
68
|
+
const result = buildResourceEnv({
|
|
69
|
+
databaseUrl: 'postgres://localhost/db',
|
|
70
|
+
apiKey: 'secret-key',
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
expect(result).toEqual({
|
|
74
|
+
DATABASE_URL: 'postgres://localhost/db',
|
|
75
|
+
API_KEY: 'secret-key',
|
|
76
|
+
});
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
it('should handle Secret resource type', () => {
|
|
80
|
+
const result = buildResourceEnv({
|
|
81
|
+
mySecret: {
|
|
82
|
+
type: ResourceType.Secret,
|
|
83
|
+
value: 'secret-value',
|
|
84
|
+
},
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
expect(result).toEqual({
|
|
88
|
+
MY_SECRET: 'secret-value',
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
it('should handle SSTSecret resource type', () => {
|
|
93
|
+
const result = buildResourceEnv({
|
|
94
|
+
apiToken: {
|
|
95
|
+
type: ResourceType.SSTSecret,
|
|
96
|
+
value: 'token-value',
|
|
97
|
+
},
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
expect(result).toEqual({
|
|
101
|
+
API_TOKEN: 'token-value',
|
|
102
|
+
});
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
it('should handle Postgres resource type', () => {
|
|
106
|
+
const result = buildResourceEnv({
|
|
107
|
+
database: {
|
|
108
|
+
type: ResourceType.Postgres,
|
|
109
|
+
database: 'mydb',
|
|
110
|
+
host: 'localhost',
|
|
111
|
+
password: 'secret',
|
|
112
|
+
port: 5432,
|
|
113
|
+
username: 'user',
|
|
114
|
+
},
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
expect(result).toEqual({
|
|
118
|
+
DATABASE_NAME: 'mydb',
|
|
119
|
+
DATABASE_HOST: 'localhost',
|
|
120
|
+
DATABASE_PASSWORD: 'secret',
|
|
121
|
+
DATABASE_PORT: 5432,
|
|
122
|
+
DATABASE_USERNAME: 'user',
|
|
123
|
+
});
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
it('should handle SSTPostgres resource type', () => {
|
|
127
|
+
const result = buildResourceEnv({
|
|
128
|
+
db: {
|
|
129
|
+
type: ResourceType.SSTPostgres,
|
|
130
|
+
database: 'testdb',
|
|
131
|
+
host: 'db.example.com',
|
|
132
|
+
password: 'pass123',
|
|
133
|
+
port: 5432,
|
|
134
|
+
username: 'admin',
|
|
135
|
+
},
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
expect(result).toEqual({
|
|
139
|
+
DB_NAME: 'testdb',
|
|
140
|
+
DB_HOST: 'db.example.com',
|
|
141
|
+
DB_PASSWORD: 'pass123',
|
|
142
|
+
DB_PORT: 5432,
|
|
143
|
+
DB_USERNAME: 'admin',
|
|
144
|
+
});
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
it('should handle Bucket resource type', () => {
|
|
148
|
+
const result = buildResourceEnv({
|
|
149
|
+
uploads: {
|
|
150
|
+
type: ResourceType.Bucket,
|
|
151
|
+
name: 'my-uploads-bucket',
|
|
152
|
+
},
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
expect(result).toEqual({
|
|
156
|
+
UPLOADS_NAME: 'my-uploads-bucket',
|
|
157
|
+
});
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
it('should handle SSTBucket resource type', () => {
|
|
161
|
+
const result = buildResourceEnv({
|
|
162
|
+
assets: {
|
|
163
|
+
type: ResourceType.SSTBucket,
|
|
164
|
+
name: 'assets-bucket',
|
|
165
|
+
},
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
expect(result).toEqual({
|
|
169
|
+
ASSETS_NAME: 'assets-bucket',
|
|
170
|
+
});
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
it('should handle SnsTopic resource type', () => {
|
|
174
|
+
const result = buildResourceEnv({
|
|
175
|
+
notifications: {
|
|
176
|
+
type: ResourceType.SnsTopic,
|
|
177
|
+
arn: 'arn:aws:sns:us-east-1:123456789:my-topic',
|
|
178
|
+
},
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
expect(result).toEqual({
|
|
182
|
+
NOTIFICATIONS_ARN: 'arn:aws:sns:us-east-1:123456789:my-topic',
|
|
183
|
+
});
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
it('should ignore ApiGatewayV2 resource type', () => {
|
|
187
|
+
const result = buildResourceEnv({
|
|
188
|
+
api: {
|
|
189
|
+
type: ResourceType.ApiGatewayV2,
|
|
190
|
+
url: 'https://api.example.com',
|
|
191
|
+
},
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
expect(result).toEqual({});
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
it('should ignore Function resource type', () => {
|
|
198
|
+
const result = buildResourceEnv({
|
|
199
|
+
handler: {
|
|
200
|
+
type: ResourceType.Function,
|
|
201
|
+
name: 'my-function',
|
|
202
|
+
},
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
expect(result).toEqual({});
|
|
206
|
+
});
|
|
207
|
+
|
|
208
|
+
it('should ignore Vpc resource type', () => {
|
|
209
|
+
const result = buildResourceEnv({
|
|
210
|
+
network: {
|
|
211
|
+
type: ResourceType.Vpc,
|
|
212
|
+
bastion: 'bastion-host',
|
|
213
|
+
},
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
expect(result).toEqual({});
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
it('should handle mixed resources', () => {
|
|
220
|
+
const result = buildResourceEnv({
|
|
221
|
+
directValue: 'direct-string',
|
|
222
|
+
secret: {
|
|
223
|
+
type: ResourceType.Secret,
|
|
224
|
+
value: 'secret-val',
|
|
225
|
+
},
|
|
226
|
+
database: {
|
|
227
|
+
type: ResourceType.Postgres,
|
|
228
|
+
database: 'app',
|
|
229
|
+
host: 'localhost',
|
|
230
|
+
password: 'pass',
|
|
231
|
+
port: 5432,
|
|
232
|
+
username: 'user',
|
|
233
|
+
},
|
|
234
|
+
bucket: {
|
|
235
|
+
type: ResourceType.Bucket,
|
|
236
|
+
name: 'my-bucket',
|
|
237
|
+
},
|
|
238
|
+
});
|
|
239
|
+
|
|
240
|
+
expect(result).toEqual({
|
|
241
|
+
DIRECT_VALUE: 'direct-string',
|
|
242
|
+
SECRET: 'secret-val',
|
|
243
|
+
DATABASE_NAME: 'app',
|
|
244
|
+
DATABASE_HOST: 'localhost',
|
|
245
|
+
DATABASE_PASSWORD: 'pass',
|
|
246
|
+
DATABASE_PORT: 5432,
|
|
247
|
+
DATABASE_USERNAME: 'user',
|
|
248
|
+
BUCKET_NAME: 'my-bucket',
|
|
249
|
+
});
|
|
250
|
+
});
|
|
251
|
+
|
|
252
|
+
it('should return empty object for empty input', () => {
|
|
253
|
+
const result = buildResourceEnv({});
|
|
254
|
+
expect(result).toEqual({});
|
|
255
|
+
});
|
|
256
|
+
});
|
package/src/utils/index.ts
CHANGED
|
@@ -1,160 +1,158 @@
|
|
|
1
|
+
import os from 'node:os';
|
|
1
2
|
import snakecase from 'lodash.snakecase';
|
|
2
3
|
|
|
3
|
-
import os from 'os';
|
|
4
|
-
|
|
5
4
|
export function getLocalIpAddress() {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
5
|
+
const networkInterfaces = os.networkInterfaces();
|
|
6
|
+
for (const interfaceName in networkInterfaces) {
|
|
7
|
+
const addresses = networkInterfaces[interfaceName] || [];
|
|
8
|
+
for (const addressInfo of addresses) {
|
|
9
|
+
// Look for an IPv4 address that is not internal (loopback)
|
|
10
|
+
if (addressInfo.family === 'IPv4' && !addressInfo.internal) {
|
|
11
|
+
return addressInfo.address;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
return null; // No suitable IP address found
|
|
17
16
|
}
|
|
18
17
|
|
|
19
18
|
export function environmentCase(name: string) {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
19
|
+
return snakecase(name)
|
|
20
|
+
.toUpperCase()
|
|
21
|
+
.replace(/_\d+/g, (r) => {
|
|
22
|
+
return r.replace('_', '');
|
|
23
|
+
});
|
|
25
24
|
}
|
|
26
25
|
export enum ResourceType {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
26
|
+
ApiGatewayV2 = 'sst.aws.ApiGatewayV2',
|
|
27
|
+
Postgres = 'sst.aws.Postgres',
|
|
28
|
+
Function = 'sst.aws.Function',
|
|
29
|
+
Bucket = 'sst.aws.Bucket',
|
|
30
|
+
Vpc = 'sst.aws.Vpc',
|
|
31
|
+
Secret = 'sst.sst.Secret',
|
|
32
|
+
SSTSecret = 'sst:sst:Secret',
|
|
33
|
+
SSTFunction = 'sst:sst:Function',
|
|
34
|
+
SSTApiGatewayV2 = 'sst:aws:ApiGatewayV2',
|
|
35
|
+
SSTPostgres = 'sst:aws:Postgres',
|
|
36
|
+
SSTBucket = 'sst:aws:Bucket',
|
|
37
|
+
SnsTopic = 'sst:aws:SnsTopic',
|
|
39
38
|
}
|
|
40
39
|
|
|
41
40
|
const secret = (name: string, value: Secret) => ({
|
|
42
|
-
|
|
41
|
+
[environmentCase(name)]: value.value,
|
|
43
42
|
});
|
|
44
43
|
const postgres = (key: string, value: Postgres) => {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
44
|
+
const prefix = `${environmentCase(key)}`;
|
|
45
|
+
return {
|
|
46
|
+
[`${prefix}_NAME`]: value.database,
|
|
47
|
+
[`${prefix}_HOST`]: value.host,
|
|
48
|
+
[`${prefix}_PASSWORD`]: value.password,
|
|
49
|
+
[`${prefix}_PORT`]: value.port,
|
|
50
|
+
[`${prefix}_USERNAME`]: value.username,
|
|
51
|
+
};
|
|
53
52
|
};
|
|
54
53
|
|
|
55
54
|
const bucket = (name: string, value: Bucket) => {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
55
|
+
const prefix = `${environmentCase(name)}`;
|
|
56
|
+
return {
|
|
57
|
+
[`${prefix}_NAME`]: value.name,
|
|
58
|
+
};
|
|
60
59
|
};
|
|
61
60
|
|
|
62
61
|
const topic = (name: string, value: SnsTopic) => {
|
|
63
|
-
|
|
64
|
-
|
|
62
|
+
const prefix = `${environmentCase(name)}`;
|
|
63
|
+
const key = `${prefix}_ARN`;
|
|
65
64
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
65
|
+
return {
|
|
66
|
+
[key]: value.arn,
|
|
67
|
+
};
|
|
69
68
|
};
|
|
70
69
|
|
|
71
|
-
const noop = (
|
|
70
|
+
const noop = (_name: string, _value: any) => ({});
|
|
72
71
|
|
|
73
72
|
const processors: Record<ResourceType, ResourceProcessor<any>> = {
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
73
|
+
[ResourceType.ApiGatewayV2]: noop,
|
|
74
|
+
[ResourceType.Function]: noop,
|
|
75
|
+
[ResourceType.Vpc]: noop,
|
|
76
|
+
[ResourceType.Secret]: secret,
|
|
77
|
+
[ResourceType.Postgres]: postgres,
|
|
78
|
+
[ResourceType.Bucket]: bucket,
|
|
79
|
+
|
|
80
|
+
[ResourceType.SSTSecret]: secret,
|
|
81
|
+
[ResourceType.SSTBucket]: bucket,
|
|
82
|
+
[ResourceType.SSTFunction]: noop,
|
|
83
|
+
[ResourceType.SSTPostgres]: postgres,
|
|
84
|
+
[ResourceType.SSTApiGatewayV2]: noop,
|
|
85
|
+
[ResourceType.SnsTopic]: topic,
|
|
87
86
|
};
|
|
88
87
|
|
|
89
88
|
export function buildResourceEnv(
|
|
90
|
-
|
|
89
|
+
record: Record<string, Resource | string>,
|
|
91
90
|
): Record<string, string> {
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
return env;
|
|
91
|
+
const env: Record<string, string> = {};
|
|
92
|
+
for (const [k, value] of Object.entries(record)) {
|
|
93
|
+
if (typeof value === 'string') {
|
|
94
|
+
env[environmentCase(k)] = value;
|
|
95
|
+
continue;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
const processor = processors[value.type];
|
|
99
|
+
if (processor) {
|
|
100
|
+
Object.assign(env, processor(k, value));
|
|
101
|
+
} else {
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
return env;
|
|
108
106
|
}
|
|
109
107
|
|
|
110
108
|
export type ApiGatewayV2 = {
|
|
111
|
-
|
|
112
|
-
|
|
109
|
+
type: ResourceType.ApiGatewayV2;
|
|
110
|
+
url: string;
|
|
113
111
|
};
|
|
114
112
|
|
|
115
113
|
export type Postgres = {
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
114
|
+
database: string;
|
|
115
|
+
host: string;
|
|
116
|
+
password: string;
|
|
117
|
+
port: number;
|
|
118
|
+
type: ResourceType.Postgres;
|
|
119
|
+
username: string;
|
|
122
120
|
};
|
|
123
121
|
|
|
124
122
|
export type Function = {
|
|
125
|
-
|
|
126
|
-
|
|
123
|
+
name: string;
|
|
124
|
+
type: ResourceType.Function;
|
|
127
125
|
};
|
|
128
126
|
|
|
129
127
|
export type Bucket = {
|
|
130
|
-
|
|
131
|
-
|
|
128
|
+
name: string;
|
|
129
|
+
type: ResourceType.Bucket;
|
|
132
130
|
};
|
|
133
131
|
|
|
134
132
|
export type SnsTopic = {
|
|
135
|
-
|
|
136
|
-
|
|
133
|
+
arn: string;
|
|
134
|
+
type: ResourceType.SnsTopic;
|
|
137
135
|
};
|
|
138
136
|
|
|
139
137
|
export type Vpc = {
|
|
140
|
-
|
|
141
|
-
|
|
138
|
+
bastion: string;
|
|
139
|
+
type: ResourceType.Vpc;
|
|
142
140
|
};
|
|
143
141
|
|
|
144
142
|
export type Secret = {
|
|
145
|
-
|
|
146
|
-
|
|
143
|
+
type: ResourceType.Secret;
|
|
144
|
+
value: string;
|
|
147
145
|
};
|
|
148
146
|
|
|
149
147
|
export type Resource =
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
148
|
+
| ApiGatewayV2
|
|
149
|
+
| Postgres
|
|
150
|
+
| Function
|
|
151
|
+
| Bucket
|
|
152
|
+
| Vpc
|
|
153
|
+
| Secret;
|
|
156
154
|
|
|
157
155
|
export type ResourceProcessor<K extends Resource> = (
|
|
158
|
-
|
|
159
|
-
|
|
156
|
+
name: string,
|
|
157
|
+
value: K,
|
|
160
158
|
) => Record<string, string | number>;
|
package/tsconfig.json
ADDED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"utils-BtXDcUV8.cjs","names":["name: string","value: Secret","key: string","value: Postgres","value: Bucket","value: SnsTopic","value: any","processors: Record<ResourceType, ResourceProcessor<any>>","record: Record<string, Resource | string>","env: Record<string, string>"],"sources":["../src/utils/index.ts"],"sourcesContent":["import snakecase from 'lodash.snakecase';\n\nimport os from 'os';\n\nexport function getLocalIpAddress() {\n const networkInterfaces = os.networkInterfaces();\n for (const interfaceName in networkInterfaces) {\n const addresses = networkInterfaces[interfaceName] || [];\n for (const addressInfo of addresses) {\n // Look for an IPv4 address that is not internal (loopback)\n if (addressInfo.family === 'IPv4' && !addressInfo.internal) {\n return addressInfo.address;\n }\n }\n }\n return null; // No suitable IP address found\n}\n\nexport function environmentCase(name: string) {\n return snakecase(name)\n .toUpperCase()\n .replace(/_\\d+/g, (r) => {\n return r.replace('_', '');\n });\n}\nexport enum ResourceType {\n ApiGatewayV2 = 'sst.aws.ApiGatewayV2',\n Postgres = 'sst.aws.Postgres',\n Function = 'sst.aws.Function',\n Bucket = 'sst.aws.Bucket',\n Vpc = 'sst.aws.Vpc',\n Secret = 'sst.sst.Secret',\n SSTSecret = 'sst:sst:Secret',\n SSTFunction = 'sst:sst:Function',\n SSTApiGatewayV2 = 'sst:aws:ApiGatewayV2',\n SSTPostgres = 'sst:aws:Postgres',\n SSTBucket = 'sst:aws:Bucket',\n SnsTopic = 'sst:aws:SnsTopic',\n}\n\nconst secret = (name: string, value: Secret) => ({\n [environmentCase(name)]: value.value,\n});\nconst postgres = (key: string, value: Postgres) => {\n const prefix = `${environmentCase(key)}`;\n return {\n [`${prefix}_NAME`]: value.database,\n [`${prefix}_HOST`]: value.host,\n [`${prefix}_PASSWORD`]: value.password,\n [`${prefix}_PORT`]: value.port,\n [`${prefix}_USERNAME`]: value.username,\n };\n};\n\nconst bucket = (name: string, value: Bucket) => {\n const prefix = `${environmentCase(name)}`;\n return {\n [`${prefix}_NAME`]: value.name,\n };\n};\n\nconst topic = (name: string, value: SnsTopic) => {\n const prefix = `${environmentCase(name)}`;\n const key = `${prefix}_ARN`;\n\n return {\n [key]: value.arn,\n };\n};\n\nconst noop = (name: string, value: any) => ({});\n\nconst processors: Record<ResourceType, ResourceProcessor<any>> = {\n [ResourceType.ApiGatewayV2]: noop,\n [ResourceType.Function]: noop,\n [ResourceType.Vpc]: noop,\n [ResourceType.Secret]: secret,\n [ResourceType.Postgres]: postgres,\n [ResourceType.Bucket]: bucket,\n\n [ResourceType.SSTSecret]: secret,\n [ResourceType.SSTBucket]: bucket,\n [ResourceType.SSTFunction]: noop,\n [ResourceType.SSTPostgres]: postgres,\n [ResourceType.SSTApiGatewayV2]: noop,\n [ResourceType.SnsTopic]: topic,\n};\n\nexport function buildResourceEnv(\n record: Record<string, Resource | string>,\n): Record<string, string> {\n const env: Record<string, string> = {};\n for (const [k, value] of Object.entries(record)) {\n if (typeof value === 'string') {\n env[environmentCase(k)] = value;\n continue;\n }\n\n const processor = processors[value.type];\n if (processor) {\n Object.assign(env, processor(k, value));\n } else {\n console.warn(`No processor found for resource type: `, { value });\n }\n }\n\n return env;\n}\n\nexport type ApiGatewayV2 = {\n type: ResourceType.ApiGatewayV2;\n url: string;\n};\n\nexport type Postgres = {\n database: string;\n host: string;\n password: string;\n port: number;\n type: ResourceType.Postgres;\n username: string;\n};\n\nexport type Function = {\n name: string;\n type: ResourceType.Function;\n};\n\nexport type Bucket = {\n name: string;\n type: ResourceType.Bucket;\n};\n\nexport type SnsTopic = {\n arn: string;\n type: ResourceType.SnsTopic;\n};\n\nexport type Vpc = {\n bastion: string;\n type: ResourceType.Vpc;\n};\n\nexport type Secret = {\n type: ResourceType.Secret;\n value: string;\n};\n\nexport type Resource =\n | ApiGatewayV2\n | Postgres\n | Function\n | Bucket\n | Vpc\n | Secret;\n\nexport type ResourceProcessor<K extends Resource> = (\n name: string,\n value: K,\n) => Record<string, string | number>;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AAIA,SAAgB,oBAAoB;CAClC,MAAM,oBAAoB,WAAG,mBAAmB;AAChD,MAAK,MAAM,iBAAiB,mBAAmB;EAC7C,MAAM,YAAY,kBAAkB,kBAAkB,CAAE;AACxD,OAAK,MAAM,eAAe,UAExB,KAAI,YAAY,WAAW,WAAW,YAAY,SAChD,QAAO,YAAY;CAGxB;AACD,QAAO;AACR;AAED,SAAgB,gBAAgBA,MAAc;AAC5C,QAAO,8BAAU,KAAK,CACnB,aAAa,CACb,QAAQ,SAAS,CAAC,MAAM;AACvB,SAAO,EAAE,QAAQ,KAAK,GAAG;CAC1B,EAAC;AACL;AACD,IAAY,wDAAL;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AACD;AAED,MAAM,SAAS,CAACA,MAAcC,WAAmB,GAC9C,gBAAgB,KAAK,GAAG,MAAM,MAChC;AACD,MAAM,WAAW,CAACC,KAAaC,UAAoB;CACjD,MAAM,UAAU,EAAE,gBAAgB,IAAI,CAAC;AACvC,QAAO;IACH,EAAE,OAAO,SAAS,MAAM;IACxB,EAAE,OAAO,SAAS,MAAM;IACxB,EAAE,OAAO,aAAa,MAAM;IAC5B,EAAE,OAAO,SAAS,MAAM;IACxB,EAAE,OAAO,aAAa,MAAM;CAC/B;AACF;AAED,MAAM,SAAS,CAACH,MAAcI,UAAkB;CAC9C,MAAM,UAAU,EAAE,gBAAgB,KAAK,CAAC;AACxC,QAAO,IACH,EAAE,OAAO,SAAS,MAAM,KAC3B;AACF;AAED,MAAM,QAAQ,CAACJ,MAAcK,UAAoB;CAC/C,MAAM,UAAU,EAAE,gBAAgB,KAAK,CAAC;CACxC,MAAM,OAAO,EAAE,OAAO;AAEtB,QAAO,GACJ,MAAM,MAAM,IACd;AACF;AAED,MAAM,OAAO,CAACL,MAAcM,WAAgB,CAAE;AAE9C,MAAMC,aAA2D;EAC9D,aAAa,eAAe;EAC5B,aAAa,WAAW;EACxB,aAAa,MAAM;EACnB,aAAa,SAAS;EACtB,aAAa,WAAW;EACxB,aAAa,SAAS;EAEtB,aAAa,YAAY;EACzB,aAAa,YAAY;EACzB,aAAa,cAAc;EAC3B,aAAa,cAAc;EAC3B,aAAa,kBAAkB;EAC/B,aAAa,WAAW;AAC1B;AAED,SAAgB,iBACdC,QACwB;CACxB,MAAMC,MAA8B,CAAE;AACtC,MAAK,MAAM,CAAC,GAAG,MAAM,IAAI,OAAO,QAAQ,OAAO,EAAE;AAC/C,aAAW,UAAU,UAAU;AAC7B,OAAI,gBAAgB,EAAE,IAAI;AAC1B;EACD;EAED,MAAM,YAAY,WAAW,MAAM;AACnC,MAAI,UACF,QAAO,OAAO,KAAK,UAAU,GAAG,MAAM,CAAC;MAEvC,SAAQ,MAAM,yCAAyC,EAAE,MAAO,EAAC;CAEpE;AAED,QAAO;AACR"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"utils-CsvKEy-e.mjs","names":["name: string","value: Secret","key: string","value: Postgres","value: Bucket","value: SnsTopic","value: any","processors: Record<ResourceType, ResourceProcessor<any>>","record: Record<string, Resource | string>","env: Record<string, string>"],"sources":["../src/utils/index.ts"],"sourcesContent":["import snakecase from 'lodash.snakecase';\n\nimport os from 'os';\n\nexport function getLocalIpAddress() {\n const networkInterfaces = os.networkInterfaces();\n for (const interfaceName in networkInterfaces) {\n const addresses = networkInterfaces[interfaceName] || [];\n for (const addressInfo of addresses) {\n // Look for an IPv4 address that is not internal (loopback)\n if (addressInfo.family === 'IPv4' && !addressInfo.internal) {\n return addressInfo.address;\n }\n }\n }\n return null; // No suitable IP address found\n}\n\nexport function environmentCase(name: string) {\n return snakecase(name)\n .toUpperCase()\n .replace(/_\\d+/g, (r) => {\n return r.replace('_', '');\n });\n}\nexport enum ResourceType {\n ApiGatewayV2 = 'sst.aws.ApiGatewayV2',\n Postgres = 'sst.aws.Postgres',\n Function = 'sst.aws.Function',\n Bucket = 'sst.aws.Bucket',\n Vpc = 'sst.aws.Vpc',\n Secret = 'sst.sst.Secret',\n SSTSecret = 'sst:sst:Secret',\n SSTFunction = 'sst:sst:Function',\n SSTApiGatewayV2 = 'sst:aws:ApiGatewayV2',\n SSTPostgres = 'sst:aws:Postgres',\n SSTBucket = 'sst:aws:Bucket',\n SnsTopic = 'sst:aws:SnsTopic',\n}\n\nconst secret = (name: string, value: Secret) => ({\n [environmentCase(name)]: value.value,\n});\nconst postgres = (key: string, value: Postgres) => {\n const prefix = `${environmentCase(key)}`;\n return {\n [`${prefix}_NAME`]: value.database,\n [`${prefix}_HOST`]: value.host,\n [`${prefix}_PASSWORD`]: value.password,\n [`${prefix}_PORT`]: value.port,\n [`${prefix}_USERNAME`]: value.username,\n };\n};\n\nconst bucket = (name: string, value: Bucket) => {\n const prefix = `${environmentCase(name)}`;\n return {\n [`${prefix}_NAME`]: value.name,\n };\n};\n\nconst topic = (name: string, value: SnsTopic) => {\n const prefix = `${environmentCase(name)}`;\n const key = `${prefix}_ARN`;\n\n return {\n [key]: value.arn,\n };\n};\n\nconst noop = (name: string, value: any) => ({});\n\nconst processors: Record<ResourceType, ResourceProcessor<any>> = {\n [ResourceType.ApiGatewayV2]: noop,\n [ResourceType.Function]: noop,\n [ResourceType.Vpc]: noop,\n [ResourceType.Secret]: secret,\n [ResourceType.Postgres]: postgres,\n [ResourceType.Bucket]: bucket,\n\n [ResourceType.SSTSecret]: secret,\n [ResourceType.SSTBucket]: bucket,\n [ResourceType.SSTFunction]: noop,\n [ResourceType.SSTPostgres]: postgres,\n [ResourceType.SSTApiGatewayV2]: noop,\n [ResourceType.SnsTopic]: topic,\n};\n\nexport function buildResourceEnv(\n record: Record<string, Resource | string>,\n): Record<string, string> {\n const env: Record<string, string> = {};\n for (const [k, value] of Object.entries(record)) {\n if (typeof value === 'string') {\n env[environmentCase(k)] = value;\n continue;\n }\n\n const processor = processors[value.type];\n if (processor) {\n Object.assign(env, processor(k, value));\n } else {\n console.warn(`No processor found for resource type: `, { value });\n }\n }\n\n return env;\n}\n\nexport type ApiGatewayV2 = {\n type: ResourceType.ApiGatewayV2;\n url: string;\n};\n\nexport type Postgres = {\n database: string;\n host: string;\n password: string;\n port: number;\n type: ResourceType.Postgres;\n username: string;\n};\n\nexport type Function = {\n name: string;\n type: ResourceType.Function;\n};\n\nexport type Bucket = {\n name: string;\n type: ResourceType.Bucket;\n};\n\nexport type SnsTopic = {\n arn: string;\n type: ResourceType.SnsTopic;\n};\n\nexport type Vpc = {\n bastion: string;\n type: ResourceType.Vpc;\n};\n\nexport type Secret = {\n type: ResourceType.Secret;\n value: string;\n};\n\nexport type Resource =\n | ApiGatewayV2\n | Postgres\n | Function\n | Bucket\n | Vpc\n | Secret;\n\nexport type ResourceProcessor<K extends Resource> = (\n name: string,\n value: K,\n) => Record<string, string | number>;\n"],"mappings":";;;;AAIA,SAAgB,oBAAoB;CAClC,MAAM,oBAAoB,GAAG,mBAAmB;AAChD,MAAK,MAAM,iBAAiB,mBAAmB;EAC7C,MAAM,YAAY,kBAAkB,kBAAkB,CAAE;AACxD,OAAK,MAAM,eAAe,UAExB,KAAI,YAAY,WAAW,WAAW,YAAY,SAChD,QAAO,YAAY;CAGxB;AACD,QAAO;AACR;AAED,SAAgB,gBAAgBA,MAAc;AAC5C,QAAO,UAAU,KAAK,CACnB,aAAa,CACb,QAAQ,SAAS,CAAC,MAAM;AACvB,SAAO,EAAE,QAAQ,KAAK,GAAG;CAC1B,EAAC;AACL;AACD,IAAY,wDAAL;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AACD;AAED,MAAM,SAAS,CAACA,MAAcC,WAAmB,GAC9C,gBAAgB,KAAK,GAAG,MAAM,MAChC;AACD,MAAM,WAAW,CAACC,KAAaC,UAAoB;CACjD,MAAM,UAAU,EAAE,gBAAgB,IAAI,CAAC;AACvC,QAAO;IACH,EAAE,OAAO,SAAS,MAAM;IACxB,EAAE,OAAO,SAAS,MAAM;IACxB,EAAE,OAAO,aAAa,MAAM;IAC5B,EAAE,OAAO,SAAS,MAAM;IACxB,EAAE,OAAO,aAAa,MAAM;CAC/B;AACF;AAED,MAAM,SAAS,CAACH,MAAcI,UAAkB;CAC9C,MAAM,UAAU,EAAE,gBAAgB,KAAK,CAAC;AACxC,QAAO,IACH,EAAE,OAAO,SAAS,MAAM,KAC3B;AACF;AAED,MAAM,QAAQ,CAACJ,MAAcK,UAAoB;CAC/C,MAAM,UAAU,EAAE,gBAAgB,KAAK,CAAC;CACxC,MAAM,OAAO,EAAE,OAAO;AAEtB,QAAO,GACJ,MAAM,MAAM,IACd;AACF;AAED,MAAM,OAAO,CAACL,MAAcM,WAAgB,CAAE;AAE9C,MAAMC,aAA2D;EAC9D,aAAa,eAAe;EAC5B,aAAa,WAAW;EACxB,aAAa,MAAM;EACnB,aAAa,SAAS;EACtB,aAAa,WAAW;EACxB,aAAa,SAAS;EAEtB,aAAa,YAAY;EACzB,aAAa,YAAY;EACzB,aAAa,cAAc;EAC3B,aAAa,cAAc;EAC3B,aAAa,kBAAkB;EAC/B,aAAa,WAAW;AAC1B;AAED,SAAgB,iBACdC,QACwB;CACxB,MAAMC,MAA8B,CAAE;AACtC,MAAK,MAAM,CAAC,GAAG,MAAM,IAAI,OAAO,QAAQ,OAAO,EAAE;AAC/C,aAAW,UAAU,UAAU;AAC7B,OAAI,gBAAgB,EAAE,IAAI;AAC1B;EACD;EAED,MAAM,YAAY,WAAW,MAAM;AACnC,MAAI,UACF,QAAO,OAAO,KAAK,UAAU,GAAG,MAAM,CAAC;MAEvC,SAAQ,MAAM,yCAAyC,EAAE,MAAO,EAAC;CAEpE;AAED,QAAO;AACR"}
|