@awsless/awsless 0.0.103 → 0.0.105

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
@@ -992,26 +992,38 @@ import { join as join2 } from "path";
992
992
 
993
993
  // src/util/fingerprint.ts
994
994
  import { createHash as createHash2 } from "crypto";
995
- import { readFile, stat as stat2 } from "fs/promises";
996
- import { basename, dirname as dirname2, join } from "path";
995
+ import { readFile, readdir, stat as stat2 } from "fs/promises";
996
+ import { basename, dirname as dirname2, extname, join } from "path";
997
997
  import parseImports from "parse-imports";
998
- var generateFingerprint = async (file) => {
999
- const hashes = /* @__PURE__ */ new Map();
1000
- const generate = async (file2) => {
1001
- if (hashes.has(file2)) {
1002
- return;
998
+ var extensions = ["js", "mjs", "jsx", "ts", "mts", "tsx"];
999
+ var generateFileHashes = async (file, hashes) => {
1000
+ if (hashes.has(file)) {
1001
+ return;
1002
+ }
1003
+ const code = await readModuleFile(file);
1004
+ const deps = await findDependencies(file, code);
1005
+ const hash = createHash2("sha1").update(code).digest();
1006
+ hashes.set(file, hash);
1007
+ for (const dep of deps) {
1008
+ if (dep.startsWith("/")) {
1009
+ await generateFileHashes(dep, hashes);
1003
1010
  }
1004
- const code = await readModuleFile(file2);
1005
- const deps = await findDependencies(file2, code);
1006
- const hash = createHash2("sha1").update(code).digest();
1007
- hashes.set(file2, hash);
1008
- for (const dep of deps) {
1009
- if (dep.startsWith("/")) {
1010
- await generate(dep);
1011
- }
1011
+ }
1012
+ };
1013
+ var fingerprintFromFile = async (file) => {
1014
+ const hashes = /* @__PURE__ */ new Map();
1015
+ await generateFileHashes(file, hashes);
1016
+ const merge = Buffer.concat(Array.from(hashes.values()).sort());
1017
+ return createHash2("sha1").update(merge).digest("hex");
1018
+ };
1019
+ var fingerprintFromDirectory = async (dir) => {
1020
+ const hashes = /* @__PURE__ */ new Map();
1021
+ const files = await readdir(dir, { recursive: true });
1022
+ for (const file of files) {
1023
+ if (extensions.includes(extname(file).substring(1))) {
1024
+ await generateFileHashes(join(dir, file), hashes);
1012
1025
  }
1013
- };
1014
- await generate(file);
1026
+ }
1015
1027
  const merge = Buffer.concat(Array.from(hashes.values()).sort());
1016
1028
  return createHash2("sha1").update(merge).digest("hex");
1017
1029
  };
@@ -1020,7 +1032,6 @@ var readModuleFile = (file) => {
1020
1032
  return readFiles([file, file.substring(0, file.length - 3) + ".ts"]);
1021
1033
  }
1022
1034
  if (!basename(file).includes(".")) {
1023
- const extensions = ["js", "mjs", "jsx", "ts", "mts", "tsx"];
1024
1035
  return readFiles([
1025
1036
  file,
1026
1037
  ...extensions.map((exp) => `${file}.${exp}`),
@@ -1091,7 +1102,7 @@ var InlineFileCode = class extends Asset {
1091
1102
  code;
1092
1103
  handler;
1093
1104
  async build({ read, write }) {
1094
- const fingerprint = await generateFingerprint(this.file);
1105
+ const fingerprint = await fingerprintFromFile(this.file);
1095
1106
  await write(fingerprint, async (write2) => {
1096
1107
  const bundler = this.bundler ?? rollupBundle();
1097
1108
  const {
@@ -1135,7 +1146,7 @@ var FileCode = class extends Asset {
1135
1146
  // private bundle?: Buffer
1136
1147
  s3;
1137
1148
  async build({ write, read }) {
1138
- this.fingerprint = await generateFingerprint(this.file);
1149
+ this.fingerprint = await fingerprintFromFile(this.file);
1139
1150
  await write(this.fingerprint, async (write2) => {
1140
1151
  const bundler = this.bundler ?? rollupBundle();
1141
1152
  const { hash, files, handler } = await bundler(this.file);
@@ -1286,6 +1297,9 @@ var directories = {
1286
1297
  },
1287
1298
  get template() {
1288
1299
  return join3(this.output, "template");
1300
+ },
1301
+ get test() {
1302
+ return join3(this.output, "test");
1289
1303
  }
1290
1304
  };
1291
1305
  var setRoot = (path = root) => {
@@ -3137,7 +3151,7 @@ var FileCode2 = class extends Asset {
3137
3151
  }
3138
3152
  code;
3139
3153
  async build({ read, write }) {
3140
- const fingerprint = await generateFingerprint(this.file);
3154
+ const fingerprint = await fingerprintFromFile(this.file);
3141
3155
  await write(fingerprint, async (write2) => {
3142
3156
  const builder = rollupResolver({ minify: false });
3143
3157
  const code2 = await builder(this.file);
@@ -8292,149 +8306,63 @@ import { configDefaults } from "vitest/config";
8292
8306
  import { startVitest } from "vitest/node";
8293
8307
  import commonjs3 from "@rollup/plugin-commonjs";
8294
8308
  import nodeResolve3 from "@rollup/plugin-node-resolve";
8295
- import json3 from "@rollup/plugin-json";
8296
8309
  import { swc as swc4 } from "rollup-plugin-swc3";
8297
8310
  import { getTests } from "@vitest/runner/utils";
8298
- import { basename as basename3, extname, join as join11, relative as relative4 } from "path";
8311
+ import { basename as basename3, extname as extname2, join as join11, relative as relative4 } from "path";
8299
8312
 
8300
8313
  // src/cli/ui/layout/text-box.ts
8301
8314
  import wrapAnsi3 from "wrap-ansi";
8302
- var textWrap = (text, width, { indent = 0, ...rest } = {}) => {
8315
+ var textWrap = (text, width, { indent = 0, skipFirstLine = false, ...rest } = {}) => {
8303
8316
  const space = " ".repeat(indent);
8304
- return wrapAnsi3(text, width - indent, rest).split(br()).map((line2) => `${space}${line2}`).join(br());
8317
+ return wrapAnsi3(text, width - indent, { hard: true, ...rest }).split(br()).map((line2, i) => i === 0 && skipFirstLine ? line2 : `${space}${line2}`).join(br());
8305
8318
  };
8306
8319
 
8307
8320
  // src/cli/ui/complex/tester.ts
8321
+ import { mkdir as mkdir6, readFile as readFile6, writeFile as writeFile5 } from "fs/promises";
8322
+ import json3 from "@rollup/plugin-json";
8308
8323
  var CustomReporter = class {
8309
- constructor(stack, out) {
8310
- this.stack = stack;
8311
- this.out = out;
8312
- }
8313
- started = false;
8314
8324
  interval;
8315
- timer;
8316
8325
  tasks;
8317
8326
  ctx;
8318
- line = new Signal([]);
8319
- icon;
8320
8327
  logs = [];
8321
- stopSpinner;
8328
+ events = {};
8329
+ on(event, cb) {
8330
+ this.events[event] = cb;
8331
+ }
8322
8332
  onInit(ctx) {
8323
8333
  this.ctx = ctx;
8324
8334
  }
8325
8335
  onCollected() {
8326
8336
  this.tasks = this.ctx?.state.getFiles();
8327
- if (!this.started) {
8328
- this.start();
8329
- this.started = true;
8337
+ if (!this.interval) {
8338
+ this.interval = setInterval(this.update.bind(this), 33);
8339
+ this.update();
8340
+ this.events.start?.();
8330
8341
  }
8331
8342
  }
8332
8343
  onFinished() {
8333
- this.stop();
8334
- }
8335
- start() {
8336
- const [icon, stop] = createSpinner();
8337
- this.icon = icon;
8338
- this.stopSpinner = stop;
8339
- this.interval = setInterval(this.update.bind(this), 33);
8340
- this.timer = createTimer();
8341
- this.update();
8342
- this.out.write(this.line);
8343
- this.out.gap();
8344
- }
8345
- stop() {
8346
8344
  clearInterval(this.interval);
8347
8345
  this.interval = void 0;
8348
- this.stopSpinner?.();
8349
8346
  const tests = getTests(this.tasks);
8350
8347
  const passed = tests.filter((t) => t.result?.state === "pass").length;
8351
8348
  const failed = tests.filter((t) => t.result?.state === "fail").length;
8352
- const icon = failed > 0 ? style.error(symbol.error) : style.success(symbol.success);
8353
- const values = [icon, " ", style.label(this.stack)];
8354
- if (passed > 0) {
8355
- values.push(" ", style.placeholder(symbol.pointerSmall), style.success(` ${passed} passed`));
8356
- }
8357
- if (failed > 0) {
8358
- values.push(" ", style.placeholder(symbol.pointerSmall), style.error(` ${failed} failed`));
8359
- }
8360
- this.line.set([
8361
- ...values,
8362
- " ",
8363
- style.placeholder(symbol.pointerSmall),
8364
- " ",
8365
- this.timer?.(),
8366
- br(),
8367
- this.formatLogs(),
8368
- this.formatErrors()
8369
- ]);
8370
- }
8371
- update() {
8372
- const tasks = this.runningTasks(this.tasks);
8373
- this.line.set([
8374
- this.icon,
8375
- " ",
8376
- style.label(this.stack),
8377
- // ' ',
8378
- // style.placeholder(`(${tests.length})`),
8379
- ...tasks.map((task, i) => [
8380
- " ",
8381
- style.placeholder(symbol.pointerSmall),
8382
- " ",
8383
- i === 0 ? this.formatFileName(task.name) : style.placeholder(task.name)
8384
- ]),
8385
- // style.placeholder(tests.length),
8386
- // ' ',
8387
- // style.placeholder(symbol.pointerSmall),
8388
- // ' ',
8389
- " ",
8390
- style.placeholder(symbol.pointerSmall),
8391
- " ",
8392
- this.timer?.(),
8393
- br(),
8394
- this.formatLogs()
8395
- // this.formatErrors(),
8396
- // ...this.renderTask(this.tasks!),
8397
- ]);
8398
- }
8399
- formatLogs() {
8400
- return this.logs.map((log) => {
8401
- return [style.placeholder(`${symbol.dot} LOG `), log];
8402
- });
8403
- }
8404
- formatErrors() {
8405
- const tests = getTests(this.tasks);
8406
- return tests.map((test2) => {
8349
+ const errors = tests.map((test2) => {
8407
8350
  if (!test2.result?.errors || test2.result.errors.length === 0) {
8408
8351
  return [];
8409
8352
  }
8410
- return [
8411
- br(),
8412
- style.error(`${symbol.dot} `),
8413
- style.error.inverse(` FAIL `),
8414
- " ",
8415
- style.placeholder(symbol.pointerSmall),
8416
- " ",
8417
- this.formatFileName(test2.file?.name),
8418
- " ",
8419
- style.placeholder(symbol.pointerSmall),
8420
- " ",
8421
- test2.name,
8422
- br(),
8423
- test2.result.errors.map((error) => {
8424
- const [message, ...comment] = error.message.split("//");
8425
- const errorMessage = [
8426
- style.error(`${style.error.bold(error.name)}: ${message}`),
8427
- comment.length > 0 ? style.placeholder(`//${comment}`) : "",
8428
- br()
8429
- ].join("");
8430
- const values = [textWrap(errorMessage, this.out.width(), { indent: 2, hard: true })];
8431
- if (error.showDiff && error.diff) {
8432
- values.push(br(), error.diff, br());
8433
- }
8434
- return values;
8435
- })
8436
- ];
8437
- });
8353
+ return test2.result.errors.map((error) => ({
8354
+ file: test2.file?.name,
8355
+ test: test2.name,
8356
+ diff: error.showDiff && error.diff ? error.diff : void 0,
8357
+ type: error.name,
8358
+ message: error.message
8359
+ }));
8360
+ }).flat();
8361
+ this.events.finished?.({ errors, passed, failed, logs: this.logs });
8362
+ }
8363
+ update() {
8364
+ const tasks = this.runningTasks(this.tasks);
8365
+ this.events.update?.({ tasks });
8438
8366
  }
8439
8367
  onUserConsoleLog(log) {
8440
8368
  if (log.taskId) {
@@ -8443,17 +8371,7 @@ var CustomReporter = class {
8443
8371
  test2.name;
8444
8372
  }
8445
8373
  }
8446
- this.logs.push(log.content);
8447
- }
8448
- formatFileName(path) {
8449
- if (!path) {
8450
- return "";
8451
- }
8452
- path = join11(process.cwd(), path);
8453
- path = relative4(this.ctx.config.dir, path);
8454
- const ext = extname(path);
8455
- const bas = basename3(path, ext);
8456
- return `${bas}${style.placeholder(ext)}`;
8374
+ this.logs.push(log.content.trimEnd());
8457
8375
  }
8458
8376
  runningTask(tasks) {
8459
8377
  return tasks.find((t) => t.result?.state === "run");
@@ -8470,8 +8388,119 @@ var CustomReporter = class {
8470
8388
  }
8471
8389
  };
8472
8390
  var singleTester = (stack, dir) => {
8391
+ const formatFileName = (path) => {
8392
+ if (!path) {
8393
+ return "";
8394
+ }
8395
+ path = join11(process.cwd(), path);
8396
+ path = relative4(dir, path);
8397
+ const ext = extname2(path);
8398
+ const bas = basename3(path, ext);
8399
+ return `${bas}${style.placeholder(ext)}`;
8400
+ };
8401
+ const formatLogs = (logs2, width) => {
8402
+ return logs2.map((log) => {
8403
+ return [
8404
+ textWrap([style.placeholder(`${symbol.dot} LOG `), log].join(""), width, {
8405
+ skipFirstLine: true,
8406
+ indent: 2
8407
+ }),
8408
+ br()
8409
+ ];
8410
+ }).flat();
8411
+ };
8412
+ const formatErrors = (errors, width) => {
8413
+ return errors.map((error) => {
8414
+ const [message, ...comment] = error.message.split("//");
8415
+ const errorMessage = [
8416
+ style.error(`${style.error.bold(error.type)}: ${message}`),
8417
+ comment.length > 0 ? style.placeholder(`//${comment}`) : "",
8418
+ br()
8419
+ ].join("");
8420
+ return [
8421
+ br(),
8422
+ style.error(`${symbol.dot} `),
8423
+ style.error.inverse(` FAIL `),
8424
+ " ",
8425
+ style.placeholder(symbol.pointerSmall),
8426
+ " ",
8427
+ formatFileName(error.file),
8428
+ " ",
8429
+ style.placeholder(symbol.pointerSmall),
8430
+ " ",
8431
+ error.test,
8432
+ br(),
8433
+ textWrap(errorMessage, width, { indent: 2 }),
8434
+ ...error.diff ? [br(), error.diff, br()] : []
8435
+ ];
8436
+ }).flat();
8437
+ };
8438
+ const formatOutput = ({ passed, failed, width, logs: logs2, errors, duration }) => {
8439
+ const icon = failed > 0 ? style.error(symbol.error) : style.success(symbol.success);
8440
+ const values = [icon, " ", style.label(stack)];
8441
+ if (passed > 0) {
8442
+ values.push(" ", style.placeholder(symbol.pointerSmall), style.success(` ${passed} passed`));
8443
+ }
8444
+ if (failed > 0) {
8445
+ values.push(" ", style.placeholder(symbol.pointerSmall), style.error(` ${failed} failed`));
8446
+ }
8447
+ return [
8448
+ ...values,
8449
+ " ",
8450
+ style.placeholder(symbol.pointerSmall),
8451
+ " ",
8452
+ duration,
8453
+ br(),
8454
+ ...formatLogs(logs2, width),
8455
+ ...formatErrors(errors, width)
8456
+ ];
8457
+ };
8473
8458
  return async (term) => {
8474
- await startVitest(
8459
+ await mkdir6(directories.test, { recursive: true });
8460
+ const fingerprint = await fingerprintFromDirectory(dir);
8461
+ const file = join11(directories.test, `${stack}.json`);
8462
+ const exists = await fileExist(file);
8463
+ const line2 = new Signal([]);
8464
+ term.out.write(line2);
8465
+ if (exists) {
8466
+ const raw = await readFile6(file, { encoding: "utf8" });
8467
+ const data2 = JSON.parse(raw);
8468
+ if (data2.fingerprint === fingerprint) {
8469
+ line2.set(formatOutput({ ...data2, width: term.out.width() }));
8470
+ return data2.failed === 0;
8471
+ }
8472
+ }
8473
+ const [icon, stop] = createSpinner();
8474
+ const timer = createTimer();
8475
+ const reporter = new CustomReporter();
8476
+ line2.set([icon, " ", style.label(stack)]);
8477
+ reporter.on("update", ({ tasks }) => {
8478
+ line2.set([
8479
+ icon,
8480
+ " ",
8481
+ style.label(stack),
8482
+ ...tasks.map((task, i) => [
8483
+ " ",
8484
+ style.placeholder(symbol.pointerSmall),
8485
+ " ",
8486
+ i === 0 ? formatFileName(task.name) : style.placeholder(task.name)
8487
+ ]).flat(),
8488
+ " ",
8489
+ style.placeholder(symbol.pointerSmall),
8490
+ " ",
8491
+ timer(),
8492
+ br()
8493
+ ]);
8494
+ });
8495
+ let data;
8496
+ reporter.on("finished", ({ errors, passed, failed, logs: logs2 }) => {
8497
+ stop();
8498
+ const duration = timer();
8499
+ const width = term.out.width();
8500
+ data = { fingerprint, errors, passed, failed, logs: logs2, duration };
8501
+ line2.set(formatOutput({ ...data, width }));
8502
+ });
8503
+ const result = await startVitest(
8475
8504
  "test",
8476
8505
  [],
8477
8506
  {
@@ -8483,7 +8512,7 @@ var singleTester = (stack, dir) => {
8483
8512
  include: ["**/*.{js,jsx,ts,tsx}"],
8484
8513
  exclude: ["**/_*", "**/_*/**", ...configDefaults.exclude],
8485
8514
  globals: true,
8486
- reporters: new CustomReporter(stack, term.out)
8515
+ reporters: reporter
8487
8516
  // outputFile: {
8488
8517
  // json: './.awsless/test/output.json',
8489
8518
  // },
@@ -8506,15 +8535,21 @@ var singleTester = (stack, dir) => {
8506
8535
  ]
8507
8536
  }
8508
8537
  );
8538
+ await writeFile5(file, JSON.stringify(data));
8539
+ return result?.state.getCountOfFailedTests() === 0;
8509
8540
  };
8510
8541
  };
8511
8542
  var runTester = (tests) => {
8512
8543
  return async (term) => {
8513
8544
  for (const [name, paths] of tests.entries()) {
8514
8545
  for (const path of paths) {
8515
- await term.out.write(singleTester(name, path));
8546
+ const result = await term.out.write(singleTester(name, path));
8547
+ if (!result) {
8548
+ return false;
8549
+ }
8516
8550
  }
8517
8551
  }
8552
+ return true;
8518
8553
  };
8519
8554
  };
8520
8555
 
@@ -8541,7 +8576,10 @@ var deploy = (program2) => {
8541
8576
  }
8542
8577
  await cleanUp();
8543
8578
  await write(typesGenerator(config2));
8544
- await write(runTester(tests));
8579
+ const passed = await write(runTester(tests));
8580
+ if (!passed) {
8581
+ throw new Cancelled();
8582
+ }
8545
8583
  await write(assetBuilder(app));
8546
8584
  await write(assetPublisher(config2, app));
8547
8585
  await write(templateBuilder(app));
package/dist/index.js CHANGED
@@ -320,7 +320,7 @@ var mockQueue = (cb) => {
320
320
  const mock = createProxy((stack) => {
321
321
  return createProxy((name) => {
322
322
  return (handle) => {
323
- list[getQueueName(stack, name)] = handle ?? (() => {
323
+ list[getQueueName(name, stack)] = handle ?? (() => {
324
324
  });
325
325
  };
326
326
  });
@@ -329,7 +329,7 @@ var mockQueue = (cb) => {
329
329
  const result = mockSQS(list);
330
330
  return createProxy((stack) => {
331
331
  return createProxy((name) => {
332
- return result[getQueueName(stack, name)];
332
+ return result[getQueueName(name, stack)];
333
333
  });
334
334
  });
335
335
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@awsless/awsless",
3
- "version": "0.0.103",
3
+ "version": "0.0.105",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -25,10 +25,10 @@
25
25
  },
26
26
  "peerDependencies": {
27
27
  "@awsless/lambda": "^0.0.13",
28
- "@awsless/sqs": "^0.0.7",
29
28
  "@awsless/redis": "^0.0.8",
30
- "@awsless/ssm": "^0.0.7",
31
29
  "@awsless/sns": "^0.0.7",
30
+ "@awsless/sqs": "^0.0.7",
31
+ "@awsless/ssm": "^0.0.7",
32
32
  "@awsless/validate": "^0.0.6"
33
33
  },
34
34
  "dependencies": {