sst 2.0.34 → 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.
Files changed (57) hide show
  1. package/constructs/Api.d.ts +2 -10
  2. package/constructs/Api.js +2 -2
  3. package/constructs/ApiGatewayV1Api.d.ts +2 -10
  4. package/constructs/ApiGatewayV1Api.js +2 -2
  5. package/constructs/App.d.ts +0 -2
  6. package/constructs/App.js +3 -7
  7. package/constructs/AppSyncApi.d.ts +2 -10
  8. package/constructs/AppSyncApi.js +2 -2
  9. package/constructs/Auth.js +10 -7
  10. package/constructs/Bucket.d.ts +2 -12
  11. package/constructs/Bucket.js +2 -2
  12. package/constructs/EventBus.d.ts +2 -12
  13. package/constructs/EventBus.js +2 -2
  14. package/constructs/Function.d.ts +3 -12
  15. package/constructs/Function.js +10 -6
  16. package/constructs/Job.d.ts +3 -13
  17. package/constructs/Job.js +9 -7
  18. package/constructs/KinesisStream.d.ts +2 -12
  19. package/constructs/KinesisStream.js +2 -2
  20. package/constructs/NextjsSite.js +19 -30
  21. package/constructs/Parameter.d.ts +2 -10
  22. package/constructs/Parameter.js +2 -2
  23. package/constructs/Queue.d.ts +2 -12
  24. package/constructs/Queue.js +2 -2
  25. package/constructs/RDS.d.ts +2 -22
  26. package/constructs/RDS.js +7 -7
  27. package/constructs/Secret.js +2 -4
  28. package/constructs/SsrSite.js +14 -9
  29. package/constructs/StaticSite.js +14 -9
  30. package/constructs/Table.d.ts +2 -12
  31. package/constructs/Table.js +2 -2
  32. package/constructs/Topic.d.ts +2 -12
  33. package/constructs/Topic.js +2 -2
  34. package/constructs/WebSocketApi.d.ts +2 -10
  35. package/constructs/WebSocketApi.js +2 -2
  36. package/constructs/deprecated/NextjsSite.js +4 -4
  37. package/constructs/util/functionBinding.d.ts +14 -3
  38. package/constructs/util/functionBinding.js +45 -11
  39. package/node/api/index.js +5 -5
  40. package/node/auth/auth.js +9 -53
  41. package/node/bucket/index.js +2 -2
  42. package/node/config/index.js +4 -56
  43. package/node/event-bus/index.js +2 -2
  44. package/node/function/index.js +2 -2
  45. package/node/job/index.js +2 -2
  46. package/node/kinesis-stream/index.js +2 -2
  47. package/node/queue/index.js +2 -2
  48. package/node/rds/index.js +2 -2
  49. package/node/site/index.js +6 -52
  50. package/node/table/index.js +2 -2
  51. package/node/topic/index.js +2 -2
  52. package/node/util/index.d.ts +1 -6
  53. package/node/util/index.js +122 -26
  54. package/package.json +1 -1
  55. package/runtime/handlers/node.js +3 -1
  56. package/sst.mjs +3 -1
  57. /package/support/{ssr-site-function-stub → sls-nextjs-site-function-stub}/index.js +0 -0
@@ -4,6 +4,7 @@ import * as rds from "aws-cdk-lib/aws-rds";
4
4
  import * as secretsManager from "aws-cdk-lib/aws-secretsmanager";
5
5
  import { SSTConstruct } from "./Construct.js";
6
6
  import { Function as Fn } from "./Function.js";
7
+ import { FunctionBindingProps } from "./util/functionBinding.js";
7
8
  export interface RDSTypes {
8
9
  path: string;
9
10
  camelCase?: boolean;
@@ -203,28 +204,7 @@ export declare class RDS extends Construct implements SSTConstruct {
203
204
  };
204
205
  };
205
206
  /** @internal */
206
- getFunctionBinding(): {
207
- clientPackage: string;
208
- variables: {
209
- clusterArn: {
210
- environment: string;
211
- parameter: string;
212
- };
213
- secretArn: {
214
- environment: string;
215
- parameter: string;
216
- };
217
- defaultDatabaseName: {
218
- environment: string;
219
- parameter: string;
220
- };
221
- };
222
- permissions: {
223
- "rds-data:*": string[];
224
- "secretsmanager:GetSecretValue": string[];
225
- "secretsmanager:DescribeSecret": string[];
226
- };
227
- };
207
+ getFunctionBinding(): FunctionBindingProps;
228
208
  private validateRequiredProps;
229
209
  private validateCDKPropWhenIsConstruct;
230
210
  private validateCDKPropWhenIsClusterProps;
package/constructs/RDS.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import path from "path";
2
2
  import glob from "glob";
3
3
  import fs from "fs";
4
+ import url from "url";
4
5
  import * as crypto from "crypto";
5
6
  import { Construct } from "constructs";
6
7
  import * as cdk from "aws-cdk-lib";
@@ -9,7 +10,6 @@ import * as rds from "aws-cdk-lib/aws-rds";
9
10
  import * as lambda from "aws-cdk-lib/aws-lambda";
10
11
  import { getFunctionRef, isCDKConstruct } from "./Construct.js";
11
12
  import { Function as Fn } from "./Function.js";
12
- import url from "url";
13
13
  const __dirname = url.fileURLToPath(new URL(".", import.meta.url));
14
14
  /////////////////////
15
15
  // Construct
@@ -117,16 +117,16 @@ export class RDS extends Construct {
117
117
  clientPackage: "rds",
118
118
  variables: {
119
119
  clusterArn: {
120
- environment: this.clusterArn,
121
- parameter: this.clusterArn,
120
+ type: "plain",
121
+ value: this.clusterArn,
122
122
  },
123
123
  secretArn: {
124
- environment: this.secretArn,
125
- parameter: this.secretArn,
124
+ type: "plain",
125
+ value: this.secretArn,
126
126
  },
127
127
  defaultDatabaseName: {
128
- environment: this.defaultDatabaseName,
129
- parameter: this.defaultDatabaseName,
128
+ type: "plain",
129
+ value: this.defaultDatabaseName,
130
130
  },
131
131
  },
132
132
  permissions: {
@@ -1,6 +1,6 @@
1
1
  import { Construct } from "constructs";
2
2
  import { Stack } from "./Stack.js";
3
- import { ENVIRONMENT_PLACEHOLDER, getParameterPath, getParameterFallbackPath, } from "./util/functionBinding.js";
3
+ import { getParameterPath, getParameterFallbackPath, } from "./util/functionBinding.js";
4
4
  /**
5
5
  * The `Secret` construct is a higher level CDK construct that makes it easy to manage app secrets.
6
6
  *
@@ -38,9 +38,7 @@ export class Secret extends Construct {
38
38
  clientPackage: "config",
39
39
  variables: {
40
40
  value: {
41
- environment: ENVIRONMENT_PLACEHOLDER,
42
- // SSM parameters will be created manually via CLI
43
- parameter: undefined,
41
+ type: "secret",
44
42
  },
45
43
  },
46
44
  permissions: {
@@ -23,7 +23,7 @@ import { getBuildCmdEnvironment, } from "./BaseSite.js";
23
23
  import { HttpsRedirect } from "./cdk/website-redirect.js";
24
24
  import { DnsValidatedCertificate } from "./cdk/dns-validated-certificate.js";
25
25
  import { attachPermissionsToRole } from "./util/permission.js";
26
- import { ENVIRONMENT_PLACEHOLDER, getParameterPath, } from "./util/functionBinding.js";
26
+ import { getParameterPath, } from "./util/functionBinding.js";
27
27
  import { SiteEnv } from "../site-env.js";
28
28
  import { useProject } from "../project.js";
29
29
  import { VisibleError } from "../error.js";
@@ -183,14 +183,19 @@ export class SsrSite extends Construct {
183
183
  return {
184
184
  clientPackage: "site",
185
185
  variables: {
186
- url: {
187
- // Do not set real value b/c we don't want to make the Lambda function
188
- // depend on the Site. B/c often the site depends on the Api, causing
189
- // a CloudFormation circular dependency if the Api and the Site belong
190
- // to different stacks.
191
- environment: this.doNotDeploy ? "" : ENVIRONMENT_PLACEHOLDER,
192
- parameter: this.customDomainUrl || this.url,
193
- },
186
+ url: this.doNotDeploy
187
+ ? {
188
+ type: "plain",
189
+ value: "localhost",
190
+ }
191
+ : {
192
+ // Do not set real value b/c we don't want to make the Lambda function
193
+ // depend on the Site. B/c often the site depends on the Api, causing
194
+ // a CloudFormation circular dependency if the Api and the Site belong
195
+ // to different stacks.
196
+ type: "site_url",
197
+ value: this.customDomainUrl || this.url,
198
+ },
194
199
  },
195
200
  permissions: {
196
201
  "ssm:GetParameters": [
@@ -19,7 +19,7 @@ import { getBuildCmdEnvironment, buildErrorResponsesFor404ErrorPage, buildErrorR
19
19
  import { HttpsRedirect } from "./cdk/website-redirect.js";
20
20
  import { DnsValidatedCertificate } from "./cdk/dns-validated-certificate.js";
21
21
  import { isCDKConstruct } from "./Construct.js";
22
- import { ENVIRONMENT_PLACEHOLDER, getParameterPath, } from "./util/functionBinding.js";
22
+ import { getParameterPath, } from "./util/functionBinding.js";
23
23
  import { gray } from "colorette";
24
24
  import { useProject } from "../project.js";
25
25
  import { SiteEnv } from "../site-env.js";
@@ -151,14 +151,19 @@ export class StaticSite extends Construct {
151
151
  return {
152
152
  clientPackage: "site",
153
153
  variables: {
154
- url: {
155
- // Do not set real value b/c we don't want to make the Lambda function
156
- // depend on the Site. B/c often the site depends on the Api, causing
157
- // a CloudFormation circular dependency if the Api and the Site belong
158
- // to different stacks.
159
- environment: this.doNotDeploy ? "" : ENVIRONMENT_PLACEHOLDER,
160
- parameter: this.customDomainUrl || this.url,
161
- },
154
+ url: this.doNotDeploy
155
+ ? {
156
+ type: "plain",
157
+ value: "localhost",
158
+ }
159
+ : {
160
+ // Do not set real value b/c we don't want to make the Lambda function
161
+ // depend on the Site. B/c often the site depends on the Api, causing
162
+ // a CloudFormation circular dependency if the Api and the Site belong
163
+ // to different stacks.
164
+ type: "site_url",
165
+ value: this.customDomainUrl || this.url,
166
+ },
162
167
  },
163
168
  permissions: {
164
169
  "ssm:GetParameters": [
@@ -4,6 +4,7 @@ import * as lambdaEventSources from "aws-cdk-lib/aws-lambda-event-sources";
4
4
  import { SSTConstruct } from "./Construct.js";
5
5
  import { Function as Fn, FunctionProps, FunctionInlineDefinition, FunctionDefinition } from "./Function.js";
6
6
  import { KinesisStream } from "./KinesisStream.js";
7
+ import { FunctionBindingProps } from "./util/functionBinding.js";
7
8
  import { Permissions } from "./util/permission.js";
8
9
  export interface TableConsumerProps {
9
10
  /**
@@ -398,18 +399,7 @@ export declare class Table extends Construct implements SSTConstruct {
398
399
  };
399
400
  };
400
401
  /** @internal */
401
- getFunctionBinding(): {
402
- clientPackage: string;
403
- variables: {
404
- tableName: {
405
- environment: string;
406
- parameter: string;
407
- };
408
- };
409
- permissions: {
410
- "dynamodb:*": string[];
411
- };
412
- };
402
+ getFunctionBinding(): FunctionBindingProps;
413
403
  private createTable;
414
404
  private addConsumer;
415
405
  private buildAttribute;
@@ -270,8 +270,8 @@ export class Table extends Construct {
270
270
  clientPackage: "table",
271
271
  variables: {
272
272
  tableName: {
273
- environment: this.tableName,
274
- parameter: this.tableName,
273
+ type: "plain",
274
+ value: this.tableName,
275
275
  },
276
276
  },
277
277
  permissions: {
@@ -4,6 +4,7 @@ import * as snsSubscriptions from "aws-cdk-lib/aws-sns-subscriptions";
4
4
  import { SSTConstruct } from "./Construct.js";
5
5
  import { Function as Fn, FunctionProps, FunctionInlineDefinition, FunctionDefinition } from "./Function.js";
6
6
  import { Queue } from "./Queue.js";
7
+ import { FunctionBindingProps } from "./util/functionBinding.js";
7
8
  import { Permissions } from "./util/permission.js";
8
9
  /**
9
10
  * Used to define a queue subscriber for a topic
@@ -248,18 +249,7 @@ export declare class Topic extends Construct implements SSTConstruct {
248
249
  };
249
250
  };
250
251
  /** @internal */
251
- getFunctionBinding(): {
252
- clientPackage: string;
253
- variables: {
254
- topicArn: {
255
- environment: string;
256
- parameter: string;
257
- };
258
- };
259
- permissions: {
260
- "sns:*": string[];
261
- };
262
- };
252
+ getFunctionBinding(): FunctionBindingProps;
263
253
  private createTopic;
264
254
  private addSubscriber;
265
255
  private addQueueSubscriber;
@@ -198,8 +198,8 @@ export class Topic extends Construct {
198
198
  clientPackage: "topic",
199
199
  variables: {
200
200
  topicArn: {
201
- environment: this.topicArn,
202
- parameter: this.topicArn,
201
+ type: "plain",
202
+ value: this.topicArn,
203
203
  },
204
204
  },
205
205
  permissions: {
@@ -5,6 +5,7 @@ import * as apig from "@aws-cdk/aws-apigatewayv2-alpha";
5
5
  import * as apigAuthorizers from "@aws-cdk/aws-apigatewayv2-authorizers-alpha";
6
6
  import { SSTConstruct } from "./Construct.js";
7
7
  import { Function as Fn, FunctionProps, FunctionInlineDefinition, FunctionDefinition } from "./Function.js";
8
+ import { FunctionBindingProps } from "./util/functionBinding.js";
8
9
  import { Permissions } from "./util/permission.js";
9
10
  import * as apigV2Domain from "./util/apiGatewayV2Domain.js";
10
11
  import * as apigV2AccessLog from "./util/apiGatewayV2AccessLog.js";
@@ -342,16 +343,7 @@ export declare class WebSocketApi extends Construct implements SSTConstruct {
342
343
  };
343
344
  };
344
345
  /** @internal */
345
- getFunctionBinding(): {
346
- clientPackage: string;
347
- variables: {
348
- url: {
349
- environment: string;
350
- parameter: string;
351
- };
352
- };
353
- permissions: {};
354
- };
346
+ getFunctionBinding(): FunctionBindingProps;
355
347
  private createWebSocketApi;
356
348
  private createWebSocketStage;
357
349
  private createCloudWatchRole;
@@ -197,8 +197,8 @@ export class WebSocketApi extends Construct {
197
197
  clientPackage: "api",
198
198
  variables: {
199
199
  url: {
200
- environment: this.customDomainUrl || this.url,
201
- parameter: this.customDomainUrl || this.url,
200
+ type: "plain",
201
+ value: this.customDomainUrl || this.url,
202
202
  },
203
203
  },
204
204
  permissions: {},
@@ -24,7 +24,7 @@ import { isCDKConstruct } from "../Construct.js";
24
24
  import { getBuildCmdEnvironment, buildErrorResponsesForRedirectToIndex, } from "../BaseSite.js";
25
25
  import { attachPermissionsToRole } from "../util/permission.js";
26
26
  import { getHandlerHash } from "../util/builder.js";
27
- import { ENVIRONMENT_PLACEHOLDER, getParameterPath, } from "../util/functionBinding.js";
27
+ import { getParameterPath, } from "../util/functionBinding.js";
28
28
  import * as crossRegionHelper from "./cross-region-helper.js";
29
29
  import { gray, red } from "colorette";
30
30
  import { SiteEnv } from "../../site-env.js";
@@ -247,8 +247,8 @@ export class NextjsSite extends Construct {
247
247
  // depend on the Site. B/c often the site depends on the Api, causing
248
248
  // a CloudFormation circular dependency if the Api and the Site belong
249
249
  // to different stacks.
250
- environment: ENVIRONMENT_PLACEHOLDER,
251
- parameter: this.customDomainUrl || this.url,
250
+ type: "site_url",
251
+ value: this.customDomainUrl || this.url,
252
252
  },
253
253
  },
254
254
  permissions: {
@@ -308,7 +308,7 @@ export class NextjsSite extends Construct {
308
308
  // Create function asset
309
309
  const assetPath = hasRealCode && this.buildOutDir
310
310
  ? path.join(this.buildOutDir, handlerPath)
311
- : path.join(__dirname, "../../support/ssr-site-function-stub");
311
+ : path.join(__dirname, "../../support/sls-nextjs-site-function-stub");
312
312
  const asset = new s3Assets.Asset(this, `${name}FunctionAsset`, {
313
313
  path: assetPath,
314
314
  });
@@ -1,11 +1,19 @@
1
1
  import { SSTConstruct } from "../Construct.js";
2
- export declare const ENVIRONMENT_PLACEHOLDER = "__FETCH_FROM_SSM__";
2
+ import { Secret } from "../Secret.js";
3
3
  export interface FunctionBindingProps {
4
4
  clientPackage: string;
5
5
  permissions: Record<string, string[]>;
6
6
  variables: Record<string, {
7
- environment: string;
8
- parameter?: string;
7
+ type: "plain";
8
+ value: string;
9
+ } | {
10
+ type: "secret";
11
+ } | {
12
+ type: "secret_reference";
13
+ secret: Secret;
14
+ } | {
15
+ type: "site_url";
16
+ value: string;
9
17
  }>;
10
18
  }
11
19
  export declare function bindEnvironment(c: SSTConstruct): Record<string, string>;
@@ -15,6 +23,9 @@ export declare function bindType(c: SSTConstruct): {
15
23
  clientPackage: string;
16
24
  variables: string[];
17
25
  } | undefined;
26
+ export declare function getReferencedSecrets(c: SSTConstruct): Secret[];
18
27
  export declare function getEnvironmentKey(c: SSTConstruct, prop: string): string;
19
28
  export declare function getParameterPath(c: SSTConstruct, prop: string): string;
20
29
  export declare function getParameterFallbackPath(c: SSTConstruct, prop: string): string;
30
+ export declare function placeholderSecretValue(): string;
31
+ export declare function placeholderSecretReferenceValue(secret: Secret): string;
@@ -1,13 +1,20 @@
1
1
  import * as ssm from "aws-cdk-lib/aws-ssm";
2
2
  import { Config } from "../../config.js";
3
- export const ENVIRONMENT_PLACEHOLDER = "__FETCH_FROM_SSM__";
4
3
  export function bindEnvironment(c) {
5
4
  const binding = c.getFunctionBinding();
6
- const environment = {};
5
+ let environment = {};
7
6
  if (binding) {
8
7
  Object.entries(binding.variables).forEach(([prop, variable]) => {
9
8
  const envName = getEnvironmentKey(c, prop);
10
- environment[envName] = variable.environment;
9
+ if (variable.type === "plain") {
10
+ environment[envName] = variable.value;
11
+ }
12
+ else if (variable.type === "secret" || variable.type === "site_url") {
13
+ environment[envName] = placeholderSecretValue();
14
+ }
15
+ else if (variable.type === "secret_reference") {
16
+ environment[envName] = placeholderSecretReferenceValue(variable.secret);
17
+ }
11
18
  });
12
19
  }
13
20
  return environment;
@@ -18,20 +25,29 @@ export function bindParameters(c) {
18
25
  return;
19
26
  }
20
27
  const app = c.node.root;
21
- Object.entries(binding.variables)
22
- .filter(([, variable]) => variable.parameter !== undefined)
23
- .forEach(([prop, variable]) => {
28
+ Object.entries(binding.variables).forEach(([prop, variable]) => {
24
29
  const resId = `Parameter_${prop}`;
25
30
  if (!c.node.tryFindChild(resId)) {
26
- new ssm.StringParameter(c, resId, {
27
- // Parameters, Secrets, and Jobs do not have a name
28
- parameterName: getParameterPath(c, prop),
29
- stringValue: variable.parameter,
30
- });
31
+ if (variable.type === "plain" || variable.type === "site_url") {
32
+ new ssm.StringParameter(c, resId, {
33
+ parameterName: getParameterPath(c, prop),
34
+ stringValue: variable.value,
35
+ });
36
+ }
37
+ else if (variable.type === "secret_reference") {
38
+ new ssm.StringParameter(c, resId, {
39
+ parameterName: getParameterPath(c, prop),
40
+ stringValue: placeholderSecretReferenceValue(variable.secret),
41
+ });
42
+ }
31
43
  }
32
44
  });
33
45
  }
34
46
  export function bindPermissions(c) {
47
+ const binding = c.getFunctionBinding();
48
+ if (!binding) {
49
+ return {};
50
+ }
35
51
  return c.getFunctionBinding()?.permissions || {};
36
52
  }
37
53
  export function bindType(c) {
@@ -44,6 +60,18 @@ export function bindType(c) {
44
60
  variables: Object.keys(binding.variables),
45
61
  };
46
62
  }
63
+ export function getReferencedSecrets(c) {
64
+ const binding = c.getFunctionBinding();
65
+ const secrets = [];
66
+ if (binding) {
67
+ Object.values(binding.variables).forEach((variable) => {
68
+ if (variable.type === "secret_reference") {
69
+ secrets.push(variable.secret);
70
+ }
71
+ });
72
+ }
73
+ return secrets;
74
+ }
47
75
  export function getEnvironmentKey(c, prop) {
48
76
  return Config.envFor({
49
77
  type: c.constructor.name,
@@ -68,3 +96,9 @@ export function getParameterFallbackPath(c, prop) {
68
96
  fallback: true,
69
97
  });
70
98
  }
99
+ export function placeholderSecretValue() {
100
+ return "__FETCH_FROM_SSM__";
101
+ }
102
+ export function placeholderSecretReferenceValue(secret) {
103
+ return "__FETCH_FROM_SECRET__:" + secret.name;
104
+ }
package/node/api/index.js CHANGED
@@ -1,14 +1,14 @@
1
- import { createProxy, parseEnvironment } from "../util/index.js";
1
+ import { createProxy, getVariables } from "../util/index.js";
2
2
  import { Context } from "../../context/context.js";
3
3
  import { useEvent, Handler } from "../../context/handler.js";
4
4
  export const Api = createProxy("Api");
5
5
  export const AppSyncApi = createProxy("AppSyncApi");
6
6
  export const ApiGatewayV1Api = createProxy("ApiGatewayV1Api");
7
7
  export const WebSocketApi = createProxy("WebSocketApi");
8
- Object.assign(Api, parseEnvironment("Api", ["url"]));
9
- Object.assign(AppSyncApi, parseEnvironment("AppSyncApi", ["url"]));
10
- Object.assign(ApiGatewayV1Api, parseEnvironment("ApiGatewayV1Api", ["url"]));
11
- Object.assign(WebSocketApi, parseEnvironment("WebSocketApi", ["url"]));
8
+ Object.assign(Api, getVariables("Api"));
9
+ Object.assign(AppSyncApi, getVariables("AppSyncApi"));
10
+ Object.assign(ApiGatewayV1Api, getVariables("ApiGatewayV1Api"));
11
+ Object.assign(WebSocketApi, getVariables("WebSocketApi"));
12
12
  /**
13
13
  * Create a new api handler that can be used to create an authenticated session.
14
14
  *
package/node/auth/auth.js CHANGED
@@ -1,62 +1,18 @@
1
- import { GetParametersCommand, SSMClient, } from "@aws-sdk/client-ssm";
2
- const ssm = new SSMClient({});
3
- import { parseEnvironment, buildSsmPath, ssmNameToPropName, } from "../util/index.js";
1
+ import { getVariables } from "../util/index.js";
4
2
  import { Handler } from "../../context/handler.js";
5
3
  import { useDomainName, usePath } from "../api/index.js";
6
4
  const className = "Auth";
7
- const authData = parseEnvironment(className, [
8
- "publicKey",
9
- "privateKey",
10
- "prefix",
11
- ]);
5
+ // Each function can only be attached to one Auth construct, so we can
6
+ // assume there is only one entry in authData.
7
+ const authData = getVariables(className);
8
+ const authValues = Object.values(authData);
12
9
  let prefix;
13
10
  let publicKey;
14
11
  let privateKey;
15
- // Each function can only be attached to one Auth construct, so we can
16
- // assume there is only one entry in authData.
17
- const authNames = Object.keys(authData);
18
- if (authNames.length !== 0) {
19
- const authName = authNames[0];
20
- await replaceWithSsmValues(authName);
21
- // @ts-ignore
22
- prefix = authData[authName].prefix;
23
- // @ts-ignore
24
- publicKey = authData[authName].publicKey;
25
- // @ts-ignore
26
- privateKey = authData[authName].privateKey;
27
- }
28
- async function replaceWithSsmValues(name) {
29
- // Fetch all secrets
30
- const props = ["privateKey", "publicKey"].filter((prop) => authData[name][prop] === "__FETCH_FROM_SSM__");
31
- if (props.length === 0) {
32
- return;
33
- }
34
- const results = await loadSsm(name, props);
35
- if (results.invalidParams.length > 0) {
36
- const missingProps = results.invalidParams.map(ssmNameToPropName);
37
- throw new Error(`The following Auth parameters were not found: ${missingProps.join(", ")}`);
38
- }
39
- // Store all secrets in a map
40
- for (const item of results.validParams) {
41
- const prop = ssmNameToPropName(item.Name);
42
- // @ts-ignore
43
- authData[name][prop] = item.Value;
44
- }
45
- }
46
- async function loadSsm(name, props) {
47
- const SSM_PREFIX = `/sst/${process.env.SST_APP}/${process.env.SST_STAGE}/${className}/${name}`;
48
- // Fetch secrets
49
- const validParams = [];
50
- const invalidParams = [];
51
- const command = new GetParametersCommand({
52
- Names: props.map((prop) => buildSsmPath(className, name, prop)),
53
- WithDecryption: true,
54
- });
55
- const result = await ssm.send(command);
56
- return {
57
- validParams: result.Parameters || [],
58
- invalidParams: result.InvalidParameters || [],
59
- };
12
+ if (authValues.length !== 0) {
13
+ prefix = authValues[0].prefix;
14
+ publicKey = authValues[0].publicKey;
15
+ privateKey = authValues[0].privateKey;
60
16
  }
61
17
  export function getPublicKey() {
62
18
  if (!publicKey) {
@@ -1,3 +1,3 @@
1
- import { createProxy, parseEnvironment } from "../util/index.js";
1
+ import { createProxy, getVariables } from "../util/index.js";
2
2
  export const Bucket = createProxy("Bucket");
3
- Object.assign(Bucket, parseEnvironment("Bucket", ["bucketName"]));
3
+ Object.assign(Bucket, getVariables("Bucket"));
@@ -1,13 +1,8 @@
1
- import { GetParametersCommand, SSMClient, } from "@aws-sdk/client-ssm";
2
- const ssm = new SSMClient({});
3
- import { createProxy, parseEnvironment, buildSsmPath, buildSsmFallbackPath, ssmNameToConstructId, ssmFallbackNameToConstructId, } from "../util/index.js";
1
+ import { createProxy, getVariables } from "../util/index.js";
4
2
  export const Config = createProxy("Config");
5
3
  const metadata = parseMetadataEnvironment();
6
- const parametersRaw = parseEnvironment("Parameter", ["value"]);
7
- const secretsRaw = parseEnvironment("Secret", ["value"]);
8
- const parameters = flattenConfigValues(parametersRaw);
9
- const secrets = flattenConfigValues(secretsRaw);
10
- await replaceSecretsWithRealValues();
4
+ const parameters = flattenValues(getVariables("Parameter"));
5
+ const secrets = flattenValues(getVariables("Secret"));
11
6
  Object.assign(Config, metadata, parameters, secrets);
12
7
  ///////////////
13
8
  // Functions
@@ -27,57 +22,10 @@ function parseMetadataEnvironment() {
27
22
  STAGE: process.env.SST_STAGE,
28
23
  };
29
24
  }
30
- function flattenConfigValues(configValues) {
25
+ function flattenValues(configValues) {
31
26
  const acc = {};
32
27
  Object.keys(configValues).forEach((name) => {
33
28
  acc[name] = configValues[name].value;
34
29
  });
35
30
  return acc;
36
31
  }
37
- async function replaceSecretsWithRealValues() {
38
- // Find all the secrets and params that match the prefix
39
- const names = Object.keys(secrets).filter((name) => secrets[name] === "__FETCH_FROM_SSM__");
40
- if (names.length === 0) {
41
- return;
42
- }
43
- // Fetch all secrets
44
- const paths = names.map((name) => buildSsmPath("Secret", name, "value"));
45
- const results = await loadSecrets(paths);
46
- results.validParams.forEach((item) => {
47
- const name = ssmNameToConstructId(item.Name);
48
- secrets[name] = item.Value;
49
- });
50
- // Fetch fallback secrets
51
- if (results.invalidParams.length > 0) {
52
- const missingNames = results.invalidParams.map(ssmNameToConstructId);
53
- const missingPaths = missingNames.map((name) => buildSsmFallbackPath("Secret", name, "value"));
54
- const missingResults = await loadSecrets(missingPaths);
55
- missingResults.validParams.forEach((item) => {
56
- const name = ssmFallbackNameToConstructId(item.Name);
57
- secrets[name] = item.Value;
58
- });
59
- if (missingResults.invalidParams.length > 0) {
60
- throw new Error(`The following secrets were not found: ${missingNames.join(", ")}`);
61
- }
62
- }
63
- }
64
- async function loadSecrets(paths) {
65
- // Split paths into chunks of 10
66
- const chunks = [];
67
- for (let i = 0; i < paths.length; i += 10) {
68
- chunks.push(paths.slice(i, i + 10));
69
- }
70
- // Fetch secrets
71
- const validParams = [];
72
- const invalidParams = [];
73
- await Promise.all(chunks.map(async (chunk) => {
74
- const command = new GetParametersCommand({
75
- Names: chunk,
76
- WithDecryption: true,
77
- });
78
- const result = await ssm.send(command);
79
- validParams.push(...(result.Parameters || []));
80
- invalidParams.push(...(result.InvalidParameters || []));
81
- }));
82
- return { validParams, invalidParams };
83
- }
@@ -1,3 +1,3 @@
1
- import { createProxy, parseEnvironment } from "../util/index.js";
1
+ import { createProxy, getVariables } from "../util/index.js";
2
2
  export const EventBus = createProxy("EventBus");
3
- Object.assign(EventBus, parseEnvironment("EventBus", ["eventBusName"]));
3
+ Object.assign(EventBus, getVariables("EventBus"));
@@ -1,3 +1,3 @@
1
- import { createProxy, parseEnvironment } from "../util/index.js";
1
+ import { createProxy, getVariables } from "../util/index.js";
2
2
  export const Function = createProxy("Function");
3
- Object.assign(Function, parseEnvironment("Function", ["functionName"]));
3
+ Object.assign(Function, getVariables("Function"));
package/node/job/index.js CHANGED
@@ -1,8 +1,8 @@
1
- import { createProxy, parseEnvironment } from "../util/index.js";
1
+ import { createProxy, getVariables } from "../util/index.js";
2
2
  import { InvokeCommand, LambdaClient } from "@aws-sdk/client-lambda";
3
3
  const lambda = new LambdaClient({});
4
4
  export const Job = createProxy("Job");
5
- const jobData = parseEnvironment("Job", ["functionName"]);
5
+ const jobData = getVariables("Job");
6
6
  Object.keys(jobData).forEach((name) => {
7
7
  // @ts-ignore
8
8
  Job[name] = JobControl(name);