sst 2.0.0-rc.51 → 2.0.0-rc.53
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/cli/commands/deploy.js +1 -1
- package/cli/commands/dev.js +27 -38
- package/cli/commands/telemetry.d.ts +15 -0
- package/cli/commands/telemetry.js +17 -0
- package/cli/program.js +1 -1
- package/cli/sst.js +2 -0
- package/cli/ui/deploy.js +1 -1
- package/constructs/AstroSite.d.ts +0 -1
- package/constructs/AstroSite.js +31 -46
- package/constructs/Job.js +6 -2
- package/constructs/NextjsSite.d.ts +2 -4
- package/constructs/NextjsSite.js +63 -101
- package/constructs/RemixSite.d.ts +0 -2
- package/constructs/RemixSite.js +4 -12
- package/constructs/SolidStartSite.d.ts +0 -1
- package/constructs/SolidStartSite.js +29 -41
- package/constructs/SsrSite.d.ts +28 -64
- package/constructs/SsrSite.js +78 -129
- package/constructs/StaticSite.d.ts +30 -50
- package/constructs/StaticSite.js +80 -105
- package/credentials.js +19 -0
- package/package.json +2 -1
- package/sst.mjs +95 -53
- package/stacks/build.js +1 -1
- package/stacks/monitor.js +1 -3
- package/support/job-invoker/index.mjs +26 -0
- package/support/astro-site-html-stub/index.html +0 -99
- package/support/nextjs-site-html-stub/index.html +0 -99
- package/support/remix-site-html-stub/index.html +0 -99
- package/support/solid-start-site-html-stub/index.html +0 -99
- package/support/static-site-stub/index.html +0 -90
package/cli/commands/deploy.js
CHANGED
|
@@ -38,7 +38,7 @@ export const deploy = (program) => program.command("deploy [filter]", "Deploy yo
|
|
|
38
38
|
return result;
|
|
39
39
|
}
|
|
40
40
|
const spinner = createSpinner({
|
|
41
|
-
text: " Building
|
|
41
|
+
text: " Building...",
|
|
42
42
|
});
|
|
43
43
|
const result = await Stacks.synth({
|
|
44
44
|
fn: project.stacks,
|
package/cli/commands/dev.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import chalk from "chalk";
|
|
2
1
|
import { Colors } from "../colors.js";
|
|
3
2
|
import { printHeader } from "../ui/header.js";
|
|
4
|
-
import { mapValues } from "remeda";
|
|
3
|
+
import { mapValues, omitBy, pipe } from "remeda";
|
|
5
4
|
export const dev = (program) => program.command(["dev", "start"], "Work on your app locally", (yargs) => yargs.option("increase-timeout", {
|
|
6
5
|
type: "boolean",
|
|
7
6
|
description: "Increase function timeout",
|
|
@@ -70,11 +69,17 @@ export const dev = (program) => program.command(["dev", "start"], "Work on your
|
|
|
70
69
|
}
|
|
71
70
|
});
|
|
72
71
|
bus.subscribe("function.build.success", async (evt) => {
|
|
73
|
-
|
|
72
|
+
const info = useFunctions().fromID(evt.properties.functionID);
|
|
73
|
+
if (!info.enableLiveDev)
|
|
74
|
+
return;
|
|
75
|
+
Colors.line(Colors.dim(Colors.prefix, "Built", info.handler));
|
|
74
76
|
});
|
|
75
77
|
bus.subscribe("function.build.failed", async (evt) => {
|
|
78
|
+
const info = useFunctions().fromID(evt.properties.functionID);
|
|
79
|
+
if (!info.enableLiveDev)
|
|
80
|
+
return;
|
|
76
81
|
Colors.gap();
|
|
77
|
-
Colors.line(Colors.danger("✖ "), "Build failed",
|
|
82
|
+
Colors.line(Colors.danger("✖ "), "Build failed", info.handler);
|
|
78
83
|
for (const line of evt.properties.errors) {
|
|
79
84
|
Colors.line(" ", line);
|
|
80
85
|
}
|
|
@@ -104,9 +109,15 @@ export const dev = (program) => program.command(["dev", "start"], "Work on your
|
|
|
104
109
|
const project = useProject();
|
|
105
110
|
const bus = useBus();
|
|
106
111
|
let lastDeployed;
|
|
107
|
-
let
|
|
108
|
-
let
|
|
112
|
+
let isWorking = false;
|
|
113
|
+
let isDirty = false;
|
|
109
114
|
async function build() {
|
|
115
|
+
if (isWorking) {
|
|
116
|
+
isDirty = true;
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
isDirty = false;
|
|
120
|
+
isWorking = true;
|
|
110
121
|
Colors.gap();
|
|
111
122
|
const spinner = createSpinner({
|
|
112
123
|
color: "gray",
|
|
@@ -127,6 +138,9 @@ export const dev = (program) => program.command(["dev", "start"], "Work on your
|
|
|
127
138
|
Logger.debug("Checksum", "next", next, "old", lastDeployed);
|
|
128
139
|
if (next === lastDeployed) {
|
|
129
140
|
spinner.succeed(Colors.dim(" Built with no changes"));
|
|
141
|
+
isWorking = false;
|
|
142
|
+
if (isDirty)
|
|
143
|
+
build();
|
|
130
144
|
return;
|
|
131
145
|
}
|
|
132
146
|
if (!lastDeployed) {
|
|
@@ -136,11 +150,9 @@ export const dev = (program) => program.command(["dev", "start"], "Work on your
|
|
|
136
150
|
}
|
|
137
151
|
else {
|
|
138
152
|
spinner.succeed(Colors.dim(` Built`));
|
|
139
|
-
Colors.
|
|
153
|
+
Colors.gap();
|
|
140
154
|
}
|
|
141
|
-
|
|
142
|
-
if (lastDeployed)
|
|
143
|
-
setTimeout(() => deploy(), 100);
|
|
155
|
+
deploy(assembly);
|
|
144
156
|
}
|
|
145
157
|
catch (ex) {
|
|
146
158
|
spinner.fail();
|
|
@@ -151,17 +163,8 @@ export const dev = (program) => program.command(["dev", "start"], "Work on your
|
|
|
151
163
|
Colors.gap();
|
|
152
164
|
}
|
|
153
165
|
}
|
|
154
|
-
async function deploy() {
|
|
155
|
-
if (!pending)
|
|
156
|
-
return;
|
|
157
|
-
if (isDeploying)
|
|
158
|
-
return;
|
|
159
|
-
isDeploying = true;
|
|
160
|
-
const assembly = pending;
|
|
166
|
+
async function deploy(assembly) {
|
|
161
167
|
const nextChecksum = await checksum(assembly.directory);
|
|
162
|
-
pending = undefined;
|
|
163
|
-
if (lastDeployed)
|
|
164
|
-
console.log();
|
|
165
168
|
const component = render(React.createElement(DeploymentUI, { assembly: assembly }));
|
|
166
169
|
const results = await Stacks.deployMany(assembly.stacks);
|
|
167
170
|
component.clear();
|
|
@@ -183,9 +186,10 @@ export const dev = (program) => program.command(["dev", "start"], "Work on your
|
|
|
183
186
|
}
|
|
184
187
|
await SiteEnv.writeValues(result);
|
|
185
188
|
}
|
|
186
|
-
fs.writeFile(path.join(project.paths.out, "outputs.json"), JSON.stringify(
|
|
187
|
-
|
|
188
|
-
|
|
189
|
+
fs.writeFile(path.join(project.paths.out, "outputs.json"), JSON.stringify(pipe(results, omitBy((_, key) => key.includes("SstSiteEnv")), mapValues((val) => val.outputs)), null, 2));
|
|
190
|
+
isWorking = false;
|
|
191
|
+
if (isDirty)
|
|
192
|
+
build();
|
|
189
193
|
}
|
|
190
194
|
async function checksum(cdkOutPath) {
|
|
191
195
|
const manifestPath = path.join(cdkOutPath, "manifest.json");
|
|
@@ -212,11 +216,7 @@ export const dev = (program) => program.command(["dev", "start"], "Work on your
|
|
|
212
216
|
build();
|
|
213
217
|
});
|
|
214
218
|
await build();
|
|
215
|
-
await deploy();
|
|
216
219
|
});
|
|
217
|
-
const project = useProject();
|
|
218
|
-
const primary = chalk.hex("#E27152");
|
|
219
|
-
const link = chalk.cyan;
|
|
220
220
|
await useLocalServer({
|
|
221
221
|
key: "",
|
|
222
222
|
cert: "",
|
|
@@ -224,17 +224,6 @@ export const dev = (program) => program.command(["dev", "start"], "Work on your
|
|
|
224
224
|
});
|
|
225
225
|
clear();
|
|
226
226
|
await printHeader({ console: true, hint: "ready!" });
|
|
227
|
-
/*
|
|
228
|
-
console.log(` ${primary(`➜`)} ${bold(dim(`Outputs:`))}`);
|
|
229
|
-
for (let i = 0; i < 3; i++) {
|
|
230
|
-
console.log(` ${dim(`thdxr-scratch-MyStack`)}`);
|
|
231
|
-
console.log(
|
|
232
|
-
` ${bold(
|
|
233
|
-
dim(`ApiEndpoint`)
|
|
234
|
-
)}: https://hdq3z0es2d.execute-api.us-east-1.amazonaws.com`
|
|
235
|
-
);
|
|
236
|
-
}
|
|
237
|
-
*/
|
|
238
227
|
await Promise.all([
|
|
239
228
|
useRuntimeWorkers(),
|
|
240
229
|
useIOTBridge(),
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/// <reference types="yargs" />
|
|
2
|
+
import type { Program } from "../program.js";
|
|
3
|
+
export declare const telemetry: (program: Program) => import("yargs").Argv<{
|
|
4
|
+
stage: string | undefined;
|
|
5
|
+
} & {
|
|
6
|
+
profile: string | undefined;
|
|
7
|
+
} & {
|
|
8
|
+
region: string | undefined;
|
|
9
|
+
} & {
|
|
10
|
+
verbose: boolean | undefined;
|
|
11
|
+
} & {
|
|
12
|
+
role: string | undefined;
|
|
13
|
+
} & {
|
|
14
|
+
action: string;
|
|
15
|
+
}>;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Colors } from "../colors.js";
|
|
2
|
+
export const telemetry = (program) => program.command("telemetry <action>", "Load environment variables and start your frontend", (yargs) => yargs.positional("action", {
|
|
3
|
+
type: "string",
|
|
4
|
+
describe: "Whether to enable or disable",
|
|
5
|
+
choices: ["enable", "disable"],
|
|
6
|
+
demandOption: true,
|
|
7
|
+
}), async (args) => {
|
|
8
|
+
const { enable, disable } = await import("../telemetry/telemetry.js");
|
|
9
|
+
if (args.action === "enable") {
|
|
10
|
+
enable();
|
|
11
|
+
Colors.line(Colors.success(`✔ `), `Telemetry enabled`);
|
|
12
|
+
}
|
|
13
|
+
if (args.action === "disable") {
|
|
14
|
+
disable();
|
|
15
|
+
Colors.line(Colors.success(`✔ `), `Telemetry disabled`);
|
|
16
|
+
}
|
|
17
|
+
});
|
package/cli/program.js
CHANGED
|
@@ -22,7 +22,7 @@ export const program = yargs(hideBin(process.argv))
|
|
|
22
22
|
type: "string",
|
|
23
23
|
describe: "ARN of the IAM role to use when invoking AWS",
|
|
24
24
|
})
|
|
25
|
-
.group(["stage", "profile", "region", "
|
|
25
|
+
.group(["stage", "profile", "region", "role", "verbose", "help"], "Global:")
|
|
26
26
|
.middleware(async (argv) => {
|
|
27
27
|
if (argv.verbose) {
|
|
28
28
|
process.env.SST_VERBOSE = "1";
|
package/cli/sst.js
CHANGED
|
@@ -20,6 +20,7 @@ import { update } from "./commands/update.js";
|
|
|
20
20
|
import { transform } from "./commands/transform.js";
|
|
21
21
|
import { diff } from "./commands/diff.js";
|
|
22
22
|
import { version } from "./commands/version.js";
|
|
23
|
+
import { telemetry } from "./commands/telemetry.js";
|
|
23
24
|
dev(program);
|
|
24
25
|
deploy(program);
|
|
25
26
|
build(program);
|
|
@@ -32,6 +33,7 @@ transform(program);
|
|
|
32
33
|
consoleCommand(program);
|
|
33
34
|
diff(program);
|
|
34
35
|
version(program);
|
|
36
|
+
telemetry(program);
|
|
35
37
|
// @ts-expect-error
|
|
36
38
|
process.setSourceMapsEnabled(true);
|
|
37
39
|
process.removeAllListeners("uncaughtException");
|
package/cli/ui/deploy.js
CHANGED
|
@@ -70,7 +70,7 @@ export function printDeploymentResults(assembly, results, remove) {
|
|
|
70
70
|
Colors.gap();
|
|
71
71
|
Colors.line(Colors.success(`✔`), Colors.bold(remove ? ` Removed:` : ` Deployed:`));
|
|
72
72
|
for (const [stack, result] of success) {
|
|
73
|
-
const outputs = Object.entries(result.outputs);
|
|
73
|
+
const outputs = Object.entries(result.outputs).filter(([key, _]) => !key.includes("SstSiteEnv"));
|
|
74
74
|
Colors.line(` ${Colors.dim(stackNameToId(stack))}`);
|
|
75
75
|
if (outputs.length > 0) {
|
|
76
76
|
for (const key of Object.keys(Object.fromEntries(outputs)).sort()) {
|
|
@@ -17,7 +17,6 @@ export declare class AstroSite extends SsrSite {
|
|
|
17
17
|
serverBuildOutputFile: string;
|
|
18
18
|
clientBuildOutputDir: string;
|
|
19
19
|
clientBuildVersionedSubDir: string;
|
|
20
|
-
siteStub: string;
|
|
21
20
|
};
|
|
22
21
|
protected validateBuildOutput(): void;
|
|
23
22
|
protected createFunctionForRegional(): lambda.Function;
|
package/constructs/AstroSite.js
CHANGED
|
@@ -4,6 +4,7 @@ import path from "path";
|
|
|
4
4
|
import * as esbuild from "esbuild";
|
|
5
5
|
import { SsrSite } from "./SsrSite.js";
|
|
6
6
|
import { Function } from "./Function.js";
|
|
7
|
+
import { useProject } from "../project.js";
|
|
7
8
|
import { EdgeFunction } from "./EdgeFunction.js";
|
|
8
9
|
const __dirname = url.fileURLToPath(new URL(".", import.meta.url));
|
|
9
10
|
/**
|
|
@@ -23,7 +24,6 @@ export class AstroSite extends SsrSite {
|
|
|
23
24
|
serverBuildOutputFile: "dist/server/entry.mjs",
|
|
24
25
|
clientBuildOutputDir: "dist/client",
|
|
25
26
|
clientBuildVersionedSubDir: "assets",
|
|
26
|
-
siteStub: path.resolve(__dirname, "../support/astro-site-html-stub"),
|
|
27
27
|
};
|
|
28
28
|
}
|
|
29
29
|
validateBuildOutput() {
|
|
@@ -36,14 +36,10 @@ export class AstroSite extends SsrSite {
|
|
|
36
36
|
}
|
|
37
37
|
createFunctionForRegional() {
|
|
38
38
|
const { defaults, environment, bind } = this.props;
|
|
39
|
-
// Bundle code
|
|
40
|
-
const handler = this.isPlaceholder
|
|
41
|
-
? path.resolve(__dirname, "../support/ssr-site-function-stub/index.handler")
|
|
42
|
-
: path.join(this.props.path, "dist", "server", "entry.handler");
|
|
43
39
|
// Create function
|
|
44
40
|
const fn = new Function(this, `ServerFunction`, {
|
|
45
41
|
description: "Server handler",
|
|
46
|
-
handler,
|
|
42
|
+
handler: path.join(this.props.path, "dist", "server", "entry.handler"),
|
|
47
43
|
bind,
|
|
48
44
|
logRetention: "three_days",
|
|
49
45
|
runtime: "nodejs16.x",
|
|
@@ -60,50 +56,39 @@ export class AstroSite extends SsrSite {
|
|
|
60
56
|
}
|
|
61
57
|
createFunctionForEdge() {
|
|
62
58
|
const { defaults, environment } = this.props;
|
|
63
|
-
//
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
`import { createRequire as topLevelCreateRequire } from 'module';`,
|
|
89
|
-
`const require = topLevelCreateRequire(import.meta.url);`,
|
|
90
|
-
].join(""),
|
|
91
|
-
},
|
|
92
|
-
});
|
|
93
|
-
if (result.errors.length > 0) {
|
|
94
|
-
result.errors.forEach((error) => console.error(error));
|
|
95
|
-
throw new Error(`There was a problem bundling the function code for the ${this.id} AstroSite.`);
|
|
96
|
-
}
|
|
97
|
-
// Create package.json
|
|
98
|
-
fs.writeFileSync(path.join(outputPath, "package.json"), `{"type":"module"}`);
|
|
99
|
-
bundlePath = outputPath;
|
|
100
|
-
handler = "entry.handler";
|
|
59
|
+
// Create a directory that we will use to create the bundled version
|
|
60
|
+
// of the "core server build" along with our custom Lamba server handler.
|
|
61
|
+
const outputPath = path.resolve(path.join(useProject().paths.artifacts, `AstroSiteFunction-${this.node.id}-${this.node.addr}`));
|
|
62
|
+
const result = esbuild.buildSync({
|
|
63
|
+
entryPoints: [
|
|
64
|
+
path.join(this.props.path, this.buildConfig.serverBuildOutputFile),
|
|
65
|
+
],
|
|
66
|
+
target: "esnext",
|
|
67
|
+
format: "esm",
|
|
68
|
+
platform: "node",
|
|
69
|
+
metafile: true,
|
|
70
|
+
bundle: true,
|
|
71
|
+
write: true,
|
|
72
|
+
allowOverwrite: true,
|
|
73
|
+
outfile: path.join(outputPath, "entry.mjs"),
|
|
74
|
+
banner: {
|
|
75
|
+
js: [
|
|
76
|
+
`import { createRequire as topLevelCreateRequire } from 'module';`,
|
|
77
|
+
`const require = topLevelCreateRequire(import.meta.url);`,
|
|
78
|
+
].join(""),
|
|
79
|
+
},
|
|
80
|
+
});
|
|
81
|
+
if (result.errors.length > 0) {
|
|
82
|
+
result.errors.forEach((error) => console.error(error));
|
|
83
|
+
throw new Error(`There was a problem bundling the function code for the ${this.id} AstroSite.`);
|
|
101
84
|
}
|
|
85
|
+
// Create package.json
|
|
86
|
+
fs.writeFileSync(path.join(outputPath, "package.json"), `{"type":"module"}`);
|
|
102
87
|
// Create function
|
|
103
88
|
return new EdgeFunction(this, `Server`, {
|
|
104
89
|
scopeOverride: this,
|
|
105
|
-
bundlePath,
|
|
106
|
-
handler,
|
|
90
|
+
bundlePath: outputPath,
|
|
91
|
+
handler: "entry.handler",
|
|
107
92
|
timeout: defaults?.function?.timeout,
|
|
108
93
|
memory: defaults?.function?.memorySize,
|
|
109
94
|
permissions: defaults?.function?.permissions,
|
package/constructs/Job.js
CHANGED
|
@@ -7,7 +7,7 @@ import * as iam from "aws-cdk-lib/aws-iam";
|
|
|
7
7
|
import * as lambda from "aws-cdk-lib/aws-lambda";
|
|
8
8
|
import * as codebuild from "aws-cdk-lib/aws-codebuild";
|
|
9
9
|
import { Stack } from "./Stack.js";
|
|
10
|
-
import { Function } from "./Function.js";
|
|
10
|
+
import { Function, useFunctions } from "./Function.js";
|
|
11
11
|
import { toCdkDuration } from "./util/duration.js";
|
|
12
12
|
import { attachPermissionsToRole } from "./util/permission.js";
|
|
13
13
|
import { bindEnvironment, bindPermissions } from "./util/functionBinding.js";
|
|
@@ -44,6 +44,10 @@ export class Job extends Construct {
|
|
|
44
44
|
const app = this.node.root;
|
|
45
45
|
this.id = id;
|
|
46
46
|
this.props = props;
|
|
47
|
+
useFunctions().add(this.node.addr, {
|
|
48
|
+
...props,
|
|
49
|
+
runtime: "nodejs16.x",
|
|
50
|
+
});
|
|
47
51
|
this.localId = path.posix
|
|
48
52
|
.join(scope.node.path, id)
|
|
49
53
|
.replace(/\$/g, "-")
|
|
@@ -254,7 +258,7 @@ export class Job extends Construct {
|
|
|
254
258
|
}
|
|
255
259
|
createCodeBuildInvoker() {
|
|
256
260
|
return new Function(this, this.node.id, {
|
|
257
|
-
handler: path.join(__dirname, "../
|
|
261
|
+
handler: path.join(__dirname, "../support/job-invoker/index.main"),
|
|
258
262
|
runtime: "nodejs16.x",
|
|
259
263
|
timeout: 10,
|
|
260
264
|
memorySize: 1024,
|
|
@@ -21,13 +21,11 @@ export declare class NextjsSite extends SsrSite {
|
|
|
21
21
|
serverBuildOutputFile: string;
|
|
22
22
|
clientBuildOutputDir: string;
|
|
23
23
|
clientBuildVersionedSubDir: string;
|
|
24
|
-
siteStub: string;
|
|
25
24
|
};
|
|
26
25
|
protected createFunctionForRegional(): lambda.Function;
|
|
26
|
+
private createImageOptimizationFunctionForRegional;
|
|
27
|
+
private createMiddlewareEdgeFunctionForRegional;
|
|
27
28
|
protected createCloudFrontDistributionForRegional(): cloudfront.Distribution;
|
|
28
|
-
protected createCloudFrontDistributionForStub(): cloudfront.Distribution;
|
|
29
29
|
protected createCloudFrontServerCachePolicy(): cloudfront.CachePolicy;
|
|
30
30
|
protected generateBuildId(): string;
|
|
31
|
-
private createImageOptimizationFunctionForRegional;
|
|
32
|
-
private createMiddlewareEdgeFunctionForRegional;
|
|
33
31
|
}
|
package/constructs/NextjsSite.js
CHANGED
|
@@ -2,14 +2,14 @@ import fs from "fs";
|
|
|
2
2
|
import url from "url";
|
|
3
3
|
import path from "path";
|
|
4
4
|
import spawn from "cross-spawn";
|
|
5
|
-
import { buildErrorResponsesForRedirectToIndex } from "./BaseSite.js";
|
|
6
5
|
import { Fn, Duration, RemovalPolicy, } from "aws-cdk-lib";
|
|
7
6
|
import * as logs from "aws-cdk-lib/aws-logs";
|
|
8
7
|
import * as lambda from "aws-cdk-lib/aws-lambda";
|
|
9
8
|
import * as cloudfront from "aws-cdk-lib/aws-cloudfront";
|
|
10
9
|
import * as origins from "aws-cdk-lib/aws-cloudfront-origins";
|
|
11
|
-
import {
|
|
10
|
+
import { useProject } from "../project.js";
|
|
12
11
|
import { EdgeFunction } from "./EdgeFunction.js";
|
|
12
|
+
import { SsrSite } from "./SsrSite.js";
|
|
13
13
|
const __dirname = url.fileURLToPath(new URL(".", import.meta.url));
|
|
14
14
|
/**
|
|
15
15
|
* The `NextjsSite` construct is a higher level CDK construct that makes it easy to create a Next.js app.
|
|
@@ -34,50 +34,82 @@ export class NextjsSite extends SsrSite {
|
|
|
34
34
|
serverBuildOutputFile: ".open-next/server-function/index.mjs",
|
|
35
35
|
clientBuildOutputDir: ".open-next/assets",
|
|
36
36
|
clientBuildVersionedSubDir: "_next",
|
|
37
|
-
siteStub: path.resolve(__dirname, "../support/nextjs-site-html-stub"),
|
|
38
37
|
};
|
|
39
38
|
}
|
|
40
39
|
createFunctionForRegional() {
|
|
41
40
|
const { defaults, environment } = this.props;
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
path.join(zipOutDir, "server-function.zip"),
|
|
59
|
-
], {
|
|
60
|
-
stdio: "inherit",
|
|
61
|
-
});
|
|
62
|
-
if (result.status !== 0) {
|
|
63
|
-
throw new Error(`There was a problem generating the assets package.`);
|
|
64
|
-
}
|
|
65
|
-
bundlePath = path.join(zipOutDir, "server-function.zip");
|
|
66
|
-
handler = "index.handler";
|
|
41
|
+
// Note: cannot point the bundlePath to the `.open-next/server-function`
|
|
42
|
+
// b/c the folder contains node_modules. And pnpm node_modules
|
|
43
|
+
// contains symlinks. CDK cannot zip symlinks correctly.
|
|
44
|
+
// https://github.com/aws/aws-cdk/issues/9251
|
|
45
|
+
// We will zip the folder ourselves.
|
|
46
|
+
const zipOutDir = path.resolve(path.join(useProject().paths.artifacts, `Site-${this.node.id}-${this.node.addr}`));
|
|
47
|
+
const script = path.resolve(__dirname, "../support/ssr-site-function-archiver.mjs");
|
|
48
|
+
const result = spawn.sync("node", [
|
|
49
|
+
script,
|
|
50
|
+
path.join(this.props.path, ".open-next", "server-function"),
|
|
51
|
+
path.join(zipOutDir, "server-function.zip"),
|
|
52
|
+
], {
|
|
53
|
+
stdio: "inherit",
|
|
54
|
+
});
|
|
55
|
+
if (result.status !== 0) {
|
|
56
|
+
throw new Error(`There was a problem generating the assets package.`);
|
|
67
57
|
}
|
|
68
58
|
return new lambda.Function(this, `ServerFunction`, {
|
|
69
59
|
description: "Server handler for Next.js",
|
|
70
|
-
handler,
|
|
60
|
+
handler: "index.handler",
|
|
61
|
+
currentVersionOptions: {
|
|
62
|
+
removalPolicy: RemovalPolicy.DESTROY,
|
|
63
|
+
},
|
|
64
|
+
logRetention: logs.RetentionDays.THREE_DAYS,
|
|
65
|
+
code: lambda.Code.fromAsset(path.join(zipOutDir, "server-function.zip")),
|
|
66
|
+
runtime: lambda.Runtime.NODEJS_18_X,
|
|
67
|
+
memorySize: defaults?.function?.memorySize || 512,
|
|
68
|
+
timeout: Duration.seconds(defaults?.function?.timeout || 10),
|
|
69
|
+
environment,
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
createImageOptimizationFunctionForRegional() {
|
|
73
|
+
const { defaults, path: sitePath } = this.props;
|
|
74
|
+
return new lambda.Function(this, `ImageFunction`, {
|
|
75
|
+
description: "Image optimization handler for Next.js",
|
|
76
|
+
handler: "index.handler",
|
|
71
77
|
currentVersionOptions: {
|
|
72
78
|
removalPolicy: RemovalPolicy.DESTROY,
|
|
73
79
|
},
|
|
74
80
|
logRetention: logs.RetentionDays.THREE_DAYS,
|
|
75
|
-
code: lambda.Code.fromAsset(
|
|
81
|
+
code: lambda.Code.fromAsset(path.join(sitePath, ".open-next/image-optimization-function")),
|
|
76
82
|
runtime: lambda.Runtime.NODEJS_18_X,
|
|
77
83
|
memorySize: defaults?.function?.memorySize || 512,
|
|
78
84
|
timeout: Duration.seconds(defaults?.function?.timeout || 10),
|
|
85
|
+
environment: {
|
|
86
|
+
BUCKET_NAME: this.cdk.bucket.bucketName,
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
createMiddlewareEdgeFunctionForRegional() {
|
|
91
|
+
const { defaults, environment, path: sitePath } = this.props;
|
|
92
|
+
const middlewarePath = path.resolve(sitePath, ".open-next/middleware-function");
|
|
93
|
+
const isMiddlewareEnabled = fs.existsSync(middlewarePath);
|
|
94
|
+
let bundlePath, handler;
|
|
95
|
+
if (isMiddlewareEnabled) {
|
|
96
|
+
bundlePath = middlewarePath;
|
|
97
|
+
handler = "index.handler";
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
bundlePath = path.resolve(__dirname, "../support/ssr-site-function-stub");
|
|
101
|
+
handler = "server.handler";
|
|
102
|
+
}
|
|
103
|
+
const fn = new EdgeFunction(this, "Middleware", {
|
|
104
|
+
bundlePath,
|
|
105
|
+
handler,
|
|
106
|
+
timeout: 5,
|
|
107
|
+
memory: 128,
|
|
108
|
+
permissions: defaults?.function?.permissions,
|
|
79
109
|
environment,
|
|
110
|
+
format: "esm",
|
|
80
111
|
});
|
|
112
|
+
return { fn, isMiddlewareEnabled };
|
|
81
113
|
}
|
|
82
114
|
createCloudFrontDistributionForRegional() {
|
|
83
115
|
const { cdk } = this.props;
|
|
@@ -96,7 +128,7 @@ export class NextjsSite extends SsrSite {
|
|
|
96
128
|
compress: true,
|
|
97
129
|
cachePolicy: cdk?.cachePolicies?.serverRequests ??
|
|
98
130
|
this.createCloudFrontServerCachePolicy(),
|
|
99
|
-
edgeLambdas: isMiddlewareEnabled
|
|
131
|
+
edgeLambdas: isMiddlewareEnabled
|
|
100
132
|
? [{
|
|
101
133
|
eventType: cloudfront.LambdaEdgeEventType.VIEWER_REQUEST,
|
|
102
134
|
functionVersion: middlewareFn.currentVersion,
|
|
@@ -208,22 +240,6 @@ export class NextjsSite extends SsrSite {
|
|
|
208
240
|
},
|
|
209
241
|
});
|
|
210
242
|
}
|
|
211
|
-
createCloudFrontDistributionForStub() {
|
|
212
|
-
// Keep creating middleware edge function b/c edge function cannot be removed
|
|
213
|
-
// immediately.
|
|
214
|
-
this.createMiddlewareEdgeFunctionForRegional();
|
|
215
|
-
// Create placeholder distribution
|
|
216
|
-
return new cloudfront.Distribution(this, "Distribution", {
|
|
217
|
-
defaultRootObject: "index.html",
|
|
218
|
-
errorResponses: buildErrorResponsesForRedirectToIndex("index.html"),
|
|
219
|
-
domainNames: this.buildDistributionDomainNames(),
|
|
220
|
-
certificate: this.cdk.certificate,
|
|
221
|
-
defaultBehavior: {
|
|
222
|
-
origin: new origins.S3Origin(this.cdk.bucket),
|
|
223
|
-
viewerProtocolPolicy: cloudfront.ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
|
|
224
|
-
},
|
|
225
|
-
});
|
|
226
|
-
}
|
|
227
243
|
createCloudFrontServerCachePolicy() {
|
|
228
244
|
return new cloudfront.CachePolicy(this, "ServerCache", {
|
|
229
245
|
queryStringBehavior: cloudfront.CacheQueryStringBehavior.all(),
|
|
@@ -242,61 +258,7 @@ export class NextjsSite extends SsrSite {
|
|
|
242
258
|
});
|
|
243
259
|
}
|
|
244
260
|
generateBuildId() {
|
|
245
|
-
if (this.isPlaceholder) {
|
|
246
|
-
return "live";
|
|
247
|
-
}
|
|
248
261
|
const filePath = path.join(this.props.path, ".next/BUILD_ID");
|
|
249
262
|
return fs.readFileSync(filePath).toString();
|
|
250
263
|
}
|
|
251
|
-
createImageOptimizationFunctionForRegional() {
|
|
252
|
-
const { defaults, path: sitePath } = this.props;
|
|
253
|
-
let bundlePath, handler;
|
|
254
|
-
if (this.isPlaceholder) {
|
|
255
|
-
bundlePath = path.resolve(__dirname, "../support/ssr-site-function-stub");
|
|
256
|
-
handler = "server.handler";
|
|
257
|
-
}
|
|
258
|
-
else {
|
|
259
|
-
bundlePath = path.join(sitePath, ".open-next/image-optimization-function");
|
|
260
|
-
handler = "index.handler";
|
|
261
|
-
}
|
|
262
|
-
return new lambda.Function(this, `ImageFunction`, {
|
|
263
|
-
description: "Image optimization handler for Next.js",
|
|
264
|
-
handler,
|
|
265
|
-
currentVersionOptions: {
|
|
266
|
-
removalPolicy: RemovalPolicy.DESTROY,
|
|
267
|
-
},
|
|
268
|
-
logRetention: logs.RetentionDays.THREE_DAYS,
|
|
269
|
-
code: lambda.Code.fromAsset(bundlePath),
|
|
270
|
-
runtime: lambda.Runtime.NODEJS_18_X,
|
|
271
|
-
memorySize: defaults?.function?.memorySize || 512,
|
|
272
|
-
timeout: Duration.seconds(defaults?.function?.timeout || 10),
|
|
273
|
-
environment: {
|
|
274
|
-
BUCKET_NAME: this.cdk.bucket.bucketName,
|
|
275
|
-
}
|
|
276
|
-
});
|
|
277
|
-
}
|
|
278
|
-
createMiddlewareEdgeFunctionForRegional() {
|
|
279
|
-
const { defaults, environment, path: sitePath } = this.props;
|
|
280
|
-
const middlewarePath = path.resolve(sitePath, ".open-next/middleware-function");
|
|
281
|
-
const isMiddlewareEnabled = fs.existsSync(middlewarePath);
|
|
282
|
-
let bundlePath, handler;
|
|
283
|
-
if (this.isPlaceholder || !isMiddlewareEnabled) {
|
|
284
|
-
bundlePath = path.resolve(__dirname, "../support/ssr-site-function-stub");
|
|
285
|
-
handler = "server.handler";
|
|
286
|
-
}
|
|
287
|
-
else {
|
|
288
|
-
bundlePath = middlewarePath;
|
|
289
|
-
handler = "index.handler";
|
|
290
|
-
}
|
|
291
|
-
const fn = new EdgeFunction(this, "Middleware", {
|
|
292
|
-
bundlePath,
|
|
293
|
-
handler,
|
|
294
|
-
timeout: 5,
|
|
295
|
-
memory: 128,
|
|
296
|
-
permissions: defaults?.function?.permissions,
|
|
297
|
-
environment,
|
|
298
|
-
format: "esm",
|
|
299
|
-
});
|
|
300
|
-
return { fn, isMiddlewareEnabled };
|
|
301
|
-
}
|
|
302
264
|
}
|
|
@@ -19,10 +19,8 @@ export declare class RemixSite extends SsrSite {
|
|
|
19
19
|
serverBuildOutputFile: string;
|
|
20
20
|
clientBuildOutputDir: string;
|
|
21
21
|
clientBuildVersionedSubDir: string;
|
|
22
|
-
siteStub: string;
|
|
23
22
|
};
|
|
24
23
|
private createServerLambdaBundle;
|
|
25
|
-
private createServerLambdaBundleWithStub;
|
|
26
24
|
protected createFunctionForRegional(): lambda.Function;
|
|
27
25
|
protected createFunctionForEdge(): EdgeFunction;
|
|
28
26
|
}
|