@geekmidas/cloud 0.1.0 → 1.0.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/CHANGELOG.md ADDED
@@ -0,0 +1,7 @@
1
+ # @geekmidas/cloud
2
+
3
+ ## 1.0.0
4
+
5
+ ### Major Changes
6
+
7
+ - [`ff7b115`](https://github.com/geekmidas/toolbox/commit/ff7b11599f60f84ac6cdc73714c853ecf786b2e8) Thanks [@geekmidas](https://github.com/geekmidas)! - Version 1 Stable release
@@ -1,5 +1,5 @@
1
1
  //#region src/utils/index.d.ts
2
- declare function getLocalIpAddress(): string;
2
+ declare function getLocalIpAddress(): string | null;
3
3
  declare function environmentCase(name: string): string;
4
4
  declare enum ResourceType {
5
5
  ApiGatewayV2 = "sst.aws.ApiGatewayV2",
@@ -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-B95qNf_3.d.mts.map
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"}
@@ -1,5 +1,5 @@
1
1
  //#region src/utils/index.d.ts
2
- declare function getLocalIpAddress(): string;
2
+ declare function getLocalIpAddress(): string | null;
3
3
  declare function environmentCase(name: string): string;
4
4
  declare enum ResourceType {
5
5
  ApiGatewayV2 = "sst.aws.ApiGatewayV2",
@@ -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-Bg4XVDkL.d.cts.map
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
@@ -1,3 +1,3 @@
1
- const require_utils = require('./utils-BtXDcUV8.cjs');
1
+ const require_utils = require('./utils-CtMjuIMR.cjs');
2
2
 
3
3
  exports.buildResourceEnv = require_utils.buildResourceEnv;
package/dist/index.d.cts CHANGED
@@ -1,2 +1,2 @@
1
- import { buildResourceEnv } from "./index-Bg4XVDkL.cjs";
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-B95qNf_3.mjs";
1
+ import { buildResourceEnv } from "./index-DZ0QrJQr.mjs";
2
2
  export { buildResourceEnv };
package/dist/index.mjs CHANGED
@@ -1,3 +1,3 @@
1
- import { buildResourceEnv } from "./utils-CsvKEy-e.mjs";
1
+ import { buildResourceEnv } from "./utils-BdKG20_m.mjs";
2
2
 
3
3
  export { buildResourceEnv };
@@ -1,4 +1,4 @@
1
- const require_utils = require('../utils-BtXDcUV8.cjs');
1
+ const require_utils = require('../utils-CtMjuIMR.cjs');
2
2
 
3
3
  exports.ResourceType = require_utils.ResourceType;
4
4
  exports.buildResourceEnv = require_utils.buildResourceEnv;
@@ -1,2 +1,2 @@
1
- import { ApiGatewayV2, Bucket, Function, Postgres, Resource, ResourceProcessor, ResourceType, Secret, SnsTopic, Vpc, buildResourceEnv, environmentCase, getLocalIpAddress } from "../index-Bg4XVDkL.cjs";
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 };
@@ -1,2 +1,2 @@
1
- import { ApiGatewayV2, Bucket, Function, Postgres, Resource, ResourceProcessor, ResourceType, Secret, SnsTopic, Vpc, buildResourceEnv, environmentCase, getLocalIpAddress } from "../index-B95qNf_3.mjs";
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 };
@@ -1,3 +1,3 @@
1
- import { ResourceType, buildResourceEnv, environmentCase, getLocalIpAddress } from "../utils-CsvKEy-e.mjs";
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 = (name, value) => ({});
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-CsvKEy-e.mjs.map
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 = os.default.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 = (name, value) => ({});
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-BtXDcUV8.cjs.map
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.1.0",
3
+ "version": "1.0.0",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {
@@ -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
+ });
@@ -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
- const networkInterfaces = os.networkInterfaces();
7
- for (const interfaceName in networkInterfaces) {
8
- const addresses = networkInterfaces[interfaceName] || [];
9
- for (const addressInfo of addresses) {
10
- // Look for an IPv4 address that is not internal (loopback)
11
- if (addressInfo.family === 'IPv4' && !addressInfo.internal) {
12
- return addressInfo.address;
13
- }
14
- }
15
- }
16
- return null; // No suitable IP address found
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
- return snakecase(name)
21
- .toUpperCase()
22
- .replace(/_\d+/g, (r) => {
23
- return r.replace('_', '');
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
- ApiGatewayV2 = 'sst.aws.ApiGatewayV2',
28
- Postgres = 'sst.aws.Postgres',
29
- Function = 'sst.aws.Function',
30
- Bucket = 'sst.aws.Bucket',
31
- Vpc = 'sst.aws.Vpc',
32
- Secret = 'sst.sst.Secret',
33
- SSTSecret = 'sst:sst:Secret',
34
- SSTFunction = 'sst:sst:Function',
35
- SSTApiGatewayV2 = 'sst:aws:ApiGatewayV2',
36
- SSTPostgres = 'sst:aws:Postgres',
37
- SSTBucket = 'sst:aws:Bucket',
38
- SnsTopic = 'sst:aws:SnsTopic',
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
- [environmentCase(name)]: value.value,
41
+ [environmentCase(name)]: value.value,
43
42
  });
44
43
  const postgres = (key: string, value: Postgres) => {
45
- const prefix = `${environmentCase(key)}`;
46
- return {
47
- [`${prefix}_NAME`]: value.database,
48
- [`${prefix}_HOST`]: value.host,
49
- [`${prefix}_PASSWORD`]: value.password,
50
- [`${prefix}_PORT`]: value.port,
51
- [`${prefix}_USERNAME`]: value.username,
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
- const prefix = `${environmentCase(name)}`;
57
- return {
58
- [`${prefix}_NAME`]: value.name,
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
- const prefix = `${environmentCase(name)}`;
64
- const key = `${prefix}_ARN`;
62
+ const prefix = `${environmentCase(name)}`;
63
+ const key = `${prefix}_ARN`;
65
64
 
66
- return {
67
- [key]: value.arn,
68
- };
65
+ return {
66
+ [key]: value.arn,
67
+ };
69
68
  };
70
69
 
71
- const noop = (name: string, value: any) => ({});
70
+ const noop = (_name: string, _value: any) => ({});
72
71
 
73
72
  const processors: Record<ResourceType, ResourceProcessor<any>> = {
74
- [ResourceType.ApiGatewayV2]: noop,
75
- [ResourceType.Function]: noop,
76
- [ResourceType.Vpc]: noop,
77
- [ResourceType.Secret]: secret,
78
- [ResourceType.Postgres]: postgres,
79
- [ResourceType.Bucket]: bucket,
80
-
81
- [ResourceType.SSTSecret]: secret,
82
- [ResourceType.SSTBucket]: bucket,
83
- [ResourceType.SSTFunction]: noop,
84
- [ResourceType.SSTPostgres]: postgres,
85
- [ResourceType.SSTApiGatewayV2]: noop,
86
- [ResourceType.SnsTopic]: topic,
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
- record: Record<string, Resource | string>,
89
+ record: Record<string, Resource | string>,
91
90
  ): Record<string, string> {
92
- const env: Record<string, string> = {};
93
- for (const [k, value] of Object.entries(record)) {
94
- if (typeof value === 'string') {
95
- env[environmentCase(k)] = value;
96
- continue;
97
- }
98
-
99
- const processor = processors[value.type];
100
- if (processor) {
101
- Object.assign(env, processor(k, value));
102
- } else {
103
- console.warn(`No processor found for resource type: `, { value });
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
- type: ResourceType.ApiGatewayV2;
112
- url: string;
109
+ type: ResourceType.ApiGatewayV2;
110
+ url: string;
113
111
  };
114
112
 
115
113
  export type Postgres = {
116
- database: string;
117
- host: string;
118
- password: string;
119
- port: number;
120
- type: ResourceType.Postgres;
121
- username: string;
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
- name: string;
126
- type: ResourceType.Function;
123
+ name: string;
124
+ type: ResourceType.Function;
127
125
  };
128
126
 
129
127
  export type Bucket = {
130
- name: string;
131
- type: ResourceType.Bucket;
128
+ name: string;
129
+ type: ResourceType.Bucket;
132
130
  };
133
131
 
134
132
  export type SnsTopic = {
135
- arn: string;
136
- type: ResourceType.SnsTopic;
133
+ arn: string;
134
+ type: ResourceType.SnsTopic;
137
135
  };
138
136
 
139
137
  export type Vpc = {
140
- bastion: string;
141
- type: ResourceType.Vpc;
138
+ bastion: string;
139
+ type: ResourceType.Vpc;
142
140
  };
143
141
 
144
142
  export type Secret = {
145
- type: ResourceType.Secret;
146
- value: string;
143
+ type: ResourceType.Secret;
144
+ value: string;
147
145
  };
148
146
 
149
147
  export type Resource =
150
- | ApiGatewayV2
151
- | Postgres
152
- | Function
153
- | Bucket
154
- | Vpc
155
- | Secret;
148
+ | ApiGatewayV2
149
+ | Postgres
150
+ | Function
151
+ | Bucket
152
+ | Vpc
153
+ | Secret;
156
154
 
157
155
  export type ResourceProcessor<K extends Resource> = (
158
- name: string,
159
- value: K,
156
+ name: string,
157
+ value: K,
160
158
  ) => Record<string, string | number>;
package/tsconfig.json ADDED
@@ -0,0 +1,9 @@
1
+ {
2
+ "extends": "../../tsconfig.base.json",
3
+ "compilerOptions": {
4
+ "outDir": "./dist",
5
+ "rootDir": "./src",
6
+ "composite": true
7
+ },
8
+ "include": ["src/**/*"]
9
+ }
@@ -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"}