sst 2.5.5 → 2.5.6
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/config.js +10 -10
- package/constructs/SsrSite.js +5 -1
- package/package.json +1 -1
- package/project.d.ts +6 -0
- package/project.js +28 -6
- package/sst.mjs +33 -19
package/config.js
CHANGED
|
@@ -10,7 +10,7 @@ export var Config;
|
|
|
10
10
|
async function parameters() {
|
|
11
11
|
const result = [];
|
|
12
12
|
for await (const p of scan(PREFIX.FALLBACK)) {
|
|
13
|
-
const parsed = parse(p.Name);
|
|
13
|
+
const parsed = parse(p.Name, PREFIX.FALLBACK);
|
|
14
14
|
if (parsed.type === "secrets")
|
|
15
15
|
continue;
|
|
16
16
|
result.push({
|
|
@@ -19,7 +19,7 @@ export var Config;
|
|
|
19
19
|
});
|
|
20
20
|
}
|
|
21
21
|
for await (const p of scan(PREFIX.STAGE)) {
|
|
22
|
-
const parsed = parse(p.Name);
|
|
22
|
+
const parsed = parse(p.Name, PREFIX.STAGE);
|
|
23
23
|
if (parsed.type === "secrets")
|
|
24
24
|
continue;
|
|
25
25
|
result.push({
|
|
@@ -45,13 +45,13 @@ export var Config;
|
|
|
45
45
|
async function secrets() {
|
|
46
46
|
const result = {};
|
|
47
47
|
for await (const p of scan(PREFIX.STAGE + "Secret")) {
|
|
48
|
-
const parsed = parse(p.Name);
|
|
48
|
+
const parsed = parse(p.Name, PREFIX.STAGE);
|
|
49
49
|
if (!result[parsed.id])
|
|
50
50
|
result[parsed.id] = {};
|
|
51
51
|
result[parsed.id].value = p.Value;
|
|
52
52
|
}
|
|
53
53
|
for await (const p of scan(PREFIX.FALLBACK + "Secret")) {
|
|
54
|
-
const parsed = parse(p.Name);
|
|
54
|
+
const parsed = parse(p.Name, PREFIX.FALLBACK);
|
|
55
55
|
if (!result[parsed.id])
|
|
56
56
|
result[parsed.id] = {};
|
|
57
57
|
result[parsed.id].fallback = p.Value;
|
|
@@ -178,19 +178,19 @@ const SECRET_UPDATED_AT_ENV = "SST_ADMIN_SECRET_UPDATED_AT";
|
|
|
178
178
|
const PREFIX = {
|
|
179
179
|
get STAGE() {
|
|
180
180
|
const project = useProject();
|
|
181
|
-
return
|
|
181
|
+
return project.config.ssmPrefix;
|
|
182
182
|
},
|
|
183
183
|
get FALLBACK() {
|
|
184
184
|
const project = useProject();
|
|
185
185
|
return `/sst/${project.config.name}/${FALLBACK_STAGE}/`;
|
|
186
186
|
},
|
|
187
187
|
};
|
|
188
|
-
function parse(ssmName) {
|
|
189
|
-
const parts = ssmName.split("/");
|
|
188
|
+
function parse(ssmName, prefix) {
|
|
189
|
+
const parts = ssmName.substring(prefix.length).split("/");
|
|
190
190
|
return {
|
|
191
|
-
type: parts[
|
|
192
|
-
id: parts[
|
|
193
|
-
prop: parts.slice(
|
|
191
|
+
type: parts[0],
|
|
192
|
+
id: parts[1],
|
|
193
|
+
prop: parts.slice(2).join("/"),
|
|
194
194
|
};
|
|
195
195
|
}
|
|
196
196
|
async function restartFunction(arn) {
|
package/constructs/SsrSite.js
CHANGED
|
@@ -165,10 +165,11 @@ export class SsrSite extends Construct {
|
|
|
165
165
|
* ```
|
|
166
166
|
*/
|
|
167
167
|
attachPermissions(permissions) {
|
|
168
|
+
this.serverLambdaForDev?.attachPermissions(permissions);
|
|
169
|
+
this.serverLambdaForEdge?.attachPermissions(permissions);
|
|
168
170
|
if (this.serverLambdaForRegional) {
|
|
169
171
|
attachPermissionsToRole(this.serverLambdaForRegional.role, permissions);
|
|
170
172
|
}
|
|
171
|
-
this.serverLambdaForEdge?.attachPermissions(permissions);
|
|
172
173
|
}
|
|
173
174
|
/** @internal */
|
|
174
175
|
getConstructMetadata() {
|
|
@@ -432,6 +433,9 @@ export class SsrSite extends Construct {
|
|
|
432
433
|
environment,
|
|
433
434
|
permissions,
|
|
434
435
|
role,
|
|
436
|
+
// Force enable live dev to prevent the function handler to be built
|
|
437
|
+
// in the case user set "enableLiveDev: false" on the app or stack.
|
|
438
|
+
enableLiveDev: true,
|
|
435
439
|
});
|
|
436
440
|
fn._doNotAllowOthersToBind = true;
|
|
437
441
|
return fn;
|
package/package.json
CHANGED
package/project.d.ts
CHANGED
|
@@ -56,4 +56,10 @@ interface GlobalOptions {
|
|
|
56
56
|
region?: string;
|
|
57
57
|
}
|
|
58
58
|
export declare function initProject(globals: GlobalOptions): Promise<void>;
|
|
59
|
+
declare function sanitizeStageName(stage: string): string;
|
|
60
|
+
declare function isValidStageName(stage: string): boolean;
|
|
61
|
+
export declare const exportedForTesting: {
|
|
62
|
+
sanitizeStageName: typeof sanitizeStageName;
|
|
63
|
+
isValidStageName: typeof isValidStageName;
|
|
64
|
+
};
|
|
59
65
|
export {};
|
package/project.js
CHANGED
|
@@ -117,21 +117,29 @@ async function usePersonalStage(out) {
|
|
|
117
117
|
return;
|
|
118
118
|
}
|
|
119
119
|
}
|
|
120
|
-
async function promptPersonalStage(out) {
|
|
120
|
+
async function promptPersonalStage(out, isRetry) {
|
|
121
121
|
const readline = await import("readline");
|
|
122
122
|
const rl = readline.createInterface({
|
|
123
123
|
input: process.stdin,
|
|
124
124
|
output: process.stdout,
|
|
125
125
|
});
|
|
126
|
-
|
|
127
|
-
const suggested = os.userInfo().username;
|
|
128
|
-
|
|
126
|
+
const stage = await new Promise((resolve) => {
|
|
127
|
+
const suggested = sanitizeStageName(os.userInfo().username) || "local";
|
|
128
|
+
const instruction = !isRetry
|
|
129
|
+
? `Please enter a name you’d like to use for your personal stage.`
|
|
130
|
+
: `Please enter a name that starts with a letter, followed by letters, numbers, or hyphens.`;
|
|
131
|
+
rl.question(`${instruction} Or hit enter to use ${blue(suggested)}: `, async (input) => {
|
|
129
132
|
rl.close();
|
|
130
|
-
const result = input
|
|
131
|
-
await fs.writeFile(path.join(out, "stage"), result);
|
|
133
|
+
const result = input === "" ? suggested : input;
|
|
132
134
|
resolve(result);
|
|
133
135
|
});
|
|
134
136
|
});
|
|
137
|
+
// Validate stage name
|
|
138
|
+
if (isValidStageName(stage)) {
|
|
139
|
+
await fs.writeFile(path.join(out, "stage"), stage);
|
|
140
|
+
return stage;
|
|
141
|
+
}
|
|
142
|
+
return await promptPersonalStage(out, true);
|
|
135
143
|
}
|
|
136
144
|
async function findRoot() {
|
|
137
145
|
async function find(dir) {
|
|
@@ -148,3 +156,17 @@ async function findRoot() {
|
|
|
148
156
|
const result = await find(process.cwd());
|
|
149
157
|
return result;
|
|
150
158
|
}
|
|
159
|
+
function sanitizeStageName(stage) {
|
|
160
|
+
return (stage
|
|
161
|
+
.replace(/[^A-Za-z0-9-]/g, "-")
|
|
162
|
+
.replace(/--+/g, "-")
|
|
163
|
+
.replace(/^[^A-Za-z]/, "")
|
|
164
|
+
.replace(/-$/, "") || "local");
|
|
165
|
+
}
|
|
166
|
+
function isValidStageName(stage) {
|
|
167
|
+
return Boolean(stage.match(/^[A-Za-z][A-Za-z0-9-]*$/));
|
|
168
|
+
}
|
|
169
|
+
export const exportedForTesting = {
|
|
170
|
+
sanitizeStageName,
|
|
171
|
+
isValidStageName,
|
|
172
|
+
};
|
package/sst.mjs
CHANGED
|
@@ -317,6 +317,7 @@ var init_build = __esm({
|
|
|
317
317
|
var project_exports = {};
|
|
318
318
|
__export(project_exports, {
|
|
319
319
|
ProjectContext: () => ProjectContext,
|
|
320
|
+
exportedForTesting: () => exportedForTesting,
|
|
320
321
|
initProject: () => initProject,
|
|
321
322
|
useProject: () => useProject
|
|
322
323
|
});
|
|
@@ -420,26 +421,29 @@ async function usePersonalStage(out) {
|
|
|
420
421
|
return;
|
|
421
422
|
}
|
|
422
423
|
}
|
|
423
|
-
async function promptPersonalStage(out) {
|
|
424
|
+
async function promptPersonalStage(out, isRetry) {
|
|
424
425
|
const readline = await import("readline");
|
|
425
426
|
const rl = readline.createInterface({
|
|
426
427
|
input: process.stdin,
|
|
427
428
|
output: process.stdout
|
|
428
429
|
});
|
|
429
|
-
|
|
430
|
-
const suggested = os.userInfo().username;
|
|
430
|
+
const stage = await new Promise((resolve) => {
|
|
431
|
+
const suggested = sanitizeStageName(os.userInfo().username) || "local";
|
|
432
|
+
const instruction = !isRetry ? `Please enter a name you\u2019d like to use for your personal stage.` : `Please enter a name that starts with a letter, followed by letters, numbers, or hyphens.`;
|
|
431
433
|
rl.question(
|
|
432
|
-
|
|
433
|
-
suggested
|
|
434
|
-
)}: `,
|
|
434
|
+
`${instruction} Or hit enter to use ${blue(suggested)}: `,
|
|
435
435
|
async (input) => {
|
|
436
436
|
rl.close();
|
|
437
|
-
const result = input
|
|
438
|
-
await fs4.writeFile(path4.join(out, "stage"), result);
|
|
437
|
+
const result = input === "" ? suggested : input;
|
|
439
438
|
resolve(result);
|
|
440
439
|
}
|
|
441
440
|
);
|
|
442
441
|
});
|
|
442
|
+
if (isValidStageName(stage)) {
|
|
443
|
+
await fs4.writeFile(path4.join(out, "stage"), stage);
|
|
444
|
+
return stage;
|
|
445
|
+
}
|
|
446
|
+
return await promptPersonalStage(out, true);
|
|
443
447
|
}
|
|
444
448
|
async function findRoot() {
|
|
445
449
|
async function find2(dir) {
|
|
@@ -460,7 +464,13 @@ async function findRoot() {
|
|
|
460
464
|
const result = await find2(process.cwd());
|
|
461
465
|
return result;
|
|
462
466
|
}
|
|
463
|
-
|
|
467
|
+
function sanitizeStageName(stage) {
|
|
468
|
+
return stage.replace(/[^A-Za-z0-9-]/g, "-").replace(/--+/g, "-").replace(/^[^A-Za-z]/, "").replace(/-$/, "") || "local";
|
|
469
|
+
}
|
|
470
|
+
function isValidStageName(stage) {
|
|
471
|
+
return Boolean(stage.match(/^[A-Za-z][A-Za-z0-9-]*$/));
|
|
472
|
+
}
|
|
473
|
+
var ProjectContext, CONFIG_EXTENSIONS, exportedForTesting;
|
|
464
474
|
var init_project = __esm({
|
|
465
475
|
"src/project.ts"() {
|
|
466
476
|
"use strict";
|
|
@@ -477,6 +487,10 @@ var init_project = __esm({
|
|
|
477
487
|
".config.mjs",
|
|
478
488
|
".config.js"
|
|
479
489
|
];
|
|
490
|
+
exportedForTesting = {
|
|
491
|
+
sanitizeStageName,
|
|
492
|
+
isValidStageName
|
|
493
|
+
};
|
|
480
494
|
}
|
|
481
495
|
});
|
|
482
496
|
|
|
@@ -6523,12 +6537,12 @@ async function* scan(prefix) {
|
|
|
6523
6537
|
token = results.NextToken;
|
|
6524
6538
|
}
|
|
6525
6539
|
}
|
|
6526
|
-
function parse(ssmName) {
|
|
6527
|
-
const parts = ssmName.split("/");
|
|
6540
|
+
function parse(ssmName, prefix) {
|
|
6541
|
+
const parts = ssmName.substring(prefix.length).split("/");
|
|
6528
6542
|
return {
|
|
6529
|
-
type: parts[
|
|
6530
|
-
id: parts[
|
|
6531
|
-
prop: parts.slice(
|
|
6543
|
+
type: parts[0],
|
|
6544
|
+
id: parts[1],
|
|
6545
|
+
prop: parts.slice(2).join("/")
|
|
6532
6546
|
};
|
|
6533
6547
|
}
|
|
6534
6548
|
async function restartFunction(arn) {
|
|
@@ -6569,7 +6583,7 @@ var init_config = __esm({
|
|
|
6569
6583
|
async function parameters() {
|
|
6570
6584
|
const result = [];
|
|
6571
6585
|
for await (const p of scan(PREFIX.FALLBACK)) {
|
|
6572
|
-
const parsed = parse(p.Name);
|
|
6586
|
+
const parsed = parse(p.Name, PREFIX.FALLBACK);
|
|
6573
6587
|
if (parsed.type === "secrets")
|
|
6574
6588
|
continue;
|
|
6575
6589
|
result.push({
|
|
@@ -6578,7 +6592,7 @@ var init_config = __esm({
|
|
|
6578
6592
|
});
|
|
6579
6593
|
}
|
|
6580
6594
|
for await (const p of scan(PREFIX.STAGE)) {
|
|
6581
|
-
const parsed = parse(p.Name);
|
|
6595
|
+
const parsed = parse(p.Name, PREFIX.STAGE);
|
|
6582
6596
|
if (parsed.type === "secrets")
|
|
6583
6597
|
continue;
|
|
6584
6598
|
result.push({
|
|
@@ -6604,13 +6618,13 @@ var init_config = __esm({
|
|
|
6604
6618
|
async function secrets2() {
|
|
6605
6619
|
const result = {};
|
|
6606
6620
|
for await (const p of scan(PREFIX.STAGE + "Secret")) {
|
|
6607
|
-
const parsed = parse(p.Name);
|
|
6621
|
+
const parsed = parse(p.Name, PREFIX.STAGE);
|
|
6608
6622
|
if (!result[parsed.id])
|
|
6609
6623
|
result[parsed.id] = {};
|
|
6610
6624
|
result[parsed.id].value = p.Value;
|
|
6611
6625
|
}
|
|
6612
6626
|
for await (const p of scan(PREFIX.FALLBACK + "Secret")) {
|
|
6613
|
-
const parsed = parse(p.Name);
|
|
6627
|
+
const parsed = parse(p.Name, PREFIX.FALLBACK);
|
|
6614
6628
|
if (!result[parsed.id])
|
|
6615
6629
|
result[parsed.id] = {};
|
|
6616
6630
|
result[parsed.id].fallback = p.Value;
|
|
@@ -6721,7 +6735,7 @@ var init_config = __esm({
|
|
|
6721
6735
|
PREFIX = {
|
|
6722
6736
|
get STAGE() {
|
|
6723
6737
|
const project = useProject();
|
|
6724
|
-
return
|
|
6738
|
+
return project.config.ssmPrefix;
|
|
6725
6739
|
},
|
|
6726
6740
|
get FALLBACK() {
|
|
6727
6741
|
const project = useProject();
|