@geekmidas/cloud 1.1.1 → 10.0.0-alpha.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.
Files changed (63) hide show
  1. package/dist/{index-ByEJy40r.d.cts → index-B5CZ1xVf.d.cts} +17 -9
  2. package/dist/index-B5CZ1xVf.d.cts.map +1 -0
  3. package/dist/{index-DZ0QrJQr.d.mts → index-DhHRjduZ.d.mts} +17 -9
  4. package/dist/index-DhHRjduZ.d.mts.map +1 -0
  5. package/dist/index.cjs +1 -1
  6. package/dist/index.d.cts +1 -1
  7. package/dist/index.d.mts +1 -1
  8. package/dist/index.mjs +1 -1
  9. package/dist/utils/index.cjs +1 -1
  10. package/dist/utils/index.d.cts +1 -1
  11. package/dist/utils/index.d.mts +1 -1
  12. package/dist/utils/index.mjs +1 -1
  13. package/dist/{utils-CtMjuIMR.cjs → utils-B1a2UuEO.cjs} +5 -5
  14. package/dist/utils-B1a2UuEO.cjs.map +1 -0
  15. package/dist/{utils-BdKG20_m.mjs → utils-DMOXJ27j.mjs} +5 -5
  16. package/dist/utils-DMOXJ27j.mjs.map +1 -0
  17. package/package.json +44 -7
  18. package/src/dokploy/Application.ts +259 -0
  19. package/src/dokploy/__tests__/Application.spec.ts +69 -0
  20. package/src/dokploy/index.ts +18 -0
  21. package/src/sst/__tests__/LinkedEnvironment.spec.ts +4 -1
  22. package/src/sst/__tests__/backends.spec.ts +249 -0
  23. package/src/sst/__tests__/bootstrap.spec.ts +140 -0
  24. package/src/sst/__tests__/database.spec.ts +119 -0
  25. package/src/sst/__tests__/fromManifest.spec.ts +266 -0
  26. package/src/sst/__tests__/provides.spec.ts +107 -0
  27. package/src/sst/__tests__/ses.spec.ts +93 -0
  28. package/src/sst/__tests__/surfaces.spec.ts +132 -0
  29. package/src/sst/__type-tests__/authorizers.type-test.ts +2 -2
  30. package/src/sst/__type-tests__/manifest.type-test.ts +3 -3
  31. package/src/sst/__type-tests__/messaging.type-test.ts +3 -3
  32. package/src/sst/__type-tests__/storage.type-test.ts +2 -2
  33. package/src/sst/{Api.ts → aws/Api.ts} +3 -3
  34. package/src/sst/aws/Cache.ts +259 -0
  35. package/src/sst/aws/Credential.ts +28 -0
  36. package/src/sst/{Cron.ts → aws/Cron.ts} +2 -2
  37. package/src/sst/aws/Database.ts +190 -0
  38. package/src/sst/aws/DatabaseBootstrap.ts +309 -0
  39. package/src/sst/aws/DerivedDatabase.ts +117 -0
  40. package/src/sst/aws/Email.ts +181 -0
  41. package/src/sst/aws/FileServer.ts +82 -0
  42. package/src/sst/{Function.ts → aws/Function.ts} +3 -3
  43. package/src/sst/aws/ObjectStorage.ts +76 -0
  44. package/src/sst/aws/Queue.ts +116 -0
  45. package/src/sst/aws/RestApiSurface.ts +92 -0
  46. package/src/sst/aws/Secret.ts +76 -0
  47. package/src/sst/aws/StaticSite.ts +92 -0
  48. package/src/sst/{Storage.ts → aws/Storage.ts} +3 -3
  49. package/src/sst/aws/Topic.ts +68 -0
  50. package/src/sst/aws/bootstrap/handler.ts +110 -0
  51. package/src/sst/aws/ses.ts +132 -0
  52. package/src/sst/errors.ts +65 -0
  53. package/src/sst/fromManifest.ts +899 -0
  54. package/src/sst/index.ts +62 -7
  55. package/src/sst/naming.ts +37 -16
  56. package/src/sst/tsconfig.json +2 -2
  57. package/src/sst/upstash.d.ts +38 -0
  58. package/dist/index-ByEJy40r.d.cts.map +0 -1
  59. package/dist/index-DZ0QrJQr.d.mts.map +0 -1
  60. package/dist/utils-BdKG20_m.mjs.map +0 -1
  61. package/dist/utils-CtMjuIMR.cjs.map +0 -1
  62. package/src/sst/Queue.ts +0 -46
  63. package/src/sst/Topic.ts +0 -37
package/src/sst/index.ts CHANGED
@@ -1,3 +1,4 @@
1
+ export { App, type AppProps, type StageValues } from './App';
1
2
  export {
2
3
  Api,
3
4
  type ApiAuthorizers,
@@ -6,18 +7,72 @@ export {
6
7
  type JwtAuthorizer,
7
8
  type LambdaAuthorizer,
8
9
  type Route,
9
- } from './Api';
10
- export { App, type AppProps, type StageValues } from './App';
10
+ } from './aws/Api';
11
+ export {
12
+ Cache,
13
+ CacheNeedsDatabase,
14
+ CacheNeedsProvider,
15
+ CacheNeedsVpc,
16
+ type CacheProps,
17
+ } from './aws/Cache';
18
+ export { Credential, type CredentialProps } from './aws/Credential';
11
19
  export {
12
20
  Cron,
13
21
  type CronExpression,
14
22
  type CronProps,
15
23
  type CronRate,
16
24
  type CronSchedule,
17
- } from './Cron';
18
- export { Function, type FunctionProps } from './Function';
25
+ } from './aws/Cron';
26
+ export {
27
+ Database,
28
+ DatabaseNeedsVpc,
29
+ type DatabaseProps,
30
+ } from './aws/Database';
31
+ export {
32
+ bootstrapEvent,
33
+ DatabaseBootstrap,
34
+ } from './aws/DatabaseBootstrap';
35
+ export { DatabaseReader, DatabaseSchema } from './aws/DerivedDatabase';
36
+ export { Email, EmailNeedsUrl, type EmailProps } from './aws/Email';
37
+ export { FileServer, type FileServerProps } from './aws/FileServer';
38
+ export { Function, type FunctionProps } from './aws/Function';
39
+ export {
40
+ ObjectStorage,
41
+ type ObjectStorageProps,
42
+ } from './aws/ObjectStorage';
43
+ export { fifoName, Queue, type QueueProps } from './aws/Queue';
44
+ export { Secret, type SecretProps } from './aws/Secret';
45
+ export { StaticSite, type StaticSiteProps } from './aws/StaticSite';
46
+ /** @deprecated renamed to `ObjectStorage`, matching the construct that declares it. */
47
+ export { Storage, type StorageProps } from './aws/Storage';
48
+ export {
49
+ NoSmtpEndpoint,
50
+ SMTP_PORT,
51
+ SMTP_REGIONS,
52
+ sesSmtpUrl,
53
+ smtpEndpoint,
54
+ smtpPassword,
55
+ } from './aws/ses';
56
+ export { Topic, type TopicProps } from './aws/Topic';
57
+ export {
58
+ ProvidesMismatch,
59
+ UnknownDeclarationKind,
60
+ UnresolvedDependency,
61
+ } from './errors';
62
+ export {
63
+ assertProvides,
64
+ type ComponentOverrides,
65
+ describeRoutes,
66
+ fromManifest,
67
+ isServed,
68
+ type ProvisionContext,
69
+ type Provisioned,
70
+ type ProvisionedManifest,
71
+ provisionerFor,
72
+ type ResolvedEdges,
73
+ resolveEdges,
74
+ siteEnvironment,
75
+ } from './fromManifest';
19
76
  export { type GkmLinkable, ResourceType } from './Linkable';
20
- export { Queue, type QueueProps } from './Queue';
77
+ export { kebab, prefixedName, regionOfArn } from './naming';
21
78
  export { Stack, type StackType } from './Stack';
22
- export { Storage, type StorageProps } from './Storage';
23
- export { Topic, type TopicProps } from './Topic';
package/src/sst/naming.ts CHANGED
@@ -1,23 +1,44 @@
1
+ import { kebabCase, scopedName } from '@geekmidas/manifest';
2
+
1
3
  /**
2
4
  * Kebab-cases an identifier: `userName` → `user-name`, `my_handler` →
3
- * `my-handler`, and acronym-aware (`APIKey` → `api-key`, `XMLParser` →
4
- * `xml-parser`).
5
+ * `my-handler`, acronym-aware (`APIKey` → `api-key`) and digit-aware
6
+ * (`S3Bucket` → `s3-bucket`).
7
+ *
8
+ * Re-exported from `@geekmidas/manifest` rather than implemented here. It used
9
+ * to be implemented here, beside a second spelling of the same rule in the
10
+ * manifest — which agreed on every id anyone had tried and disagreed on
11
+ * `S3Bucket`.
5
12
  */
6
- export function kebab(value: string): string {
7
- return value
8
- .replace(/([A-Z]+)([A-Z][a-z])/g, '$1-$2')
9
- .replace(/([a-z0-9])([A-Z])/g, '$1-$2')
10
- .replace(/[\s_]+/g, '-')
11
- .toLowerCase();
12
- }
13
+ export const kebab = kebabCase;
14
+
15
+ /**
16
+ * A kebab-cased, prefixed physical resource name — `[stage, app]` and the
17
+ * resource, joined and lower-cased, without doubling a prefix the resource
18
+ * already carries.
19
+ *
20
+ * The same rule every other target names by: this is `cloudName` for a caller
21
+ * whose prefix is a list, because an SST stack contributes a segment of its
22
+ * own. A construct is named the same thing here and on Dokploy, which is the
23
+ * property that lets one name be read across providers.
24
+ */
25
+ export const prefixedName = scopedName;
13
26
 
14
27
  /**
15
- * Builds a kebab-cased, prefixed physical resource name. The `prefix` parts
16
- * (e.g. `[stage, name]`) are joined and lower-cased; if `resource` already
17
- * starts with that prefix it is returned as-is (kebab-cased) to avoid doubling.
28
+ * The region out of an AWS ARN — `arn:aws:sqs:eu-west-1:123:emails` →
29
+ * `eu-west-1`.
30
+ *
31
+ * Every connection string this package composes carries the region explicitly,
32
+ * because `AWS_REGION` inside a Lambda is the *function's* region and not the
33
+ * resource's. A cross-region queue then works right up until it doesn't, and
34
+ * fails at runtime with nothing in the URL to explain why.
35
+ *
36
+ * Returns `undefined` for the ARN shapes that carry no region — an IAM ARN, or
37
+ * anything that is not an ARN at all — so a caller omits the parameter rather
38
+ * than writing an empty one.
18
39
  */
19
- export function prefixedName(prefix: string[], resource: string): string {
20
- const joined = prefix.join('-').toLowerCase();
21
- const name = kebab(resource);
22
- return name.startsWith(joined) ? name : `${joined}-${name}`;
40
+ export function regionOfArn(arn: string): string | undefined {
41
+ const [prefix, , , region] = arn.split(':');
42
+
43
+ return prefix === 'arn' && region ? region : undefined;
23
44
  }
@@ -1,5 +1,5 @@
1
1
  {
2
- "//": "Project config for the source-only `src/sst` constructs. It lives here (not at the package root) so editors pick it as the NEAREST tsconfig for these files and resolve the ambient `sst`/`aws`/`$util` globals from `.sst/platform` plus node's `process` — the package's main tsconfig.json excludes `src/sst`. Compiler options are shared via `../../tsconfig.sst.json`; this file only adds the file set. Run via `pnpm --filter @geekmidas/cloud ts:check:sst` after `sst install`.",
2
+ "//": "Project config for the source-only `src/sst` and `src/dokploy` constructs. It lives here (not at the package root) so editors pick it as the NEAREST tsconfig for these files and resolve the ambient `sst`/`aws`/`$util` globals from `.sst/platform` plus node's `process` — the package's main tsconfig.json excludes `src/sst`. Compiler options are shared via `../../tsconfig.sst.json`; this file only adds the file set. Run via `pnpm --filter @geekmidas/cloud ts:check:sst` after `sst install`.",
3
3
  "extends": "../../tsconfig.sst.json",
4
- "include": ["**/*", "../../.sst/platform/config.d.ts"]
4
+ "include": ["**/*", "../dokploy/**/*", "../../.sst/platform/config.d.ts"]
5
5
  }
@@ -0,0 +1,38 @@
1
+ /**
2
+ * The slice of Upstash's provider this package uses.
3
+ *
4
+ * SST preloads AWS and Cloudflare and installs everything else on demand — `sst
5
+ * add upstash` — which "adds the namespace of the provider to your globals".
6
+ * So at runtime this global exists in an app that ran the command and does not
7
+ * in one that did not, and there is no package here to import types from.
8
+ *
9
+ * Declared rather than depended on, for the same reason `sst.aws.*` is: taking
10
+ * `@upstash/pulumi` as a real dependency would install a provider for every
11
+ * consumer, including the ones caching in Postgres.
12
+ *
13
+ * Narrow on purpose. It describes what `Cache` reads and nothing else, so it
14
+ * cannot drift into claiming knowledge of an API this package does not use.
15
+ */
16
+ declare namespace upstash {
17
+ class RedisDatabase {
18
+ constructor(
19
+ name: string,
20
+ args: {
21
+ databaseName: $util.Input<string>;
22
+ /** A region name, or `global` with `primaryRegion` set alongside it. */
23
+ region: $util.Input<string>;
24
+ primaryRegion?: $util.Input<string>;
25
+ tls?: $util.Input<boolean>;
26
+ eviction?: $util.Input<boolean>;
27
+ },
28
+ opts?: unknown,
29
+ );
30
+
31
+ /** The host to reach it on. Not a URL despite the name — no scheme. */
32
+ readonly endpoint: $util.Output<string>;
33
+ /** The bearer token the HTTP client sends. */
34
+ readonly restToken: $util.Output<string>;
35
+ readonly readOnlyRestToken: $util.Output<string>;
36
+ readonly port: $util.Output<number>;
37
+ }
38
+ }
@@ -1 +0,0 @@
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 +0,0 @@
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"}
@@ -1 +0,0 @@
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"}
@@ -1 +0,0 @@
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/src/sst/Queue.ts DELETED
@@ -1,46 +0,0 @@
1
- import { type GkmLinkable, ResourceType } from './Linkable';
2
- import type { StackType } from './Stack';
3
-
4
- /**
5
- * `Queue` — a linkable SQS queue (wraps `sst.aws.Queue`), the point-to-point
6
- * work queue. Link it to a producer and the runtime resolves `<NAME>_URL`,
7
- * `<NAME>_ARN`, and a `<NAME>_PUBLISHER_CONNECTION_STRING` (`sqs://?queueUrl=…`)
8
- * that `@geekmidas/events`'s `Publisher.fromConnectionString` consumes. Its
9
- * single consumer is wired by `QueueSubscriber`.
10
- *
11
- * SST's native `Queue` link exposes only `url`, so `getSSTLink` is overridden to
12
- * also expose `arn` (what the resolver needs). `QueueProps` extends
13
- * `sst.aws.QueueArgs`. Source-only (extends ambient `sst.aws.*`); see docs §2.
14
- */
15
- export class Queue<
16
- TStage extends string = string,
17
- TDomain extends string = string,
18
- >
19
- extends sst.aws.Queue
20
- implements GkmLinkable
21
- {
22
- readonly _id!: string;
23
-
24
- get _type() {
25
- return ResourceType.Queue;
26
- }
27
-
28
- constructor(
29
- _stack: StackType<TStage, TDomain>,
30
- name: string,
31
- props: QueueProps = {},
32
- ) {
33
- super(name, props);
34
- this._id = name;
35
- }
36
-
37
- override getSSTLink() {
38
- const link = super.getSSTLink();
39
- return {
40
- ...link,
41
- properties: { ...link.properties, arn: this.arn },
42
- };
43
- }
44
- }
45
-
46
- export interface QueueProps extends sst.aws.QueueArgs {}
package/src/sst/Topic.ts DELETED
@@ -1,37 +0,0 @@
1
- import { type GkmLinkable, ResourceType } from './Linkable';
2
- import type { StackType } from './Stack';
3
-
4
- /**
5
- * `Topic` — a linkable SNS topic (wraps `sst.aws.SnsTopic`), the pub/sub fan-out
6
- * bus. Link it to a publisher and the runtime resolves `<NAME>_ARN` and a
7
- * `<NAME>_PUBLISHER_CONNECTION_STRING` (`sns://?topicArn=…`) that
8
- * `@geekmidas/events`'s `Publisher.fromConnectionString` consumes. Subscribers
9
- * attach via `TopicSubscriber`/`Subscriber`.
10
- *
11
- * `StorageProps`-style: `TopicProps` extends `sst.aws.SnsTopicArgs`.
12
- * Source-only (extends ambient `sst.aws.*`); see docs §2.
13
- */
14
- export class Topic<
15
- TStage extends string = string,
16
- TDomain extends string = string,
17
- >
18
- extends sst.aws.SnsTopic
19
- implements GkmLinkable
20
- {
21
- readonly _id!: string;
22
-
23
- get _type() {
24
- return ResourceType.SnsTopic;
25
- }
26
-
27
- constructor(
28
- _stack: StackType<TStage, TDomain>,
29
- name: string,
30
- props: TopicProps = {},
31
- ) {
32
- super(name, props);
33
- this._id = name;
34
- }
35
- }
36
-
37
- export interface TopicProps extends sst.aws.SnsTopicArgs {}