@geekmidas/cloud 10.0.0-alpha.12 → 10.0.0-alpha.13

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.
@@ -0,0 +1,192 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { App } from '../App';
3
+ import { Cron } from '../aws/Cron';
4
+ import { Function } from '../aws/Function';
5
+ import { type GkmLinkable, ResourceType } from '../Linkable';
6
+
7
+ /**
8
+ * A Lambda and a schedule as data: the args each hands SST (a recording stub
9
+ * in `test/sst-globals.ts`), and the env validation that fails before deploy.
10
+ */
11
+
12
+ const app = new App({
13
+ name: 'shop',
14
+ stage: 'prod',
15
+ domain: 'shop.test',
16
+ hostedZoneId: 'Z1',
17
+ region: 'eu-west-1',
18
+ });
19
+ const stack = app.stack('jobs');
20
+ const db: GkmLinkable = { _id: 'db', _type: ResourceType.Postgres };
21
+
22
+ const argsOf = (component: unknown) =>
23
+ (component as { args: Record<string, unknown> }).args;
24
+
25
+ describe('Function', () => {
26
+ it('defaults the runtime and logging, and links only what its variables need', () => {
27
+ const fn = new Function(stack, 'Reports', {
28
+ handler: 'reports.handler',
29
+ links: [db],
30
+ envVars: ['DB_URL'],
31
+ environment: { FEATURE: 'on' },
32
+ });
33
+
34
+ expect(fn._type).toBe(ResourceType.Function);
35
+ expect(argsOf(fn)).toMatchObject({
36
+ handler: 'reports.handler',
37
+ runtime: 'nodejs24.x',
38
+ logging: { format: 'json' },
39
+ link: [db],
40
+ environment: expect.objectContaining({
41
+ SERVICE_NAME: 'Reports',
42
+ STAGE: 'prod',
43
+ FEATURE: 'on',
44
+ }),
45
+ });
46
+ expect(fn.validate().valid).toBe(true);
47
+ });
48
+
49
+ it('keeps a runtime and logging it was given', () => {
50
+ const fn = new Function(stack, 'Legacy', {
51
+ handler: 'legacy.handler',
52
+ runtime: 'nodejs20.x',
53
+ logging: { format: 'text' },
54
+ });
55
+
56
+ expect(argsOf(fn)).toMatchObject({
57
+ runtime: 'nodejs20.x',
58
+ logging: { format: 'text' },
59
+ link: [],
60
+ });
61
+ });
62
+
63
+ it('fails the synth on a variable no link provides, unless told not to check', () => {
64
+ expect(
65
+ () =>
66
+ new Function(stack, 'Mailer', {
67
+ handler: 'mailer.handler',
68
+ envVars: ['SMTP_URL'],
69
+ }),
70
+ ).toThrow(/SMTP_URL/);
71
+
72
+ const unchecked = new Function(stack, 'Mailer', {
73
+ handler: 'mailer.handler',
74
+ envVars: ['SMTP_URL'],
75
+ autoValidate: false,
76
+ });
77
+ expect(unchecked.validate()).toMatchObject({
78
+ valid: false,
79
+ invalidVars: ['SMTP_URL'],
80
+ });
81
+ });
82
+
83
+ it('builds one function per manifest entry, named for the stack', () => {
84
+ const functions = Function.fromManifest(
85
+ stack,
86
+ {
87
+ billing: [
88
+ {
89
+ name: 'Invoice',
90
+ handler: '.gkm/aws-lambda/functions/invoice.handler',
91
+ environment: ['DB_URL'],
92
+ timeout: 60,
93
+ memorySize: 512,
94
+ },
95
+ ],
96
+ ops: [
97
+ {
98
+ name: 'Ping',
99
+ handler: '.gkm/aws-lambda/functions/ping.handler',
100
+ environment: [],
101
+ },
102
+ ],
103
+ } as never,
104
+ { links: [db] },
105
+ );
106
+
107
+ expect(functions.map((f) => argsOf(f))).toEqual([
108
+ expect.objectContaining({
109
+ name: stack.logicalPrefixedName('Invoice'),
110
+ timeout: '60 seconds',
111
+ memory: '512 MB',
112
+ link: [db],
113
+ }),
114
+ expect.objectContaining({
115
+ name: stack.logicalPrefixedName('Ping'),
116
+ timeout: undefined,
117
+ memory: undefined,
118
+ link: [],
119
+ }),
120
+ ]);
121
+ });
122
+ });
123
+
124
+ describe('Cron', () => {
125
+ it('schedules the function it is given, by ARN', () => {
126
+ const processor = { arn: 'arn:aws:lambda:eu-west-1:1:function:nightly' };
127
+ const cron = new Cron(stack, 'Nightly', {
128
+ processor: processor as never,
129
+ schedule: 'rate(1 day)',
130
+ enabled: false,
131
+ });
132
+
133
+ expect(argsOf(cron)).toEqual({
134
+ enabled: false,
135
+ schedule: 'rate(1 day)',
136
+ function: processor.arn,
137
+ });
138
+ });
139
+
140
+ it('builds a validated function and a schedule per manifest cron', () => {
141
+ const crons = Cron.fromManifest(
142
+ stack,
143
+ [
144
+ {
145
+ name: 'Digest',
146
+ handler: '.gkm/aws-lambda/crons/digest.handler',
147
+ schedule: 'cron(0 8 * * ? *)',
148
+ environment: ['DB_URL'],
149
+ timeout: 120,
150
+ memorySize: 1024,
151
+ },
152
+ {
153
+ name: 'Sweep',
154
+ handler: '.gkm/aws-lambda/crons/sweep.handler',
155
+ schedule: 'rate(1 hour)',
156
+ environment: [],
157
+ },
158
+ ] as never,
159
+ { links: [db], enabled: true },
160
+ );
161
+
162
+ const [digest, sweep] = crons.map((c) => argsOf(c));
163
+ expect(digest).toMatchObject({
164
+ schedule: 'cron(0 8 * * ? *)',
165
+ enabled: true,
166
+ function: expect.stringContaining('DigestFunction'),
167
+ });
168
+ expect(sweep).toMatchObject({ schedule: 'rate(1 hour)' });
169
+ });
170
+ });
171
+
172
+ describe('App and Stack', () => {
173
+ it('pick a value for the stage, falling back to the default', () => {
174
+ expect(app.select({ prod: 'live', default: 'test' })).toBe('live');
175
+ expect(stack.select({ staging: 'test', default: 'dev' } as never)).toBe(
176
+ 'dev',
177
+ );
178
+ });
179
+
180
+ it('name subdomains and URLs under the root domain', () => {
181
+ expect(stack.domain).toBe('shop.test');
182
+ expect(stack.getSubdomain('api')).toBe('api.shop.test');
183
+ expect(stack.getURL('api')).toBe('https://api.shop.test');
184
+ expect(stack.getURL()).toBe('https://shop.test');
185
+ expect(app.getURL()).toBe('https://shop.test');
186
+ });
187
+
188
+ it('prefix physical names with the stage, app and stack', () => {
189
+ expect(app.logicalPrefixedName('Uploads')).toBe('prod-shop-uploads');
190
+ expect(stack.logicalPrefixedName('Uploads')).toBe('prod-shop-jobs-uploads');
191
+ });
192
+ });
@@ -0,0 +1,209 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { Cache, CacheNeedsProvider, CacheNeedsVpc } from '../aws/Cache';
3
+ import { Database } from '../aws/Database';
4
+ import { DatabaseReader, DatabaseSchema } from '../aws/DerivedDatabase';
5
+ import { Email } from '../aws/Email';
6
+ import { FileServer } from '../aws/FileServer';
7
+ import { Queue } from '../aws/Queue';
8
+ import { RestApiSurface } from '../aws/RestApiSurface';
9
+ import { Secret } from '../aws/Secret';
10
+ import { StaticSite } from '../aws/StaticSite';
11
+ import { Storage } from '../aws/Storage';
12
+ import { Topic } from '../aws/Topic';
13
+ import { ResourceType } from '../Linkable';
14
+
15
+ /**
16
+ * What a linked function receives from each component, and the type that
17
+ * decides which variables a link provides. `getSSTLink()` is the payload SST
18
+ * injects into every handler linked to the resource; `_type` is what
19
+ * `LinkedEnvironment` keys the variable names off.
20
+ */
21
+
22
+ const stack = {} as never;
23
+ const vpc = { subnets: ['subnet-1'], securityGroups: ['sg-1'] } as never;
24
+
25
+ /** Resolves `$util.output(promise)`, which the stub leaves as the promise. */
26
+ const settle = async (value: unknown) =>
27
+ (value as { apply: (fn: (v: unknown) => unknown) => unknown }).apply(
28
+ (v) => v,
29
+ );
30
+
31
+ describe('link payloads', () => {
32
+ it('a queue adds its ARN and connection string to SST’s own link', () => {
33
+ const queue = new Queue(stack, 'Emails');
34
+
35
+ expect(queue._type).toBe(ResourceType.Queue);
36
+ // The connection string itself is parsed back in provides.spec; here, the
37
+ // link carries exactly what `provides()` resolved.
38
+ expect(queue.getSSTLink().properties).toEqual({
39
+ name: 'Emails',
40
+ arn: queue.arn,
41
+ ...queue.provides(),
42
+ });
43
+ });
44
+
45
+ it('a topic carries its publisher connection string', () => {
46
+ const topic = new Topic(stack, 'Users');
47
+
48
+ expect(topic._type).toBe(ResourceType.SnsTopic);
49
+ expect(topic.getSSTLink().properties).toEqual({
50
+ name: 'Users',
51
+ ...topic.provides(),
52
+ });
53
+ });
54
+
55
+ it('a secret carries its value', () => {
56
+ const secret = new Secret(stack, 'AuthSecret');
57
+
58
+ expect(secret._type).toBe(ResourceType.SSTSecret);
59
+ expect(secret.getSSTLink().properties).toMatchObject(secret.provides());
60
+ });
61
+
62
+ it('a mailer carries its URL and sending identity, and nothing else', () => {
63
+ const email = new Email(stack, 'Mail', {
64
+ backend: 'smtp',
65
+ url: 'smtp://relay.test:587',
66
+ from: 'hello@shop.test',
67
+ } as never);
68
+
69
+ expect(email._type).toBe(ResourceType.Email);
70
+ expect(email.getSSTLink()).toEqual({
71
+ properties: { url: 'smtp://relay.test:587', from: 'hello@shop.test' },
72
+ });
73
+ });
74
+
75
+ it('a file server routes everything to its bucket, and links its URL', () => {
76
+ const origin = new Storage(stack, 'Uploads');
77
+ const server = new FileServer(stack, 'Files', { origin } as never);
78
+
79
+ expect(origin._type).toBe(ResourceType.ObjectStorage);
80
+ expect(origin._id).toBe('Uploads');
81
+ expect(server._type).toBe(ResourceType.FileServer);
82
+ expect((server as unknown as { routed: unknown[] }).routed).toEqual([
83
+ { pattern: '/*', bucket: origin },
84
+ ]);
85
+ expect(server.getSSTLink().properties).toMatchObject({
86
+ url: server.url,
87
+ });
88
+ });
89
+
90
+ it('a site is built the way its variant builds, and links its URL', () => {
91
+ const vite = new StaticSite(stack, 'Web');
92
+ const next = new StaticSite(stack, 'Admin', {
93
+ variant: 'next',
94
+ build: { command: 'pnpm build:custom', output: 'out' },
95
+ } as never);
96
+ const args = (site: unknown) => (site as { args: { build: unknown } }).args;
97
+
98
+ expect(vite._type).toBe(ResourceType.StaticSite);
99
+ expect(args(vite).build).toEqual(expect.objectContaining({}));
100
+ // A build the caller supplied wins over the variant's.
101
+ expect(args(next).build).toEqual({
102
+ command: 'pnpm build:custom',
103
+ output: 'out',
104
+ });
105
+ expect(vite.getSSTLink().properties).toMatchObject({ url: vite.url });
106
+ });
107
+
108
+ it('a surface links its address and, once resolved, who may call it', async () => {
109
+ const bare = new RestApiSurface(stack, 'Api');
110
+ const called = new RestApiSurface(stack, 'Api', {
111
+ callers: Promise.resolve({
112
+ trustedOrigins: 'https://web.shop.test',
113
+ cookieDomain: 'shop.test',
114
+ }),
115
+ });
116
+
117
+ expect(bare._type).toBe(ResourceType.ApiGatewayV2);
118
+ expect(await settle(bare.provides().trustedOrigins)).toBe('');
119
+ expect(await settle(bare.provides().cookieDomain)).toBe('');
120
+
121
+ const link = called.getSSTLink().properties as Record<string, unknown>;
122
+ expect(link.url).toBe(called.url);
123
+ expect(await settle(link.trustedOrigins)).toBe('https://web.shop.test');
124
+ expect(await settle(link.cookieDomain)).toBe('shop.test');
125
+ });
126
+
127
+ it('a database and the nodes derived from it each link only their own URL', () => {
128
+ const cluster = new Database(stack, 'Orders', { vpc, schema: 'app' });
129
+ const reader = new DatabaseReader('OrdersReader', cluster);
130
+ const tenant = new DatabaseSchema('AuthDb', cluster, 'authdb');
131
+
132
+ expect(cluster._type).toBe(ResourceType.SSTPostgres);
133
+ expect(reader._type).toBe(ResourceType.SSTPostgres);
134
+ expect(tenant._type).toBe(ResourceType.SSTPostgres);
135
+ expect(cluster.getSSTLink().properties).toMatchObject({
136
+ url: cluster.provides().url,
137
+ });
138
+ // Least privilege: the reader's link is its URL and not the writer's.
139
+ expect(reader.getSSTLink()).toEqual({
140
+ properties: { url: reader.provides().url },
141
+ });
142
+ expect(tenant.getSSTLink()).toEqual({
143
+ properties: { url: tenant.provides().url },
144
+ });
145
+ });
146
+
147
+ it('a cache given its URL links it as-is', () => {
148
+ const cache = new Cache(stack, 'Sessions', {
149
+ backend: 'db',
150
+ url: 'postgres://db.test/app',
151
+ });
152
+
153
+ expect(cache._type).toBe(ResourceType.Cache);
154
+ expect(cache.getSSTLink()).toEqual({
155
+ properties: { url: 'postgres://db.test/app' },
156
+ });
157
+ });
158
+ });
159
+
160
+ describe('Cache on Upstash', () => {
161
+ /** `sst add upstash` installs this global; here, a recording stand-in. */
162
+ const created: { name: string; args: Record<string, unknown> }[] = [];
163
+ class RedisDatabase {
164
+ readonly endpoint = 'eu1-cache.upstash.io';
165
+ readonly restToken = 'tok/en+1';
166
+ constructor(name: string, args: Record<string, unknown>) {
167
+ created.push({ name, args });
168
+ }
169
+ }
170
+
171
+ it('creates a TLS database and puts its token in the URL', () => {
172
+ (globalThis as Record<string, unknown>).upstash = { RedisDatabase };
173
+ try {
174
+ const defaulted = new Cache(stack, 'Sessions', { backend: 'upstash' });
175
+ new Cache(stack, 'Rates', { backend: 'upstash', region: 'us-east-1' });
176
+
177
+ expect(created).toEqual([
178
+ {
179
+ name: 'SessionsCache',
180
+ args: { databaseName: 'Sessions', region: 'eu-west-1', tls: true },
181
+ },
182
+ {
183
+ name: 'RatesCache',
184
+ args: { databaseName: 'Rates', region: 'us-east-1', tls: true },
185
+ },
186
+ ]);
187
+ // The address and the credential that opens it are one fact.
188
+ expect(defaulted.provides().url).toBe(
189
+ `https://:${encodeURIComponent('tok/en+1')}@eu1-cache.upstash.io`,
190
+ );
191
+ } finally {
192
+ delete (globalThis as Record<string, unknown>).upstash;
193
+ }
194
+ });
195
+ });
196
+
197
+ describe('Cache provisioning refusals', () => {
198
+ it('asks for the Upstash provider when it is not installed', () => {
199
+ expect(() => new Cache(stack, 'Sessions', { backend: 'upstash' })).toThrow(
200
+ CacheNeedsProvider,
201
+ );
202
+ });
203
+
204
+ it('asks for a VPC before creating an ElastiCache', () => {
205
+ expect(
206
+ () => new Cache(stack, 'Sessions', { backend: 'elasticache' }),
207
+ ).toThrow(CacheNeedsVpc);
208
+ });
209
+ });
@@ -84,7 +84,21 @@ export class Database<
84
84
  * produces a database that looks empty.
85
85
  */
86
86
  provides(): Record<string, $util.Input<string>> {
87
- return { url: this.urlFor({}) };
87
+ return { url: this.urlFor(this.role ? { as: this.role } : {}) };
88
+ }
89
+
90
+ /**
91
+ * The runtime role this database's own handlers connect as.
92
+ *
93
+ * Set by the adapter once the bootstrap has registered the role — the
94
+ * cluster exists before any role does, so it cannot be a constructor
95
+ * argument. Until it is set (and under `roles: false`, where it never is),
96
+ * the URL is the master's.
97
+ */
98
+ private role: { user: string; password: $util.Input<string> } | undefined;
99
+
100
+ connectAs(role: { user: string; password: $util.Input<string> }): void {
101
+ this.role = role;
88
102
  }
89
103
 
90
104
  /**
@@ -232,13 +232,20 @@ const PROVISIONERS: Partial<Record<DeclarationKind, Provisioner>> = {
232
232
  const bootstrap = bootstrapFor(cluster, d.id, context);
233
233
  const runtime = roleNameFor(d, context);
234
234
 
235
- bootstrap?.add({
235
+ const credentials = bootstrap?.add({
236
236
  id: d.id,
237
237
  schema: d.schema,
238
238
  runtime,
239
239
  owner: ownerRole(runtime),
240
240
  ...(hasReader(d.id, context) ? { reader: readerRole(runtime) } : {}),
241
241
  });
242
+
243
+ // Registering the role was half of it: its handlers have to connect as
244
+ // it too, or the DDL creates a role nothing uses and every handler
245
+ // linked to the database still holds the master.
246
+ if (credentials) {
247
+ cluster.connectAs({ user: runtime, password: credentials.runtime });
248
+ }
242
249
  }
243
250
 
244
251
  return cluster;
@@ -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"}