@awsless/awsless 0.0.584 → 0.0.585

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/bin.js CHANGED
@@ -9,12 +9,78 @@ import { createCredentialChain } from "@aws-sdk/credential-providers";
9
9
 
10
10
  // src/cli/ui/complex/fetch-credentials.ts
11
11
  import { log, prompt } from "@awsless/clui";
12
+
13
+ // src/error.ts
14
+ var ExpectedError = class extends Error {
15
+ };
16
+ var ConfigError = class extends Error {
17
+ constructor(file, error, data) {
18
+ super(error.message);
19
+ this.file = file;
20
+ this.error = error;
21
+ this.data = data;
22
+ }
23
+ };
24
+ var FileError = class extends Error {
25
+ constructor(file, message) {
26
+ super(message);
27
+ this.file = file;
28
+ }
29
+ };
30
+ var Cancelled = class extends Error {
31
+ constructor() {
32
+ super("Cancelled");
33
+ }
34
+ };
35
+
36
+ // src/cli/ui/style.ts
37
+ import chalk from "chalk";
38
+ var icon = {
39
+ // info: 'ℹ',
40
+ // success: '✓',
41
+ // warning: '⚠',
42
+ // question: '?',
43
+ error: "\xD7",
44
+ dot: "\xB7",
45
+ // line: '─',
46
+ // ellipsis: '…',
47
+ arrow: {
48
+ top: "^",
49
+ right: "\u203A"
50
+ }
51
+ // pointer: '❯',
52
+ };
53
+ var color = {
54
+ primary: chalk.bold.hex("#FF9000"),
55
+ // primary: chalk.bold.magentaBright,
56
+ // title: chalk.white,
57
+ normal: chalk.reset.white,
58
+ label: chalk.reset.white.bold,
59
+ dim: chalk.dim,
60
+ line: chalk.black,
61
+ // link: chalk.cyan,
62
+ info: chalk.blue,
63
+ success: chalk.green,
64
+ warning: chalk.yellow,
65
+ error: chalk.red,
66
+ attr: chalk.yellow
67
+ // cursor: chalk.bgWhite.blackBright,
68
+ };
69
+
70
+ // src/cli/ui/complex/fetch-credentials.ts
71
+ var assertBunSecretFeature = () => {
72
+ if (!("secrets" in Bun)) {
73
+ throw new ExpectedError(`Your current version of Bun doesn't support the Bun.secrets API. Please upgrade.`);
74
+ }
75
+ };
12
76
  var fetchCredentials = async (profile) => {
77
+ assertBunSecretFeature();
13
78
  let credentialsString = await Bun.secrets.get({
14
79
  service: "awsless",
15
80
  name: profile
16
81
  });
17
82
  if (!credentialsString) {
83
+ log.warning(`You haven't configured AWS credentials for the ${color.info(profile)} profile.`);
18
84
  const accessKeyId = await prompt.password({
19
85
  message: "Enter your AWS access key ID",
20
86
  validate: (value) => {
@@ -100,29 +166,6 @@ import {
100
166
  } from "@aws-sdk/client-s3";
101
167
  import { log as log2, prompt as prompt2 } from "@awsless/clui";
102
168
 
103
- // src/error.ts
104
- var ExpectedError = class extends Error {
105
- };
106
- var ConfigError = class extends Error {
107
- constructor(file, error, data) {
108
- super(error.message);
109
- this.file = file;
110
- this.error = error;
111
- this.data = data;
112
- }
113
- };
114
- var FileError = class extends Error {
115
- constructor(file, message) {
116
- super(message);
117
- this.file = file;
118
- }
119
- };
120
- var Cancelled = class extends Error {
121
- constructor() {
122
- super("Cancelled");
123
- }
124
- };
125
-
126
169
  // src/util/workspace.ts
127
170
  import { aws } from "@terraforge/aws";
128
171
  import { DynamoLockBackend, enableDebug, S3StateBackend, WorkSpace } from "@terraforge/core";
@@ -366,42 +409,6 @@ import { GetHostedZoneCommand, Route53Client } from "@aws-sdk/client-route-53";
366
409
  import { createCustomProvider as createCustomProvider4, createCustomResourceClass as createCustomResourceClass4 } from "@terraforge/core";
367
410
  import { resolveNs } from "node:dns/promises";
368
411
  import { z as z4 } from "zod";
369
-
370
- // src/cli/ui/style.ts
371
- import chalk from "chalk";
372
- var icon = {
373
- // info: 'ℹ',
374
- // success: '✓',
375
- // warning: '⚠',
376
- // question: '?',
377
- error: "\xD7",
378
- dot: "\xB7",
379
- // line: '─',
380
- // ellipsis: '…',
381
- arrow: {
382
- top: "^",
383
- right: "\u203A"
384
- }
385
- // pointer: '❯',
386
- };
387
- var color = {
388
- primary: chalk.bold.hex("#FF9000"),
389
- // primary: chalk.bold.magentaBright,
390
- // title: chalk.white,
391
- normal: chalk.reset.white,
392
- label: chalk.reset.white.bold,
393
- dim: chalk.dim,
394
- line: chalk.black,
395
- // link: chalk.cyan,
396
- info: chalk.blue,
397
- success: chalk.green,
398
- warning: chalk.yellow,
399
- error: chalk.red,
400
- attr: chalk.yellow
401
- // cursor: chalk.bgWhite.blackBright,
402
- };
403
-
404
- // src/formation/ns-check.ts
405
412
  var NsCheck = createCustomResourceClass4("nameservers", "check");
406
413
  var createNameServersProvider = ({ profile, region }) => {
407
414
  const client = new Route53Client({ profile, region });
@@ -2340,12 +2347,11 @@ var StackSchema = z44.object({
2340
2347
 
2341
2348
  // src/config/load/read.ts
2342
2349
  import { readFile as readFile2 } from "fs/promises";
2343
- import JSON5 from "json5";
2344
2350
  import { basename, dirname as dirname2, extname, join as join4 } from "path";
2345
2351
  var readConfig = async (file) => {
2346
2352
  try {
2347
2353
  const json3 = await readFile2(file, "utf8");
2348
- const data = JSON5.parse(json3);
2354
+ const data = Bun.JSON5.parse(json3);
2349
2355
  return data;
2350
2356
  } catch (error) {
2351
2357
  if (error instanceof Error) {
@@ -6517,10 +6523,13 @@ var buildExecutable = async (input, outputPath, architecture) => {
6517
6523
  bytecode: true
6518
6524
  });
6519
6525
  } catch (error) {
6520
- throw new Error(`Executable build failed: ${error instanceof Error ? error.message : JSON.stringify(error)}`);
6526
+ throw new ExpectedError(
6527
+ `Executable build failed: ${error instanceof Error ? error.message : JSON.stringify(error)}`
6528
+ );
6521
6529
  }
6522
6530
  if (!result.success) {
6523
- throw new Error(`Executable build failed: ${result.logs?.map((log27) => log27.message).join("\n")}`);
6531
+ throw new ExpectedError(`Executable build failed:
6532
+ ${result.logs?.map((log27) => log27.message).join("\n")}`);
6524
6533
  }
6525
6534
  const file = await readFile4(filePath);
6526
6535
  return {
@@ -7882,8 +7891,15 @@ var logError = (error) => {
7882
7891
  );
7883
7892
  } else if (typeof error === "string") {
7884
7893
  log8.error(color.error(error));
7894
+ } else if (Array.isArray(error)) {
7895
+ error.map(logError);
7885
7896
  } else {
7886
- log8.error(color.error("Unknown error!"));
7897
+ try {
7898
+ const strError = JSON.stringify(error);
7899
+ log8.error(color.error(strError));
7900
+ } catch {
7901
+ log8.error(color.error("Unknown error!"));
7902
+ }
7887
7903
  }
7888
7904
  };
7889
7905
 
@@ -7895,7 +7911,7 @@ var logo = () => {
7895
7911
  // src/cli/ui/complex/layout.ts
7896
7912
  var layout = async (command, cb) => {
7897
7913
  console.log();
7898
- log9.intro(`${logo()} ${color.dim(command)}`);
7914
+ log9.intro(`${logo()} ${color.line(command)}`);
7899
7915
  try {
7900
7916
  const options = program.optsWithGlobals();
7901
7917
  const appConfig = await loadAppConfig(options);
@@ -8291,8 +8307,11 @@ var buildAssets = async (builders, stackFilters, showResult = false) => {
8291
8307
  });
8292
8308
  results.push({ ...builder, result });
8293
8309
  } catch (error) {
8294
- logError(new Error(`Build failed for: ${builder.type} ${builder.name}`));
8295
- throw error;
8310
+ throw [
8311
+ //
8312
+ new ExpectedError(`Build failed for: ${builder.type} ${builder.name}`),
8313
+ error
8314
+ ];
8296
8315
  }
8297
8316
  }
8298
8317
  }
@@ -8599,7 +8618,6 @@ import wildstring4 from "wildstring";
8599
8618
 
8600
8619
  // src/cli/ui/complex/run-tests.ts
8601
8620
  import { log as log16 } from "@awsless/clui";
8602
- import chalk4 from "chalk";
8603
8621
  import { mkdir as mkdir4, readFile as readFile6, writeFile as writeFile3 } from "fs/promises";
8604
8622
  import { join as join19 } from "path";
8605
8623
  import wildstring3 from "wildstring";
@@ -8666,99 +8684,8 @@ var findDependencies = async (file, code) => {
8666
8684
  return imports.map((entry) => entry.moduleName).filter(Boolean).map((value) => value?.startsWith(".") ? join17(dirname10(file), value) : value);
8667
8685
  };
8668
8686
 
8669
- // src/test/reporter.ts
8670
- import { getSuites, getTests } from "@vitest/runner/utils";
8671
- import { parseStacktrace } from "@vitest/utils/source-map";
8672
- var CustomReporter = class {
8673
- interval;
8674
- tasks;
8675
- ctx;
8676
- logs = [];
8677
- events = {};
8678
- cache;
8679
- startTime;
8680
- on(event, cb) {
8681
- this.events[event] = cb;
8682
- }
8683
- onInit(ctx) {
8684
- this.ctx = ctx;
8685
- this.startTime = process.hrtime.bigint();
8686
- }
8687
- // onTestRunStart(specifications: ReadonlyArray<TestSpecification>) {
8688
- // // specifications.
8689
- // }
8690
- onCollected() {
8691
- this.tasks = this.ctx?.state.getFiles();
8692
- if (!this.interval) {
8693
- this.interval = setInterval(this.update.bind(this), 33);
8694
- this.update();
8695
- this.events.start?.();
8696
- }
8697
- }
8698
- onFinished() {
8699
- clearInterval(this.interval);
8700
- this.interval = void 0;
8701
- const suites = getSuites(this.tasks);
8702
- const tests = getTests(this.tasks);
8703
- const passed = tests.filter((t) => t.result?.state === "pass").length;
8704
- const failed = tests.filter((t) => t.result?.state === "fail").length;
8705
- const errors = [...suites, ...tests].map((test2) => {
8706
- if (!test2.result?.errors || test2.result.errors.length === 0) {
8707
- return [];
8708
- }
8709
- const item = test2.type === "suite" ? test2 : test2.file;
8710
- return test2.result.errors.map((error) => {
8711
- const traces = error.stackStr ? parseStacktrace(error.stackStr) : [];
8712
- return {
8713
- location: {
8714
- line: traces[0]?.line ?? item.location?.line,
8715
- column: traces[0]?.column ?? item.location?.column
8716
- },
8717
- file: item.name,
8718
- test: test2.type === "test" ? test2.name : void 0,
8719
- diff: error.showDiff && error.diff ? error.diff : void 0,
8720
- type: error.name,
8721
- message: error.message
8722
- };
8723
- });
8724
- }).flat();
8725
- const event = {
8726
- errors,
8727
- passed,
8728
- failed,
8729
- duration: (this.startTime ?? 0n) - process.hrtime.bigint(),
8730
- logs: this.logs
8731
- };
8732
- this.events.finished?.(event);
8733
- }
8734
- update() {
8735
- const tasks = this.runningTasks(this.tasks);
8736
- if (tasks.length === 0) {
8737
- return;
8738
- }
8739
- const cache = JSON.stringify(tasks.map((t) => t.id));
8740
- if (this.cache !== cache) {
8741
- this.events.update?.({ tasks });
8742
- this.cache = cache;
8743
- }
8744
- }
8745
- onUserConsoleLog(log27) {
8746
- this.logs.push(log27.content.trimEnd());
8747
- }
8748
- runningTask(tasks) {
8749
- return tasks.find((t) => t.result?.state === "run");
8750
- }
8751
- runningTasks(tasks) {
8752
- const task2 = this.runningTask(tasks);
8753
- if (!task2) {
8754
- return [];
8755
- }
8756
- if (task2.type === "suite") {
8757
- return [task2, ...this.runningTasks(task2.tasks)];
8758
- }
8759
- return [task2];
8760
- }
8761
- };
8687
+ // src/cli/ui/complex/run-tests.ts
8688
+ import { parse as parse4, stringify } from "@awsless/json";
8762
8689
 
8763
8690
  // src/test/start.ts
8764
8691
  import commonjs2 from "@rollup/plugin-commonjs";
@@ -8769,9 +8696,12 @@ import { swc as swc2 } from "rollup-plugin-swc3";
8769
8696
  import { fileURLToPath as fileURLToPath4 } from "url";
8770
8697
  import { configDefaults } from "vitest/config";
8771
8698
  import { startVitest } from "vitest/node";
8699
+ var NullReporter = class {
8700
+ };
8772
8701
  var startTest = async (props) => {
8773
8702
  const __dirname4 = dirname11(fileURLToPath4(import.meta.url));
8774
- const result = await startVitest(
8703
+ const startTime = process.hrtime.bigint();
8704
+ const vitest = await startVitest(
8775
8705
  "test",
8776
8706
  props.filters,
8777
8707
  {
@@ -8783,7 +8713,8 @@ var startTest = async (props) => {
8783
8713
  include: ["**/*.{js,jsx,ts,tsx}"],
8784
8714
  exclude: ["**/_*", "**/_*/**", ...configDefaults.exclude],
8785
8715
  globals: true,
8786
- reporters: props.reporter,
8716
+ reporters: [new NullReporter()],
8717
+ // reporters: 'json',
8787
8718
  // typecheck: {
8788
8719
  // checker: 'tsc',
8789
8720
  // enabled: true,
@@ -8829,34 +8760,116 @@ var startTest = async (props) => {
8829
8760
  ]
8830
8761
  }
8831
8762
  );
8832
- return result;
8763
+ let skipped = 0;
8764
+ let passed = 0;
8765
+ let failed = 0;
8766
+ const duration = startTime - process.hrtime.bigint();
8767
+ const errors = [];
8768
+ const tests = [];
8769
+ const modules = vitest.state.getTestModules();
8770
+ for (const module of modules) {
8771
+ for (const test2 of module.children.allTests()) {
8772
+ const result = test2.result();
8773
+ switch (result.state) {
8774
+ case "pending":
8775
+ break;
8776
+ case "skipped":
8777
+ skipped++;
8778
+ break;
8779
+ case "passed":
8780
+ passed++;
8781
+ break;
8782
+ case "failed":
8783
+ failed++;
8784
+ break;
8785
+ }
8786
+ const entry = {
8787
+ file: test2.module.relativeModuleId,
8788
+ name: test2.name,
8789
+ logs: [],
8790
+ errors: []
8791
+ };
8792
+ tests.push(entry);
8793
+ if ("task" in test2) {
8794
+ const task2 = test2.task;
8795
+ for (const log27 of task2.logs ?? []) {
8796
+ entry.logs.push({
8797
+ time: log27.time,
8798
+ text: log27.content
8799
+ });
8800
+ }
8801
+ }
8802
+ for (const error of result.errors ?? []) {
8803
+ const stack = error.stacks?.[0];
8804
+ entry.errors.push({
8805
+ location: stack ? { line: stack.line, column: stack.column } : test2.location,
8806
+ message: error.message,
8807
+ diff: error.diff,
8808
+ type: error.name
8809
+ });
8810
+ }
8811
+ }
8812
+ for (const error of module.errors()) {
8813
+ const stack = error.stacks?.[0];
8814
+ errors.push({
8815
+ type: error.name,
8816
+ message: error.message,
8817
+ location: stack ? { line: stack.line, column: stack.column } : void 0
8818
+ });
8819
+ }
8820
+ }
8821
+ await vitest.close();
8822
+ return {
8823
+ tests,
8824
+ errors,
8825
+ passed,
8826
+ failed,
8827
+ skipped,
8828
+ duration
8829
+ };
8833
8830
  };
8834
8831
 
8835
8832
  // src/cli/ui/complex/run-tests.ts
8836
8833
  var formatResult = (props) => {
8837
- const line = [`Test ${chalk4.magenta(props.stack)}`];
8834
+ const line = [`Test ${color.info(props.stack)}`, color.dim(icon.arrow.right)];
8835
+ const stats2 = [];
8838
8836
  if (props.cached) {
8839
8837
  line.push(color.warning(`(from cache)`));
8840
8838
  }
8841
8839
  if (props.event.passed > 0) {
8842
- line.push(color.success(`${props.event.passed} passed`));
8840
+ stats2.push(color.success(`${props.event.passed} passed`));
8841
+ }
8842
+ if (props.event.skipped > 0) {
8843
+ stats2.push(color.warning(`${props.event.skipped} skipped`));
8843
8844
  }
8844
8845
  if (props.event.failed > 0) {
8845
- line.push(color.error(`${props.event.failed} failed`));
8846
+ stats2.push(color.error(`${props.event.failed} failed`));
8846
8847
  }
8847
- if (props.event.duration > 0) {
8848
+ if (props.event.duration > 0n) {
8848
8849
  }
8850
+ line.push(stats2.join(color.line.dim(` ${icon.dot} `)));
8849
8851
  return line.join(` `);
8850
8852
  };
8851
8853
  var logTestLogs = (event) => {
8852
- if (event.logs.length > 0) {
8853
- log16.message(color.info.bold.inverse(" LOGS "), color.dim(icon.dot));
8854
- log16.message(event.logs.map((log27) => wrap(log27, { hard: true })).join("\n"));
8854
+ for (const test2 of event.tests) {
8855
+ if (test2.logs.length > 0) {
8856
+ log16.message(
8857
+ [
8858
+ color.info.bold.inverse(" LOGS "),
8859
+ color.dim(icon.arrow.right),
8860
+ formatFileName(test2),
8861
+ color.dim(icon.arrow.right),
8862
+ color.dim(test2.name)
8863
+ ].join(" "),
8864
+ color.line(icon.dot)
8865
+ );
8866
+ log16.message(test2.logs.map((log27) => log27.text).join("\n"));
8867
+ }
8855
8868
  }
8856
8869
  };
8857
- var formatFileName = (error) => {
8858
- const name = [error.file];
8859
- const loc = error.location;
8870
+ var formatFileName = (test2, error) => {
8871
+ const name = [test2.file];
8872
+ const loc = error?.location;
8860
8873
  if (loc) {
8861
8874
  if (typeof loc.line === "number") {
8862
8875
  name.push(`:${loc.line}`);
@@ -8867,31 +8880,37 @@ var formatFileName = (error) => {
8867
8880
  }
8868
8881
  return name.join("");
8869
8882
  };
8870
- var logTestErrors = (event) => {
8871
- event.errors.forEach((error, i) => {
8872
- const [message, ...comment] = error.message.split("//");
8873
- const errorMessage = [
8874
- color.error.bold(error.type + ":"),
8875
- message,
8876
- comment.length > 0 ? color.dim(`//${comment}`) : ""
8877
- ].join(" ");
8878
- log16.error(
8879
- [
8880
- //
8881
- color.error.inverse.bold(` FAIL `),
8882
- color.dim(`(${i + 1}/${event.errors.length})`),
8883
- color.dim(icon.arrow.right),
8884
- formatFileName(error),
8885
- color.dim(icon.arrow.right),
8886
- // `\n${color.label.inverse.bold(` TEST `)}`,
8887
- color.dim(error.test),
8888
- [`
8883
+ var logTestError = (index, event, test2, error) => {
8884
+ const [message, ...comment] = error.message.split("//");
8885
+ const errorMessage = [
8886
+ color.error.bold(error.type + ":"),
8887
+ message,
8888
+ comment.length > 0 ? color.dim(`//${comment}`) : ""
8889
+ ].join(" ");
8890
+ log16.error(
8891
+ [
8892
+ //
8893
+ color.error.inverse.bold(` FAIL `),
8894
+ color.dim(`(${index}/${event.errors.length + event.failed})`),
8895
+ color.dim(icon.arrow.right),
8896
+ formatFileName(test2, error),
8897
+ color.dim(icon.arrow.right),
8898
+ // `\n${color.label.inverse.bold(` TEST `)}`,
8899
+ color.dim(test2.name),
8900
+ [`
8889
8901
 
8890
8902
  `, errorMessage, ...error.diff ? ["\n\n", error.diff] : []].join("")
8891
- // error.test,
8892
- ].join(" ")
8893
- );
8894
- });
8903
+ // error.test,
8904
+ ].join(" ")
8905
+ );
8906
+ };
8907
+ var logTestErrors = (event) => {
8908
+ let i = 0;
8909
+ for (const test2 of event.tests) {
8910
+ for (const error of test2.errors) {
8911
+ logTestError(++i, event, test2, error);
8912
+ }
8913
+ }
8895
8914
  };
8896
8915
  var runTest = async (stack, dir, filters, opts) => {
8897
8916
  await mkdir4(directories.test, { recursive: true });
@@ -8901,7 +8920,7 @@ var runTest = async (stack, dir, filters, opts) => {
8901
8920
  const exists = await fileExist(file);
8902
8921
  if (exists) {
8903
8922
  const raw = await readFile6(file, { encoding: "utf8" });
8904
- const data = JSON.parse(raw);
8923
+ const data = parse4(raw);
8905
8924
  if (data.fingerprint === fingerprint) {
8906
8925
  log16.step(
8907
8926
  formatResult({
@@ -8918,30 +8937,26 @@ var runTest = async (stack, dir, filters, opts) => {
8918
8937
  }
8919
8938
  }
8920
8939
  }
8921
- const reporter = new CustomReporter();
8922
- const result = await task(`Run tests for ${stack} stack`, async (update) => {
8923
- let result2;
8924
- reporter.on("update", ({ tasks }) => {
8925
- update(
8926
- [
8927
- //
8940
+ const result = await log16.task({
8941
+ initialMessage: `Run tests for the ${color.info(stack)} stack`,
8942
+ errorMessage: `Running tests for the ${color.info(stack)} stack failed`,
8943
+ async task(ctx) {
8944
+ const result2 = await startTest({
8945
+ dir,
8946
+ filters
8947
+ });
8948
+ if (result2.errors.length > 0) {
8949
+ throw result2.errors.map((error) => new ExpectedError(error.message));
8950
+ }
8951
+ ctx.updateSuccessMessage(
8952
+ formatResult({
8928
8953
  stack,
8929
- icon.arrow.right,
8930
- tasks.at(-1)?.name
8931
- // tasks.map(t => t.name).join(` ${icon.arrow.right} `),
8932
- ].join(" ")
8954
+ cached: false,
8955
+ event: result2
8956
+ })
8933
8957
  );
8934
- });
8935
- reporter.on("finished", (event) => {
8936
- result2 = event;
8937
- update(formatResult({ event, stack, cached: false }));
8938
- });
8939
- await startTest({
8940
- reporter,
8941
- dir,
8942
- filters
8943
- });
8944
- return result2;
8958
+ return result2;
8959
+ }
8945
8960
  });
8946
8961
  if (opts.showLogs) {
8947
8962
  logTestLogs(result);
@@ -8949,12 +8964,12 @@ var runTest = async (stack, dir, filters, opts) => {
8949
8964
  logTestErrors(result);
8950
8965
  await writeFile3(
8951
8966
  file,
8952
- JSON.stringify({
8967
+ stringify({
8953
8968
  ...result,
8954
8969
  fingerprint
8955
8970
  })
8956
8971
  );
8957
- return result.errors.length === 0;
8972
+ return result.errors.length === 0 && result.failed === 0;
8958
8973
  };
8959
8974
  var runTests = async (tests, stackFilters = [], testFilters = [], opts) => {
8960
8975
  for (const test2 of tests) {
@@ -9315,6 +9330,8 @@ var dev = (program2) => {
9315
9330
 
9316
9331
  // src/cli/command/resources.ts
9317
9332
  import { log as log21 } from "@awsless/clui";
9333
+ import chalk4 from "chalk";
9334
+ import wildstring5 from "wildstring";
9318
9335
  var resources = (program2) => {
9319
9336
  program2.command("resources").argument("[stacks...]", "Optionally filter stack resources to list").description(`List all defined resources in your app`).action(async (filters) => {
9320
9337
  await layout("resources", async ({ appConfig, stackConfigs }) => {
@@ -9330,9 +9347,9 @@ var resources = (program2) => {
9330
9347
  profile,
9331
9348
  region
9332
9349
  });
9333
- const resources2 = await workspace.status(app);
9334
- const formatResource = (urn) => {
9335
- return urn.replace(app.urn + ":", "").replace(/\{([a-z0-9\-\s\/\.\@\_]+)\}/gi, (_, v) => {
9350
+ const stacks = await workspace.status(app);
9351
+ const formatResource = (stackUrn, urn) => {
9352
+ return urn.replace(stackUrn + ":", "").replace(/\{([a-z0-9\-\s\/\.\@\_]+)\}/gi, (_, v) => {
9336
9353
  return `${color.dim("{")}${color.warning(v)}${color.dim("}")}`;
9337
9354
  }).replaceAll(":", color.dim(":"));
9338
9355
  };
@@ -9348,16 +9365,29 @@ var resources = (program2) => {
9348
9365
  }
9349
9366
  return color.dim(status);
9350
9367
  };
9351
- log21.message(
9352
- resources2.map((r) => {
9353
- return [
9354
- //
9355
- formatStatus(r.status),
9356
- color.dim(icon.arrow.right),
9357
- formatResource(r.urn)
9358
- ].join(" ");
9359
- }).join("\n")
9360
- );
9368
+ for (const stack of stacks) {
9369
+ if (filters.length > 0) {
9370
+ const found = filters.find((f) => wildstring5.match(f, stack.name));
9371
+ if (!found) {
9372
+ continue;
9373
+ }
9374
+ }
9375
+ log21.step(chalk4.magenta(stack.name));
9376
+ if (stack.resources.length) {
9377
+ log21.message(
9378
+ stack.resources.map((r) => {
9379
+ return [
9380
+ //
9381
+ formatStatus(r.status),
9382
+ color.dim(icon.arrow.right),
9383
+ formatResource(stack.urn, r.urn)
9384
+ ].join(" ");
9385
+ }).join("\n")
9386
+ );
9387
+ } else {
9388
+ log21.message(color.line(`(empty)`));
9389
+ }
9390
+ }
9361
9391
  });
9362
9392
  });
9363
9393
  };
@@ -9401,9 +9431,17 @@ var run = (program2) => {
9401
9431
  process.env.APP_ID = appId;
9402
9432
  process.env.AWS_REGION = region;
9403
9433
  process.env.AWS_ACCOUNT_ID = accountId;
9404
- const module = await tsImport(command.file, {
9405
- parentURL: import.meta.url
9406
- });
9434
+ let module;
9435
+ try {
9436
+ module = await tsImport(command.file, {
9437
+ parentURL: import.meta.url
9438
+ });
9439
+ } catch (error) {
9440
+ if (typeof error === "object" && error !== null && "message" in error) {
9441
+ throw error.message;
9442
+ }
9443
+ throw new ExpectedError(`Failed to import: ${command.file}`);
9444
+ }
9407
9445
  const handler = module[command.handler];
9408
9446
  if (!handler) {
9409
9447
  throw new ExpectedError(`No "${command.handler}" handler found.`);
@@ -9447,7 +9485,7 @@ var push = (program2) => {
9447
9485
  await layout("state pull", async ({ appConfig, stackConfigs }) => {
9448
9486
  const region = appConfig.region;
9449
9487
  const profile = appConfig.profile;
9450
- const credentials = getCredentials(appConfig.profile);
9488
+ const credentials = await getCredentials(appConfig.profile);
9451
9489
  const accountId = await getAccountId(credentials, region);
9452
9490
  const { app } = createApp({ appConfig, stackConfigs, accountId });
9453
9491
  const { state: state2 } = await createWorkSpace({ credentials, region, accountId, profile });
@@ -9626,7 +9664,7 @@ import { log as log24 } from "@awsless/clui";
9626
9664
  import chalk5 from "chalk";
9627
9665
  import chunk2 from "chunk";
9628
9666
  import { formatDate } from "date-fns";
9629
- import wildstring5 from "wildstring";
9667
+ import wildstring6 from "wildstring";
9630
9668
  var logs = (program2) => {
9631
9669
  program2.command("logs").argument(`<stacks...>`, "Provide a list of stacks to stream logs from.").description("Stream the latest logs from you app.").action(async (filters) => {
9632
9670
  await layout(`logs`, async ({ appConfig, stackConfigs }) => {
@@ -9644,7 +9682,7 @@ var logs = (program2) => {
9644
9682
  await workspace.hydrate(app);
9645
9683
  const logGroupArns = [];
9646
9684
  for (const stack of app.stacks) {
9647
- if (filters.find((f) => wildstring5.match(f, stack.name))) {
9685
+ if (filters.find((f) => wildstring6.match(f, stack.name))) {
9648
9686
  for (const resource of stack.resources) {
9649
9687
  if (resource.type === "aws_cloudwatch_log_group") {
9650
9688
  const logGroup = resource;
@@ -9667,7 +9705,7 @@ var logs = (program2) => {
9667
9705
  const streams = await log24.task({
9668
9706
  initialMessage: "Connecting to the log stream...",
9669
9707
  errorMessage: "Failed to connect to the log stream.",
9670
- async task(update) {
9708
+ async task(ctx) {
9671
9709
  const result = await Promise.all(
9672
9710
  chunk2(logGroupArns, 10).map(async (arns) => {
9673
9711
  const command = new StartLiveTailCommand({
@@ -9682,7 +9720,7 @@ var logs = (program2) => {
9682
9720
  return response.responseStream;
9683
9721
  })
9684
9722
  );
9685
- update(
9723
+ ctx.updateMessage(
9686
9724
  `Connected to ${result.length} log stream${plural(result.length)} for ${logGroupArns.length} function${plural(logGroupArns.length)}.`
9687
9725
  );
9688
9726
  return result;
@@ -10068,7 +10106,7 @@ program.on("option:skip-prompt", () => {
10068
10106
  process.env.SKIP_PROMPT = program.opts().skipPrompt ? "1" : void 0;
10069
10107
  });
10070
10108
  program.on("option:no-cache", () => {
10071
- process.env.NO_CACHE = program.opts().noCache ? "1" : void 0;
10109
+ process.env.NO_CACHE = program.opts().cache === false ? "1" : void 0;
10072
10110
  });
10073
10111
  commands8.forEach((fn) => fn(program));
10074
10112
 
Binary file
Binary file
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@awsless/awsless",
3
- "version": "0.0.584",
3
+ "version": "0.0.585",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -34,22 +34,22 @@
34
34
  },
35
35
  "peerDependencies": {
36
36
  "@awsless/big-float": "^0.1.5",
37
- "@awsless/clui": "^0.0.7",
38
37
  "@awsless/cloudwatch": "^0.0.1",
39
38
  "@awsless/duration": "^0.0.4",
39
+ "@awsless/clui": "^0.0.8",
40
40
  "@awsless/dynamodb": "^0.3.6",
41
- "@awsless/json": "^0.0.10",
42
41
  "@awsless/lambda": "^0.0.35",
43
- "@awsless/mqtt": "^0.0.2",
44
- "@awsless/open-search": "^0.0.21",
42
+ "@awsless/json": "^0.0.10",
43
+ "@awsless/iot": "^0.0.3",
45
44
  "@awsless/redis": "^0.0.14",
46
- "@awsless/sns": "^0.0.10",
47
45
  "@awsless/s3": "^0.0.21",
48
- "@awsless/sqs": "^0.0.16",
49
- "@awsless/iot": "^0.0.3",
46
+ "@awsless/open-search": "^0.0.21",
50
47
  "@awsless/validate": "^0.1.3",
48
+ "@awsless/sns": "^0.0.10",
51
49
  "@awsless/ssm": "^0.0.7",
52
- "@awsless/weak-cache": "^0.0.1"
50
+ "@awsless/weak-cache": "^0.0.1",
51
+ "@awsless/sqs": "^0.0.16",
52
+ "@awsless/mqtt": "^0.0.2"
53
53
  },
54
54
  "dependencies": {
55
55
  "@arcanyx/cidr-slicer": "^0.3.0",
@@ -78,7 +78,7 @@
78
78
  "@terraforge/core": "^0.0.19",
79
79
  "@terraforge/terraform": "^0.0.13",
80
80
  "@types/aws-lambda": "^8.10.110",
81
- "@types/bun": "1.3.5",
81
+ "@types/bun": "1.3.8",
82
82
  "@types/chunk": "^0.0.0",
83
83
  "@types/decompress": "^4.2.4",
84
84
  "@types/folder-hash": "^4.0.4",
@@ -133,7 +133,7 @@
133
133
  "type-fest": "^4.20.1",
134
134
  "uuid": "^9.0.0",
135
135
  "vite": "^5.0.0",
136
- "vitest": "^3.1.4",
136
+ "vitest": "^4.0.18",
137
137
  "wildstring": "^1.0.9",
138
138
  "wrap-ansi": "^8.1.0",
139
139
  "zip-a-folder": "^3.1.6",
@@ -142,11 +142,11 @@
142
142
  "@awsless/big-float": "^0.1.5",
143
143
  "@awsless/cloudwatch": "^0.0.1",
144
144
  "@awsless/duration": "^0.0.4",
145
- "@awsless/json": "^0.0.10",
146
145
  "@awsless/graphql": "^0.0.9",
147
146
  "@awsless/scheduler": "^0.0.4",
148
147
  "@awsless/size": "^0.0.2",
149
- "@awsless/clui": "^0.0.7",
148
+ "@awsless/json": "^0.0.10",
149
+ "@awsless/clui": "^0.0.8",
150
150
  "@awsless/validate": "^0.1.3",
151
151
  "@awsless/ts-file-cache": "^0.0.12"
152
152
  },