@geekmidas/cloud 10.0.0-alpha.12 → 10.0.0-alpha.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +3 -3
- package/dist/index.d.cts +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.mjs +2 -3
- package/dist/utils/index.cjs +106 -5
- package/dist/utils/index.cjs.map +1 -0
- package/dist/utils/index.d.cts +62 -2
- package/dist/utils/index.d.cts.map +1 -0
- package/dist/utils/index.d.mts +62 -2
- package/dist/utils/index.d.mts.map +1 -0
- package/dist/utils/index.mjs +78 -2
- package/dist/utils/index.mjs.map +1 -0
- package/package.json +7 -7
- package/src/dokploy/Application.ts +52 -5
- package/src/dokploy/__tests__/Application.provider.spec.ts +206 -0
- package/src/sst/__tests__/api.spec.ts +231 -0
- package/src/sst/__tests__/fromManifest.integration.spec.ts +368 -0
- package/src/sst/__tests__/function.spec.ts +192 -0
- package/src/sst/__tests__/links.spec.ts +209 -0
- package/src/sst/aws/Api.ts +16 -1
- package/src/sst/aws/Database.ts +15 -1
- package/src/sst/fromManifest.ts +8 -1
- package/dist/index-B5CZ1xVf.d.cts +0 -64
- package/dist/index-B5CZ1xVf.d.cts.map +0 -1
- package/dist/index-DhHRjduZ.d.mts +0 -64
- package/dist/index-DhHRjduZ.d.mts.map +0 -1
- package/dist/utils-B1a2UuEO.cjs +0 -129
- package/dist/utils-B1a2UuEO.cjs.map +0 -1
- package/dist/utils-DMOXJ27j.mjs +0 -83
- package/dist/utils-DMOXJ27j.mjs.map +0 -1
|
@@ -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
|
+
});
|
package/src/sst/aws/Api.ts
CHANGED
|
@@ -153,7 +153,7 @@ export class Api<
|
|
|
153
153
|
// Fail the whole synth if any route is misconfigured, with one actionable
|
|
154
154
|
// message per offending route.
|
|
155
155
|
if (failures.length) {
|
|
156
|
-
throw new
|
|
156
|
+
throw new RoutesMissingEnvironment(id, failures);
|
|
157
157
|
}
|
|
158
158
|
}
|
|
159
159
|
|
|
@@ -307,3 +307,18 @@ export interface ApiProps<TAuthorizers extends Record<string, unknown> = {}>
|
|
|
307
307
|
* may override it. */
|
|
308
308
|
runtime?: sst.aws.FunctionArgs['runtime'];
|
|
309
309
|
}
|
|
310
|
+
|
|
311
|
+
/**
|
|
312
|
+
* Routes that read variables nothing links or whitelists. Collected across
|
|
313
|
+
* every route so one synth reports all of them, each with its own suggestions,
|
|
314
|
+
* rather than stopping at the first.
|
|
315
|
+
*/
|
|
316
|
+
export class RoutesMissingEnvironment extends Error {
|
|
317
|
+
constructor(
|
|
318
|
+
readonly api: string,
|
|
319
|
+
readonly failures: readonly EnvValidationError[],
|
|
320
|
+
) {
|
|
321
|
+
super(failures.map((f) => f.message).join('\n\n'));
|
|
322
|
+
this.name = 'RoutesMissingEnvironment';
|
|
323
|
+
}
|
|
324
|
+
}
|
package/src/sst/aws/Database.ts
CHANGED
|
@@ -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
|
/**
|
package/src/sst/fromManifest.ts
CHANGED
|
@@ -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"}
|
package/dist/utils-B1a2UuEO.cjs
DELETED
|
@@ -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"}
|
package/dist/utils-DMOXJ27j.mjs
DELETED
|
@@ -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"}
|