sst 2.0.35 → 2.0.36
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/constructs/Api.d.ts +2 -10
- package/constructs/Api.js +2 -2
- package/constructs/ApiGatewayV1Api.d.ts +2 -10
- package/constructs/ApiGatewayV1Api.js +2 -2
- package/constructs/App.d.ts +0 -2
- package/constructs/App.js +3 -7
- package/constructs/AppSyncApi.d.ts +2 -10
- package/constructs/AppSyncApi.js +2 -2
- package/constructs/Auth.js +10 -7
- package/constructs/Bucket.d.ts +2 -12
- package/constructs/Bucket.js +2 -2
- package/constructs/EventBus.d.ts +2 -12
- package/constructs/EventBus.js +2 -2
- package/constructs/Function.d.ts +3 -12
- package/constructs/Function.js +10 -6
- package/constructs/Job.d.ts +3 -13
- package/constructs/Job.js +9 -7
- package/constructs/KinesisStream.d.ts +2 -12
- package/constructs/KinesisStream.js +2 -2
- package/constructs/NextjsSite.js +19 -30
- package/constructs/Parameter.d.ts +2 -10
- package/constructs/Parameter.js +2 -2
- package/constructs/Queue.d.ts +2 -12
- package/constructs/Queue.js +2 -2
- package/constructs/RDS.d.ts +2 -22
- package/constructs/RDS.js +7 -7
- package/constructs/Secret.js +2 -4
- package/constructs/SsrSite.js +14 -9
- package/constructs/StaticSite.js +14 -9
- package/constructs/Table.d.ts +2 -12
- package/constructs/Table.js +2 -2
- package/constructs/Topic.d.ts +2 -12
- package/constructs/Topic.js +2 -2
- package/constructs/WebSocketApi.d.ts +2 -10
- package/constructs/WebSocketApi.js +2 -2
- package/constructs/deprecated/NextjsSite.js +4 -4
- package/constructs/util/functionBinding.d.ts +14 -3
- package/constructs/util/functionBinding.js +45 -11
- package/node/api/index.js +5 -5
- package/node/auth/auth.js +9 -53
- package/node/bucket/index.js +2 -2
- package/node/config/index.js +4 -56
- package/node/event-bus/index.js +2 -2
- package/node/function/index.js +2 -2
- package/node/job/index.js +2 -2
- package/node/kinesis-stream/index.js +2 -2
- package/node/queue/index.js +2 -2
- package/node/rds/index.js +2 -2
- package/node/site/index.js +6 -52
- package/node/table/index.js +2 -2
- package/node/topic/index.js +2 -2
- package/node/util/index.d.ts +1 -6
- package/node/util/index.js +122 -26
- package/package.json +1 -1
- package/runtime/handlers/node.js +2 -0
- package/sst.mjs +2 -0
- /package/support/{ssr-site-function-stub → sls-nextjs-site-function-stub}/index.js +0 -0
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { createProxy,
|
|
1
|
+
import { createProxy, getVariables } from "../util/index.js";
|
|
2
2
|
export const KinesisStream = createProxy("KinesisStream");
|
|
3
|
-
Object.assign(KinesisStream,
|
|
3
|
+
Object.assign(KinesisStream, getVariables("KinesisStream"));
|
package/node/queue/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { createProxy,
|
|
1
|
+
import { createProxy, getVariables } from "../util/index.js";
|
|
2
2
|
export const Queue = createProxy("Queue");
|
|
3
|
-
Object.assign(Queue,
|
|
3
|
+
Object.assign(Queue, getVariables("Queue"));
|
package/node/rds/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { createProxy,
|
|
1
|
+
import { createProxy, getVariables } from "../util/index.js";
|
|
2
2
|
export const RDS = createProxy("RDS");
|
|
3
|
-
Object.assign(RDS,
|
|
3
|
+
Object.assign(RDS, getVariables("RDS"));
|
package/node/site/index.js
CHANGED
|
@@ -1,62 +1,16 @@
|
|
|
1
|
-
import {
|
|
2
|
-
const ssm = new SSMClient({});
|
|
3
|
-
import { createProxy, parseEnvironment, buildSsmPath, ssmNameToConstructId, } from "../util/index.js";
|
|
1
|
+
import { createProxy, getVariables } from "../util/index.js";
|
|
4
2
|
export const StaticSite = createProxy("StaticSite");
|
|
5
3
|
export const ReactStaticSite = createProxy("ReactStaticSite");
|
|
6
4
|
export const ViteStaticSite = createProxy("ViteStaticSite");
|
|
7
5
|
export const RemixSite = createProxy("RemixSite");
|
|
8
6
|
export const NextjsSite = createProxy("NextjsSite");
|
|
9
|
-
const staticSiteData =
|
|
10
|
-
const reactSiteData =
|
|
11
|
-
const viteSiteData =
|
|
12
|
-
const nextjsSiteData =
|
|
13
|
-
const remixSiteData =
|
|
14
|
-
await replaceWithSsmValues("StaticSite", staticSiteData);
|
|
15
|
-
await replaceWithSsmValues("ReactStaticSite", reactSiteData);
|
|
16
|
-
await replaceWithSsmValues("ViteStaticSite", viteSiteData);
|
|
17
|
-
await replaceWithSsmValues("NextjsSite", nextjsSiteData);
|
|
18
|
-
await replaceWithSsmValues("RemixSite", remixSiteData);
|
|
7
|
+
const staticSiteData = getVariables("StaticSite");
|
|
8
|
+
const reactSiteData = getVariables("ReactStaticSite");
|
|
9
|
+
const viteSiteData = getVariables("ViteStaticSite");
|
|
10
|
+
const nextjsSiteData = getVariables("NextjsSite");
|
|
11
|
+
const remixSiteData = getVariables("RemixSite");
|
|
19
12
|
Object.assign(StaticSite, staticSiteData);
|
|
20
13
|
Object.assign(ReactStaticSite, reactSiteData);
|
|
21
14
|
Object.assign(ViteStaticSite, viteSiteData);
|
|
22
15
|
Object.assign(NextjsSite, nextjsSiteData);
|
|
23
16
|
Object.assign(RemixSite, remixSiteData);
|
|
24
|
-
async function replaceWithSsmValues(className, siteData) {
|
|
25
|
-
// Find all the site data that match the prefix
|
|
26
|
-
const names = Object.keys(siteData).filter((name) => siteData[name].url === "__FETCH_FROM_SSM__");
|
|
27
|
-
if (names.length === 0) {
|
|
28
|
-
return;
|
|
29
|
-
}
|
|
30
|
-
// Fetch all secrets
|
|
31
|
-
const results = await loadSsm(className, names);
|
|
32
|
-
if (results.invalidParams.length > 0) {
|
|
33
|
-
const missingNames = results.invalidParams.map(ssmNameToConstructId);
|
|
34
|
-
throw new Error(`The following ${className} were not found: ${missingNames.join(", ")}`);
|
|
35
|
-
}
|
|
36
|
-
// Store all secrets in a map
|
|
37
|
-
for (const item of results.validParams) {
|
|
38
|
-
const name = ssmNameToConstructId(item.Name);
|
|
39
|
-
// @ts-ignore
|
|
40
|
-
siteData[name] = { url: item.Value };
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
async function loadSsm(className, names) {
|
|
44
|
-
// Split names into chunks of 10
|
|
45
|
-
const chunks = [];
|
|
46
|
-
for (let i = 0; i < names.length; i += 10) {
|
|
47
|
-
chunks.push(names.slice(i, i + 10));
|
|
48
|
-
}
|
|
49
|
-
// Fetch secrets
|
|
50
|
-
const validParams = [];
|
|
51
|
-
const invalidParams = [];
|
|
52
|
-
await Promise.all(chunks.map(async (chunk) => {
|
|
53
|
-
const command = new GetParametersCommand({
|
|
54
|
-
Names: chunk.map((name) => buildSsmPath(className, name, "url")),
|
|
55
|
-
WithDecryption: true,
|
|
56
|
-
});
|
|
57
|
-
const result = await ssm.send(command);
|
|
58
|
-
validParams.push(...(result.Parameters || []));
|
|
59
|
-
invalidParams.push(...(result.InvalidParameters || []));
|
|
60
|
-
}));
|
|
61
|
-
return { validParams, invalidParams };
|
|
62
|
-
}
|
package/node/table/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { createProxy,
|
|
1
|
+
import { createProxy, getVariables } from "../util/index.js";
|
|
2
2
|
export const Table = createProxy("Table");
|
|
3
|
-
Object.assign(Table,
|
|
3
|
+
Object.assign(Table, getVariables("Table"));
|
package/node/topic/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { createProxy,
|
|
1
|
+
import { createProxy, getVariables } from "../util/index.js";
|
|
2
2
|
export const Topic = createProxy("Topic");
|
|
3
|
-
Object.assign(Topic,
|
|
3
|
+
Object.assign(Topic, getVariables("Topic"));
|
package/node/util/index.d.ts
CHANGED
|
@@ -1,7 +1,2 @@
|
|
|
1
1
|
export declare function createProxy<T extends object>(constructName: string): T;
|
|
2
|
-
export declare function
|
|
3
|
-
export declare function buildSsmPath(constructName: string, id: string, prop: string): string;
|
|
4
|
-
export declare function buildSsmFallbackPath(constructName: string, id: string, prop: string): string;
|
|
5
|
-
export declare function ssmNameToConstructId(ssmName: string): string;
|
|
6
|
-
export declare function ssmFallbackNameToConstructId(ssmName: string): string;
|
|
7
|
-
export declare function ssmNameToPropName(ssmName: string): string | undefined;
|
|
2
|
+
export declare function getVariables(constructName: string): Record<string, Record<string, string>>;
|
package/node/util/index.js
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
import { GetParametersCommand, SSMClient, } from "@aws-sdk/client-ssm";
|
|
2
|
+
const ssm = new SSMClient({});
|
|
3
|
+
// Example:
|
|
4
|
+
// {
|
|
5
|
+
// Bucket: {
|
|
6
|
+
// myBucket: {
|
|
7
|
+
// name: "my-bucket",
|
|
8
|
+
// }
|
|
9
|
+
// }
|
|
10
|
+
// }
|
|
11
|
+
let allVariables = {};
|
|
12
|
+
await parseEnvironment();
|
|
1
13
|
export function createProxy(constructName) {
|
|
2
14
|
return new Proxy({}, {
|
|
3
15
|
get(target, prop) {
|
|
@@ -13,41 +25,119 @@ export function createProxy(constructName) {
|
|
|
13
25
|
},
|
|
14
26
|
});
|
|
15
27
|
}
|
|
16
|
-
export function
|
|
17
|
-
|
|
28
|
+
export function getVariables(constructName) {
|
|
29
|
+
return allVariables[constructName] || {};
|
|
30
|
+
}
|
|
31
|
+
async function parseEnvironment() {
|
|
32
|
+
const variablesFromSsm = [];
|
|
33
|
+
const variablesFromSecret = [];
|
|
18
34
|
Object.keys(process.env)
|
|
19
|
-
.filter((
|
|
20
|
-
.forEach((
|
|
21
|
-
const
|
|
22
|
-
//
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
35
|
+
.filter((name) => name.startsWith("SST_"))
|
|
36
|
+
.forEach((name) => {
|
|
37
|
+
const variable = parseEnvName(name);
|
|
38
|
+
// Ignore if env var is not in the correct format
|
|
39
|
+
if (!variable.constructName ||
|
|
40
|
+
!variable.constructId ||
|
|
41
|
+
!variable.propName) {
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
const value = process.env[name];
|
|
45
|
+
if (value === "__FETCH_FROM_SSM__") {
|
|
46
|
+
variablesFromSsm.push(variable);
|
|
47
|
+
}
|
|
48
|
+
else if (value.startsWith("__FETCH_FROM_SECRET__:")) {
|
|
49
|
+
variablesFromSecret.push([variable, value.split(":")[1]]);
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
storeVariable(variable, value);
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
// Fetch values from SSM
|
|
56
|
+
await fetchValuesFromSSM(variablesFromSsm);
|
|
57
|
+
// Fetch values from Secrets
|
|
58
|
+
variablesFromSecret.forEach(([variable, secretName]) => {
|
|
59
|
+
const value = allVariables["Secret"]?.[secretName]?.value;
|
|
60
|
+
if (value) {
|
|
61
|
+
storeVariable(variable, value);
|
|
62
|
+
}
|
|
29
63
|
});
|
|
30
|
-
return
|
|
64
|
+
return allVariables;
|
|
31
65
|
}
|
|
32
|
-
function
|
|
33
|
-
|
|
66
|
+
async function fetchValuesFromSSM(variablesFromSsm) {
|
|
67
|
+
// Get all env vars that need to be fetched from SSM
|
|
68
|
+
const ssmPaths = variablesFromSsm.map((variable) => buildSsmPath(variable));
|
|
69
|
+
if (ssmPaths.length === 0)
|
|
70
|
+
return;
|
|
71
|
+
// Fetch
|
|
72
|
+
const results = await loadSecrets(ssmPaths);
|
|
73
|
+
results.validParams.forEach((item) => {
|
|
74
|
+
const variable = parseSsmPath(item.Name);
|
|
75
|
+
storeVariable(variable, item.Value);
|
|
76
|
+
});
|
|
77
|
+
// Get all fallback values to be fetched
|
|
78
|
+
const ssmFallbackPaths = results.invalidParams
|
|
79
|
+
.map((name) => parseSsmPath(name))
|
|
80
|
+
.filter((variable) => variable.constructName === "Secret")
|
|
81
|
+
.map((variable) => buildSsmFallbackPath(variable));
|
|
82
|
+
if (ssmFallbackPaths.length === 0)
|
|
83
|
+
return;
|
|
84
|
+
// Fetch fallback values
|
|
85
|
+
const fallbackResults = await loadSecrets(ssmFallbackPaths);
|
|
86
|
+
fallbackResults.validParams.forEach((item) => {
|
|
87
|
+
const variable = parseSsmFallbackPath(item.Name);
|
|
88
|
+
storeVariable(variable, item.Value);
|
|
89
|
+
});
|
|
34
90
|
}
|
|
35
|
-
|
|
36
|
-
|
|
91
|
+
async function loadSecrets(paths) {
|
|
92
|
+
// Split paths into chunks of 10
|
|
93
|
+
const chunks = [];
|
|
94
|
+
for (let i = 0; i < paths.length; i += 10) {
|
|
95
|
+
chunks.push(paths.slice(i, i + 10));
|
|
96
|
+
}
|
|
97
|
+
// Fetch secrets
|
|
98
|
+
const validParams = [];
|
|
99
|
+
const invalidParams = [];
|
|
100
|
+
await Promise.all(chunks.map(async (chunk) => {
|
|
101
|
+
const command = new GetParametersCommand({
|
|
102
|
+
Names: chunk,
|
|
103
|
+
WithDecryption: true,
|
|
104
|
+
});
|
|
105
|
+
const result = await ssm.send(command);
|
|
106
|
+
validParams.push(...(result.Parameters || []));
|
|
107
|
+
invalidParams.push(...(result.InvalidParameters || []));
|
|
108
|
+
}));
|
|
109
|
+
return { validParams, invalidParams };
|
|
37
110
|
}
|
|
38
|
-
|
|
39
|
-
|
|
111
|
+
function parseEnvName(env) {
|
|
112
|
+
const [_SST, constructName, propName, ...idParts] = env.split("_");
|
|
113
|
+
return {
|
|
114
|
+
constructName,
|
|
115
|
+
constructId: idParts.join("_"),
|
|
116
|
+
propName,
|
|
117
|
+
};
|
|
40
118
|
}
|
|
41
|
-
|
|
119
|
+
function parseSsmPath(path) {
|
|
42
120
|
const prefix = ssmPrefix();
|
|
43
|
-
|
|
121
|
+
const parts = path.substring(prefix.length).split("/");
|
|
122
|
+
return {
|
|
123
|
+
constructName: parts[0],
|
|
124
|
+
constructId: parts[1],
|
|
125
|
+
propName: parts[2],
|
|
126
|
+
};
|
|
44
127
|
}
|
|
45
|
-
|
|
46
|
-
|
|
128
|
+
function parseSsmFallbackPath(path) {
|
|
129
|
+
const parts = path.split("/");
|
|
130
|
+
return {
|
|
131
|
+
constructName: parts[4],
|
|
132
|
+
constructId: parts[5],
|
|
133
|
+
propName: parts[6],
|
|
134
|
+
};
|
|
47
135
|
}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
136
|
+
function buildSsmPath(data) {
|
|
137
|
+
return `${ssmPrefix()}${data.constructName}/${data.constructId}/${data.propName}`;
|
|
138
|
+
}
|
|
139
|
+
function buildSsmFallbackPath(data) {
|
|
140
|
+
return `/sst/${process.env.SST_APP}/.fallback/${data.constructName}/${data.constructId}/${data.propName}`;
|
|
51
141
|
}
|
|
52
142
|
function normalizeId(name) {
|
|
53
143
|
return name.replace(/-/g, "_");
|
|
@@ -55,3 +145,9 @@ function normalizeId(name) {
|
|
|
55
145
|
function ssmPrefix() {
|
|
56
146
|
return process.env.SST_SSM_PREFIX || "";
|
|
57
147
|
}
|
|
148
|
+
function storeVariable(variable, value) {
|
|
149
|
+
const { constructId: id, constructName: c, propName: prop } = variable;
|
|
150
|
+
allVariables[c] = allVariables[c] || {};
|
|
151
|
+
allVariables[c][id] = allVariables[c][id] || {};
|
|
152
|
+
allVariables[c][id][prop] = value;
|
|
153
|
+
}
|
package/package.json
CHANGED
package/runtime/handlers/node.js
CHANGED
|
@@ -118,6 +118,8 @@ export const useNodeHandler = Context.memo(async () => {
|
|
|
118
118
|
js: [
|
|
119
119
|
`import { createRequire as topLevelCreateRequire } from 'module';`,
|
|
120
120
|
`const require = topLevelCreateRequire(import.meta.url);`,
|
|
121
|
+
`import { fileURLToPath as topLevelFileUrlToPath } from "url"`,
|
|
122
|
+
`const __dirname = topLevelFileUrlToPath(new URL(".", import.meta.url))`,
|
|
121
123
|
nodejs.banner || "",
|
|
122
124
|
].join("\n"),
|
|
123
125
|
},
|
package/sst.mjs
CHANGED
|
@@ -4869,6 +4869,8 @@ var init_node = __esm({
|
|
|
4869
4869
|
js: [
|
|
4870
4870
|
`import { createRequire as topLevelCreateRequire } from 'module';`,
|
|
4871
4871
|
`const require = topLevelCreateRequire(import.meta.url);`,
|
|
4872
|
+
`import { fileURLToPath as topLevelFileUrlToPath } from "url"`,
|
|
4873
|
+
`const __dirname = topLevelFileUrlToPath(new URL(".", import.meta.url))`,
|
|
4872
4874
|
nodejs.banner || ""
|
|
4873
4875
|
].join("\n")
|
|
4874
4876
|
}
|
|
File without changes
|