sst 2.24.12 → 2.24.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/constructs/ApiGatewayV1Api.d.ts +2 -2
- package/constructs/ApiGatewayV1Api.js +2 -1
- package/constructs/App.js +37 -4
- package/constructs/Function.d.ts +13 -0
- package/constructs/Function.js +29 -11
- package/node/future/auth/adapter/microsoft.d.ts +1 -0
- package/node/future/auth/adapter/microsoft.js +8 -6
- package/package.json +1 -1
- package/runtime/handlers/node.js +8 -1
- package/runtime/handlers.js +3 -16
- package/support/custom-resources/index.mjs +138 -104
- package/support/event-bus-retrier/index.mjs +21 -21
- package/support/python-runtime/Dockerfile.dependencies +1 -1
|
@@ -145,7 +145,7 @@ export interface ApiGatewayV1ApiProps<Authorizers extends Record<string, ApiGate
|
|
|
145
145
|
* });
|
|
146
146
|
* ```
|
|
147
147
|
*/
|
|
148
|
-
authorizer?: "none" | "iam" | (string extends AuthorizerKeys ?
|
|
148
|
+
authorizer?: "none" | "iam" | (string extends AuthorizerKeys ? Omit<AuthorizerKeys, "none" | "iam"> : AuthorizerKeys);
|
|
149
149
|
/**
|
|
150
150
|
* An array of scopes to include in the authorization when using `user_pool` or `jwt` authorizers. These will be merged with the scopes from the attached authorizer.
|
|
151
151
|
* @default []
|
|
@@ -220,7 +220,7 @@ export type ApiGatewayV1ApiRouteProps<AuthorizerKeys> = FunctionInlineDefinition
|
|
|
220
220
|
*/
|
|
221
221
|
export interface ApiGatewayV1ApiFunctionRouteProps<AuthorizerKeys = never> {
|
|
222
222
|
function?: FunctionDefinition;
|
|
223
|
-
authorizer?: "none" | "iam" | (string extends AuthorizerKeys ?
|
|
223
|
+
authorizer?: "none" | "iam" | (string extends AuthorizerKeys ? Omit<AuthorizerKeys, "none" | "iam"> : AuthorizerKeys);
|
|
224
224
|
authorizationScopes?: string[];
|
|
225
225
|
cdk?: {
|
|
226
226
|
method?: Omit<apig.MethodOptions, "authorizer" | "authorizationType" | "authorizationScopes">;
|
|
@@ -735,7 +735,8 @@ export class ApiGatewayV1Api extends Construct {
|
|
|
735
735
|
...routeProps.cdk?.method,
|
|
736
736
|
};
|
|
737
737
|
}
|
|
738
|
-
if (!this.props.authorizers ||
|
|
738
|
+
if (!this.props.authorizers ||
|
|
739
|
+
!this.props.authorizers[authorizerKey]) {
|
|
739
740
|
throw new Error(`Cannot find authorizer "${authorizerKey.toString()}"`);
|
|
740
741
|
}
|
|
741
742
|
const authorizer = this.authorizersData[authorizerKey];
|
package/constructs/App.js
CHANGED
|
@@ -2,19 +2,20 @@ import path from "path";
|
|
|
2
2
|
import fs from "fs";
|
|
3
3
|
import { Stack } from "./Stack.js";
|
|
4
4
|
import { isSSTConstruct, isStackConstruct, } from "./Construct.js";
|
|
5
|
+
import { useFunctions } from "./Function.js";
|
|
5
6
|
import { bindParameters, bindType } from "./util/functionBinding.js";
|
|
6
7
|
import { stack } from "./FunctionalStack.js";
|
|
7
|
-
import { createRequire } from "module";
|
|
8
8
|
import { Auth } from "./Auth.js";
|
|
9
9
|
import { useDeferredTasks } from "./deferred_task.js";
|
|
10
10
|
import { AppContext } from "./context.js";
|
|
11
11
|
import { useProject } from "../project.js";
|
|
12
12
|
import { Logger } from "../logger.js";
|
|
13
|
-
import { App as CDKApp, Tags, CfnResource, RemovalPolicy, Aspects, } from "aws-cdk-lib/core";
|
|
13
|
+
import { App as CDKApp, Tags, CfnResource, RemovalPolicy, CustomResource, Aspects, } from "aws-cdk-lib/core";
|
|
14
14
|
import { CfnFunction } from "aws-cdk-lib/aws-lambda";
|
|
15
15
|
import { Bucket } from "aws-cdk-lib/aws-s3";
|
|
16
|
+
import { Effect, Policy, PolicyStatement } from "aws-cdk-lib/aws-iam";
|
|
16
17
|
import { CfnLogGroup } from "aws-cdk-lib/aws-logs";
|
|
17
|
-
|
|
18
|
+
import { useBootstrap } from "../bootstrap.js";
|
|
18
19
|
function exitWithMessage(message) {
|
|
19
20
|
console.error(message);
|
|
20
21
|
process.exit(1);
|
|
@@ -177,6 +178,7 @@ export class App extends CDKApp {
|
|
|
177
178
|
if (this.isFinished)
|
|
178
179
|
return;
|
|
179
180
|
this.isFinished = true;
|
|
181
|
+
const { config, paths } = useProject();
|
|
180
182
|
Auth.injectConfig();
|
|
181
183
|
this.buildConstructsMetadata();
|
|
182
184
|
this.ensureUniqueConstructIds();
|
|
@@ -189,12 +191,43 @@ export class App extends CDKApp {
|
|
|
189
191
|
await useDeferredTasks().run();
|
|
190
192
|
this.createBindingSsmParameters();
|
|
191
193
|
this.removeGovCloudUnsupportedResourceProperties();
|
|
192
|
-
const
|
|
194
|
+
const bootstrap = await useBootstrap();
|
|
193
195
|
for (const child of this.node.children) {
|
|
194
196
|
if (isStackConstruct(child)) {
|
|
195
197
|
// Tag stacks
|
|
196
198
|
Tags.of(child).add("sst:app", this.name);
|
|
197
199
|
Tags.of(child).add("sst:stage", this.stage);
|
|
200
|
+
if (child instanceof Stack) {
|
|
201
|
+
const functions = useFunctions();
|
|
202
|
+
const sourcemaps = functions.sourcemaps.forStack(child.stackName);
|
|
203
|
+
if (sourcemaps.length) {
|
|
204
|
+
const policy = new Policy(child, "FunctionSourcemapUploaderPolicy", {
|
|
205
|
+
statements: [
|
|
206
|
+
new PolicyStatement({
|
|
207
|
+
effect: Effect.ALLOW,
|
|
208
|
+
actions: ["s3:GetObject", "s3:PutObject"],
|
|
209
|
+
resources: [
|
|
210
|
+
sourcemaps[0].bucket.bucketArn + "/*",
|
|
211
|
+
`arn:${child.partition}:s3:::${bootstrap.bucket}/*`,
|
|
212
|
+
],
|
|
213
|
+
}),
|
|
214
|
+
],
|
|
215
|
+
});
|
|
216
|
+
child.customResourceHandler.role?.attachInlinePolicy(policy);
|
|
217
|
+
const resource = new CustomResource(child, "FunctionSourcemapUploader", {
|
|
218
|
+
serviceToken: child.customResourceHandler.functionArn,
|
|
219
|
+
resourceType: "Custom::FunctionSourcemapUploader",
|
|
220
|
+
properties: {
|
|
221
|
+
app: this.name,
|
|
222
|
+
stage: this.stage,
|
|
223
|
+
bootstrap: bootstrap.bucket,
|
|
224
|
+
bucket: sourcemaps[0].bucket.bucketName,
|
|
225
|
+
functions: sourcemaps.map((s) => [s.arn, s.key]),
|
|
226
|
+
},
|
|
227
|
+
});
|
|
228
|
+
resource.node.addDependency(policy);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
198
231
|
// Set removal policy
|
|
199
232
|
this.applyRemovalPolicy(child);
|
|
200
233
|
// Stack names need to be parameterized with the stage name
|
package/constructs/Function.d.ts
CHANGED
|
@@ -10,6 +10,7 @@ import * as functionUrlCors from "./util/functionUrlCors.js";
|
|
|
10
10
|
import { Architecture, Function as CDKFunction, FunctionOptions, ILayerVersion, Runtime as CDKRuntime, Tracing } from "aws-cdk-lib/aws-lambda";
|
|
11
11
|
import { RetentionDays } from "aws-cdk-lib/aws-logs";
|
|
12
12
|
import { Size as CDKSize, Duration as CDKDuration } from "aws-cdk-lib/core";
|
|
13
|
+
import { IBucket } from "aws-cdk-lib/aws-s3";
|
|
13
14
|
declare const supportedRuntimes: {
|
|
14
15
|
container: CDKRuntime;
|
|
15
16
|
rust: CDKRuntime;
|
|
@@ -657,6 +658,18 @@ export declare class Function extends CDKFunction implements SSTConstruct {
|
|
|
657
658
|
static mergeProps(baseProps?: FunctionProps, props?: FunctionProps): FunctionProps;
|
|
658
659
|
}
|
|
659
660
|
export declare const useFunctions: () => {
|
|
661
|
+
sourcemaps: {
|
|
662
|
+
add(stack: string, source: {
|
|
663
|
+
arn: string;
|
|
664
|
+
bucket: IBucket;
|
|
665
|
+
key: string;
|
|
666
|
+
}): void;
|
|
667
|
+
forStack(stack: string): {
|
|
668
|
+
arn: string;
|
|
669
|
+
bucket: IBucket;
|
|
670
|
+
key: string;
|
|
671
|
+
}[];
|
|
672
|
+
};
|
|
660
673
|
fromID(id: string): FunctionProps | undefined;
|
|
661
674
|
add(name: string, props: FunctionProps): void;
|
|
662
675
|
readonly all: Record<string, FunctionProps>;
|
package/constructs/Function.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/ban-types */
|
|
2
2
|
// Note: disabling ban-type rule so we don't get an error referencing the class Function
|
|
3
3
|
import path from "path";
|
|
4
|
+
import fs from "fs/promises";
|
|
5
|
+
import zlib from "zlib";
|
|
4
6
|
import { Stack } from "./Stack.js";
|
|
5
7
|
import { Job } from "./Job.js";
|
|
6
8
|
import { Secret } from "./Config.js";
|
|
@@ -24,8 +26,7 @@ import { StringParameter } from "aws-cdk-lib/aws-ssm";
|
|
|
24
26
|
import { Platform } from "aws-cdk-lib/aws-ecr-assets";
|
|
25
27
|
import { useBootstrap } from "../bootstrap.js";
|
|
26
28
|
import { Colors } from "../cli/colors.js";
|
|
27
|
-
import {
|
|
28
|
-
import { Bucket } from "aws-cdk-lib/aws-s3";
|
|
29
|
+
import { Asset } from "aws-cdk-lib/aws-s3-assets";
|
|
29
30
|
const __dirname = url.fileURLToPath(new URL(".", import.meta.url));
|
|
30
31
|
const supportedRuntimes = {
|
|
31
32
|
container: CDKRuntime.FROM_IMAGE,
|
|
@@ -231,6 +232,7 @@ export class Function extends CDKFunction {
|
|
|
231
232
|
useDeferredTasks().add(async () => {
|
|
232
233
|
if (props.runtime === "container")
|
|
233
234
|
Colors.line(`➜ Building the container image for the "${this.node.id}" function...`);
|
|
235
|
+
const project = useProject();
|
|
234
236
|
// Build function
|
|
235
237
|
const result = await useRuntimeHandlers().build(this.node.addr, "deploy");
|
|
236
238
|
if (result.type === "error") {
|
|
@@ -242,19 +244,23 @@ export class Function extends CDKFunction {
|
|
|
242
244
|
// No need to update code if runtime is container
|
|
243
245
|
if (props.runtime === "container")
|
|
244
246
|
return;
|
|
247
|
+
if (result.sourcemap) {
|
|
248
|
+
const data = await fs.readFile(result.sourcemap);
|
|
249
|
+
await fs.writeFile(result.sourcemap, zlib.gzipSync(data));
|
|
250
|
+
const asset = new Asset(stack, this.id + "-Sourcemap", {
|
|
251
|
+
path: result.sourcemap,
|
|
252
|
+
});
|
|
253
|
+
await fs.rm(result.sourcemap);
|
|
254
|
+
useFunctions().sourcemaps.add(stack.stackName, {
|
|
255
|
+
bucket: asset.bucket,
|
|
256
|
+
key: asset.s3ObjectKey,
|
|
257
|
+
arn: this.functionArn,
|
|
258
|
+
});
|
|
259
|
+
}
|
|
245
260
|
// Update code
|
|
246
261
|
const cfnFunction = this.node.defaultChild;
|
|
247
262
|
const code = AssetCode.fromAsset(result.out);
|
|
248
263
|
const codeConfig = code.bind(this);
|
|
249
|
-
const bootstrap = await useBootstrap();
|
|
250
|
-
if (result.sourcemap)
|
|
251
|
-
new BucketDeployment(this, "Sourcemap", {
|
|
252
|
-
sources: [Source.asset(result.sourcemap)],
|
|
253
|
-
contentEncoding: "gzip",
|
|
254
|
-
contentType: "application/json",
|
|
255
|
-
destinationBucket: Bucket.fromBucketName(this, "BootstrapBucket", bootstrap.bucket),
|
|
256
|
-
destinationKeyPrefix: `sourcemap/${app.name}/${app.stage}/${this.functionArn}/`,
|
|
257
|
-
});
|
|
258
264
|
cfnFunction.code = {
|
|
259
265
|
s3Bucket: codeConfig.s3Location?.bucketName,
|
|
260
266
|
s3Key: codeConfig.s3Location?.objectKey,
|
|
@@ -548,7 +554,19 @@ export class Function extends CDKFunction {
|
|
|
548
554
|
}
|
|
549
555
|
export const useFunctions = createAppContext(() => {
|
|
550
556
|
const functions = {};
|
|
557
|
+
const sourcemaps = {};
|
|
551
558
|
return {
|
|
559
|
+
sourcemaps: {
|
|
560
|
+
add(stack, source) {
|
|
561
|
+
let arr = sourcemaps[stack];
|
|
562
|
+
if (!arr)
|
|
563
|
+
sourcemaps[stack] = arr = [];
|
|
564
|
+
arr.push(source);
|
|
565
|
+
},
|
|
566
|
+
forStack(stack) {
|
|
567
|
+
return sourcemaps[stack] || [];
|
|
568
|
+
},
|
|
569
|
+
},
|
|
552
570
|
fromID(id) {
|
|
553
571
|
const result = functions[id];
|
|
554
572
|
if (!result)
|
|
@@ -2,6 +2,7 @@ import { OidcBasicConfig } from "./oidc.js";
|
|
|
2
2
|
type MicrosoftConfig = OidcBasicConfig & {
|
|
3
3
|
mode: "oidc";
|
|
4
4
|
prompt?: "login" | "none" | "consent" | "select_account";
|
|
5
|
+
tenantID?: string;
|
|
5
6
|
};
|
|
6
7
|
export declare function MicrosoftAdapter(config: MicrosoftConfig): () => Promise<{
|
|
7
8
|
type: "success";
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import { Issuer } from "openid-client";
|
|
2
2
|
import { OidcAdapter } from "./oidc.js";
|
|
3
|
-
// These are the different Microsoft auth urls for different types of accounts:
|
|
4
|
-
// Common: https://login.microsoftonline.com/common/v2.0 (both business and private)
|
|
5
|
-
// Business: https://login.microsoftonline.com/{tenant}/v2.0
|
|
6
|
-
// Private: https://login.microsoftonline.com/consumers/v2.0
|
|
7
|
-
const issuer = await Issuer.discover("https://login.microsoftonline.com/common/v2.0");
|
|
8
3
|
export function MicrosoftAdapter(config) {
|
|
4
|
+
const authority = config?.tenantID ?? "common";
|
|
5
|
+
const issuer = `https://login.microsoftonline.com/${authority}`;
|
|
9
6
|
return OidcAdapter({
|
|
10
|
-
issuer
|
|
7
|
+
issuer: new Issuer({
|
|
8
|
+
issuer: `${issuer}/v2.0`,
|
|
9
|
+
authorization_endpoint: `${issuer}/oauth2/v2.0/authorize`,
|
|
10
|
+
token_endpoint: `${issuer}/oauth2/v2.0/token`,
|
|
11
|
+
jwks_uri: `${issuer}/discovery/v2.0/keys`,
|
|
12
|
+
}),
|
|
11
13
|
scope: "openid email profile",
|
|
12
14
|
...config,
|
|
13
15
|
});
|
package/package.json
CHANGED
package/runtime/handlers/node.js
CHANGED
|
@@ -158,7 +158,14 @@ export const useNodeHandler = Context.memo(async () => {
|
|
|
158
158
|
: undefined,
|
|
159
159
|
}),
|
|
160
160
|
outfile: target,
|
|
161
|
-
|
|
161
|
+
// always generate sourcemaps in local
|
|
162
|
+
// never generate sourcemaps if explicitly false
|
|
163
|
+
// otherwise generate sourcemaps
|
|
164
|
+
sourcemap: input.mode === "start"
|
|
165
|
+
? "linked"
|
|
166
|
+
: nodejs.sourcemap === false
|
|
167
|
+
? false
|
|
168
|
+
: true,
|
|
162
169
|
minify: nodejs.minify,
|
|
163
170
|
...override,
|
|
164
171
|
};
|
package/runtime/handlers.js
CHANGED
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
import { Context } from "../context/context.js";
|
|
2
2
|
import { Logger } from "../logger.js";
|
|
3
3
|
import path from "path";
|
|
4
|
-
import zlib from "zlib";
|
|
5
4
|
import fs from "fs/promises";
|
|
6
5
|
import { useWatcher } from "../watcher.js";
|
|
7
6
|
import { useBus } from "../bus.js";
|
|
8
|
-
import crypto from "crypto";
|
|
9
7
|
import { useProject } from "../project.js";
|
|
10
8
|
import { useFunctions } from "../constructs/Function.js";
|
|
11
9
|
export const useRuntimeHandlers = Context.memo(() => {
|
|
@@ -77,22 +75,11 @@ export const useRuntimeHandlers = Context.memo(() => {
|
|
|
77
75
|
}
|
|
78
76
|
if (func.hooks?.afterBuild)
|
|
79
77
|
await func.hooks.afterBuild(func, out);
|
|
80
|
-
let sourcemap;
|
|
81
|
-
if (built.sourcemap && mode === "deploy") {
|
|
82
|
-
const data = await fs.readFile(built.sourcemap);
|
|
83
|
-
await fs.rm(built.sourcemap);
|
|
84
|
-
const hash = crypto.createHash("md5").update(data).digest("hex");
|
|
85
|
-
const dir = path.join(project.paths.artifacts, "sourcemaps", functionID);
|
|
86
|
-
await fs.rm(dir, { recursive: true, force: true });
|
|
87
|
-
await fs.mkdir(dir, { recursive: true });
|
|
88
|
-
sourcemap = dir;
|
|
89
|
-
await fs.writeFile(path.join(dir, `${hash}.map`), zlib.gzipSync(data));
|
|
90
|
-
}
|
|
91
78
|
bus.publish("function.build.success", { functionID });
|
|
92
79
|
return {
|
|
93
80
|
...built,
|
|
94
81
|
out,
|
|
95
|
-
sourcemap,
|
|
82
|
+
sourcemap: built.sourcemap,
|
|
96
83
|
};
|
|
97
84
|
}
|
|
98
85
|
if (pendingBuilds.has(functionID)) {
|
|
@@ -132,8 +119,8 @@ export const useFunctionBuilder = Context.memo(() => {
|
|
|
132
119
|
watcher.subscribe("file.changed", async (evt) => {
|
|
133
120
|
try {
|
|
134
121
|
const functions = useFunctions();
|
|
135
|
-
for (const [functionID,
|
|
136
|
-
const handler = handlers.for(
|
|
122
|
+
for (const [functionID, info] of Object.entries(functions.all)) {
|
|
123
|
+
const handler = handlers.for(info.runtime);
|
|
137
124
|
if (!handler?.shouldBuild({
|
|
138
125
|
functionID,
|
|
139
126
|
file: evt.properties.file,
|