@effortless-aws/cli 0.3.0 → 0.4.0
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/dist/cli/index.js +440 -184
- package/package.json +2 -2
package/dist/cli/index.js
CHANGED
|
@@ -8,16 +8,16 @@ var __export = (target, all) => {
|
|
|
8
8
|
// src/cli/index.ts
|
|
9
9
|
import { CliConfig, Command as Command7 } from "@effect/cli";
|
|
10
10
|
import { NodeContext, NodeRuntime } from "@effect/platform-node";
|
|
11
|
-
import { Effect as
|
|
11
|
+
import { Effect as Effect45 } from "effect";
|
|
12
12
|
import { createRequire as createRequire2 } from "module";
|
|
13
13
|
|
|
14
14
|
// src/cli/commands/deploy.ts
|
|
15
15
|
import { Args, Command } from "@effect/cli";
|
|
16
|
-
import { Effect as
|
|
17
|
-
import * as
|
|
16
|
+
import { Effect as Effect38, Console as Console3, Logger, LogLevel, Option } from "effect";
|
|
17
|
+
import * as path10 from "path";
|
|
18
18
|
|
|
19
19
|
// src/deploy/deploy.ts
|
|
20
|
-
import { Effect as
|
|
20
|
+
import { Effect as Effect35, Console as Console2 } from "effect";
|
|
21
21
|
|
|
22
22
|
// src/cli/colors.ts
|
|
23
23
|
var wrap = (code) => (s) => `\x1B[${code}m${s}\x1B[0m`;
|
|
@@ -2960,6 +2960,7 @@ var syncFiles = (input) => Effect19.gen(function* () {
|
|
|
2960
2960
|
walkDir(sourceDir, "");
|
|
2961
2961
|
let uploaded = 0;
|
|
2962
2962
|
let unchanged = 0;
|
|
2963
|
+
const uploadedKeys = [];
|
|
2963
2964
|
for (const [key, filePath] of localFiles) {
|
|
2964
2965
|
const content = fs2.readFileSync(filePath);
|
|
2965
2966
|
const md5 = crypto3.createHash("md5").update(content).digest("hex");
|
|
@@ -2980,8 +2981,9 @@ var syncFiles = (input) => Effect19.gen(function* () {
|
|
|
2980
2981
|
CacheControl: cacheControl
|
|
2981
2982
|
});
|
|
2982
2983
|
uploaded++;
|
|
2984
|
+
uploadedKeys.push(key);
|
|
2983
2985
|
}
|
|
2984
|
-
const keysToDelete = [...existingObjects.keys()].filter((k) => !localFiles.has(k));
|
|
2986
|
+
const keysToDelete = [...existingObjects.keys()].filter((k) => !localFiles.has(k) && !k.startsWith("_effortless/"));
|
|
2985
2987
|
let deleted = 0;
|
|
2986
2988
|
if (keysToDelete.length > 0) {
|
|
2987
2989
|
for (let i = 0; i < keysToDelete.length; i += 1e3) {
|
|
@@ -2997,7 +2999,7 @@ var syncFiles = (input) => Effect19.gen(function* () {
|
|
|
2997
2999
|
}
|
|
2998
3000
|
}
|
|
2999
3001
|
yield* Effect19.logDebug(`S3 sync: ${uploaded} uploaded, ${deleted} deleted, ${unchanged} unchanged`);
|
|
3000
|
-
return { uploaded, deleted, unchanged };
|
|
3002
|
+
return { uploaded, deleted, unchanged, uploadedKeys };
|
|
3001
3003
|
});
|
|
3002
3004
|
var putObject = (input) => s3_exports.make("put_object", {
|
|
3003
3005
|
Bucket: input.bucketName,
|
|
@@ -4823,14 +4825,217 @@ var deployApp = (input) => Effect29.gen(function* () {
|
|
|
4823
4825
|
});
|
|
4824
4826
|
|
|
4825
4827
|
// src/deploy/deploy-static-site.ts
|
|
4826
|
-
import { Effect as
|
|
4828
|
+
import { Effect as Effect31 } from "effect";
|
|
4827
4829
|
import { Architecture as Architecture3 } from "@aws-sdk/client-lambda";
|
|
4828
4830
|
import { execSync as execSync2 } from "child_process";
|
|
4831
|
+
import * as fs5 from "fs";
|
|
4832
|
+
import * as path7 from "path";
|
|
4833
|
+
|
|
4834
|
+
// src/deploy/seo.ts
|
|
4835
|
+
import { Effect as Effect30 } from "effect";
|
|
4836
|
+
import * as fs4 from "fs";
|
|
4829
4837
|
import * as path6 from "path";
|
|
4830
|
-
|
|
4838
|
+
import * as crypto4 from "crypto";
|
|
4839
|
+
import * as os from "os";
|
|
4840
|
+
var collectHtmlPaths = (sourceDir) => {
|
|
4841
|
+
const paths = [];
|
|
4842
|
+
const walk = (dir, prefix) => {
|
|
4843
|
+
for (const entry of fs4.readdirSync(dir, { withFileTypes: true })) {
|
|
4844
|
+
const key = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
4845
|
+
if (entry.isDirectory()) {
|
|
4846
|
+
walk(path6.join(dir, entry.name), key);
|
|
4847
|
+
} else if (entry.name.endsWith(".html") || entry.name.endsWith(".htm")) {
|
|
4848
|
+
if (entry.name === "404.html" || entry.name === "500.html") continue;
|
|
4849
|
+
let urlPath = "/" + key;
|
|
4850
|
+
if (urlPath.endsWith("/index.html")) {
|
|
4851
|
+
urlPath = urlPath.slice(0, -"index.html".length);
|
|
4852
|
+
} else if (urlPath.endsWith("/index.htm")) {
|
|
4853
|
+
urlPath = urlPath.slice(0, -"index.htm".length);
|
|
4854
|
+
}
|
|
4855
|
+
paths.push(urlPath);
|
|
4856
|
+
}
|
|
4857
|
+
}
|
|
4858
|
+
};
|
|
4859
|
+
walk(sourceDir, "");
|
|
4860
|
+
return paths.sort();
|
|
4861
|
+
};
|
|
4862
|
+
var generateSitemap = (siteUrl, sourceDir) => {
|
|
4863
|
+
const baseUrl = siteUrl.replace(/\/$/, "");
|
|
4864
|
+
const paths = collectHtmlPaths(sourceDir);
|
|
4865
|
+
const urls = paths.map((urlPath) => ` <url>
|
|
4866
|
+
<loc>${baseUrl}${urlPath}</loc>
|
|
4867
|
+
</url>`).join("\n");
|
|
4868
|
+
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
4869
|
+
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
|
4870
|
+
${urls}
|
|
4871
|
+
</urlset>
|
|
4872
|
+
`;
|
|
4873
|
+
};
|
|
4874
|
+
var generateRobots = (siteUrl, sitemapName = "sitemap.xml") => {
|
|
4875
|
+
const baseUrl = siteUrl.replace(/\/$/, "");
|
|
4876
|
+
return `User-agent: *
|
|
4877
|
+
Allow: /
|
|
4878
|
+
|
|
4879
|
+
Sitemap: ${baseUrl}/${sitemapName}
|
|
4880
|
+
`;
|
|
4881
|
+
};
|
|
4882
|
+
var createJwt = (serviceAccount) => {
|
|
4883
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
4884
|
+
const header = Buffer.from(JSON.stringify({ alg: "RS256", typ: "JWT" })).toString("base64url");
|
|
4885
|
+
const payload = Buffer.from(
|
|
4886
|
+
JSON.stringify({
|
|
4887
|
+
iss: serviceAccount.client_email,
|
|
4888
|
+
scope: "https://www.googleapis.com/auth/indexing",
|
|
4889
|
+
aud: "https://oauth2.googleapis.com/token",
|
|
4890
|
+
iat: now,
|
|
4891
|
+
exp: now + 3600
|
|
4892
|
+
})
|
|
4893
|
+
).toString("base64url");
|
|
4894
|
+
const signInput = `${header}.${payload}`;
|
|
4895
|
+
const signature = crypto4.createSign("RSA-SHA256").update(signInput).sign(serviceAccount.private_key, "base64url");
|
|
4896
|
+
return `${signInput}.${signature}`;
|
|
4897
|
+
};
|
|
4898
|
+
var getAccessToken = async (serviceAccount) => {
|
|
4899
|
+
const jwt = createJwt(serviceAccount);
|
|
4900
|
+
const response = await fetch("https://oauth2.googleapis.com/token", {
|
|
4901
|
+
method: "POST",
|
|
4902
|
+
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
4903
|
+
body: `grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&assertion=${jwt}`
|
|
4904
|
+
});
|
|
4905
|
+
if (!response.ok) {
|
|
4906
|
+
const text = await response.text();
|
|
4907
|
+
throw new Error(`Failed to get Google access token: ${response.status} ${text}`);
|
|
4908
|
+
}
|
|
4909
|
+
const data = await response.json();
|
|
4910
|
+
return data.access_token;
|
|
4911
|
+
};
|
|
4912
|
+
var publishUrl = async (accessToken, url) => {
|
|
4913
|
+
const response = await fetch("https://indexing.googleapis.com/v3/urlNotifications:publish", {
|
|
4914
|
+
method: "POST",
|
|
4915
|
+
headers: {
|
|
4916
|
+
"Content-Type": "application/json",
|
|
4917
|
+
Authorization: `Bearer ${accessToken}`
|
|
4918
|
+
},
|
|
4919
|
+
body: JSON.stringify({ url, type: "URL_UPDATED" })
|
|
4920
|
+
});
|
|
4921
|
+
if (!response.ok) {
|
|
4922
|
+
const text = await response.text();
|
|
4923
|
+
return { url, ok: false, error: `${response.status} ${text}` };
|
|
4924
|
+
}
|
|
4925
|
+
return { url, ok: true };
|
|
4926
|
+
};
|
|
4927
|
+
var collectHtmlKeys = (sourceDir) => {
|
|
4928
|
+
const keys = [];
|
|
4929
|
+
const walk = (dir, prefix) => {
|
|
4930
|
+
for (const entry of fs4.readdirSync(dir, { withFileTypes: true })) {
|
|
4931
|
+
const fullPath = path6.join(dir, entry.name);
|
|
4932
|
+
const key = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
4933
|
+
if (entry.isDirectory()) {
|
|
4934
|
+
walk(fullPath, key);
|
|
4935
|
+
} else if (entry.name.endsWith(".html") || entry.name.endsWith(".htm")) {
|
|
4936
|
+
if (entry.name === "404.html" || entry.name === "500.html") continue;
|
|
4937
|
+
keys.push(key);
|
|
4938
|
+
}
|
|
4939
|
+
}
|
|
4940
|
+
};
|
|
4941
|
+
walk(sourceDir, "");
|
|
4942
|
+
return keys;
|
|
4943
|
+
};
|
|
4944
|
+
var keysToUrls = (siteUrl, keys) => {
|
|
4945
|
+
const baseUrl = siteUrl.replace(/\/$/, "");
|
|
4946
|
+
return keys.map((key) => {
|
|
4947
|
+
let urlPath = "/" + key;
|
|
4948
|
+
if (urlPath.endsWith("/index.html")) {
|
|
4949
|
+
urlPath = urlPath.slice(0, -"index.html".length);
|
|
4950
|
+
} else if (urlPath.endsWith("/index.htm")) {
|
|
4951
|
+
urlPath = urlPath.slice(0, -"index.htm".length);
|
|
4952
|
+
}
|
|
4953
|
+
return `${baseUrl}${urlPath}`;
|
|
4954
|
+
});
|
|
4955
|
+
};
|
|
4956
|
+
var INDEXED_URLS_KEY = "_effortless/indexed-urls.json";
|
|
4957
|
+
var loadIndexedUrls = (bucketName) => Effect30.gen(function* () {
|
|
4958
|
+
const result = yield* s3_exports.make("get_object", {
|
|
4959
|
+
Bucket: bucketName,
|
|
4960
|
+
Key: INDEXED_URLS_KEY
|
|
4961
|
+
}).pipe(Effect30.option);
|
|
4962
|
+
if (result._tag === "None") return /* @__PURE__ */ new Set();
|
|
4963
|
+
const body = yield* Effect30.tryPromise({
|
|
4964
|
+
try: () => result.value.Body?.transformToString("utf-8") ?? Promise.resolve("[]"),
|
|
4965
|
+
catch: () => new Error("Failed to read indexed URLs from S3")
|
|
4966
|
+
});
|
|
4967
|
+
const urls = JSON.parse(body);
|
|
4968
|
+
return new Set(urls);
|
|
4969
|
+
});
|
|
4970
|
+
var saveIndexedUrls = (bucketName, urls) => s3_exports.make("put_object", {
|
|
4971
|
+
Bucket: bucketName,
|
|
4972
|
+
Key: INDEXED_URLS_KEY,
|
|
4973
|
+
Body: JSON.stringify([...urls].sort(), null, 2),
|
|
4974
|
+
ContentType: "application/json; charset=utf-8"
|
|
4975
|
+
});
|
|
4976
|
+
var submitToGoogleIndexing = (input) => Effect30.gen(function* () {
|
|
4977
|
+
const { serviceAccountPath, projectDir, bucketName, allPageUrls } = input;
|
|
4978
|
+
const indexedUrls = yield* loadIndexedUrls(bucketName);
|
|
4979
|
+
const urlsToSubmit = allPageUrls.filter((url) => !indexedUrls.has(url));
|
|
4980
|
+
const currentUrlSet = new Set(allPageUrls);
|
|
4981
|
+
for (const url of indexedUrls) {
|
|
4982
|
+
if (!currentUrlSet.has(url)) {
|
|
4983
|
+
indexedUrls.delete(url);
|
|
4984
|
+
}
|
|
4985
|
+
}
|
|
4986
|
+
if (urlsToSubmit.length === 0) {
|
|
4987
|
+
yield* Effect30.logDebug("All pages already indexed, skipping Google Indexing API");
|
|
4988
|
+
return { submitted: 0, failed: 0, skipped: allPageUrls.length };
|
|
4989
|
+
}
|
|
4990
|
+
const expanded = serviceAccountPath.startsWith("~/") ? path6.join(os.homedir(), serviceAccountPath.slice(2)) : serviceAccountPath;
|
|
4991
|
+
const keyPath = path6.resolve(projectDir, expanded);
|
|
4992
|
+
if (!fs4.existsSync(keyPath)) {
|
|
4993
|
+
return yield* Effect30.fail(
|
|
4994
|
+
new Error(`Google service account key not found: ${keyPath}`)
|
|
4995
|
+
);
|
|
4996
|
+
}
|
|
4997
|
+
const serviceAccount = JSON.parse(fs4.readFileSync(keyPath, "utf-8"));
|
|
4998
|
+
if (!serviceAccount.client_email || !serviceAccount.private_key) {
|
|
4999
|
+
return yield* Effect30.fail(
|
|
5000
|
+
new Error(`Invalid service account key: missing client_email or private_key`)
|
|
5001
|
+
);
|
|
5002
|
+
}
|
|
5003
|
+
yield* Effect30.logDebug(`Authenticating with Google as ${serviceAccount.client_email}`);
|
|
5004
|
+
const accessToken = yield* Effect30.tryPromise({
|
|
5005
|
+
try: () => getAccessToken(serviceAccount),
|
|
5006
|
+
catch: (error) => new Error(`Google auth failed: ${error}`)
|
|
5007
|
+
});
|
|
5008
|
+
const maxUrls = Math.min(urlsToSubmit.length, 200);
|
|
5009
|
+
if (urlsToSubmit.length > 200) {
|
|
5010
|
+
yield* Effect30.logDebug(
|
|
5011
|
+
`Google Indexing API daily quota is 200. Submitting first 200 of ${urlsToSubmit.length} URLs.`
|
|
5012
|
+
);
|
|
5013
|
+
}
|
|
5014
|
+
let submitted = 0;
|
|
5015
|
+
let failed = 0;
|
|
5016
|
+
for (const url of urlsToSubmit.slice(0, maxUrls)) {
|
|
5017
|
+
const result = yield* Effect30.tryPromise({
|
|
5018
|
+
try: () => publishUrl(accessToken, url),
|
|
5019
|
+
catch: (error) => new Error(`Failed to submit ${url}: ${error}`)
|
|
5020
|
+
});
|
|
5021
|
+
if (result.ok) {
|
|
5022
|
+
submitted++;
|
|
5023
|
+
indexedUrls.add(url);
|
|
5024
|
+
} else {
|
|
5025
|
+
failed++;
|
|
5026
|
+
yield* Effect30.logDebug(`Failed to index ${result.url}: ${result.error}`);
|
|
5027
|
+
}
|
|
5028
|
+
}
|
|
5029
|
+
yield* saveIndexedUrls(bucketName, indexedUrls);
|
|
5030
|
+
yield* Effect30.logDebug(`Google Indexing: ${submitted} submitted, ${failed} failed, ${allPageUrls.length - urlsToSubmit.length} already indexed`);
|
|
5031
|
+
return { submitted, failed, skipped: allPageUrls.length - urlsToSubmit.length };
|
|
5032
|
+
});
|
|
5033
|
+
|
|
5034
|
+
// src/deploy/deploy-static-site.ts
|
|
5035
|
+
var deployMiddlewareLambda = (input) => Effect31.gen(function* () {
|
|
4831
5036
|
const { projectDir, project, stage, handlerName, file, exportName, tagCtx } = input;
|
|
4832
5037
|
const middlewareName = `${handlerName}-middleware`;
|
|
4833
|
-
yield*
|
|
5038
|
+
yield* Effect31.logDebug(`Deploying middleware Lambda@Edge: ${middlewareName}`);
|
|
4834
5039
|
const roleArn = yield* ensureEdgeRole(
|
|
4835
5040
|
project,
|
|
4836
5041
|
stage,
|
|
@@ -4856,14 +5061,14 @@ var deployMiddlewareLambda = (input) => Effect30.gen(function* () {
|
|
|
4856
5061
|
architecture: Architecture3.x86_64,
|
|
4857
5062
|
tags: makeTags(tagCtx, "lambda")
|
|
4858
5063
|
}).pipe(
|
|
4859
|
-
|
|
5064
|
+
Effect31.provide(clients_exports.makeClients({ lambda: { region: "us-east-1" } }))
|
|
4860
5065
|
);
|
|
4861
5066
|
const { versionArn } = yield* publishVersion(
|
|
4862
5067
|
`${project}-${stage}-${middlewareName}`
|
|
4863
5068
|
).pipe(
|
|
4864
|
-
|
|
5069
|
+
Effect31.provide(clients_exports.makeClients({ lambda: { region: "us-east-1" } }))
|
|
4865
5070
|
);
|
|
4866
|
-
yield*
|
|
5071
|
+
yield* Effect31.logDebug(`Middleware deployed: ${versionArn}`);
|
|
4867
5072
|
return { versionArn };
|
|
4868
5073
|
});
|
|
4869
5074
|
var ERROR_PAGE_KEY = "_effortless/404.html";
|
|
@@ -4901,7 +5106,7 @@ var generateErrorPageHtml = () => `<!DOCTYPE html>
|
|
|
4901
5106
|
</div>
|
|
4902
5107
|
</body>
|
|
4903
5108
|
</html>`;
|
|
4904
|
-
var deployStaticSite = (input) =>
|
|
5109
|
+
var deployStaticSite = (input) => Effect31.gen(function* () {
|
|
4905
5110
|
const { projectDir, project, region, fn: fn13 } = input;
|
|
4906
5111
|
const { exportName, config } = fn13;
|
|
4907
5112
|
const stage = resolveStage(input.stage);
|
|
@@ -4910,16 +5115,16 @@ var deployStaticSite = (input) => Effect30.gen(function* () {
|
|
|
4910
5115
|
const tagCtx = { project, stage, handler: handlerName };
|
|
4911
5116
|
const routePatterns = fn13.routePatterns;
|
|
4912
5117
|
if (routePatterns.length > 0 && !input.apiOriginDomain) {
|
|
4913
|
-
return yield*
|
|
5118
|
+
return yield* Effect31.fail(
|
|
4914
5119
|
new Error(
|
|
4915
5120
|
`Static site "${exportName}" has routes but no API handler was deployed. Ensure defineApi() handlers are included in the discovery patterns.`
|
|
4916
5121
|
)
|
|
4917
5122
|
);
|
|
4918
5123
|
}
|
|
4919
5124
|
if (config.build) {
|
|
4920
|
-
yield*
|
|
5125
|
+
yield* Effect31.logDebug(`Building site: ${config.build}`);
|
|
4921
5126
|
const buildStart = Date.now();
|
|
4922
|
-
yield*
|
|
5127
|
+
yield* Effect31.try({
|
|
4923
5128
|
try: () => execSync2(config.build, {
|
|
4924
5129
|
cwd: projectDir,
|
|
4925
5130
|
stdio: input.verbose ? "inherit" : "pipe"
|
|
@@ -4932,7 +5137,7 @@ var deployStaticSite = (input) => Effect30.gen(function* () {
|
|
|
4932
5137
|
return new Error(`Site build failed: ${config.build}`);
|
|
4933
5138
|
}
|
|
4934
5139
|
});
|
|
4935
|
-
yield*
|
|
5140
|
+
yield* Effect31.logDebug(`Site built in ${((Date.now() - buildStart) / 1e3).toFixed(1)}s`);
|
|
4936
5141
|
}
|
|
4937
5142
|
const bucketName = `${project}-${stage}-${handlerName}-site`.toLowerCase();
|
|
4938
5143
|
yield* ensureBucket({
|
|
@@ -4956,10 +5161,10 @@ var deployStaticSite = (input) => Effect30.gen(function* () {
|
|
|
4956
5161
|
if (certCoversWww) {
|
|
4957
5162
|
aliases = [domain, wwwCandidate];
|
|
4958
5163
|
wwwDomain = wwwCandidate;
|
|
4959
|
-
yield*
|
|
5164
|
+
yield* Effect31.logDebug(`ACM certificate covers ${wwwCandidate}, enabling www \u2192 non-www redirect`);
|
|
4960
5165
|
} else {
|
|
4961
5166
|
aliases = [domain];
|
|
4962
|
-
yield*
|
|
5167
|
+
yield* Effect31.logWarning(
|
|
4963
5168
|
`ACM certificate does not cover ${wwwCandidate}. For SEO, add ${wwwCandidate} to your ACM certificate in us-east-1 to enable www \u2192 non-www redirect.`
|
|
4964
5169
|
);
|
|
4965
5170
|
}
|
|
@@ -4980,7 +5185,7 @@ var deployStaticSite = (input) => Effect30.gen(function* () {
|
|
|
4980
5185
|
exportName,
|
|
4981
5186
|
tagCtx
|
|
4982
5187
|
}).pipe(
|
|
4983
|
-
|
|
5188
|
+
Effect31.provide(clients_exports.makeClients({ iam: { region: "us-east-1" } }))
|
|
4984
5189
|
);
|
|
4985
5190
|
lambdaEdgeArn = result.versionArn;
|
|
4986
5191
|
} else {
|
|
@@ -5015,8 +5220,32 @@ var deployStaticSite = (input) => Effect30.gen(function* () {
|
|
|
5015
5220
|
...input.apiOriginDomain && routePatterns.length > 0 ? { apiOriginDomain: input.apiOriginDomain, routePatterns } : {}
|
|
5016
5221
|
});
|
|
5017
5222
|
yield* putBucketPolicyForOAC(bucketName, distributionArn);
|
|
5018
|
-
const sourceDir =
|
|
5223
|
+
const sourceDir = path7.resolve(projectDir, config.dir);
|
|
5019
5224
|
yield* syncFiles({ bucketName, sourceDir });
|
|
5225
|
+
const seo = config.seo;
|
|
5226
|
+
const siteUrl = domain ? `https://${domain}` : `https://${domainName}`;
|
|
5227
|
+
const seoGenerated = [];
|
|
5228
|
+
if (seo) {
|
|
5229
|
+
const sitemapName = seo.sitemap;
|
|
5230
|
+
if (!fs5.existsSync(path7.join(sourceDir, sitemapName))) {
|
|
5231
|
+
const sitemap = generateSitemap(siteUrl, sourceDir);
|
|
5232
|
+
yield* putObject({
|
|
5233
|
+
bucketName,
|
|
5234
|
+
key: sitemapName,
|
|
5235
|
+
body: sitemap,
|
|
5236
|
+
contentType: "application/xml; charset=utf-8"
|
|
5237
|
+
});
|
|
5238
|
+
seoGenerated.push(sitemapName);
|
|
5239
|
+
}
|
|
5240
|
+
const robots = generateRobots(siteUrl, sitemapName);
|
|
5241
|
+
yield* putObject({
|
|
5242
|
+
bucketName,
|
|
5243
|
+
key: "robots.txt",
|
|
5244
|
+
body: robots,
|
|
5245
|
+
contentType: "text/plain; charset=utf-8"
|
|
5246
|
+
});
|
|
5247
|
+
seoGenerated.push("robots.txt");
|
|
5248
|
+
}
|
|
5020
5249
|
if (!isSpa && !config.errorPage) {
|
|
5021
5250
|
yield* putObject({
|
|
5022
5251
|
bucketName,
|
|
@@ -5026,21 +5255,33 @@ var deployStaticSite = (input) => Effect30.gen(function* () {
|
|
|
5026
5255
|
});
|
|
5027
5256
|
}
|
|
5028
5257
|
yield* invalidateDistribution(distributionId);
|
|
5029
|
-
|
|
5030
|
-
|
|
5258
|
+
let indexingResult;
|
|
5259
|
+
if (seo?.googleIndexing) {
|
|
5260
|
+
const allHtmlKeys = collectHtmlKeys(sourceDir);
|
|
5261
|
+
const allPageUrls = keysToUrls(siteUrl, allHtmlKeys);
|
|
5262
|
+
indexingResult = yield* submitToGoogleIndexing({
|
|
5263
|
+
serviceAccountPath: seo.googleIndexing,
|
|
5264
|
+
projectDir,
|
|
5265
|
+
bucketName,
|
|
5266
|
+
allPageUrls
|
|
5267
|
+
});
|
|
5268
|
+
}
|
|
5269
|
+
yield* Effect31.logDebug(`Static site deployed: ${siteUrl}`);
|
|
5031
5270
|
return {
|
|
5032
5271
|
exportName,
|
|
5033
5272
|
handlerName,
|
|
5034
|
-
url,
|
|
5273
|
+
url: siteUrl,
|
|
5035
5274
|
distributionId,
|
|
5036
|
-
bucketName
|
|
5275
|
+
bucketName,
|
|
5276
|
+
seoGenerated: seoGenerated.length > 0 ? seoGenerated : void 0,
|
|
5277
|
+
indexingResult
|
|
5037
5278
|
};
|
|
5038
5279
|
});
|
|
5039
5280
|
|
|
5040
5281
|
// src/deploy/deploy-fifo-queue.ts
|
|
5041
|
-
import { Effect as
|
|
5282
|
+
import { Effect as Effect32 } from "effect";
|
|
5042
5283
|
var FIFO_QUEUE_DEFAULT_PERMISSIONS = ["sqs:*", "logs:*"];
|
|
5043
|
-
var deployFifoQueueFunction = ({ input, fn: fn13, layerArn, external, depsEnv, depsPermissions, staticGlobs }) =>
|
|
5284
|
+
var deployFifoQueueFunction = ({ input, fn: fn13, layerArn, external, depsEnv, depsPermissions, staticGlobs }) => Effect32.gen(function* () {
|
|
5044
5285
|
const { exportName, config } = fn13;
|
|
5045
5286
|
const handlerName = exportName;
|
|
5046
5287
|
const tagCtx = {
|
|
@@ -5048,7 +5289,7 @@ var deployFifoQueueFunction = ({ input, fn: fn13, layerArn, external, depsEnv, d
|
|
|
5048
5289
|
stage: resolveStage(input.stage),
|
|
5049
5290
|
handler: handlerName
|
|
5050
5291
|
};
|
|
5051
|
-
yield*
|
|
5292
|
+
yield* Effect32.logDebug("Creating SQS FIFO queue...");
|
|
5052
5293
|
const queueName = `${input.project}-${tagCtx.stage}-${handlerName}`;
|
|
5053
5294
|
const timeout = config.timeout ?? 30;
|
|
5054
5295
|
const { queueUrl, queueArn } = yield* ensureFifoQueue({
|
|
@@ -5078,14 +5319,14 @@ var deployFifoQueueFunction = ({ input, fn: fn13, layerArn, external, depsEnv, d
|
|
|
5078
5319
|
...depsPermissions ? { depsPermissions } : {},
|
|
5079
5320
|
...staticGlobs && staticGlobs.length > 0 ? { staticGlobs } : {}
|
|
5080
5321
|
});
|
|
5081
|
-
yield*
|
|
5322
|
+
yield* Effect32.logDebug("Setting up SQS event source mapping...");
|
|
5082
5323
|
yield* ensureSqsEventSourceMapping({
|
|
5083
5324
|
functionArn,
|
|
5084
5325
|
queueArn,
|
|
5085
5326
|
batchSize: config.batchSize ?? 10,
|
|
5086
5327
|
batchWindow: config.batchWindow
|
|
5087
5328
|
});
|
|
5088
|
-
yield*
|
|
5329
|
+
yield* Effect32.logDebug(`FIFO queue deployment complete! Queue: ${queueUrl}`);
|
|
5089
5330
|
return {
|
|
5090
5331
|
exportName,
|
|
5091
5332
|
functionArn,
|
|
@@ -5096,9 +5337,9 @@ var deployFifoQueueFunction = ({ input, fn: fn13, layerArn, external, depsEnv, d
|
|
|
5096
5337
|
});
|
|
5097
5338
|
|
|
5098
5339
|
// src/deploy/deploy-bucket.ts
|
|
5099
|
-
import { Effect as
|
|
5340
|
+
import { Effect as Effect33 } from "effect";
|
|
5100
5341
|
var BUCKET_DEFAULT_PERMISSIONS = ["s3:*", "logs:*"];
|
|
5101
|
-
var deployBucketFunction = ({ input, fn: fn13, layerArn, external, depsEnv, depsPermissions, staticGlobs }) =>
|
|
5342
|
+
var deployBucketFunction = ({ input, fn: fn13, layerArn, external, depsEnv, depsPermissions, staticGlobs }) => Effect33.gen(function* () {
|
|
5102
5343
|
const { exportName, config, hasHandler } = fn13;
|
|
5103
5344
|
const handlerName = exportName;
|
|
5104
5345
|
const tagCtx = {
|
|
@@ -5106,7 +5347,7 @@ var deployBucketFunction = ({ input, fn: fn13, layerArn, external, depsEnv, deps
|
|
|
5106
5347
|
stage: resolveStage(input.stage),
|
|
5107
5348
|
handler: handlerName
|
|
5108
5349
|
};
|
|
5109
|
-
yield*
|
|
5350
|
+
yield* Effect33.logDebug("Creating S3 bucket...");
|
|
5110
5351
|
const bucketName = `${input.project}-${tagCtx.stage}-${handlerName}`;
|
|
5111
5352
|
const { bucketArn } = yield* ensureBucket({
|
|
5112
5353
|
name: bucketName,
|
|
@@ -5114,7 +5355,7 @@ var deployBucketFunction = ({ input, fn: fn13, layerArn, external, depsEnv, deps
|
|
|
5114
5355
|
tags: makeTags(tagCtx, "s3-bucket")
|
|
5115
5356
|
});
|
|
5116
5357
|
if (!hasHandler) {
|
|
5117
|
-
yield*
|
|
5358
|
+
yield* Effect33.logDebug(`Bucket deployment complete (resource-only)! Bucket: ${bucketName}`);
|
|
5118
5359
|
return {
|
|
5119
5360
|
exportName,
|
|
5120
5361
|
status: "resource-only",
|
|
@@ -5146,7 +5387,7 @@ var deployBucketFunction = ({ input, fn: fn13, layerArn, external, depsEnv, deps
|
|
|
5146
5387
|
prefix: config.prefix,
|
|
5147
5388
|
suffix: config.suffix
|
|
5148
5389
|
});
|
|
5149
|
-
yield*
|
|
5390
|
+
yield* Effect33.logDebug(`Bucket deployment complete! Bucket: ${bucketName}`);
|
|
5150
5391
|
return {
|
|
5151
5392
|
exportName,
|
|
5152
5393
|
functionArn,
|
|
@@ -5157,8 +5398,8 @@ var deployBucketFunction = ({ input, fn: fn13, layerArn, external, depsEnv, deps
|
|
|
5157
5398
|
});
|
|
5158
5399
|
|
|
5159
5400
|
// src/deploy/deploy-mailer.ts
|
|
5160
|
-
import { Effect as
|
|
5161
|
-
var deployMailer = ({ project, stage, region, fn: fn13 }) =>
|
|
5401
|
+
import { Effect as Effect34, Console } from "effect";
|
|
5402
|
+
var deployMailer = ({ project, stage, region, fn: fn13 }) => Effect34.gen(function* () {
|
|
5162
5403
|
const { exportName, config } = fn13;
|
|
5163
5404
|
const handlerName = exportName;
|
|
5164
5405
|
const resolvedStage = resolveStage(stage);
|
|
@@ -5167,7 +5408,7 @@ var deployMailer = ({ project, stage, region, fn: fn13 }) => Effect33.gen(functi
|
|
|
5167
5408
|
stage: resolvedStage,
|
|
5168
5409
|
handler: handlerName
|
|
5169
5410
|
};
|
|
5170
|
-
yield*
|
|
5411
|
+
yield* Effect34.logDebug(`Ensuring SES identity for ${config.domain}...`);
|
|
5171
5412
|
const { domain, verified, dkimRecords } = yield* ensureSesIdentity({
|
|
5172
5413
|
domain: config.domain,
|
|
5173
5414
|
tags: makeTags(tagCtx, "ses")
|
|
@@ -5231,7 +5472,7 @@ var createLiveProgress = (manifest) => {
|
|
|
5231
5472
|
const sec = ((Date.now() - startTime) / 1e3).toFixed(1);
|
|
5232
5473
|
return c.dim(`${sec}s`);
|
|
5233
5474
|
};
|
|
5234
|
-
return (name, type, status) =>
|
|
5475
|
+
return (name, type, status) => Effect35.sync(() => {
|
|
5235
5476
|
const key = `${name}:${type}`;
|
|
5236
5477
|
results.set(key, status);
|
|
5237
5478
|
const line = ` ${name} ${c.dim(`(${type})`)} ${statusLabel(status)} ${formatDuration()}`;
|
|
@@ -5249,27 +5490,27 @@ var createLiveProgress = (manifest) => {
|
|
|
5249
5490
|
});
|
|
5250
5491
|
};
|
|
5251
5492
|
var DEPLOY_CONCURRENCY = 5;
|
|
5252
|
-
var prepareLayer = (input) =>
|
|
5493
|
+
var prepareLayer = (input) => Effect35.gen(function* () {
|
|
5253
5494
|
const layerResult = yield* ensureLayer({
|
|
5254
5495
|
project: input.project,
|
|
5255
5496
|
stage: input.stage,
|
|
5256
5497
|
region: input.region,
|
|
5257
5498
|
projectDir: input.packageDir
|
|
5258
5499
|
}).pipe(
|
|
5259
|
-
|
|
5500
|
+
Effect35.provide(
|
|
5260
5501
|
clients_exports.makeClients({
|
|
5261
5502
|
lambda: { region: input.region }
|
|
5262
5503
|
})
|
|
5263
5504
|
)
|
|
5264
5505
|
);
|
|
5265
5506
|
const prodDeps = layerResult ? yield* readProductionDependencies(input.packageDir) : [];
|
|
5266
|
-
const { packages: external, warnings: layerWarnings } = prodDeps.length > 0 ? yield*
|
|
5507
|
+
const { packages: external, warnings: layerWarnings } = prodDeps.length > 0 ? yield* Effect35.sync(() => collectLayerPackages(input.packageDir, prodDeps)) : { packages: [], warnings: [] };
|
|
5267
5508
|
for (const warning of layerWarnings) {
|
|
5268
|
-
yield*
|
|
5509
|
+
yield* Effect35.logWarning(`[layer] ${warning}`);
|
|
5269
5510
|
}
|
|
5270
|
-
yield*
|
|
5511
|
+
yield* Effect35.logDebug(`Layer result: ${layerResult ? "exists" : "null"}, external packages: ${external.length}`);
|
|
5271
5512
|
if (external.length > 0) {
|
|
5272
|
-
yield*
|
|
5513
|
+
yield* Effect35.logDebug(`Bundling with ${external.length} external packages from layer`);
|
|
5273
5514
|
}
|
|
5274
5515
|
return {
|
|
5275
5516
|
layerArn: layerResult?.layerVersionArn,
|
|
@@ -5425,7 +5666,7 @@ var buildTableTasks = (ctx, handlers, results) => {
|
|
|
5425
5666
|
for (const { file, exports } of handlers) {
|
|
5426
5667
|
for (const fn13 of exports) {
|
|
5427
5668
|
tasks.push(
|
|
5428
|
-
|
|
5669
|
+
Effect35.gen(function* () {
|
|
5429
5670
|
const env = resolveHandlerEnv(fn13.depsKeys, fn13.paramEntries, ctx);
|
|
5430
5671
|
const result = yield* deployTableFunction({
|
|
5431
5672
|
input: makeDeployInput(ctx, file),
|
|
@@ -5435,7 +5676,7 @@ var buildTableTasks = (ctx, handlers, results) => {
|
|
|
5435
5676
|
depsEnv: env.depsEnv,
|
|
5436
5677
|
depsPermissions: env.depsPermissions,
|
|
5437
5678
|
...fn13.staticGlobs.length > 0 ? { staticGlobs: fn13.staticGlobs } : {}
|
|
5438
|
-
}).pipe(
|
|
5679
|
+
}).pipe(Effect35.provide(clients_exports.makeClients({ lambda: { region }, iam: { region }, dynamodb: { region } })));
|
|
5439
5680
|
results.push(result);
|
|
5440
5681
|
yield* ctx.logComplete(fn13.exportName, "table", result.status);
|
|
5441
5682
|
})
|
|
@@ -5450,7 +5691,7 @@ var buildAppTasks = (ctx, handlers, results, apiOriginDomain) => {
|
|
|
5450
5691
|
for (const { exports } of handlers) {
|
|
5451
5692
|
for (const fn13 of exports) {
|
|
5452
5693
|
tasks.push(
|
|
5453
|
-
|
|
5694
|
+
Effect35.gen(function* () {
|
|
5454
5695
|
const result = yield* deployApp({
|
|
5455
5696
|
projectDir: ctx.input.projectDir,
|
|
5456
5697
|
project: ctx.input.project,
|
|
@@ -5459,7 +5700,7 @@ var buildAppTasks = (ctx, handlers, results, apiOriginDomain) => {
|
|
|
5459
5700
|
fn: fn13,
|
|
5460
5701
|
verbose: ctx.input.verbose,
|
|
5461
5702
|
...apiOriginDomain ? { apiOriginDomain } : {}
|
|
5462
|
-
}).pipe(
|
|
5703
|
+
}).pipe(Effect35.provide(clients_exports.makeClients({
|
|
5463
5704
|
lambda: { region },
|
|
5464
5705
|
iam: { region },
|
|
5465
5706
|
s3: { region },
|
|
@@ -5481,7 +5722,7 @@ var buildStaticSiteTasks = (ctx, handlers, results, apiOriginDomain) => {
|
|
|
5481
5722
|
for (const { file, exports } of handlers) {
|
|
5482
5723
|
for (const fn13 of exports) {
|
|
5483
5724
|
tasks.push(
|
|
5484
|
-
|
|
5725
|
+
Effect35.gen(function* () {
|
|
5485
5726
|
const result = yield* deployStaticSite({
|
|
5486
5727
|
projectDir: ctx.input.projectDir,
|
|
5487
5728
|
project: ctx.input.project,
|
|
@@ -5491,7 +5732,7 @@ var buildStaticSiteTasks = (ctx, handlers, results, apiOriginDomain) => {
|
|
|
5491
5732
|
verbose: ctx.input.verbose,
|
|
5492
5733
|
...fn13.hasHandler ? { file } : {},
|
|
5493
5734
|
...apiOriginDomain ? { apiOriginDomain } : {}
|
|
5494
|
-
}).pipe(
|
|
5735
|
+
}).pipe(Effect35.provide(clients_exports.makeClients({
|
|
5495
5736
|
s3: { region },
|
|
5496
5737
|
cloudfront: { region: "us-east-1" },
|
|
5497
5738
|
resource_groups_tagging_api: { region: "us-east-1" },
|
|
@@ -5511,7 +5752,7 @@ var buildFifoQueueTasks = (ctx, handlers, results) => {
|
|
|
5511
5752
|
for (const { file, exports } of handlers) {
|
|
5512
5753
|
for (const fn13 of exports) {
|
|
5513
5754
|
tasks.push(
|
|
5514
|
-
|
|
5755
|
+
Effect35.gen(function* () {
|
|
5515
5756
|
const env = resolveHandlerEnv(fn13.depsKeys, fn13.paramEntries, ctx);
|
|
5516
5757
|
const result = yield* deployFifoQueueFunction({
|
|
5517
5758
|
input: makeDeployInput(ctx, file),
|
|
@@ -5521,7 +5762,7 @@ var buildFifoQueueTasks = (ctx, handlers, results) => {
|
|
|
5521
5762
|
depsEnv: env.depsEnv,
|
|
5522
5763
|
depsPermissions: env.depsPermissions,
|
|
5523
5764
|
...fn13.staticGlobs.length > 0 ? { staticGlobs: fn13.staticGlobs } : {}
|
|
5524
|
-
}).pipe(
|
|
5765
|
+
}).pipe(Effect35.provide(clients_exports.makeClients({ lambda: { region }, iam: { region }, sqs: { region } })));
|
|
5525
5766
|
results.push(result);
|
|
5526
5767
|
yield* ctx.logComplete(fn13.exportName, "queue", result.status);
|
|
5527
5768
|
})
|
|
@@ -5536,7 +5777,7 @@ var buildBucketTasks = (ctx, handlers, results) => {
|
|
|
5536
5777
|
for (const { file, exports } of handlers) {
|
|
5537
5778
|
for (const fn13 of exports) {
|
|
5538
5779
|
tasks.push(
|
|
5539
|
-
|
|
5780
|
+
Effect35.gen(function* () {
|
|
5540
5781
|
const env = resolveHandlerEnv(fn13.depsKeys, fn13.paramEntries, ctx);
|
|
5541
5782
|
const result = yield* deployBucketFunction({
|
|
5542
5783
|
input: makeDeployInput(ctx, file),
|
|
@@ -5546,7 +5787,7 @@ var buildBucketTasks = (ctx, handlers, results) => {
|
|
|
5546
5787
|
depsEnv: env.depsEnv,
|
|
5547
5788
|
depsPermissions: env.depsPermissions,
|
|
5548
5789
|
...fn13.staticGlobs.length > 0 ? { staticGlobs: fn13.staticGlobs } : {}
|
|
5549
|
-
}).pipe(
|
|
5790
|
+
}).pipe(Effect35.provide(clients_exports.makeClients({ lambda: { region }, iam: { region }, s3: { region } })));
|
|
5550
5791
|
results.push(result);
|
|
5551
5792
|
const status = result.status === "resource-only" ? "created" : result.status;
|
|
5552
5793
|
yield* ctx.logComplete(fn13.exportName, "bucket", status);
|
|
@@ -5562,13 +5803,13 @@ var buildMailerTasks = (ctx, handlers, results) => {
|
|
|
5562
5803
|
for (const { exports } of handlers) {
|
|
5563
5804
|
for (const fn13 of exports) {
|
|
5564
5805
|
tasks.push(
|
|
5565
|
-
|
|
5806
|
+
Effect35.gen(function* () {
|
|
5566
5807
|
const result = yield* deployMailer({
|
|
5567
5808
|
project: ctx.input.project,
|
|
5568
5809
|
stage: ctx.input.stage,
|
|
5569
5810
|
region,
|
|
5570
5811
|
fn: fn13
|
|
5571
|
-
}).pipe(
|
|
5812
|
+
}).pipe(Effect35.provide(clients_exports.makeClients({ sesv2: { region } })));
|
|
5572
5813
|
results.push(result);
|
|
5573
5814
|
yield* ctx.logComplete(fn13.exportName, "mailer", result.verified ? "unchanged" : "created");
|
|
5574
5815
|
})
|
|
@@ -5583,7 +5824,7 @@ var buildApiTasks = (ctx, handlers, results) => {
|
|
|
5583
5824
|
for (const { file, exports } of handlers) {
|
|
5584
5825
|
for (const fn13 of exports) {
|
|
5585
5826
|
tasks.push(
|
|
5586
|
-
|
|
5827
|
+
Effect35.gen(function* () {
|
|
5587
5828
|
const env = resolveHandlerEnv(fn13.depsKeys, fn13.paramEntries, ctx);
|
|
5588
5829
|
const { exportName, functionArn, status, handlerName } = yield* deployApiFunction({
|
|
5589
5830
|
input: makeDeployInput(ctx, file),
|
|
@@ -5593,13 +5834,13 @@ var buildApiTasks = (ctx, handlers, results) => {
|
|
|
5593
5834
|
depsEnv: env.depsEnv,
|
|
5594
5835
|
depsPermissions: env.depsPermissions,
|
|
5595
5836
|
...fn13.staticGlobs.length > 0 ? { staticGlobs: fn13.staticGlobs } : {}
|
|
5596
|
-
}).pipe(
|
|
5837
|
+
}).pipe(Effect35.provide(clients_exports.makeClients({ lambda: { region }, iam: { region } })));
|
|
5597
5838
|
const lambdaName = `${ctx.input.project}-${ctx.stage}-${handlerName}`;
|
|
5598
5839
|
const { functionUrl } = yield* ensureFunctionUrl(lambdaName).pipe(
|
|
5599
|
-
|
|
5840
|
+
Effect35.provide(clients_exports.makeClients({ lambda: { region } }))
|
|
5600
5841
|
);
|
|
5601
5842
|
yield* addFunctionUrlPublicAccess(lambdaName).pipe(
|
|
5602
|
-
|
|
5843
|
+
Effect35.provide(clients_exports.makeClients({ lambda: { region } }))
|
|
5603
5844
|
);
|
|
5604
5845
|
results.push({ exportName, url: functionUrl, functionArn });
|
|
5605
5846
|
yield* ctx.logComplete(exportName, "api", status);
|
|
@@ -5609,13 +5850,13 @@ var buildApiTasks = (ctx, handlers, results) => {
|
|
|
5609
5850
|
}
|
|
5610
5851
|
return tasks;
|
|
5611
5852
|
};
|
|
5612
|
-
var deployProject = (input) =>
|
|
5853
|
+
var deployProject = (input) => Effect35.gen(function* () {
|
|
5613
5854
|
const stage = resolveStage(input.stage);
|
|
5614
5855
|
const files = findHandlerFiles(input.patterns, input.projectDir);
|
|
5615
5856
|
if (files.length === 0) {
|
|
5616
|
-
return yield*
|
|
5857
|
+
return yield* Effect35.fail(new Error(`No files match patterns: ${input.patterns.join(", ")}`));
|
|
5617
5858
|
}
|
|
5618
|
-
yield*
|
|
5859
|
+
yield* Effect35.logDebug(`Found ${files.length} file(s) matching patterns`);
|
|
5619
5860
|
const { tableHandlers, appHandlers, staticSiteHandlers, fifoQueueHandlers, bucketHandlers, mailerHandlers, apiHandlers } = discoverHandlers(files);
|
|
5620
5861
|
const totalTableHandlers = tableHandlers.reduce((acc, h) => acc + h.exports.length, 0);
|
|
5621
5862
|
const totalAppHandlers = appHandlers.reduce((acc, h) => acc + h.exports.length, 0);
|
|
@@ -5626,7 +5867,7 @@ var deployProject = (input) => Effect34.gen(function* () {
|
|
|
5626
5867
|
const totalApiHandlers = apiHandlers.reduce((acc, h) => acc + h.exports.length, 0);
|
|
5627
5868
|
const totalAllHandlers = totalTableHandlers + totalAppHandlers + totalStaticSiteHandlers + totalFifoQueueHandlers + totalBucketHandlers + totalMailerHandlers + totalApiHandlers;
|
|
5628
5869
|
if (totalAllHandlers === 0) {
|
|
5629
|
-
return yield*
|
|
5870
|
+
return yield* Effect35.fail(new Error("No handlers found in matched files"));
|
|
5630
5871
|
}
|
|
5631
5872
|
const parts = [];
|
|
5632
5873
|
if (totalTableHandlers > 0) parts.push(`${totalTableHandlers} table`);
|
|
@@ -5642,7 +5883,7 @@ var deployProject = (input) => Effect34.gen(function* () {
|
|
|
5642
5883
|
const requiredParams = collectRequiredParams(discovered, input.project, stage);
|
|
5643
5884
|
if (requiredParams.length > 0) {
|
|
5644
5885
|
const { missing } = yield* checkMissingParams(requiredParams).pipe(
|
|
5645
|
-
|
|
5886
|
+
Effect35.provide(clients_exports.makeClients({ ssm: { region: input.region } }))
|
|
5646
5887
|
);
|
|
5647
5888
|
if (missing.length > 0) {
|
|
5648
5889
|
yield* Console2.log(`
|
|
@@ -5664,14 +5905,15 @@ var deployProject = (input) => Effect34.gen(function* () {
|
|
|
5664
5905
|
for (const err of depsErrors) {
|
|
5665
5906
|
yield* Console2.log(` ${c.red("\u2717")} ${err}`);
|
|
5666
5907
|
}
|
|
5667
|
-
return yield*
|
|
5908
|
+
return yield* Effect35.fail(new Error("Unresolved deps \u2014 aborting deploy"));
|
|
5668
5909
|
}
|
|
5669
|
-
const
|
|
5910
|
+
const needsLambda = totalTableHandlers + totalAppHandlers + totalFifoQueueHandlers + totalBucketHandlers + totalMailerHandlers + totalApiHandlers > 0;
|
|
5911
|
+
const { layerArn, layerVersion, layerStatus, external } = needsLambda ? yield* prepareLayer({
|
|
5670
5912
|
project: input.project,
|
|
5671
5913
|
stage,
|
|
5672
5914
|
region: input.region,
|
|
5673
5915
|
packageDir: input.packageDir ?? input.projectDir
|
|
5674
|
-
});
|
|
5916
|
+
}) : { layerArn: void 0, layerVersion: void 0, layerStatus: void 0, external: [] };
|
|
5675
5917
|
if (layerArn && layerStatus) {
|
|
5676
5918
|
const status = layerStatus === "cached" ? c.dim("cached") : c.green("created");
|
|
5677
5919
|
yield* Console2.log(` ${c.dim("Layer:")} ${status} ${c.dim(`v${layerVersion}`)} (${external.length} packages)`);
|
|
@@ -5728,7 +5970,7 @@ var deployProject = (input) => Effect34.gen(function* () {
|
|
|
5728
5970
|
...buildBucketTasks(ctx, bucketHandlers, bucketResults),
|
|
5729
5971
|
...buildMailerTasks(ctx, mailerHandlers, mailerResults)
|
|
5730
5972
|
];
|
|
5731
|
-
yield*
|
|
5973
|
+
yield* Effect35.all(phase1Tasks, { concurrency: DEPLOY_CONCURRENCY, discard: true });
|
|
5732
5974
|
const firstApiUrl = apiResults[0]?.url;
|
|
5733
5975
|
const apiOriginDomain = firstApiUrl ? firstApiUrl.replace("https://", "").replace(/\/$/, "") : void 0;
|
|
5734
5976
|
const phase2Tasks = [
|
|
@@ -5736,7 +5978,7 @@ var deployProject = (input) => Effect34.gen(function* () {
|
|
|
5736
5978
|
...input.noSites ? [] : buildStaticSiteTasks(ctx, staticSiteHandlers, staticSiteResults, apiOriginDomain)
|
|
5737
5979
|
];
|
|
5738
5980
|
if (phase2Tasks.length > 0) {
|
|
5739
|
-
yield*
|
|
5981
|
+
yield* Effect35.all(phase2Tasks, { concurrency: DEPLOY_CONCURRENCY, discard: true });
|
|
5740
5982
|
}
|
|
5741
5983
|
} else {
|
|
5742
5984
|
const tasks = [
|
|
@@ -5748,16 +5990,16 @@ var deployProject = (input) => Effect34.gen(function* () {
|
|
|
5748
5990
|
...buildBucketTasks(ctx, bucketHandlers, bucketResults),
|
|
5749
5991
|
...buildMailerTasks(ctx, mailerHandlers, mailerResults)
|
|
5750
5992
|
];
|
|
5751
|
-
yield*
|
|
5993
|
+
yield* Effect35.all(tasks, { concurrency: DEPLOY_CONCURRENCY, discard: true });
|
|
5752
5994
|
}
|
|
5753
5995
|
if (!input.noSites && staticSiteResults.length > 0 || appResults.length > 0) {
|
|
5754
5996
|
yield* cleanupOrphanedFunctions(input.project, stage).pipe(
|
|
5755
|
-
|
|
5997
|
+
Effect35.provide(clients_exports.makeClients({
|
|
5756
5998
|
cloudfront: { region: "us-east-1" },
|
|
5757
5999
|
resource_groups_tagging_api: { region: "us-east-1" }
|
|
5758
6000
|
})),
|
|
5759
|
-
|
|
5760
|
-
(error) =>
|
|
6001
|
+
Effect35.catchAll(
|
|
6002
|
+
(error) => Effect35.logDebug(`CloudFront Function cleanup failed (non-fatal): ${error}`)
|
|
5761
6003
|
)
|
|
5762
6004
|
);
|
|
5763
6005
|
}
|
|
@@ -5766,17 +6008,17 @@ var deployProject = (input) => Effect34.gen(function* () {
|
|
|
5766
6008
|
|
|
5767
6009
|
// src/cli/config.ts
|
|
5768
6010
|
import { Options } from "@effect/cli";
|
|
5769
|
-
import * as
|
|
5770
|
-
import * as
|
|
6011
|
+
import * as path8 from "path";
|
|
6012
|
+
import * as fs6 from "fs";
|
|
5771
6013
|
import { pathToFileURL } from "url";
|
|
5772
6014
|
import * as esbuild2 from "esbuild";
|
|
5773
|
-
import { Effect as
|
|
5774
|
-
var loadConfig =
|
|
5775
|
-
const configPath =
|
|
5776
|
-
if (!
|
|
6015
|
+
import { Effect as Effect36 } from "effect";
|
|
6016
|
+
var loadConfig = Effect36.fn("loadConfig")(function* () {
|
|
6017
|
+
const configPath = path8.resolve(process.cwd(), "effortless.config.ts");
|
|
6018
|
+
if (!fs6.existsSync(configPath)) {
|
|
5777
6019
|
return null;
|
|
5778
6020
|
}
|
|
5779
|
-
const result = yield*
|
|
6021
|
+
const result = yield* Effect36.tryPromise({
|
|
5780
6022
|
try: () => esbuild2.build({
|
|
5781
6023
|
entryPoints: [configPath],
|
|
5782
6024
|
bundle: true,
|
|
@@ -5792,12 +6034,12 @@ var loadConfig = Effect35.fn("loadConfig")(function* () {
|
|
|
5792
6034
|
return null;
|
|
5793
6035
|
}
|
|
5794
6036
|
const code = output.text;
|
|
5795
|
-
const tempFile =
|
|
5796
|
-
|
|
5797
|
-
const mod = yield*
|
|
6037
|
+
const tempFile = path8.join(process.cwd(), ".effortless-config.mjs");
|
|
6038
|
+
fs6.writeFileSync(tempFile, code);
|
|
6039
|
+
const mod = yield* Effect36.tryPromise({
|
|
5798
6040
|
try: () => import(pathToFileURL(tempFile).href),
|
|
5799
6041
|
catch: (error) => new Error(`Failed to load config: ${error}`)
|
|
5800
|
-
}).pipe(
|
|
6042
|
+
}).pipe(Effect36.ensuring(Effect36.sync(() => fs6.unlinkSync(tempFile))));
|
|
5801
6043
|
return mod.default;
|
|
5802
6044
|
});
|
|
5803
6045
|
var projectOption = Options.text("project").pipe(
|
|
@@ -5848,15 +6090,15 @@ var getPatternsFromConfig = (config) => {
|
|
|
5848
6090
|
// src/cli/project-config.ts
|
|
5849
6091
|
import * as Context13 from "effect/Context";
|
|
5850
6092
|
import * as Layer14 from "effect/Layer";
|
|
5851
|
-
import * as
|
|
5852
|
-
import * as
|
|
6093
|
+
import * as Effect37 from "effect/Effect";
|
|
6094
|
+
import * as path9 from "path";
|
|
5853
6095
|
var ProjectConfig = class _ProjectConfig extends Context13.Tag("ProjectConfig")() {
|
|
5854
6096
|
static Live = Layer14.effect(
|
|
5855
6097
|
_ProjectConfig,
|
|
5856
|
-
|
|
6098
|
+
Effect37.gen(function* () {
|
|
5857
6099
|
const config = yield* loadConfig();
|
|
5858
6100
|
const cwd = process.cwd();
|
|
5859
|
-
const projectDir = config?.root ?
|
|
6101
|
+
const projectDir = config?.root ? path9.resolve(cwd, config.root) : cwd;
|
|
5860
6102
|
return { config, cwd, projectDir };
|
|
5861
6103
|
})
|
|
5862
6104
|
);
|
|
@@ -5873,7 +6115,7 @@ var isFilePath = (target) => {
|
|
|
5873
6115
|
var deployCommand = Command.make(
|
|
5874
6116
|
"deploy",
|
|
5875
6117
|
{ target: deployTargetArg, project: projectOption, stage: stageOption, region: regionOption, verbose: verboseOption, noSites: noSitesOption },
|
|
5876
|
-
({ target, project: projectOpt, stage, region, verbose, noSites }) =>
|
|
6118
|
+
({ target, project: projectOpt, stage, region, verbose, noSites }) => Effect38.gen(function* () {
|
|
5877
6119
|
const { config, cwd, projectDir } = yield* ProjectConfig;
|
|
5878
6120
|
const project = Option.getOrElse(projectOpt, () => config?.name ?? "");
|
|
5879
6121
|
const finalStage = config?.stage ?? stage;
|
|
@@ -5893,7 +6135,7 @@ var deployCommand = Command.make(
|
|
|
5893
6135
|
});
|
|
5894
6136
|
const logLevel = verbose ? LogLevel.Debug : LogLevel.Warning;
|
|
5895
6137
|
yield* Option.match(target, {
|
|
5896
|
-
onNone: () =>
|
|
6138
|
+
onNone: () => Effect38.gen(function* () {
|
|
5897
6139
|
const patterns = getPatternsFromConfig(config);
|
|
5898
6140
|
if (!patterns) {
|
|
5899
6141
|
yield* Console3.error("Error: No target specified and no 'handlers' patterns in config");
|
|
@@ -5923,16 +6165,30 @@ ${c.green(`Deployed ${total} handler(s):`)}`);
|
|
|
5923
6165
|
summaryLines.push({ name: r.exportName, line: ` ${c.cyan("[api]")} ${c.bold(r.exportName)} ${c.dim(r.url)}` });
|
|
5924
6166
|
}
|
|
5925
6167
|
for (const r of results.staticSiteResults) {
|
|
5926
|
-
|
|
6168
|
+
let line = ` ${c.cyan("[site]")} ${c.bold(r.exportName)}: ${c.cyan(r.url)}`;
|
|
6169
|
+
const extras = [];
|
|
6170
|
+
if (r.seoGenerated) extras.push(`seo: ${r.seoGenerated.join(", ")}`);
|
|
6171
|
+
if (r.indexingResult) {
|
|
6172
|
+
const { submitted, skipped, failed } = r.indexingResult;
|
|
6173
|
+
if (submitted > 0 || failed > 0) {
|
|
6174
|
+
const parts = [`${submitted} submitted`];
|
|
6175
|
+
if (failed > 0) parts.push(c.red(`${failed} failed`));
|
|
6176
|
+
extras.push(`indexing: ${parts.join(", ")}`);
|
|
6177
|
+
} else {
|
|
6178
|
+
extras.push(`indexing: all ${skipped} pages already indexed`);
|
|
6179
|
+
}
|
|
6180
|
+
}
|
|
6181
|
+
if (extras.length > 0) line += ` ${c.dim(extras.join(" | "))}`;
|
|
6182
|
+
summaryLines.push({ name: r.exportName, line });
|
|
5927
6183
|
}
|
|
5928
6184
|
summaryLines.sort((a, b) => a.name.localeCompare(b.name));
|
|
5929
6185
|
for (const { line } of summaryLines) {
|
|
5930
6186
|
yield* Console3.log(line);
|
|
5931
6187
|
}
|
|
5932
6188
|
}),
|
|
5933
|
-
onSome: (targetValue) =>
|
|
6189
|
+
onSome: (targetValue) => Effect38.gen(function* () {
|
|
5934
6190
|
if (isFilePath(targetValue)) {
|
|
5935
|
-
const fullPath =
|
|
6191
|
+
const fullPath = path10.isAbsolute(targetValue) ? targetValue : path10.resolve(projectDir, targetValue);
|
|
5936
6192
|
const input = {
|
|
5937
6193
|
projectDir,
|
|
5938
6194
|
packageDir: cwd,
|
|
@@ -5942,9 +6198,9 @@ ${c.green(`Deployed ${total} handler(s):`)}`);
|
|
|
5942
6198
|
region: finalRegion
|
|
5943
6199
|
};
|
|
5944
6200
|
const tableResults = yield* deployAllTables(input).pipe(
|
|
5945
|
-
|
|
6201
|
+
Effect38.catchIf(
|
|
5946
6202
|
(e) => e instanceof Error && e.message.includes("No defineTable"),
|
|
5947
|
-
() =>
|
|
6203
|
+
() => Effect38.succeed([])
|
|
5948
6204
|
)
|
|
5949
6205
|
);
|
|
5950
6206
|
if (tableResults.length === 0) {
|
|
@@ -5979,7 +6235,7 @@ Deployed ${tableResults.length} table handler(s):`));
|
|
|
5979
6235
|
const foundFile = found.file;
|
|
5980
6236
|
const foundExport = found.exportName;
|
|
5981
6237
|
const handlerType = found.type;
|
|
5982
|
-
yield* Console3.log(`Found handler ${c.bold(targetValue)} in ${c.dim(
|
|
6238
|
+
yield* Console3.log(`Found handler ${c.bold(targetValue)} in ${c.dim(path10.relative(projectDir, foundFile))}`);
|
|
5983
6239
|
const input = {
|
|
5984
6240
|
projectDir,
|
|
5985
6241
|
packageDir: cwd,
|
|
@@ -6001,15 +6257,15 @@ ${c.green("Deployed:")} ${c.cyan(result.url)}`);
|
|
|
6001
6257
|
}
|
|
6002
6258
|
})
|
|
6003
6259
|
}).pipe(
|
|
6004
|
-
|
|
6260
|
+
Effect38.provide(clientsLayer),
|
|
6005
6261
|
Logger.withMinimumLogLevel(logLevel)
|
|
6006
6262
|
);
|
|
6007
|
-
}).pipe(
|
|
6263
|
+
}).pipe(Effect38.provide(ProjectConfig.Live))
|
|
6008
6264
|
).pipe(Command.withDescription("Deploy handlers to AWS Lambda. Accepts a handler name, file path, or deploys all from config"));
|
|
6009
6265
|
|
|
6010
6266
|
// src/cli/commands/status.ts
|
|
6011
6267
|
import { Command as Command2 } from "@effect/cli";
|
|
6012
|
-
import { Effect as
|
|
6268
|
+
import { Effect as Effect39, Console as Console4, Logger as Logger2, LogLevel as LogLevel2, Option as Option2 } from "effect";
|
|
6013
6269
|
var { lambda } = clients_exports;
|
|
6014
6270
|
var INTERNAL_HANDLERS = /* @__PURE__ */ new Set(["api", "platform"]);
|
|
6015
6271
|
var extractFunctionName = (arn) => {
|
|
@@ -6030,7 +6286,7 @@ var formatDate = (date) => {
|
|
|
6030
6286
|
if (days < 7) return `${days}d ago`;
|
|
6031
6287
|
return d.toLocaleDateString("en-US", { month: "short", day: "numeric" });
|
|
6032
6288
|
};
|
|
6033
|
-
var getLambdaDetails = (functionName) =>
|
|
6289
|
+
var getLambdaDetails = (functionName) => Effect39.gen(function* () {
|
|
6034
6290
|
const config = yield* lambda.make("get_function_configuration", {
|
|
6035
6291
|
FunctionName: functionName
|
|
6036
6292
|
});
|
|
@@ -6040,7 +6296,7 @@ var getLambdaDetails = (functionName) => Effect38.gen(function* () {
|
|
|
6040
6296
|
timeout: config.Timeout
|
|
6041
6297
|
};
|
|
6042
6298
|
}).pipe(
|
|
6043
|
-
|
|
6299
|
+
Effect39.catchAll(() => Effect39.succeed({}))
|
|
6044
6300
|
);
|
|
6045
6301
|
var discoverCodeHandlers = (projectDir, patterns) => {
|
|
6046
6302
|
const files = findHandlerFiles(patterns, projectDir);
|
|
@@ -6092,9 +6348,9 @@ var STATUS_COLORS = {
|
|
|
6092
6348
|
var formatStatus = (status) => {
|
|
6093
6349
|
return STATUS_COLORS[status](status.padEnd(10));
|
|
6094
6350
|
};
|
|
6095
|
-
var formatRoute = (method,
|
|
6096
|
-
if (method &&
|
|
6097
|
-
if (
|
|
6351
|
+
var formatRoute = (method, path12) => {
|
|
6352
|
+
if (method && path12) return `${method.padEnd(5)} ${path12}`;
|
|
6353
|
+
if (path12) return path12;
|
|
6098
6354
|
return "";
|
|
6099
6355
|
};
|
|
6100
6356
|
var formatEntry = (entry) => {
|
|
@@ -6116,7 +6372,7 @@ var formatEntry = (entry) => {
|
|
|
6116
6372
|
var statusCommand = Command2.make(
|
|
6117
6373
|
"status",
|
|
6118
6374
|
{ project: projectOption, stage: stageOption, region: regionOption, verbose: verboseOption },
|
|
6119
|
-
({ project: projectOpt, stage, region, verbose }) =>
|
|
6375
|
+
({ project: projectOpt, stage, region, verbose }) => Effect39.gen(function* () {
|
|
6120
6376
|
const { config, projectDir } = yield* ProjectConfig;
|
|
6121
6377
|
const project = Option2.getOrElse(projectOpt, () => config?.name ?? "");
|
|
6122
6378
|
const finalStage = config?.stage ?? stage;
|
|
@@ -6133,7 +6389,7 @@ var statusCommand = Command2.make(
|
|
|
6133
6389
|
const patterns = getPatternsFromConfig(config);
|
|
6134
6390
|
const codeHandlers = patterns ? discoverCodeHandlers(projectDir, patterns) : [];
|
|
6135
6391
|
const codeHandlerNames = new Set(codeHandlers.map((h) => h.name));
|
|
6136
|
-
yield*
|
|
6392
|
+
yield* Effect39.gen(function* () {
|
|
6137
6393
|
yield* Console4.log(`
|
|
6138
6394
|
Status for ${c.bold(project + "/" + finalStage)}:
|
|
6139
6395
|
`);
|
|
@@ -6207,7 +6463,7 @@ Status for ${c.bold(project + "/" + finalStage)}:
|
|
|
6207
6463
|
yield* Console4.log(`
|
|
6208
6464
|
Total: ${parts.join(", ")}`);
|
|
6209
6465
|
const depWarnings = yield* checkDependencyWarnings(projectDir).pipe(
|
|
6210
|
-
|
|
6466
|
+
Effect39.catchAll(() => Effect39.succeed([]))
|
|
6211
6467
|
);
|
|
6212
6468
|
if (depWarnings.length > 0) {
|
|
6213
6469
|
yield* Console4.log("");
|
|
@@ -6216,18 +6472,18 @@ Total: ${parts.join(", ")}`);
|
|
|
6216
6472
|
}
|
|
6217
6473
|
}
|
|
6218
6474
|
}).pipe(
|
|
6219
|
-
|
|
6475
|
+
Effect39.provide(clientsLayer),
|
|
6220
6476
|
Logger2.withMinimumLogLevel(logLevel)
|
|
6221
6477
|
);
|
|
6222
|
-
}).pipe(
|
|
6478
|
+
}).pipe(Effect39.provide(ProjectConfig.Live))
|
|
6223
6479
|
).pipe(Command2.withDescription("Compare local handlers with deployed AWS resources. Shows new, deployed, and orphaned handlers"));
|
|
6224
6480
|
|
|
6225
6481
|
// src/cli/commands/cleanup.ts
|
|
6226
6482
|
import { Command as Command3, Options as Options2 } from "@effect/cli";
|
|
6227
|
-
import { Effect as
|
|
6483
|
+
import { Effect as Effect41, Console as Console5, Logger as Logger3, LogLevel as LogLevel3, Option as Option3 } from "effect";
|
|
6228
6484
|
|
|
6229
6485
|
// src/deploy/cleanup.ts
|
|
6230
|
-
import { Effect as
|
|
6486
|
+
import { Effect as Effect40 } from "effect";
|
|
6231
6487
|
var extractResourceName = (arn, type) => {
|
|
6232
6488
|
switch (type) {
|
|
6233
6489
|
case "lambda": {
|
|
@@ -6270,7 +6526,7 @@ var extractLayerInfo = (arn) => {
|
|
|
6270
6526
|
version: parseInt(parts[parts.length - 1] ?? "0", 10)
|
|
6271
6527
|
};
|
|
6272
6528
|
};
|
|
6273
|
-
var deleteResource = (resource) =>
|
|
6529
|
+
var deleteResource = (resource) => Effect40.gen(function* () {
|
|
6274
6530
|
const name = extractResourceName(resource.arn, resource.type);
|
|
6275
6531
|
switch (resource.type) {
|
|
6276
6532
|
case "lambda":
|
|
@@ -6303,18 +6559,18 @@ var deleteResource = (resource) => Effect39.gen(function* () {
|
|
|
6303
6559
|
yield* deleteSesIdentity(name);
|
|
6304
6560
|
break;
|
|
6305
6561
|
default:
|
|
6306
|
-
yield*
|
|
6562
|
+
yield* Effect40.logWarning(`Unknown resource type: ${resource.type}, skipping ${resource.arn}`);
|
|
6307
6563
|
}
|
|
6308
6564
|
});
|
|
6309
|
-
var deleteResources = (resources) =>
|
|
6565
|
+
var deleteResources = (resources) => Effect40.gen(function* () {
|
|
6310
6566
|
const orderedTypes = ["lambda", "api-gateway", "cloudfront-distribution", "sqs", "ses", "dynamodb", "s3-bucket", "lambda-layer", "iam-role"];
|
|
6311
6567
|
const iamRolesToDelete = /* @__PURE__ */ new Set();
|
|
6312
6568
|
for (const type of orderedTypes) {
|
|
6313
6569
|
const resourcesOfType = resources.filter((r) => r.type === type);
|
|
6314
6570
|
for (const resource of resourcesOfType) {
|
|
6315
6571
|
yield* deleteResource(resource).pipe(
|
|
6316
|
-
|
|
6317
|
-
(error) =>
|
|
6572
|
+
Effect40.catchAll(
|
|
6573
|
+
(error) => Effect40.logError(`Failed to delete ${resource.type} ${resource.arn}: ${error}`)
|
|
6318
6574
|
)
|
|
6319
6575
|
);
|
|
6320
6576
|
if (resource.type === "lambda") {
|
|
@@ -6326,8 +6582,8 @@ var deleteResources = (resources) => Effect39.gen(function* () {
|
|
|
6326
6582
|
}
|
|
6327
6583
|
for (const roleName of iamRolesToDelete) {
|
|
6328
6584
|
yield* deleteRole(roleName).pipe(
|
|
6329
|
-
|
|
6330
|
-
(error) =>
|
|
6585
|
+
Effect40.catchAll(
|
|
6586
|
+
(error) => Effect40.logError(`Failed to delete IAM role ${roleName}: ${error}`)
|
|
6331
6587
|
)
|
|
6332
6588
|
);
|
|
6333
6589
|
}
|
|
@@ -6354,7 +6610,7 @@ var orphanedOption = Options2.boolean("orphaned").pipe(
|
|
|
6354
6610
|
var cleanupCommand = Command3.make(
|
|
6355
6611
|
"cleanup",
|
|
6356
6612
|
{ project: projectOption, stage: stageOption, region: regionOption, handler: handlerOption, layer: layerOption, roles: rolesOption, orphaned: orphanedOption, all: cleanupAllOption, dryRun: dryRunOption, verbose: verboseOption },
|
|
6357
|
-
({ project: projectOpt, stage, region, handler: handlerOpt, layer: cleanupLayer, roles: cleanupRoles, orphaned: cleanupOrphaned, all: deleteAll, dryRun, verbose }) =>
|
|
6613
|
+
({ project: projectOpt, stage, region, handler: handlerOpt, layer: cleanupLayer, roles: cleanupRoles, orphaned: cleanupOrphaned, all: deleteAll, dryRun, verbose }) => Effect41.gen(function* () {
|
|
6358
6614
|
const { config, projectDir } = yield* ProjectConfig;
|
|
6359
6615
|
const project = Option3.getOrElse(projectOpt, () => config?.name ?? "");
|
|
6360
6616
|
const finalStage = config?.stage ?? stage;
|
|
@@ -6366,14 +6622,14 @@ var cleanupCommand = Command3.make(
|
|
|
6366
6622
|
const logLevel = verbose ? LogLevel3.Debug : LogLevel3.Info;
|
|
6367
6623
|
if (cleanupLayer) {
|
|
6368
6624
|
yield* cleanupLayerVersions({ project, region: finalRegion, deleteAll, dryRun }).pipe(
|
|
6369
|
-
|
|
6625
|
+
Effect41.provide(clients_exports.makeClients({ lambda: { region: finalRegion } })),
|
|
6370
6626
|
Logger3.withMinimumLogLevel(logLevel)
|
|
6371
6627
|
);
|
|
6372
6628
|
return;
|
|
6373
6629
|
}
|
|
6374
6630
|
if (cleanupRoles) {
|
|
6375
6631
|
yield* cleanupIamRoles({ project, stage: finalStage, region: finalRegion, deleteAll, dryRun }).pipe(
|
|
6376
|
-
|
|
6632
|
+
Effect41.provide(clients_exports.makeClients({ iam: { region: finalRegion } })),
|
|
6377
6633
|
Logger3.withMinimumLogLevel(logLevel)
|
|
6378
6634
|
);
|
|
6379
6635
|
return;
|
|
@@ -6388,7 +6644,7 @@ var cleanupCommand = Command3.make(
|
|
|
6388
6644
|
s3: { region: finalRegion },
|
|
6389
6645
|
cloudfront: { region: "us-east-1" }
|
|
6390
6646
|
});
|
|
6391
|
-
yield*
|
|
6647
|
+
yield* Effect41.gen(function* () {
|
|
6392
6648
|
yield* Console5.log(`
|
|
6393
6649
|
Looking for resources in ${c.bold(project + "/" + finalStage)}...
|
|
6394
6650
|
`);
|
|
@@ -6468,12 +6724,12 @@ ${c.yellow("[DRY RUN]")} No resources were deleted.`);
|
|
|
6468
6724
|
yield* deleteResources(resourcesToDelete);
|
|
6469
6725
|
yield* Console5.log(c.green("\nDone!"));
|
|
6470
6726
|
}).pipe(
|
|
6471
|
-
|
|
6727
|
+
Effect41.provide(clientsLayer),
|
|
6472
6728
|
Logger3.withMinimumLogLevel(logLevel)
|
|
6473
6729
|
);
|
|
6474
|
-
}).pipe(
|
|
6730
|
+
}).pipe(Effect41.provide(ProjectConfig.Live))
|
|
6475
6731
|
).pipe(Command3.withDescription("Delete deployed resources (Lambda, API Gateway, DynamoDB, IAM roles, layers)"));
|
|
6476
|
-
var cleanupLayerVersions = (input) =>
|
|
6732
|
+
var cleanupLayerVersions = (input) => Effect41.gen(function* () {
|
|
6477
6733
|
const layerName = `${input.project}-deps`;
|
|
6478
6734
|
yield* Console5.log(`
|
|
6479
6735
|
Searching for layer versions: ${layerName}
|
|
@@ -6505,7 +6761,7 @@ ${c.yellow("[DRY RUN]")} No layers were deleted.`);
|
|
|
6505
6761
|
yield* Console5.log(c.green(`
|
|
6506
6762
|
Deleted ${deleted} layer version(s).`));
|
|
6507
6763
|
});
|
|
6508
|
-
var cleanupIamRoles = (input) =>
|
|
6764
|
+
var cleanupIamRoles = (input) => Effect41.gen(function* () {
|
|
6509
6765
|
yield* Console5.log("\nSearching for effortless IAM roles...\n");
|
|
6510
6766
|
const allRoles = yield* listEffortlessRoles();
|
|
6511
6767
|
if (allRoles.length === 0) {
|
|
@@ -6554,8 +6810,8 @@ ${c.yellow("[DRY RUN]")} No roles were deleted.`);
|
|
|
6554
6810
|
yield* Console5.log(c.red("\nDeleting roles..."));
|
|
6555
6811
|
for (const role of roles) {
|
|
6556
6812
|
yield* deleteRole(role.name).pipe(
|
|
6557
|
-
|
|
6558
|
-
(error) =>
|
|
6813
|
+
Effect41.catchAll(
|
|
6814
|
+
(error) => Effect41.logError(`Failed to delete ${role.name}: ${error}`)
|
|
6559
6815
|
)
|
|
6560
6816
|
);
|
|
6561
6817
|
}
|
|
@@ -6564,7 +6820,7 @@ ${c.yellow("[DRY RUN]")} No roles were deleted.`);
|
|
|
6564
6820
|
|
|
6565
6821
|
// src/cli/commands/logs.ts
|
|
6566
6822
|
import { Args as Args2, Command as Command4, Options as Options3 } from "@effect/cli";
|
|
6567
|
-
import { Effect as
|
|
6823
|
+
import { Effect as Effect42, Console as Console6, Logger as Logger4, LogLevel as LogLevel4, Option as Option4, Schedule as Schedule4 } from "effect";
|
|
6568
6824
|
var { cloudwatch_logs } = clients_exports;
|
|
6569
6825
|
var handlerArg = Args2.text({ name: "handler" }).pipe(
|
|
6570
6826
|
Args2.withDescription("Handler name to show logs for")
|
|
@@ -6635,7 +6891,7 @@ var fetchLogs = (logGroupName, startTime, nextToken) => cloudwatch_logs.make("fi
|
|
|
6635
6891
|
var logsCommand = Command4.make(
|
|
6636
6892
|
"logs",
|
|
6637
6893
|
{ handler: handlerArg, project: projectOption, stage: stageOption, region: regionOption, tail: tailOption, since: sinceOption, verbose: verboseOption },
|
|
6638
|
-
({ handler: handlerName, project: projectOpt, stage, region, tail, since, verbose }) =>
|
|
6894
|
+
({ handler: handlerName, project: projectOpt, stage, region, tail, since, verbose }) => Effect42.gen(function* () {
|
|
6639
6895
|
const { config, projectDir } = yield* ProjectConfig;
|
|
6640
6896
|
const project = Option4.getOrElse(projectOpt, () => config?.name ?? "");
|
|
6641
6897
|
const finalStage = config?.stage ?? stage;
|
|
@@ -6666,18 +6922,18 @@ var logsCommand = Command4.make(
|
|
|
6666
6922
|
cloudwatch_logs: { region: finalRegion }
|
|
6667
6923
|
});
|
|
6668
6924
|
const logLevel = verbose ? LogLevel4.Debug : LogLevel4.Info;
|
|
6669
|
-
yield*
|
|
6925
|
+
yield* Effect42.gen(function* () {
|
|
6670
6926
|
const durationMs = parseDuration(since);
|
|
6671
6927
|
let startTime = Date.now() - durationMs;
|
|
6672
6928
|
yield* Console6.log(`Logs for ${c.bold(handlerName)} ${c.dim(`(${logGroupName})`)}:
|
|
6673
6929
|
`);
|
|
6674
6930
|
let hasLogs = false;
|
|
6675
6931
|
const result = yield* fetchLogs(logGroupName, startTime).pipe(
|
|
6676
|
-
|
|
6932
|
+
Effect42.catchAll((error) => {
|
|
6677
6933
|
if (error instanceof clients_exports.cloudwatch_logs.CloudWatchLogsError && error.cause.name === "ResourceNotFoundException") {
|
|
6678
|
-
return
|
|
6934
|
+
return Effect42.succeed({ events: void 0, nextToken: void 0 });
|
|
6679
6935
|
}
|
|
6680
|
-
return
|
|
6936
|
+
return Effect42.fail(error);
|
|
6681
6937
|
})
|
|
6682
6938
|
);
|
|
6683
6939
|
if (result.events && result.events.length > 0) {
|
|
@@ -6701,10 +6957,10 @@ var logsCommand = Command4.make(
|
|
|
6701
6957
|
if (!hasLogs) {
|
|
6702
6958
|
yield* Console6.log("Waiting for logs... (Ctrl+C to stop)\n");
|
|
6703
6959
|
}
|
|
6704
|
-
yield*
|
|
6705
|
-
|
|
6960
|
+
yield* Effect42.repeat(
|
|
6961
|
+
Effect42.gen(function* () {
|
|
6706
6962
|
const result2 = yield* fetchLogs(logGroupName, startTime).pipe(
|
|
6707
|
-
|
|
6963
|
+
Effect42.catchAll(() => Effect42.succeed({ events: void 0, nextToken: void 0 }))
|
|
6708
6964
|
);
|
|
6709
6965
|
if (result2.events && result2.events.length > 0) {
|
|
6710
6966
|
for (const event of result2.events) {
|
|
@@ -6722,45 +6978,45 @@ var logsCommand = Command4.make(
|
|
|
6722
6978
|
Schedule4.spaced("2 seconds")
|
|
6723
6979
|
);
|
|
6724
6980
|
}).pipe(
|
|
6725
|
-
|
|
6981
|
+
Effect42.provide(clientsLayer),
|
|
6726
6982
|
Logger4.withMinimumLogLevel(logLevel)
|
|
6727
6983
|
);
|
|
6728
|
-
}).pipe(
|
|
6984
|
+
}).pipe(Effect42.provide(ProjectConfig.Live))
|
|
6729
6985
|
).pipe(Command4.withDescription("Stream CloudWatch logs for a handler. Supports --tail for live tailing and --since for time range"));
|
|
6730
6986
|
|
|
6731
6987
|
// src/cli/commands/layer.ts
|
|
6732
6988
|
import { Command as Command5, Options as Options4 } from "@effect/cli";
|
|
6733
|
-
import { Effect as
|
|
6734
|
-
import * as
|
|
6735
|
-
import * as
|
|
6989
|
+
import { Effect as Effect43, Console as Console7 } from "effect";
|
|
6990
|
+
import * as path11 from "path";
|
|
6991
|
+
import * as fs7 from "fs";
|
|
6736
6992
|
var buildOption = Options4.boolean("build").pipe(
|
|
6737
6993
|
Options4.withDescription("Build layer directory locally (for debugging)")
|
|
6738
6994
|
);
|
|
6739
6995
|
var layerCommand = Command5.make(
|
|
6740
6996
|
"layer",
|
|
6741
6997
|
{ build: buildOption, output: outputOption, verbose: verboseOption },
|
|
6742
|
-
({ build: build3, output, verbose }) =>
|
|
6998
|
+
({ build: build3, output, verbose }) => Effect43.gen(function* () {
|
|
6743
6999
|
const { config, cwd } = yield* ProjectConfig;
|
|
6744
7000
|
if (build3) {
|
|
6745
7001
|
yield* buildLayer(cwd, output, verbose);
|
|
6746
7002
|
} else {
|
|
6747
7003
|
yield* showLayerInfo(cwd, config?.name, verbose);
|
|
6748
7004
|
}
|
|
6749
|
-
}).pipe(
|
|
7005
|
+
}).pipe(Effect43.provide(ProjectConfig.Live))
|
|
6750
7006
|
).pipe(Command5.withDescription("Inspect or locally build the shared Lambda dependency layer from package.json"));
|
|
6751
|
-
var showLayerInfo = (projectDir, projectName, verbose) =>
|
|
7007
|
+
var showLayerInfo = (projectDir, projectName, verbose) => Effect43.gen(function* () {
|
|
6752
7008
|
yield* Console7.log(`
|
|
6753
7009
|
${c.bold("=== Layer Packages Preview ===")}
|
|
6754
7010
|
`);
|
|
6755
7011
|
const depWarnings = yield* checkDependencyWarnings(projectDir).pipe(
|
|
6756
|
-
|
|
7012
|
+
Effect43.catchAll(() => Effect43.succeed([]))
|
|
6757
7013
|
);
|
|
6758
7014
|
for (const w of depWarnings) {
|
|
6759
7015
|
yield* Console7.log(c.yellow(` \u26A0 ${w}`));
|
|
6760
7016
|
}
|
|
6761
7017
|
if (depWarnings.length > 0) yield* Console7.log("");
|
|
6762
7018
|
const prodDeps = yield* readProductionDependencies(projectDir).pipe(
|
|
6763
|
-
|
|
7019
|
+
Effect43.catchAll(() => Effect43.succeed([]))
|
|
6764
7020
|
);
|
|
6765
7021
|
if (prodDeps.length === 0) {
|
|
6766
7022
|
yield* Console7.log("No production dependencies found in package.json");
|
|
@@ -6772,7 +7028,7 @@ ${c.bold("=== Layer Packages Preview ===")}
|
|
|
6772
7028
|
yield* Console7.log(` ${dep}`);
|
|
6773
7029
|
}
|
|
6774
7030
|
const hash = yield* computeLockfileHash(projectDir).pipe(
|
|
6775
|
-
|
|
7031
|
+
Effect43.catchAll(() => Effect43.succeed(null))
|
|
6776
7032
|
);
|
|
6777
7033
|
if (hash) {
|
|
6778
7034
|
yield* Console7.log(`
|
|
@@ -6780,7 +7036,7 @@ Lockfile hash: ${hash}`);
|
|
|
6780
7036
|
} else {
|
|
6781
7037
|
yield* Console7.log("\nNo lockfile found (package-lock.json, pnpm-lock.yaml, or yarn.lock)");
|
|
6782
7038
|
}
|
|
6783
|
-
const { packages: allPackages, warnings: layerWarnings } = yield*
|
|
7039
|
+
const { packages: allPackages, warnings: layerWarnings } = yield* Effect43.sync(() => collectLayerPackages(projectDir, prodDeps));
|
|
6784
7040
|
if (layerWarnings.length > 0) {
|
|
6785
7041
|
yield* Console7.log(c.yellow(`
|
|
6786
7042
|
Warnings (${layerWarnings.length}):`));
|
|
@@ -6809,26 +7065,26 @@ Total packages for layer ${c.dim(`(${allPackages.length})`)}:`);
|
|
|
6809
7065
|
Layer name: ${projectName}-deps`);
|
|
6810
7066
|
}
|
|
6811
7067
|
});
|
|
6812
|
-
var buildLayer = (projectDir, output, verbose) =>
|
|
6813
|
-
const outputDir =
|
|
6814
|
-
const layerDir =
|
|
6815
|
-
const layerRoot =
|
|
6816
|
-
if (
|
|
6817
|
-
|
|
6818
|
-
}
|
|
6819
|
-
|
|
7068
|
+
var buildLayer = (projectDir, output, verbose) => Effect43.gen(function* () {
|
|
7069
|
+
const outputDir = path11.isAbsolute(output) ? output : path11.resolve(projectDir, output);
|
|
7070
|
+
const layerDir = path11.join(outputDir, "nodejs", "node_modules");
|
|
7071
|
+
const layerRoot = path11.join(outputDir, "nodejs");
|
|
7072
|
+
if (fs7.existsSync(layerRoot)) {
|
|
7073
|
+
fs7.rmSync(layerRoot, { recursive: true });
|
|
7074
|
+
}
|
|
7075
|
+
fs7.mkdirSync(layerDir, { recursive: true });
|
|
6820
7076
|
yield* Console7.log(`
|
|
6821
7077
|
${c.bold("=== Building Layer Locally ===")}
|
|
6822
7078
|
`);
|
|
6823
7079
|
const depWarnings = yield* checkDependencyWarnings(projectDir).pipe(
|
|
6824
|
-
|
|
7080
|
+
Effect43.catchAll(() => Effect43.succeed([]))
|
|
6825
7081
|
);
|
|
6826
7082
|
for (const w of depWarnings) {
|
|
6827
7083
|
yield* Console7.log(c.yellow(` \u26A0 ${w}`));
|
|
6828
7084
|
}
|
|
6829
7085
|
if (depWarnings.length > 0) yield* Console7.log("");
|
|
6830
7086
|
const prodDeps = yield* readProductionDependencies(projectDir).pipe(
|
|
6831
|
-
|
|
7087
|
+
Effect43.catchAll(() => Effect43.succeed([]))
|
|
6832
7088
|
);
|
|
6833
7089
|
if (prodDeps.length === 0) {
|
|
6834
7090
|
yield* Console7.log("No production dependencies found in package.json");
|
|
@@ -6840,11 +7096,11 @@ ${c.bold("=== Building Layer Locally ===")}
|
|
|
6840
7096
|
yield* Console7.log(` ${dep}`);
|
|
6841
7097
|
}
|
|
6842
7098
|
const hash = yield* computeLockfileHash(projectDir).pipe(
|
|
6843
|
-
|
|
7099
|
+
Effect43.catchAll(() => Effect43.succeed("unknown"))
|
|
6844
7100
|
);
|
|
6845
7101
|
yield* Console7.log(`
|
|
6846
7102
|
Lockfile hash: ${hash}`);
|
|
6847
|
-
const { packages: allPackages, resolvedPaths, warnings: layerWarnings } = yield*
|
|
7103
|
+
const { packages: allPackages, resolvedPaths, warnings: layerWarnings } = yield* Effect43.sync(() => collectLayerPackages(projectDir, prodDeps));
|
|
6848
7104
|
if (layerWarnings.length > 0) {
|
|
6849
7105
|
yield* Console7.log(`
|
|
6850
7106
|
Warnings (${layerWarnings.length}):`);
|
|
@@ -6871,14 +7127,14 @@ Collected ${allPackages.length} packages for layer`);
|
|
|
6871
7127
|
}
|
|
6872
7128
|
continue;
|
|
6873
7129
|
}
|
|
6874
|
-
const destPath =
|
|
7130
|
+
const destPath = path11.join(layerDir, pkgName);
|
|
6875
7131
|
if (pkgName.startsWith("@")) {
|
|
6876
|
-
const scopeDir =
|
|
6877
|
-
if (!
|
|
6878
|
-
|
|
7132
|
+
const scopeDir = path11.join(layerDir, pkgName.split("/")[0] ?? pkgName);
|
|
7133
|
+
if (!fs7.existsSync(scopeDir)) {
|
|
7134
|
+
fs7.mkdirSync(scopeDir, { recursive: true });
|
|
6879
7135
|
}
|
|
6880
7136
|
}
|
|
6881
|
-
|
|
7137
|
+
fs7.cpSync(srcPath, destPath, { recursive: true });
|
|
6882
7138
|
copied++;
|
|
6883
7139
|
}
|
|
6884
7140
|
yield* Console7.log(c.green(`
|
|
@@ -6894,18 +7150,18 @@ To inspect: ls ${layerDir}`);
|
|
|
6894
7150
|
// src/cli/commands/config.ts
|
|
6895
7151
|
import { Args as Args3, Command as Command6 } from "@effect/cli";
|
|
6896
7152
|
import { Prompt } from "@effect/cli";
|
|
6897
|
-
import { Effect as
|
|
6898
|
-
var loadRequiredParams = (projectOpt, stage, region) =>
|
|
7153
|
+
import { Effect as Effect44, Console as Console8, Logger as Logger5, LogLevel as LogLevel5, Option as Option5 } from "effect";
|
|
7154
|
+
var loadRequiredParams = (projectOpt, stage, region) => Effect44.gen(function* () {
|
|
6899
7155
|
const { config, projectDir } = yield* ProjectConfig;
|
|
6900
7156
|
const project = Option5.getOrElse(projectOpt, () => config?.name ?? "");
|
|
6901
7157
|
if (!project) {
|
|
6902
7158
|
yield* Console8.error("Error: --project is required (or set 'name' in effortless.config.ts)");
|
|
6903
|
-
return yield*
|
|
7159
|
+
return yield* Effect44.fail(new Error("Missing project name"));
|
|
6904
7160
|
}
|
|
6905
7161
|
const patterns = getPatternsFromConfig(config);
|
|
6906
7162
|
if (!patterns) {
|
|
6907
7163
|
yield* Console8.error("Error: No 'handlers' patterns in config");
|
|
6908
|
-
return yield*
|
|
7164
|
+
return yield* Effect44.fail(new Error("Missing handler patterns"));
|
|
6909
7165
|
}
|
|
6910
7166
|
const files = findHandlerFiles(patterns, projectDir);
|
|
6911
7167
|
const handlers = discoverHandlers(files);
|
|
@@ -6917,7 +7173,7 @@ var loadRequiredParams = (projectOpt, stage, region) => Effect43.gen(function* (
|
|
|
6917
7173
|
var listCommand = Command6.make(
|
|
6918
7174
|
"list",
|
|
6919
7175
|
{ project: projectOption, stage: stageOption, region: regionOption, verbose: verboseOption },
|
|
6920
|
-
({ project: projectOpt, stage, region, verbose }) =>
|
|
7176
|
+
({ project: projectOpt, stage, region, verbose }) => Effect44.gen(function* () {
|
|
6921
7177
|
const ctx = yield* loadRequiredParams(projectOpt, stage, region);
|
|
6922
7178
|
const { params } = ctx;
|
|
6923
7179
|
if (params.length === 0) {
|
|
@@ -6925,7 +7181,7 @@ var listCommand = Command6.make(
|
|
|
6925
7181
|
return;
|
|
6926
7182
|
}
|
|
6927
7183
|
const { existing, missing } = yield* checkMissingParams(params).pipe(
|
|
6928
|
-
|
|
7184
|
+
Effect44.provide(clients_exports.makeClients({ ssm: { region: ctx.region } }))
|
|
6929
7185
|
);
|
|
6930
7186
|
yield* Console8.log(`
|
|
6931
7187
|
${c.bold("Config parameters")} ${c.dim(`(${ctx.project} / ${ctx.stage})`)}
|
|
@@ -6949,7 +7205,7 @@ ${c.bold("Config parameters")} ${c.dim(`(${ctx.project} / ${ctx.stage})`)}
|
|
|
6949
7205
|
}
|
|
6950
7206
|
yield* Console8.log("");
|
|
6951
7207
|
}).pipe(
|
|
6952
|
-
|
|
7208
|
+
Effect44.provide(ProjectConfig.Live),
|
|
6953
7209
|
Logger5.withMinimumLogLevel(LogLevel5.Warning)
|
|
6954
7210
|
)
|
|
6955
7211
|
).pipe(Command6.withDescription("List all declared config parameters and show which are set vs missing"));
|
|
@@ -6959,7 +7215,7 @@ var setKeyArg = Args3.text({ name: "key" }).pipe(
|
|
|
6959
7215
|
var setCommand = Command6.make(
|
|
6960
7216
|
"set",
|
|
6961
7217
|
{ key: setKeyArg, project: projectOption, stage: stageOption, region: regionOption, verbose: verboseOption },
|
|
6962
|
-
({ key, project: projectOpt, stage, region, verbose }) =>
|
|
7218
|
+
({ key, project: projectOpt, stage, region, verbose }) => Effect44.gen(function* () {
|
|
6963
7219
|
const { config } = yield* ProjectConfig;
|
|
6964
7220
|
const project = Option5.getOrElse(projectOpt, () => config?.name ?? "");
|
|
6965
7221
|
if (!project) {
|
|
@@ -6977,18 +7233,18 @@ var setCommand = Command6.make(
|
|
|
6977
7233
|
Value: value,
|
|
6978
7234
|
Type: "SecureString",
|
|
6979
7235
|
Overwrite: true
|
|
6980
|
-
}).pipe(
|
|
7236
|
+
}).pipe(Effect44.provide(clients_exports.makeClients({ ssm: { region: finalRegion } })));
|
|
6981
7237
|
yield* Console8.log(`
|
|
6982
7238
|
${c.green("\u2713")} ${c.cyan(ssmPath)} ${c.dim("(SecureString)")}`);
|
|
6983
7239
|
}).pipe(
|
|
6984
|
-
|
|
7240
|
+
Effect44.provide(ProjectConfig.Live),
|
|
6985
7241
|
Logger5.withMinimumLogLevel(LogLevel5.Warning)
|
|
6986
7242
|
)
|
|
6987
7243
|
).pipe(Command6.withDescription("Set a config parameter value (stored encrypted in AWS)"));
|
|
6988
7244
|
var configRootCommand = Command6.make(
|
|
6989
7245
|
"config",
|
|
6990
7246
|
{ project: projectOption, stage: stageOption, region: regionOption, verbose: verboseOption },
|
|
6991
|
-
({ project: projectOpt, stage, region, verbose }) =>
|
|
7247
|
+
({ project: projectOpt, stage, region, verbose }) => Effect44.gen(function* () {
|
|
6992
7248
|
const ctx = yield* loadRequiredParams(projectOpt, stage, region);
|
|
6993
7249
|
const { params } = ctx;
|
|
6994
7250
|
if (params.length === 0) {
|
|
@@ -6996,7 +7252,7 @@ var configRootCommand = Command6.make(
|
|
|
6996
7252
|
return;
|
|
6997
7253
|
}
|
|
6998
7254
|
const { missing } = yield* checkMissingParams(params).pipe(
|
|
6999
|
-
|
|
7255
|
+
Effect44.provide(clients_exports.makeClients({ ssm: { region: ctx.region } }))
|
|
7000
7256
|
);
|
|
7001
7257
|
if (missing.length === 0) {
|
|
7002
7258
|
yield* Console8.log(`
|
|
@@ -7021,7 +7277,7 @@ ${c.bold("Missing parameters")} ${c.dim(`(${ctx.project} / ${ctx.stage})`)}
|
|
|
7021
7277
|
Value: value,
|
|
7022
7278
|
Type: "SecureString",
|
|
7023
7279
|
Overwrite: false
|
|
7024
|
-
}).pipe(
|
|
7280
|
+
}).pipe(Effect44.provide(clients_exports.makeClients({ ssm: { region: ctx.region } })));
|
|
7025
7281
|
yield* Console8.log(` ${c.green("\u2713")} created`);
|
|
7026
7282
|
created++;
|
|
7027
7283
|
}
|
|
@@ -7035,7 +7291,7 @@ ${c.bold("Missing parameters")} ${c.dim(`(${ctx.project} / ${ctx.stage})`)}
|
|
|
7035
7291
|
`);
|
|
7036
7292
|
}
|
|
7037
7293
|
}).pipe(
|
|
7038
|
-
|
|
7294
|
+
Effect44.provide(ProjectConfig.Live),
|
|
7039
7295
|
Logger5.withMinimumLogLevel(LogLevel5.Warning)
|
|
7040
7296
|
)
|
|
7041
7297
|
).pipe(
|
|
@@ -7056,7 +7312,7 @@ var cli = Command7.run(mainCommand, {
|
|
|
7056
7312
|
version
|
|
7057
7313
|
});
|
|
7058
7314
|
cli(process.argv).pipe(
|
|
7059
|
-
|
|
7060
|
-
|
|
7315
|
+
Effect45.provide(NodeContext.layer),
|
|
7316
|
+
Effect45.provide(CliConfig.layer({ showBuiltIns: false, showTypes: false })),
|
|
7061
7317
|
NodeRuntime.runMain
|
|
7062
7318
|
);
|