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