@effortless-aws/cli 0.6.0 → 0.8.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.
Files changed (2) hide show
  1. package/dist/cli/index.js +169 -9
  2. package/package.json +2 -2
package/dist/cli/index.js CHANGED
@@ -4055,7 +4055,14 @@ var extractDepsKeys = (obj) => {
4055
4055
  return false;
4056
4056
  });
4057
4057
  if (!depsProp || depsProp.getKind() !== SyntaxKind.PropertyAssignment) return [];
4058
- const init = depsProp.getInitializer();
4058
+ let init = depsProp.getInitializer();
4059
+ if (!init) return [];
4060
+ if (init.getKind() === SyntaxKind.ArrowFunction) {
4061
+ const body = init.getBody();
4062
+ if (body.getKind() === SyntaxKind.ParenthesizedExpression) {
4063
+ init = body.getExpression();
4064
+ }
4065
+ }
4059
4066
  if (!init || init.getKind() !== SyntaxKind.ObjectLiteralExpression) return [];
4060
4067
  const depsObj = init;
4061
4068
  return depsObj.getProperties().map((p) => {
@@ -4231,6 +4238,56 @@ var extractHandlerConfigs = (source, type) => {
4231
4238
  });
4232
4239
  return results;
4233
4240
  };
4241
+ var generateMiddlewareEntryPoint = (source, runtimeDir2) => {
4242
+ const sourceFile = parseSource(source);
4243
+ const imports = sourceFile.getImportDeclarations().map((d) => d.getText()).join("\n");
4244
+ const defineFn = handlerRegistry.staticSite.defineFn;
4245
+ let middlewareFnText;
4246
+ let exportName;
4247
+ const exportDefault = sourceFile.getExportAssignment((e) => !e.isExportEquals());
4248
+ if (exportDefault) {
4249
+ const expr = exportDefault.getExpression();
4250
+ if (expr.getKind() === SyntaxKind.CallExpression) {
4251
+ const callExpr = expr.asKindOrThrow(SyntaxKind.CallExpression);
4252
+ if (callExpr.getExpression().getText() === defineFn) {
4253
+ const args = callExpr.getArguments();
4254
+ const firstArg = args[0];
4255
+ if (firstArg?.getKind() === SyntaxKind.ObjectLiteralExpression) {
4256
+ middlewareFnText = extractPropertyFromObject(firstArg, "middleware");
4257
+ exportName = "default";
4258
+ }
4259
+ }
4260
+ }
4261
+ }
4262
+ if (!middlewareFnText) {
4263
+ sourceFile.getVariableStatements().forEach((stmt) => {
4264
+ if (middlewareFnText || !stmt.isExported()) return;
4265
+ stmt.getDeclarations().forEach((decl) => {
4266
+ if (middlewareFnText) return;
4267
+ const init = decl.getInitializer();
4268
+ if (!init || init.getKind() !== SyntaxKind.CallExpression) return;
4269
+ const callExpr = init.asKindOrThrow(SyntaxKind.CallExpression);
4270
+ if (callExpr.getExpression().getText() !== defineFn) return;
4271
+ const args = callExpr.getArguments();
4272
+ const firstArg = args[0];
4273
+ if (firstArg?.getKind() === SyntaxKind.ObjectLiteralExpression) {
4274
+ middlewareFnText = extractPropertyFromObject(firstArg, "middleware");
4275
+ exportName = decl.getName();
4276
+ }
4277
+ });
4278
+ });
4279
+ }
4280
+ if (!middlewareFnText || !exportName) {
4281
+ throw new Error("Could not extract middleware function from source");
4282
+ }
4283
+ const wrapperPath = runtimeDir2 ? handlerRegistry.staticSite.wrapperPath.replace("~/runtime", runtimeDir2) : handlerRegistry.staticSite.wrapperPath;
4284
+ const entryPoint = `${imports}
4285
+ import { wrapMiddlewareFn } from "${wrapperPath}";
4286
+ const __middleware = ${middlewareFnText};
4287
+ export const handler = wrapMiddlewareFn(__middleware);
4288
+ `;
4289
+ return { entryPoint, exportName };
4290
+ };
4234
4291
  var generateEntryPoint = (sourcePath, exportName, type, runtimeDir2) => {
4235
4292
  const { wrapperFn, wrapperPath } = handlerRegistry[type];
4236
4293
  const resolvedWrapperPath = runtimeDir2 ? wrapperPath.replace("~/runtime", runtimeDir2) : wrapperPath;
@@ -4284,6 +4341,36 @@ var bundle = (input) => Effect24.gen(function* () {
4284
4341
  }
4285
4342
  return output.text;
4286
4343
  });
4344
+ var bundleMiddleware = (input) => Effect24.gen(function* () {
4345
+ const absFile = path3.isAbsolute(input.file) ? input.file : path3.resolve(input.projectDir, input.file);
4346
+ const source = fsSync2.readFileSync(absFile, "utf-8");
4347
+ const sourceDir = path3.dirname(absFile);
4348
+ const { entryPoint } = generateMiddlewareEntryPoint(source, runtimeDir);
4349
+ const awsExternals = ["@aws-sdk/*", "@smithy/*"];
4350
+ const result = yield* Effect24.tryPromise({
4351
+ try: () => esbuild.build({
4352
+ stdin: {
4353
+ contents: entryPoint,
4354
+ loader: "ts",
4355
+ resolveDir: sourceDir
4356
+ },
4357
+ bundle: true,
4358
+ platform: "node",
4359
+ target: "node22",
4360
+ write: false,
4361
+ minify: false,
4362
+ sourcemap: false,
4363
+ format: "esm",
4364
+ external: awsExternals
4365
+ }),
4366
+ catch: (error) => new Error(`esbuild failed (middleware): ${error}`)
4367
+ });
4368
+ const output = result.outputFiles?.[0];
4369
+ if (!output) {
4370
+ throw new Error("esbuild produced no output for middleware");
4371
+ }
4372
+ return output.text;
4373
+ });
4287
4374
  var FIXED_DATE2 = /* @__PURE__ */ new Date(0);
4288
4375
  var zip = (input) => Effect24.async((resume) => {
4289
4376
  const chunks = [];
@@ -5041,7 +5128,7 @@ var submitToGoogleIndexing = (input) => Effect30.gen(function* () {
5041
5128
 
5042
5129
  // src/deploy/deploy-static-site.ts
5043
5130
  var deployMiddlewareLambda = (input) => Effect31.gen(function* () {
5044
- const { projectDir, project, stage, handlerName, file, exportName, tagCtx } = input;
5131
+ const { projectDir, project, stage, handlerName, file, tagCtx } = input;
5045
5132
  const middlewareName = `${handlerName}-middleware`;
5046
5133
  yield* Effect31.logDebug(`Deploying middleware Lambda@Edge: ${middlewareName}`);
5047
5134
  const roleArn = yield* ensureEdgeRole(
@@ -5050,12 +5137,7 @@ var deployMiddlewareLambda = (input) => Effect31.gen(function* () {
5050
5137
  middlewareName,
5051
5138
  makeTags(tagCtx, "iam-role")
5052
5139
  );
5053
- const bundled = yield* bundle({
5054
- projectDir,
5055
- file,
5056
- exportName,
5057
- type: "staticSite"
5058
- });
5140
+ const bundled = yield* bundleMiddleware({ projectDir, file });
5059
5141
  const code = yield* zip({ content: bundled });
5060
5142
  const { functionArn } = yield* ensureLambda({
5061
5143
  project,
@@ -5190,7 +5272,6 @@ var deployStaticSite = (input) => Effect31.gen(function* () {
5190
5272
  stage,
5191
5273
  handlerName,
5192
5274
  file: input.file,
5193
- exportName,
5194
5275
  tagCtx
5195
5276
  }).pipe(
5196
5277
  Effect31.provide(clients_exports.makeClients({ iam: { region: "us-east-1" } }))
@@ -7335,6 +7416,83 @@ ${c.bold("Missing parameters")} ${c.dim(`(${ctx.project} / ${ctx.stage})`)}
7335
7416
  );
7336
7417
  var configCommand = configRootCommand;
7337
7418
 
7419
+ // src/cli/update-check.ts
7420
+ import { homedir as homedir2 } from "os";
7421
+ import { join as join9 } from "path";
7422
+ import { readFileSync as readFileSync5, writeFileSync as writeFileSync2, mkdirSync as mkdirSync2 } from "fs";
7423
+ var PACKAGE_NAME = "@effortless-aws/cli";
7424
+ var CHECK_INTERVAL_MS = 24 * 60 * 60 * 1e3;
7425
+ var CACHE_DIR = join9(homedir2(), ".effortless-aws");
7426
+ var CACHE_FILE = join9(CACHE_DIR, "update-check.json");
7427
+ function readCache() {
7428
+ try {
7429
+ return JSON.parse(readFileSync5(CACHE_FILE, "utf-8"));
7430
+ } catch {
7431
+ return void 0;
7432
+ }
7433
+ }
7434
+ function writeCache(data) {
7435
+ try {
7436
+ mkdirSync2(CACHE_DIR, { recursive: true });
7437
+ writeFileSync2(CACHE_FILE, JSON.stringify(data));
7438
+ } catch {
7439
+ }
7440
+ }
7441
+ async function fetchLatestVersion() {
7442
+ try {
7443
+ const controller = new AbortController();
7444
+ const timeout = setTimeout(() => controller.abort(), 3e3);
7445
+ const res = await fetch(
7446
+ `https://registry.npmjs.org/${PACKAGE_NAME}/latest`,
7447
+ { signal: controller.signal }
7448
+ );
7449
+ clearTimeout(timeout);
7450
+ if (!res.ok) return void 0;
7451
+ const data = await res.json();
7452
+ return data.version;
7453
+ } catch {
7454
+ return void 0;
7455
+ }
7456
+ }
7457
+ function compareVersions(current, latest) {
7458
+ const parse = (v) => v.split(".").map(Number);
7459
+ const [cMajor, cMinor, cPatch] = parse(current);
7460
+ const [lMajor, lMinor, lPatch] = parse(latest);
7461
+ if (lMajor !== cMajor) return lMajor > cMajor;
7462
+ if (lMinor !== cMinor) return lMinor > cMinor;
7463
+ return lPatch > cPatch;
7464
+ }
7465
+ async function checkForUpdate(currentVersion) {
7466
+ const cache = readCache();
7467
+ const now = Date.now();
7468
+ let latestVersion;
7469
+ if (cache && now - cache.lastCheck < CHECK_INTERVAL_MS) {
7470
+ latestVersion = cache.latestVersion;
7471
+ } else {
7472
+ latestVersion = await fetchLatestVersion();
7473
+ if (latestVersion) {
7474
+ writeCache({ lastCheck: now, latestVersion });
7475
+ }
7476
+ }
7477
+ if (latestVersion && compareVersions(currentVersion, latestVersion)) {
7478
+ const border = "\u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510";
7479
+ const bottom = "\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518";
7480
+ const pad = (line, width) => {
7481
+ const visible = line.replace(/\x1b\[[0-9;]*m/g, "");
7482
+ return line + " ".repeat(Math.max(0, width - visible.length));
7483
+ };
7484
+ const W = 39;
7485
+ const line1 = `Update available! ${c.dim(currentVersion)} ${c.dim("\u2192")} ${c.green(latestVersion)}`;
7486
+ const line2 = `Run ${c.cyan(`pnpm i -g ${PACKAGE_NAME}`)} to update`;
7487
+ console.log();
7488
+ console.log(` ${border}`);
7489
+ console.log(` \u2502 ${pad(line1, W)} \u2502`);
7490
+ console.log(` \u2502 ${pad(line2, W)} \u2502`);
7491
+ console.log(` ${bottom}`);
7492
+ console.log();
7493
+ }
7494
+ }
7495
+
7338
7496
  // src/cli/index.ts
7339
7497
  var require2 = createRequire2(import.meta.url);
7340
7498
  var { version } = require2("../../package.json");
@@ -7346,8 +7504,10 @@ var cli = Command7.run(mainCommand, {
7346
7504
  name: "effortless",
7347
7505
  version
7348
7506
  });
7507
+ var updateCheck = checkForUpdate(version);
7349
7508
  cli(process.argv).pipe(
7350
7509
  Effect45.provide(NodeContext.layer),
7351
7510
  Effect45.provide(CliConfig.layer({ showBuiltIns: false, showTypes: false })),
7511
+ Effect45.tap(() => Effect45.promise(() => updateCheck)),
7352
7512
  NodeRuntime.runMain
7353
7513
  );
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@effortless-aws/cli",
3
- "version": "0.6.0",
3
+ "version": "0.8.0",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "description": "CLI and deploy tooling for effortless-aws",
@@ -39,7 +39,7 @@
39
39
  "esbuild": "^0.25.0",
40
40
  "glob": "^13.0.0",
41
41
  "ts-morph": "^27.0.2",
42
- "effortless-aws": "0.22.0"
42
+ "effortless-aws": "0.23.1"
43
43
  },
44
44
  "devDependencies": {
45
45
  "@effect-ak/aws-sdk": "1.0.0-rc.3",