@geekmidas/cloud 10.0.0-alpha.4 → 10.0.0-alpha.41

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 (37) hide show
  1. package/dist/index.cjs +3 -3
  2. package/dist/index.d.cts +1 -1
  3. package/dist/index.d.mts +1 -1
  4. package/dist/index.mjs +2 -3
  5. package/dist/utils/index.cjs +106 -5
  6. package/dist/utils/index.cjs.map +1 -0
  7. package/dist/utils/index.d.cts +62 -2
  8. package/dist/utils/index.d.cts.map +1 -0
  9. package/dist/utils/index.d.mts +62 -2
  10. package/dist/utils/index.d.mts.map +1 -0
  11. package/dist/utils/index.mjs +78 -2
  12. package/dist/utils/index.mjs.map +1 -0
  13. package/package.json +7 -7
  14. package/src/dokploy/Application.ts +52 -5
  15. package/src/dokploy/__tests__/Application.provider.spec.ts +206 -0
  16. package/src/sst/__tests__/api.spec.ts +231 -0
  17. package/src/sst/__tests__/fromManifest.integration.spec.ts +427 -0
  18. package/src/sst/__tests__/fromManifest.spec.ts +141 -5
  19. package/src/sst/__tests__/function.spec.ts +192 -0
  20. package/src/sst/__tests__/links.spec.ts +209 -0
  21. package/src/sst/aws/Api.ts +16 -1
  22. package/src/sst/aws/Cache.ts +4 -4
  23. package/src/sst/aws/Credential.ts +42 -9
  24. package/src/sst/aws/Database.ts +15 -1
  25. package/src/sst/aws/DatabaseBootstrap.ts +3 -0
  26. package/src/sst/aws/ExternalApi.ts +58 -0
  27. package/src/sst/aws/Queue.ts +31 -1
  28. package/src/sst/aws/bootstrap/handler.ts +10 -1
  29. package/src/sst/fromManifest.ts +90 -7
  30. package/dist/index-B5CZ1xVf.d.cts +0 -64
  31. package/dist/index-B5CZ1xVf.d.cts.map +0 -1
  32. package/dist/index-DhHRjduZ.d.mts +0 -64
  33. package/dist/index-DhHRjduZ.d.mts.map +0 -1
  34. package/dist/utils-B1a2UuEO.cjs +0 -129
  35. package/dist/utils-B1a2UuEO.cjs.map +0 -1
  36. package/dist/utils-DMOXJ27j.mjs +0 -83
  37. package/dist/utils-DMOXJ27j.mjs.map +0 -1
@@ -28,6 +28,11 @@ export interface BootstrapTenant {
28
28
  runtime: string;
29
29
  owner: string;
30
30
  reader?: string;
31
+ /**
32
+ * The database's own roles rather than a tenant's: its owner may create in
33
+ * the database, for trusted extensions.
34
+ */
35
+ ownsDatabase?: boolean;
31
36
  passwords: { runtime: string; owner: string; reader?: string };
32
37
  }
33
38
 
@@ -75,7 +80,11 @@ export async function handler(event: BootstrapEvent): Promise<BootstrapResult> {
75
80
 
76
81
  try {
77
82
  for (const tenant of event.tenants) {
78
- for (const statement of roleStatements(tenant)) {
83
+ const spec = {
84
+ ...tenant,
85
+ ...(tenant.ownsDatabase ? { database: event.master.database } : {}),
86
+ };
87
+ for (const statement of roleStatements(spec)) {
79
88
  if (statement.exists) {
80
89
  const { rows } = await client.query(
81
90
  statement.exists.sql,
@@ -26,10 +26,12 @@ import {
26
26
  cookieDomain,
27
27
  DEFAULT_POSTGRES_VERSION,
28
28
  dependentsOf,
29
+ mobileOrigins,
29
30
  PUBLIC,
30
31
  PUBLIC_PREFIX,
31
32
  providedKeyFor,
32
33
  provisionOrder,
34
+ schemeBase,
33
35
  } from '@geekmidas/manifest';
34
36
  import {
35
37
  Cache,
@@ -39,10 +41,11 @@ import {
39
41
  withCacheTable,
40
42
  } from './aws/Cache';
41
43
  import { Credential } from './aws/Credential';
42
- import { Database, DatabaseNeedsVpc } from './aws/Database';
44
+ import { Database, DatabaseNeedsVpc, type DatabaseProps } from './aws/Database';
43
45
  import { DatabaseBootstrap } from './aws/DatabaseBootstrap';
44
46
  import { DatabaseReader, DatabaseSchema } from './aws/DerivedDatabase';
45
47
  import { Email, EmailNeedsSender } from './aws/Email';
48
+ import { ExternalApi, type ExternalApiProps } from './aws/ExternalApi';
46
49
  import { FileServer } from './aws/FileServer';
47
50
  import { ObjectStorage } from './aws/ObjectStorage';
48
51
  import { Queue } from './aws/Queue';
@@ -98,8 +101,8 @@ export interface ProvisionContext {
98
101
  /**
99
102
  * Where a declared cache lives, and who delivers mail.
100
103
  *
101
- * Deployment choices rather than declarations, for the same reason
102
- * `services.events` is: the same application code caches into any of them and
104
+ * Deployment choices rather than declarations, for the same reason the
105
+ * event broker is: the same application code caches into any of them and
103
106
  * sends through any of them. They reach the provisioner here because it is
104
107
  * the only place that knows both the choice and the manifest.
105
108
  */
@@ -220,7 +223,11 @@ const PROVISIONERS: Partial<Record<DeclarationKind, Provisioner>> = {
220
223
  // rather than whatever Aurora defaults to that month. Local ran 18
221
224
  // while this ran 17.7, and neither was written down anywhere.
222
225
  version: String(d.version ?? DEFAULT_POSTGRES_VERSION),
223
- ...(props as unknown as sst.aws.PostgresArgs),
226
+ // `DatabaseProps`, not `sst.aws.PostgresArgs`: the database needs the
227
+ // `Vpc` component itself (its bootstrap function runs in the same VPC
228
+ // and needs the security groups too), where RDS would accept bare
229
+ // subnet ids. TS 7 checks the spread; 6 let the wider type through.
230
+ ...(props as unknown as Omit<DatabaseProps, 'schema'>),
224
231
  });
225
232
 
226
233
  // A database needs its own roles, not just its tenants'. Registering only
@@ -232,13 +239,21 @@ const PROVISIONERS: Partial<Record<DeclarationKind, Provisioner>> = {
232
239
  const bootstrap = bootstrapFor(cluster, d.id, context);
233
240
  const runtime = roleNameFor(d, context);
234
241
 
235
- bootstrap?.add({
242
+ const credentials = bootstrap?.add({
236
243
  id: d.id,
237
244
  schema: d.schema,
238
245
  runtime,
239
246
  owner: ownerRole(runtime),
247
+ ownsDatabase: true,
240
248
  ...(hasReader(d.id, context) ? { reader: readerRole(runtime) } : {}),
241
249
  });
250
+
251
+ // Registering the role was half of it: its handlers have to connect as
252
+ // it too, or the DDL creates a role nothing uses and every handler
253
+ // linked to the database still holds the master.
254
+ if (credentials) {
255
+ cluster.connectAs({ user: runtime, password: credentials.runtime });
256
+ }
242
257
  }
243
258
 
244
259
  return cluster;
@@ -385,6 +400,19 @@ const PROVISIONERS: Partial<Record<DeclarationKind, Provisioner>> = {
385
400
 
386
401
  // The same storage as a secret, under a different role — see the component.
387
402
  credential: (stack, d, props) => new Credential(stack, d.id, props),
403
+
404
+ // Nothing to provision: the URL this stage calls, and the credentials kept
405
+ // as a secret.
406
+ 'external-api': (stack, d, props) => {
407
+ if (d.kind !== 'external-api') {
408
+ throw new UnknownDeclarationKind(d.kind, []);
409
+ }
410
+
411
+ return new ExternalApi(stack, d.id, {
412
+ ...(props as Partial<ExternalApiProps>),
413
+ url: d.url,
414
+ });
415
+ },
388
416
  };
389
417
 
390
418
  /**
@@ -636,6 +664,8 @@ async function callersOf(
636
664
  id: string,
637
665
  manifest: ConstructManifest,
638
666
  provisioned: ProvisionedManifest,
667
+ /** The app's name — a mobile caller's scheme base when it gives none. */
668
+ project: string,
639
669
  ): Promise<{ trustedOrigins: string; cookieDomain?: string }> {
640
670
  // Every address here is a Pulumi output, not a string — a CloudFront domain
641
671
  // and an API Gateway endpoint are both known only after their resource
@@ -660,8 +690,17 @@ async function callersOf(
660
690
  const own = await resolved(provisioned[id]?.provides().url);
661
691
  const domain = cookieDomain([...(own ? [own] : []), ...origins]);
662
692
 
693
+ // A mobile caller is reached by its scheme — the bare one, deployed: what
694
+ // the store build registers.
695
+ const schemes = dependentsOf(manifest, id).flatMap((caller) => {
696
+ const app = manifest[caller];
697
+ return app?.kind === 'mobile-app'
698
+ ? mobileOrigins(schemeBase(project, app.scheme))
699
+ : [];
700
+ });
701
+
663
702
  return {
664
- trustedOrigins: origins.join(','),
703
+ trustedOrigins: [...origins, ...schemes].join(','),
665
704
  ...(domain ? { cookieDomain: domain } : {}),
666
705
  };
667
706
  }
@@ -711,6 +750,46 @@ export function isServed(id: string, manifest: ConstructManifest): boolean {
711
750
  );
712
751
  }
713
752
 
753
+ /**
754
+ * Kinds this stack provisions nothing for of their own.
755
+ *
756
+ * - `mobile-app` ships through EAS and the stores. It is in the manifest for
757
+ * what it makes the surfaces trust, which `callersOf` reads off the graph.
758
+ * - `worker` is a process, not a resource: what it runs is provisioned as
759
+ * what it is — a queue's consumer by {@link subscribeConsumers}.
760
+ * - `cron` and `function` are Lambdas built from `manifest.crons` and
761
+ * `manifest.functions` (`Cron.fromManifest`, `Function.fromManifest`).
762
+ */
763
+ export const PROVISIONED_ELSEWHERE: ReadonlySet<DeclarationKind> =
764
+ new Set<DeclarationKind>(['mobile-app', 'worker', 'cron', 'function']);
765
+
766
+ /** A provisioned queue: what {@link subscribeConsumers} subscribes through. */
767
+ interface Consumable {
768
+ consume(consumer: { handler: string; link?: unknown[] }): unknown;
769
+ }
770
+
771
+ /**
772
+ * Subscribe every queue's one consumer — the handler the build wrote for it,
773
+ * linked to what that consumer depends on.
774
+ *
775
+ * After every construct is provisioned, because a consumer links to things
776
+ * that `provisionOrder` does not order before the queue.
777
+ */
778
+ export function subscribeConsumers(
779
+ manifest: ConstructManifest,
780
+ provisioned: ProvisionedManifest,
781
+ ): void {
782
+ for (const [id, declaration] of Object.entries(manifest)) {
783
+ if (declaration?.kind !== 'queue') continue;
784
+
785
+ const queue = provisioned[id] as unknown as Consumable | undefined;
786
+ if (!queue) continue;
787
+
788
+ const { link } = resolveEdges(declaration.worker.dependencies, provisioned);
789
+ queue.consume({ handler: declaration.worker.handler, link });
790
+ }
791
+ }
792
+
714
793
  /** The provisioner for a kind. Pure — the lookup is testable without Pulumi. */
715
794
  export function provisionerFor(kind: DeclarationKind): Provisioner {
716
795
  const provisioner = PROVISIONERS[kind];
@@ -799,6 +878,7 @@ export function fromManifest(
799
878
  for (const id of [...rest, ...sites]) {
800
879
  const declaration = manifest[id];
801
880
  if (!declaration) continue;
881
+ if (PROVISIONED_ELSEWHERE.has(declaration.kind)) continue;
802
882
 
803
883
  const component = provisionerFor(declaration.kind)(
804
884
  stack,
@@ -822,6 +902,9 @@ export function fromManifest(
822
902
  provisioned[id] = component;
823
903
  }
824
904
 
905
+ // Each queue's one consumer, once everything it links to exists.
906
+ subscribeConsumers(manifest, provisioned);
907
+
825
908
  for (const line of describeRoutes(manifest)) console.log(line);
826
909
 
827
910
  // Now everything exists, so every surface's callers can be resolved — the
@@ -829,7 +912,7 @@ export function fromManifest(
829
912
  for (const [id, deferred] of callers) {
830
913
  // Resolved with the promise itself: the addresses it needs are Pulumi
831
914
  // outputs, so the answer arrives when they do.
832
- deferred.resolve(callersOf(id, manifest, provisioned));
915
+ deferred.resolve(callersOf(id, manifest, provisioned, $app.name));
833
916
  }
834
917
 
835
918
  // Last, and only now: the roles exist as passwords and secrets from the
@@ -1,64 +0,0 @@
1
- //#region src/utils/index.d.ts
2
- declare function getLocalIpAddress(): string | null;
3
- declare function environmentCase(name: string): string;
4
- declare enum ResourceType {
5
- ApiGatewayV2 = "sst.aws.ApiGatewayV2",
6
- Postgres = "sst.aws.Postgres",
7
- Function = "sst.aws.Function",
8
- ObjectStorage = "sst.aws.Bucket",
9
- Vpc = "sst.aws.Vpc",
10
- Secret = "sst.sst.Secret",
11
- SSTSecret = "sst:sst:Secret",
12
- SSTFunction = "sst:sst:Function",
13
- SSTApiGatewayV2 = "sst:aws:ApiGatewayV2",
14
- SSTPostgres = "sst:aws:Postgres",
15
- SSTObjectStorage = "sst:aws:Bucket",
16
- SnsTopic = "sst:aws:SnsTopic",
17
- }
18
- declare function buildResourceEnv(record: Record<string, Resource | string>): Record<string, string>;
19
- /**
20
- * SST links a resource under one of two spellings — `sst.aws.Bucket` when it
21
- * comes from the state file, `sst:aws:Bucket` when it comes from the runtime —
22
- * and `processors` has always handled both. Only the dotted half was admitted
23
- * here, so the colon half could not be passed to `buildResourceEnv` without a
24
- * cast, and `SnsTopic` was missing from `Resource` altogether despite being the
25
- * only thing that produces `*_ARN`.
26
- */
27
- type ApiGatewayV2 = {
28
- type: ResourceType.ApiGatewayV2 | ResourceType.SSTApiGatewayV2;
29
- url: string;
30
- };
31
- type Postgres = {
32
- database: string;
33
- host: string;
34
- password: string;
35
- port: number;
36
- type: ResourceType.Postgres | ResourceType.SSTPostgres;
37
- username: string;
38
- };
39
- type Function = {
40
- name: string;
41
- type: ResourceType.Function | ResourceType.SSTFunction;
42
- };
43
- type Bucket = {
44
- name: string;
45
- type: ResourceType.ObjectStorage | ResourceType.SSTObjectStorage;
46
- };
47
- type SnsTopic = {
48
- arn: string;
49
- type: ResourceType.SnsTopic;
50
- };
51
- type Vpc = {
52
- bastion: string;
53
- type: ResourceType.Vpc;
54
- };
55
- type Secret = {
56
- type: ResourceType.Secret | ResourceType.SSTSecret;
57
- value: string;
58
- };
59
- type Resource = ApiGatewayV2 | Postgres | Function | Bucket | SnsTopic | Vpc | Secret;
60
- type ResourceProcessor<K extends Resource> = (name: string, value: K) => Record<string, string | number>;
61
- //# sourceMappingURL=index.d.ts.map
62
- //#endregion
63
- export { ApiGatewayV2, Bucket, Function, Postgres, Resource, ResourceProcessor, ResourceType, Secret, SnsTopic, Vpc, buildResourceEnv, environmentCase, getLocalIpAddress };
64
- //# sourceMappingURL=index-B5CZ1xVf.d.cts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index-B5CZ1xVf.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,aACR,GAAA,gBAAA;EAAQ,GAAvB,GAAA,aAAA;EAAM,MACZ,GAAA,gBAAA;EAAM,SAAA,GAAA,gBAAA;EA0BG,WAAA,GAAA,kBAAY;EAAA,eAAA,GAAA,sBAAA;EAAA,WACjB,GAAA,kBAAa;EAAY,gBAAgB,GAAA,gBAAA;EAAe,QAAA,GAAA,kBAAA;AAI/D;AAAoB,iBAjCJ,gBAAA,CAiCI,MAAA,EAhCX,MAgCW,CAAA,MAAA,EAhCI,QAgCJ,GAAA,MAAA,CAAA,CAAA,EA/BjB,MA+BiB,CAAA,MAAA,EAAA,MAAA,CAAA;;;AAKmC;AAIvD;;;;AAEuD;AAG3C,KAnBA,YAAA,GAmBM;EAAA,IAAA,EAlBX,YAAA,CAAa,YAkBF,GAlBiB,YAAA,CAAa,eAkB9B;EAAA,GAEX,EAAA,MAAA;CAA0B;AAAgC,KAhBrD,QAAA,GAgBqD;EAGrD,QAAA,EAAA,MAAQ;EAKR,IAAA,EAAG,MAAA;EAKH,QAAA,EAAM,MAAA;EAAA,IAAA,EAAA,MAAA;EAAA,IACX,EAzBA,YAAA,CAAa,QAyBA,GAzBW,YAAA,CAAa,WAyBxB;EAAM,QAAG,EAAA,MAAa;AAAS,CAAA;AAIvC,KAzBA,QAAA,GAyBQ;EAAA,IAAA,EAAA,MAAA;EAAA,IACjB,EAxBI,YAAA,CAAa,QAwBjB,GAxB4B,YAAA,CAAa,WAwBzC;CAAY;AAEZ,KAvBS,MAAA,GAuBT;EAAQ,IACR,EAAA,MAAA;EAAM,IACN,EAvBI,YAAA,CAAa,aAuBjB,GAvBiC,YAAA,CAAa,gBAuB9C;CAAQ;AAER,KAtBS,QAAA,GAsBT;EAAM,GAAA,EAAA,MAAA;EAEG,IAAA,EAtBL,YAAA,CAAa,QAsBS;CAAA;AAAW,KAnB5B,GAAA,GAmB4B;EAAQ,OAExC,EAAA,MAAA;EAAC,IACJ,EApBE,YAAA,CAAa,GAoBf;AAAM,CAAA;KAjBC,MAAA;QACL,YAAA,CAAa,SAAS,YAAA,CAAa;;;KAI9B,QAAA,GACT,eACA,WACA,WACA,SACA,WACA,MACA;KAES,4BAA4B,kCAEhC,MACH"}
@@ -1,64 +0,0 @@
1
- //#region src/utils/index.d.ts
2
- declare function getLocalIpAddress(): string | null;
3
- declare function environmentCase(name: string): string;
4
- declare enum ResourceType {
5
- ApiGatewayV2 = "sst.aws.ApiGatewayV2",
6
- Postgres = "sst.aws.Postgres",
7
- Function = "sst.aws.Function",
8
- ObjectStorage = "sst.aws.Bucket",
9
- Vpc = "sst.aws.Vpc",
10
- Secret = "sst.sst.Secret",
11
- SSTSecret = "sst:sst:Secret",
12
- SSTFunction = "sst:sst:Function",
13
- SSTApiGatewayV2 = "sst:aws:ApiGatewayV2",
14
- SSTPostgres = "sst:aws:Postgres",
15
- SSTObjectStorage = "sst:aws:Bucket",
16
- SnsTopic = "sst:aws:SnsTopic",
17
- }
18
- declare function buildResourceEnv(record: Record<string, Resource | string>): Record<string, string>;
19
- /**
20
- * SST links a resource under one of two spellings — `sst.aws.Bucket` when it
21
- * comes from the state file, `sst:aws:Bucket` when it comes from the runtime —
22
- * and `processors` has always handled both. Only the dotted half was admitted
23
- * here, so the colon half could not be passed to `buildResourceEnv` without a
24
- * cast, and `SnsTopic` was missing from `Resource` altogether despite being the
25
- * only thing that produces `*_ARN`.
26
- */
27
- type ApiGatewayV2 = {
28
- type: ResourceType.ApiGatewayV2 | ResourceType.SSTApiGatewayV2;
29
- url: string;
30
- };
31
- type Postgres = {
32
- database: string;
33
- host: string;
34
- password: string;
35
- port: number;
36
- type: ResourceType.Postgres | ResourceType.SSTPostgres;
37
- username: string;
38
- };
39
- type Function = {
40
- name: string;
41
- type: ResourceType.Function | ResourceType.SSTFunction;
42
- };
43
- type Bucket = {
44
- name: string;
45
- type: ResourceType.ObjectStorage | ResourceType.SSTObjectStorage;
46
- };
47
- type SnsTopic = {
48
- arn: string;
49
- type: ResourceType.SnsTopic;
50
- };
51
- type Vpc = {
52
- bastion: string;
53
- type: ResourceType.Vpc;
54
- };
55
- type Secret = {
56
- type: ResourceType.Secret | ResourceType.SSTSecret;
57
- value: string;
58
- };
59
- type Resource = ApiGatewayV2 | Postgres | Function | Bucket | SnsTopic | Vpc | Secret;
60
- type ResourceProcessor<K extends Resource> = (name: string, value: K) => Record<string, string | number>;
61
- //# sourceMappingURL=index.d.ts.map
62
- //#endregion
63
- export { ApiGatewayV2, Bucket, Function, Postgres, Resource, ResourceProcessor, ResourceType, Secret, SnsTopic, Vpc, buildResourceEnv, environmentCase, getLocalIpAddress };
64
- //# sourceMappingURL=index-DhHRjduZ.d.mts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index-DhHRjduZ.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,aACR,GAAA,gBAAA;EAAQ,GAAvB,GAAA,aAAA;EAAM,MACZ,GAAA,gBAAA;EAAM,SAAA,GAAA,gBAAA;EA0BG,WAAA,GAAA,kBAAY;EAAA,eAAA,GAAA,sBAAA;EAAA,WACjB,GAAA,kBAAa;EAAY,gBAAgB,GAAA,gBAAA;EAAe,QAAA,GAAA,kBAAA;AAI/D;AAAoB,iBAjCJ,gBAAA,CAiCI,MAAA,EAhCX,MAgCW,CAAA,MAAA,EAhCI,QAgCJ,GAAA,MAAA,CAAA,CAAA,EA/BjB,MA+BiB,CAAA,MAAA,EAAA,MAAA,CAAA;;;AAKmC;AAIvD;;;;AAEuD;AAG3C,KAnBA,YAAA,GAmBM;EAAA,IAAA,EAlBX,YAAA,CAAa,YAkBF,GAlBiB,YAAA,CAAa,eAkB9B;EAAA,GAEX,EAAA,MAAA;CAA0B;AAAgC,KAhBrD,QAAA,GAgBqD;EAGrD,QAAA,EAAA,MAAQ;EAKR,IAAA,EAAG,MAAA;EAKH,QAAA,EAAM,MAAA;EAAA,IAAA,EAAA,MAAA;EAAA,IACX,EAzBA,YAAA,CAAa,QAyBA,GAzBW,YAAA,CAAa,WAyBxB;EAAM,QAAG,EAAA,MAAa;AAAS,CAAA;AAIvC,KAzBA,QAAA,GAyBQ;EAAA,IAAA,EAAA,MAAA;EAAA,IACjB,EAxBI,YAAA,CAAa,QAwBjB,GAxB4B,YAAA,CAAa,WAwBzC;CAAY;AAEZ,KAvBS,MAAA,GAuBT;EAAQ,IACR,EAAA,MAAA;EAAM,IACN,EAvBI,YAAA,CAAa,aAuBjB,GAvBiC,YAAA,CAAa,gBAuB9C;CAAQ;AAER,KAtBS,QAAA,GAsBT;EAAM,GAAA,EAAA,MAAA;EAEG,IAAA,EAtBL,YAAA,CAAa,QAsBS;CAAA;AAAW,KAnB5B,GAAA,GAmB4B;EAAQ,OAExC,EAAA,MAAA;EAAC,IACJ,EApBE,YAAA,CAAa,GAoBf;AAAM,CAAA;KAjBC,MAAA;QACL,YAAA,CAAa,SAAS,YAAA,CAAa;;;KAI9B,QAAA,GACT,eACA,WACA,WACA,SACA,WACA,MACA;KAES,4BAA4B,kCAEhC,MACH"}
@@ -1,129 +0,0 @@
1
- //#region rolldown:runtime
2
- var __create = Object.create;
3
- var __defProp = Object.defineProperty;
4
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
- var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getProtoOf = Object.getPrototypeOf;
7
- var __hasOwnProp = Object.prototype.hasOwnProperty;
8
- var __copyProps = (to, from, except, desc) => {
9
- if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
10
- key = keys[i];
11
- if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
12
- get: ((k) => from[k]).bind(null, key),
13
- enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
14
- });
15
- }
16
- return to;
17
- };
18
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
19
- value: mod,
20
- enumerable: true
21
- }) : target, mod));
22
-
23
- //#endregion
24
- const node_os = __toESM(require("node:os"));
25
- const lodash_snakecase = __toESM(require("lodash.snakecase"));
26
-
27
- //#region src/utils/index.ts
28
- function getLocalIpAddress() {
29
- const networkInterfaces = node_os.default.networkInterfaces();
30
- for (const interfaceName in networkInterfaces) {
31
- const addresses = networkInterfaces[interfaceName] || [];
32
- for (const addressInfo of addresses) if (addressInfo.family === "IPv4" && !addressInfo.internal) return addressInfo.address;
33
- }
34
- return null;
35
- }
36
- function environmentCase(name) {
37
- return (0, lodash_snakecase.default)(name).toUpperCase().replace(/_\d+/g, (r) => {
38
- return r.replace("_", "");
39
- });
40
- }
41
- let ResourceType = /* @__PURE__ */ function(ResourceType$1) {
42
- ResourceType$1["ApiGatewayV2"] = "sst.aws.ApiGatewayV2";
43
- ResourceType$1["Postgres"] = "sst.aws.Postgres";
44
- ResourceType$1["Function"] = "sst.aws.Function";
45
- ResourceType$1["ObjectStorage"] = "sst.aws.Bucket";
46
- ResourceType$1["Vpc"] = "sst.aws.Vpc";
47
- ResourceType$1["Secret"] = "sst.sst.Secret";
48
- ResourceType$1["SSTSecret"] = "sst:sst:Secret";
49
- ResourceType$1["SSTFunction"] = "sst:sst:Function";
50
- ResourceType$1["SSTApiGatewayV2"] = "sst:aws:ApiGatewayV2";
51
- ResourceType$1["SSTPostgres"] = "sst:aws:Postgres";
52
- ResourceType$1["SSTObjectStorage"] = "sst:aws:Bucket";
53
- ResourceType$1["SnsTopic"] = "sst:aws:SnsTopic";
54
- return ResourceType$1;
55
- }({});
56
- const secret = (name, value) => ({ [environmentCase(name)]: value.value });
57
- const postgres = (key, value) => {
58
- const prefix = `${environmentCase(key)}`;
59
- return {
60
- [`${prefix}_NAME`]: value.database,
61
- [`${prefix}_HOST`]: value.host,
62
- [`${prefix}_PASSWORD`]: value.password,
63
- [`${prefix}_PORT`]: value.port,
64
- [`${prefix}_USERNAME`]: value.username
65
- };
66
- };
67
- const bucket = (name, value) => {
68
- const prefix = `${environmentCase(name)}`;
69
- return { [`${prefix}_NAME`]: value.name };
70
- };
71
- const topic = (name, value) => {
72
- const prefix = `${environmentCase(name)}`;
73
- const key = `${prefix}_ARN`;
74
- return { [key]: value.arn };
75
- };
76
- const noop = (_name, _value) => ({});
77
- const processors = {
78
- [ResourceType.ApiGatewayV2]: noop,
79
- [ResourceType.Function]: noop,
80
- [ResourceType.Vpc]: noop,
81
- [ResourceType.Secret]: secret,
82
- [ResourceType.Postgres]: postgres,
83
- [ResourceType.ObjectStorage]: bucket,
84
- [ResourceType.SSTSecret]: secret,
85
- [ResourceType.SSTObjectStorage]: bucket,
86
- [ResourceType.SSTFunction]: noop,
87
- [ResourceType.SSTPostgres]: postgres,
88
- [ResourceType.SSTApiGatewayV2]: noop,
89
- [ResourceType.SnsTopic]: topic
90
- };
91
- function buildResourceEnv(record) {
92
- const env = {};
93
- for (const [k, value] of Object.entries(record)) {
94
- if (typeof value === "string") {
95
- env[environmentCase(k)] = value;
96
- continue;
97
- }
98
- const processor = processors[value.type];
99
- if (processor) Object.assign(env, processor(k, value));
100
- }
101
- return env;
102
- }
103
-
104
- //#endregion
105
- Object.defineProperty(exports, 'ResourceType', {
106
- enumerable: true,
107
- get: function () {
108
- return ResourceType;
109
- }
110
- });
111
- Object.defineProperty(exports, 'buildResourceEnv', {
112
- enumerable: true,
113
- get: function () {
114
- return buildResourceEnv;
115
- }
116
- });
117
- Object.defineProperty(exports, 'environmentCase', {
118
- enumerable: true,
119
- get: function () {
120
- return environmentCase;
121
- }
122
- });
123
- Object.defineProperty(exports, 'getLocalIpAddress', {
124
- enumerable: true,
125
- get: function () {
126
- return getLocalIpAddress;
127
- }
128
- });
129
- //# sourceMappingURL=utils-B1a2UuEO.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"utils-B1a2UuEO.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\tObjectStorage = '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\tSSTObjectStorage = '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.ObjectStorage]: bucket,\n\n\t[ResourceType.SSTSecret]: secret,\n\t[ResourceType.SSTObjectStorage]: 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\n/**\n * SST links a resource under one of two spellings — `sst.aws.Bucket` when it\n * comes from the state file, `sst:aws:Bucket` when it comes from the runtime —\n * and `processors` has always handled both. Only the dotted half was admitted\n * here, so the colon half could not be passed to `buildResourceEnv` without a\n * cast, and `SnsTopic` was missing from `Resource` altogether despite being the\n * only thing that produces `*_ARN`.\n */\nexport type ApiGatewayV2 = {\n\ttype: ResourceType.ApiGatewayV2 | ResourceType.SSTApiGatewayV2;\n\turl: string;\n};\n\nexport type Postgres = {\n\tdatabase: string;\n\thost: string;\n\tpassword: string;\n\tport: number;\n\ttype: ResourceType.Postgres | ResourceType.SSTPostgres;\n\tusername: string;\n};\n\nexport type Function = {\n\tname: string;\n\ttype: ResourceType.Function | ResourceType.SSTFunction;\n};\n\nexport type Bucket = {\n\tname: string;\n\ttype: ResourceType.ObjectStorage | ResourceType.SSTObjectStorage;\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 | ResourceType.SSTSecret;\n\tvalue: string;\n};\n\nexport type Resource =\n\t| ApiGatewayV2\n\t| Postgres\n\t| Function\n\t| Bucket\n\t| SnsTopic\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,gBAAgB;EAE7B,aAAa,YAAY;EACzB,aAAa,mBAAmB;EAChC,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,83 +0,0 @@
1
- import os from "node:os";
2
- import snakecase from "lodash.snakecase";
3
-
4
- //#region src/utils/index.ts
5
- function getLocalIpAddress() {
6
- const networkInterfaces = os.networkInterfaces();
7
- for (const interfaceName in networkInterfaces) {
8
- const addresses = networkInterfaces[interfaceName] || [];
9
- for (const addressInfo of addresses) if (addressInfo.family === "IPv4" && !addressInfo.internal) return addressInfo.address;
10
- }
11
- return null;
12
- }
13
- function environmentCase(name) {
14
- return snakecase(name).toUpperCase().replace(/_\d+/g, (r) => {
15
- return r.replace("_", "");
16
- });
17
- }
18
- let ResourceType = /* @__PURE__ */ function(ResourceType$1) {
19
- ResourceType$1["ApiGatewayV2"] = "sst.aws.ApiGatewayV2";
20
- ResourceType$1["Postgres"] = "sst.aws.Postgres";
21
- ResourceType$1["Function"] = "sst.aws.Function";
22
- ResourceType$1["ObjectStorage"] = "sst.aws.Bucket";
23
- ResourceType$1["Vpc"] = "sst.aws.Vpc";
24
- ResourceType$1["Secret"] = "sst.sst.Secret";
25
- ResourceType$1["SSTSecret"] = "sst:sst:Secret";
26
- ResourceType$1["SSTFunction"] = "sst:sst:Function";
27
- ResourceType$1["SSTApiGatewayV2"] = "sst:aws:ApiGatewayV2";
28
- ResourceType$1["SSTPostgres"] = "sst:aws:Postgres";
29
- ResourceType$1["SSTObjectStorage"] = "sst:aws:Bucket";
30
- ResourceType$1["SnsTopic"] = "sst:aws:SnsTopic";
31
- return ResourceType$1;
32
- }({});
33
- const secret = (name, value) => ({ [environmentCase(name)]: value.value });
34
- const postgres = (key, value) => {
35
- const prefix = `${environmentCase(key)}`;
36
- return {
37
- [`${prefix}_NAME`]: value.database,
38
- [`${prefix}_HOST`]: value.host,
39
- [`${prefix}_PASSWORD`]: value.password,
40
- [`${prefix}_PORT`]: value.port,
41
- [`${prefix}_USERNAME`]: value.username
42
- };
43
- };
44
- const bucket = (name, value) => {
45
- const prefix = `${environmentCase(name)}`;
46
- return { [`${prefix}_NAME`]: value.name };
47
- };
48
- const topic = (name, value) => {
49
- const prefix = `${environmentCase(name)}`;
50
- const key = `${prefix}_ARN`;
51
- return { [key]: value.arn };
52
- };
53
- const noop = (_name, _value) => ({});
54
- const processors = {
55
- [ResourceType.ApiGatewayV2]: noop,
56
- [ResourceType.Function]: noop,
57
- [ResourceType.Vpc]: noop,
58
- [ResourceType.Secret]: secret,
59
- [ResourceType.Postgres]: postgres,
60
- [ResourceType.ObjectStorage]: bucket,
61
- [ResourceType.SSTSecret]: secret,
62
- [ResourceType.SSTObjectStorage]: bucket,
63
- [ResourceType.SSTFunction]: noop,
64
- [ResourceType.SSTPostgres]: postgres,
65
- [ResourceType.SSTApiGatewayV2]: noop,
66
- [ResourceType.SnsTopic]: topic
67
- };
68
- function buildResourceEnv(record) {
69
- const env = {};
70
- for (const [k, value] of Object.entries(record)) {
71
- if (typeof value === "string") {
72
- env[environmentCase(k)] = value;
73
- continue;
74
- }
75
- const processor = processors[value.type];
76
- if (processor) Object.assign(env, processor(k, value));
77
- }
78
- return env;
79
- }
80
-
81
- //#endregion
82
- export { ResourceType, buildResourceEnv, environmentCase, getLocalIpAddress };
83
- //# sourceMappingURL=utils-DMOXJ27j.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"utils-DMOXJ27j.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\tObjectStorage = '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\tSSTObjectStorage = '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.ObjectStorage]: bucket,\n\n\t[ResourceType.SSTSecret]: secret,\n\t[ResourceType.SSTObjectStorage]: 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\n/**\n * SST links a resource under one of two spellings — `sst.aws.Bucket` when it\n * comes from the state file, `sst:aws:Bucket` when it comes from the runtime —\n * and `processors` has always handled both. Only the dotted half was admitted\n * here, so the colon half could not be passed to `buildResourceEnv` without a\n * cast, and `SnsTopic` was missing from `Resource` altogether despite being the\n * only thing that produces `*_ARN`.\n */\nexport type ApiGatewayV2 = {\n\ttype: ResourceType.ApiGatewayV2 | ResourceType.SSTApiGatewayV2;\n\turl: string;\n};\n\nexport type Postgres = {\n\tdatabase: string;\n\thost: string;\n\tpassword: string;\n\tport: number;\n\ttype: ResourceType.Postgres | ResourceType.SSTPostgres;\n\tusername: string;\n};\n\nexport type Function = {\n\tname: string;\n\ttype: ResourceType.Function | ResourceType.SSTFunction;\n};\n\nexport type Bucket = {\n\tname: string;\n\ttype: ResourceType.ObjectStorage | ResourceType.SSTObjectStorage;\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 | ResourceType.SSTSecret;\n\tvalue: string;\n};\n\nexport type Resource =\n\t| ApiGatewayV2\n\t| Postgres\n\t| Function\n\t| Bucket\n\t| SnsTopic\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,gBAAgB;EAE7B,aAAa,YAAY;EACzB,aAAa,mBAAmB;EAChC,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"}