@awsless/cli 0.0.46-local.1 → 0.0.46-local.2

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
@@ -102748,7 +102748,7 @@ var init_find_cache_dir = __esm(() => {
102748
102748
  ({ env: env3, cwd } = process4);
102749
102749
  });
102750
102750
 
102751
- // ../open-search/dist/chunk-7I7EB23J.js
102751
+ // ../open-search/dist/chunk-M36HBITL.js
102752
102752
  import { mkdir as mkdir6, rename as rename4, rm as rm7, stat as stat5 } from "fs/promises";
102753
102753
  import { join as join27, resolve as resolve3 } from "path";
102754
102754
  import { mkdir as mkdir22, readdir as readdir4, rename as rename22, rm as rm22, stat as stat22 } from "fs/promises";
@@ -102842,7 +102842,7 @@ var import_decompress, import_decompress2, getArchiveName = (version2) => {
102842
102842
  }
102843
102843
  return findJavaHome(dir);
102844
102844
  }, VERSION_2_8_0;
102845
- var init_chunk_7I7EB23J = __esm(() => {
102845
+ var init_chunk_M36HBITL = __esm(() => {
102846
102846
  init_find_cache_dir();
102847
102847
  init_find_cache_dir();
102848
102848
  import_decompress = __toESM(require_decompress(), 1);
@@ -102856,7 +102856,8 @@ var init_chunk_7I7EB23J = __esm(() => {
102856
102856
  "http.port": port,
102857
102857
  "path.data": `${cache3}/data`,
102858
102858
  "path.logs": `${cache3}/logs`,
102859
- "plugins.security.disabled": true
102859
+ "plugins.security.disabled": true,
102860
+ "cluster.routing.allocation.disk.threshold_enabled": false
102860
102861
  })
102861
102862
  };
102862
102863
  });
@@ -103462,7 +103463,7 @@ var import_sleep_await, mock, searchClient = (options = {}, service = "es") => {
103462
103463
  return new Schema2((input) => [...input].map((item) => struct.encode(item)), (encoded) => new Set(encoded.map((item) => struct.decode(item))), struct.mapping);
103463
103464
  }, string2 = (props = {}) => new Schema2((value) => value, (value) => value, { type: "keyword", ...props }), uuid = (props = {}) => new Schema2((value) => value, (value) => value, { type: "keyword", ...props });
103464
103465
  var init_dist2 = __esm(() => {
103465
- init_chunk_7I7EB23J();
103466
+ init_chunk_M36HBITL();
103466
103467
  init_dist();
103467
103468
  import_sleep_await = __toESM(require_dist3(), 1);
103468
103469
  BulkError = class extends Error {
@@ -105671,7 +105672,7 @@ var require_readdirp = __commonJS((exports, module) => {
105671
105672
  var sysPath = __require("path");
105672
105673
  var { promisify: promisify2 } = __require("util");
105673
105674
  var picomatch = require_picomatch3();
105674
- var readdir6 = promisify2(fs5.readdir);
105675
+ var readdir7 = promisify2(fs5.readdir);
105675
105676
  var stat7 = promisify2(fs5.stat);
105676
105677
  var lstat4 = promisify2(fs5.lstat);
105677
105678
  var realpath2 = promisify2(fs5.realpath);
@@ -105804,7 +105805,7 @@ var require_readdirp = __commonJS((exports, module) => {
105804
105805
  async _exploreDir(path6, depth) {
105805
105806
  let files;
105806
105807
  try {
105807
- files = await readdir6(path6, this._rdOptions);
105808
+ files = await readdir7(path6, this._rdOptions);
105808
105809
  } catch (error3) {
105809
105810
  this._onError(error3);
105810
105811
  }
@@ -151372,6 +151373,22 @@ var AppSchema = exports_external.object({
151372
151373
  test: TestDefaultSchema
151373
151374
  }).strict();
151374
151375
 
151376
+ // src/config/schema/local-entry.ts
151377
+ import { stat as stat4 } from "fs/promises";
151378
+ var LocalEntrySchema = exports_external.union([
151379
+ RelativePathSchema.refine(async (path2) => {
151380
+ try {
151381
+ const s2 = await stat4(path2);
151382
+ return s2.isFile() || s2.isDirectory();
151383
+ } catch (error3) {
151384
+ return false;
151385
+ }
151386
+ }, `File or directory doesn't exist`),
151387
+ exports_external.object({
151388
+ nocheck: RelativePathSchema.describe("Specifies a local file or directory without checking if the file or directory exists.")
151389
+ }).transform((v3) => v3.nocheck)
151390
+ ]);
151391
+
151375
151392
  // src/feature/cache/schema.ts
151376
151393
  var StorageSchema = SizeSchema.refine(sizeMin(gibibytes(1)), "Minimum storage size is 1 GB").refine(sizeMax(gibibytes(5000)), "Maximum storage size is 5000 GB");
151377
151394
  var MinimumStorageSchema = StorageSchema.describe("The lower limit for data storage the cache is set to use. You can specify a size value from 1 GB to 5000 GB.");
@@ -151453,22 +151470,6 @@ example: "5 minutes"`),
151453
151470
  payload: exports_external.unknown().optional().describe("The JSON payload that will be passed to the consumer.")
151454
151471
  })).optional().describe(`Define the cron jobs in your stack.`);
151455
151472
 
151456
- // src/config/schema/local-entry.ts
151457
- import { stat as stat4 } from "fs/promises";
151458
- var LocalEntrySchema = exports_external.union([
151459
- RelativePathSchema.refine(async (path2) => {
151460
- try {
151461
- const s2 = await stat4(path2);
151462
- return s2.isFile() || s2.isDirectory();
151463
- } catch (error3) {
151464
- return false;
151465
- }
151466
- }, `File or directory doesn't exist`),
151467
- exports_external.object({
151468
- nocheck: RelativePathSchema.describe("Specifies a local file or directory without checking if the file or directory exists.")
151469
- }).transform((v3) => v3.nocheck)
151470
- ]);
151471
-
151472
151473
  // src/feature/site/schema.ts
151473
151474
  var SitesSchema = exports_external.record(ResourceIdSchema, exports_external.object({
151474
151475
  router: ResourceIdSchema.describe("The router id to link your site with."),
@@ -151710,6 +151711,7 @@ var StackSchema = exports_external.object({
151710
151711
  pubsub: PubSubSchema,
151711
151712
  searchs: SearchsSchema,
151712
151713
  sites: SitesSchema,
151714
+ seed: LocalEntrySchema.optional().describe("The file that seeds your local dev environment with data. It runs with the full local environment on the first dev boot & through the dashboard reseed button."),
151713
151715
  tests: TestsSchema,
151714
151716
  images: ImagesSchema,
151715
151717
  icons: IconsSchema,
@@ -158989,7 +158991,83 @@ import { toSeconds as toSeconds9 } from "@awsless/duration";
158989
158991
  import { CreateTableCommand as CreateTableCommand2, DeleteTableCommand } from "@aws-sdk/client-dynamodb";
158990
158992
  import { PutCommand } from "@aws-sdk/lib-dynamodb";
158991
158993
  import { readFile as readFile15 } from "fs/promises";
158994
+ import { join as join37 } from "path";
158995
+
158996
+ // src/dev/reset.ts
158997
+ var import_ioredis4 = __toESM(require_built3(), 1);
158998
+ import { DeleteCommand, ScanCommand } from "@aws-sdk/lib-dynamodb";
158999
+ import { Client as Client6 } from "@opensearch-project/opensearch";
159000
+ import { readdir as readdir6, rm as rm9 } from "fs/promises";
158992
159001
  import { join as join36 } from "path";
159002
+ var wiping = false;
159003
+ var isWiping = () => wiping;
159004
+ var createDataReset = (props) => {
159005
+ return async () => {
159006
+ wiping = true;
159007
+ try {
159008
+ const dynamo = props.pool.peek("dynamo");
159009
+ if (dynamo) {
159010
+ const client = dynamo.server.getDocumentClient();
159011
+ for (const [name, fingerprint] of dynamo.tableFingerprints) {
159012
+ const keys = JSON.parse(fingerprint).KeySchema.map((key) => key.AttributeName);
159013
+ let cursor;
159014
+ do {
159015
+ const result = await client.send(new ScanCommand({ TableName: name, ExclusiveStartKey: cursor }));
159016
+ for (const item of result.Items ?? []) {
159017
+ await client.send(new DeleteCommand({
159018
+ TableName: name,
159019
+ Key: Object.fromEntries(keys.map((key) => [key, item[key]]))
159020
+ }));
159021
+ }
159022
+ cursor = result.LastEvaluatedKey;
159023
+ } while (cursor);
159024
+ }
159025
+ }
159026
+ for (const stack of props.stackConfigs) {
159027
+ for (const id of Object.keys(stack.caches ?? {})) {
159028
+ const port = props.pool.peek(`cache:${stack.name}:${id}`);
159029
+ if (!port) {
159030
+ continue;
159031
+ }
159032
+ const redis = new import_ioredis4.Redis({ host: "127.0.0.1", port, lazyConnect: true });
159033
+ await redis.connect();
159034
+ await redis.flushall();
159035
+ redis.disconnect();
159036
+ }
159037
+ }
159038
+ const search2 = props.pool.peek("opensearch");
159039
+ if (search2) {
159040
+ const client = new Client6({ node: `http://localhost:${search2.port}` });
159041
+ for (const stack of props.stackConfigs) {
159042
+ for (const [id, searchProps] of Object.entries(stack.searchs ?? {})) {
159043
+ const index = formatSearchIndexName(stack.name, id);
159044
+ try {
159045
+ await client.indices.delete({ index });
159046
+ } catch (_3) {}
159047
+ await applySearchIndex(client, {
159048
+ index,
159049
+ mappings: resolveSearchMappings(searchProps),
159050
+ settings: searchProps.settings
159051
+ });
159052
+ }
159053
+ }
159054
+ }
159055
+ const storeRoot = join36(directories.output, "local", "store");
159056
+ try {
159057
+ for (const bucket of await readdir6(storeRoot)) {
159058
+ for (const entry of await readdir6(join36(storeRoot, bucket))) {
159059
+ if (entry === "image" || entry === "icon") {
159060
+ continue;
159061
+ }
159062
+ await rm9(join36(storeRoot, bucket, entry), { recursive: true, force: true });
159063
+ }
159064
+ }
159065
+ } catch (_3) {}
159066
+ } finally {
159067
+ wiping = false;
159068
+ }
159069
+ };
159070
+ };
158993
159071
 
158994
159072
  // src/feature/table/util.ts
158995
159073
  var formatTableKeys = (props) => {
@@ -159049,7 +159127,7 @@ var createTableInput = (name, props) => {
159049
159127
  };
159050
159128
  };
159051
159129
  var loadSeed = async (stackName, id) => {
159052
- const file2 = join36(directories.output, "local", "seed", "table", stackName, `${id}.json`);
159130
+ const file2 = join37(directories.output, "local", "seed", "table", stackName, `${id}.json`);
159053
159131
  try {
159054
159132
  const items = JSON.parse(await readFile15(file2, "utf8"));
159055
159133
  return Array.isArray(items) ? items : [];
@@ -159123,6 +159201,9 @@ var tableOnDev = async (ctx) => {
159123
159201
  const routeKey = formatRouteKey(stackName, "table", id);
159124
159202
  const eventSourceARN = `arn:aws:dynamodb:${ctx.appConfig.region}:000000000000:table/${name}/stream/local`;
159125
159203
  const unsubscribe = server.onStreamRecord(name, (record) => {
159204
+ if (isWiping()) {
159205
+ return;
159206
+ }
159126
159207
  const event = { Records: [{ ...record, eventSourceARN }] };
159127
159208
  dispatch(event).catch((error3) => {
159128
159209
  reportFailure({
@@ -159959,12 +160040,12 @@ import { toDays as toDays9 } from "@awsless/duration";
159959
160040
  import { formatRouteEnvName as formatRouteEnvName5 } from "awsless";
159960
160041
  import { createHash as createHash18 } from "crypto";
159961
160042
  import { readFile as readFile16 } from "fs/promises";
159962
- import { dirname as dirname18, join as join38 } from "path";
160043
+ import { dirname as dirname18, join as join39 } from "path";
159963
160044
  import { fileURLToPath as fileURLToPath13 } from "url";
159964
160045
 
159965
160046
  // src/feature/image/dev.ts
159966
160047
  import { cp } from "fs/promises";
159967
- import { isAbsolute as isAbsolute2, join as join37 } from "path";
160048
+ import { isAbsolute as isAbsolute2, join as join38 } from "path";
159968
160049
  var imageOnDev = async (ctx) => {
159969
160050
  const images = ctx.stackConfigs.flatMap((stack) => Object.keys(stack.images ?? {}));
159970
160051
  if (images.length === 0) {
@@ -160002,8 +160083,8 @@ var imageOnDev = async (ctx) => {
160002
160083
  }
160003
160084
  if (props.origin.static) {
160004
160085
  ctx.addEnv(`${routeKey}:IMAGE_ORIGIN_S3`, "true");
160005
- const source = isAbsolute2(props.origin.static) ? props.origin.static : join37(directories.root, props.origin.static);
160006
- await cp(source, join37(directories.output, "local", "store", bucket, folder, "origin"), {
160086
+ const source = isAbsolute2(props.origin.static) ? props.origin.static : join38(directories.root, props.origin.static);
160087
+ await cp(source, join38(directories.output, "local", "store", bucket, folder, "origin"), {
160007
160088
  recursive: true
160008
160089
  });
160009
160090
  }
@@ -160033,7 +160114,7 @@ var imageFeature = defineFeature({
160033
160114
  throw new FileError("app.json", "The image feature requires an arm64 function bundle.");
160034
160115
  }
160035
160116
  const group4 = new Group(ctx.base, "image", "layer");
160036
- const path6 = join38(dirname18(fileURLToPath13(import.meta.url)), "/layers/sharp-arm.zip");
160117
+ const path6 = join39(dirname18(fileURLToPath13(import.meta.url)), "/layers/sharp-arm.zip");
160037
160118
  const layerId = formatGlobalResourceName({
160038
160119
  appName: ctx.appConfig.name,
160039
160120
  resourceType: "layer",
@@ -160113,7 +160194,7 @@ var imageFeature = defineFeature({
160113
160194
  const serverRouteKey = formatRouteKey(ctx.stack.name, "image", id);
160114
160195
  bundle.addHandler({
160115
160196
  routeKey: serverRouteKey,
160116
- file: join38(dirname18(fileURLToPath13(import.meta.url)), "/handlers/image.js"),
160197
+ file: join39(dirname18(fileURLToPath13(import.meta.url)), "/handlers/image.js"),
160117
160198
  exportName: "default",
160118
160199
  external: ["sharp"]
160119
160200
  });
@@ -160151,8 +160232,8 @@ var imageFeature = defineFeature({
160151
160232
  new aws2.s3.BucketObject(group4, `static-${file2}`, {
160152
160233
  bucket: bucket.name,
160153
160234
  key: `${folder}origin/${file2}`,
160154
- source: join38(props.origin.static, file2),
160155
- sourceHash: $hash(join38(props.origin.static, file2))
160235
+ source: join39(props.origin.static, file2),
160236
+ sourceHash: $hash(join39(props.origin.static, file2))
160156
160237
  }, {
160157
160238
  replaceOnChanges: ["bucket", "key"]
160158
160239
  });
@@ -160168,12 +160249,12 @@ var imageFeature = defineFeature({
160168
160249
  // src/feature/icon/index.ts
160169
160250
  import { toDays as toDays10 } from "@awsless/duration";
160170
160251
  import { formatRouteEnvName as formatRouteEnvName6 } from "awsless";
160171
- import { dirname as dirname19, join as join40 } from "path";
160252
+ import { dirname as dirname19, join as join41 } from "path";
160172
160253
  import { fileURLToPath as fileURLToPath14 } from "url";
160173
160254
 
160174
160255
  // src/feature/icon/dev.ts
160175
160256
  import { cp as cp2 } from "fs/promises";
160176
- import { isAbsolute as isAbsolute3, join as join39 } from "path";
160257
+ import { isAbsolute as isAbsolute3, join as join40 } from "path";
160177
160258
  var iconOnDev = async (ctx) => {
160178
160259
  const icons = ctx.stackConfigs.flatMap((stack) => Object.keys(stack.icons ?? {}));
160179
160260
  if (icons.length === 0) {
@@ -160211,8 +160292,8 @@ var iconOnDev = async (ctx) => {
160211
160292
  }
160212
160293
  if (props.origin.static) {
160213
160294
  ctx.addEnv(`${routeKey}:ICON_ORIGIN_S3`, "true");
160214
- const source = isAbsolute3(props.origin.static) ? props.origin.static : join39(directories.root, props.origin.static);
160215
- await cp2(source, join39(directories.output, "local", "store", bucket, folder, "origin"), {
160295
+ const source = isAbsolute3(props.origin.static) ? props.origin.static : join40(directories.root, props.origin.static);
160296
+ await cp2(source, join40(directories.output, "local", "store", bucket, folder, "origin"), {
160216
160297
  recursive: true
160217
160298
  });
160218
160299
  }
@@ -160259,7 +160340,7 @@ var iconFeature = defineFeature({
160259
160340
  const serverRouteKey = formatRouteKey(ctx.stack.name, "icon", id);
160260
160341
  bundle.addHandler({
160261
160342
  routeKey: serverRouteKey,
160262
- file: join40(dirname19(fileURLToPath14(import.meta.url)), "/handlers/icon.js"),
160343
+ file: join41(dirname19(fileURLToPath14(import.meta.url)), "/handlers/icon.js"),
160263
160344
  exportName: "default"
160264
160345
  });
160265
160346
  addRoutes({
@@ -160299,8 +160380,8 @@ var iconFeature = defineFeature({
160299
160380
  new aws2.s3.BucketObject(group4, `static-${file2}`, {
160300
160381
  bucket: bucket.name,
160301
160382
  key: `${folder}origin/${file2}`,
160302
- source: join40(props.origin.static, file2),
160303
- sourceHash: $hash(join40(props.origin.static, file2))
160383
+ source: join41(props.origin.static, file2),
160384
+ sourceHash: $hash(join41(props.origin.static, file2))
160304
160385
  }, {
160305
160386
  replaceOnChanges: ["bucket", "key"]
160306
160387
  });
@@ -160327,10 +160408,10 @@ var import_deepmerge4 = __toESM(require_cjs2(), 1);
160327
160408
  // src/feature/job/build/executable.ts
160328
160409
  import { createHash as createHash19 } from "crypto";
160329
160410
  import { readFile as readFile17, writeFile as writeFile8 } from "fs/promises";
160330
- import { join as join41, resolve as resolve4 } from "path";
160411
+ import { join as join42, resolve as resolve4 } from "path";
160331
160412
  var buildJobExecutable = async (input, outputPath, architecture) => {
160332
- const filePath = join41(outputPath, "program");
160333
- const wrapperPath = join41(outputPath, "wrapper.ts");
160413
+ const filePath = join42(outputPath, "program");
160414
+ const wrapperPath = join42(outputPath, "wrapper.ts");
160334
160415
  const handlerPath = resolve4(input);
160335
160416
  await writeFile8(wrapperPath, `import { parse } from '@awsless/json'
160336
160417
  import { getObject } from '@awsless/s3'
@@ -160843,7 +160924,7 @@ import { stringify as stringify3 } from "@awsless/json";
160843
160924
  import { generateFileHash as generateFileHash4 } from "@awsless/ts-file-cache";
160844
160925
  var import_deepmerge6 = __toESM(require_cjs2(), 1);
160845
160926
  import { createHash as createHash21 } from "crypto";
160846
- import { join as join42 } from "path";
160927
+ import { join as join43 } from "path";
160847
160928
  var createFargateTask = (parentGroup, ctx, ns, id, local) => {
160848
160929
  const group4 = new Group(parentGroup, "instance", ns);
160849
160930
  const name = formatLocalResourceName({
@@ -161048,7 +161129,7 @@ var createFargateTask = (parentGroup, ctx, ns, id, local) => {
161048
161129
  healthCheck: props.healthCheck ? {
161049
161130
  command: [
161050
161131
  "CMD-SHELL",
161051
- `curl -f http://${join42("localhost", props.healthCheck.path)} || exit 1`
161132
+ `curl -f http://${join43("localhost", props.healthCheck.path)} || exit 1`
161052
161133
  ],
161053
161134
  interval: toSeconds11(props.healthCheck.interval),
161054
161135
  retries: props.healthCheck.retries,
@@ -163803,12 +163884,12 @@ import { DynamoDBClient as DynamoDBClient3 } from "@awsless/dynamodb";
163803
163884
  // src/cli/ui/complex/run-tests.ts
163804
163885
  var import_wildstring3 = __toESM(require_wildstring(), 1);
163805
163886
  import { mkdir as mkdir7, readFile as readFile18, writeFile as writeFile9 } from "fs/promises";
163806
- import { join as join44 } from "path";
163887
+ import { join as join45 } from "path";
163807
163888
  import { parse as parse7, stringify as stringify4 } from "@awsless/json";
163808
163889
  import { generateFolderHash, loadWorkspace as loadWorkspace2 } from "@awsless/ts-file-cache";
163809
163890
 
163810
163891
  // src/test/start.ts
163811
- import { dirname as dirname20, join as join43 } from "path";
163892
+ import { dirname as dirname20, join as join44 } from "path";
163812
163893
  import { fileURLToPath as fileURLToPath15 } from "url";
163813
163894
  import { configDefaults } from "vitest/config";
163814
163895
  import { startVitest } from "vitest/node";
@@ -163876,7 +163957,7 @@ var startTest = async (props) => {
163876
163957
  reporters: [new NullReporter],
163877
163958
  env: props.env,
163878
163959
  setupFiles: [
163879
- join43(__dirname4, "test-global-setup.js")
163960
+ join44(__dirname4, "test-global-setup.js")
163880
163961
  ]
163881
163962
  }, {
163882
163963
  logLevel: "silent",
@@ -164032,7 +164113,7 @@ var logTestErrors = (event) => {
164032
164113
  };
164033
164114
  var runTest = async (stack, dir, filters, workspace, opts) => {
164034
164115
  await mkdir7(directories.test, { recursive: true });
164035
- const file2 = join44(directories.test, `${stack}.json`);
164116
+ const file2 = join45(directories.test, `${stack}.json`);
164036
164117
  const fingerprint = await generateFolderHash(workspace, dir);
164037
164118
  if (!process.env.NO_CACHE) {
164038
164119
  const exists5 = await fileExist(file2);
@@ -164905,12 +164986,12 @@ var auth = (program3) => {
164905
164986
 
164906
164987
  // src/cli/command/bind.ts
164907
164988
  import { readFile as readFile19 } from "fs/promises";
164908
- import { join as join45 } from "path";
164989
+ import { join as join46 } from "path";
164909
164990
  var bind = (program3) => {
164910
164991
  program3.command("bind").argument("[command...]", "The command to execute").option("--config <string...>", "List of config values that will be accessable", (v3) => v3.split(",")).option("--local", "Bind against the running local dev environment instead of the deployed app").description(`Bind your site environment variables to a command`).action(async (commands5 = [], opts) => {
164911
164992
  await layout("bind", async ({ appConfig, stackConfigs }) => {
164912
164993
  if (opts.local) {
164913
- const file2 = join45(directories.output, "local", "env.json");
164994
+ const file2 = join46(directories.output, "local", "env.json");
164914
164995
  let env5;
164915
164996
  try {
164916
164997
  env5 = JSON.parse(await readFile19(file2, "utf8"));
@@ -165044,7 +165125,7 @@ var {
165044
165125
  isIBMi
165045
165126
  } = require_constants7();
165046
165127
  var stat7 = promisify2(fs5.stat);
165047
- var readdir6 = promisify2(fs5.readdir);
165128
+ var readdir7 = promisify2(fs5.readdir);
165048
165129
  var arrify = (value = []) => Array.isArray(value) ? value : [value];
165049
165130
  var flatten = (list3, result = []) => {
165050
165131
  list3.forEach((item) => {
@@ -165116,7 +165197,7 @@ class DirEntry {
165116
165197
  return;
165117
165198
  const dir = this.path;
165118
165199
  try {
165119
- await readdir6(dir);
165200
+ await readdir7(dir);
165120
165201
  } catch (err) {
165121
165202
  if (this._removeWatcher) {
165122
165203
  this._removeWatcher(sysPath.dirname(dir), sysPath.basename(dir));
@@ -165703,18 +165784,18 @@ var watchConfig = async (options, resolve5, reject) => {
165703
165784
 
165704
165785
  // src/dev/index.ts
165705
165786
  import { loadWorkspace as loadWorkspace3 } from "@awsless/ts-file-cache";
165706
- import { mkdir as mkdir10, rm as rm11, writeFile as writeFile13 } from "fs/promises";
165707
- import { join as join51 } from "path";
165787
+ import { mkdir as mkdir10, rm as rm12, writeFile as writeFile13 } from "fs/promises";
165788
+ import { join as join53 } from "path";
165708
165789
 
165709
165790
  // src/dev/context.ts
165710
165791
  import { DynamoDBServer } from "@awsless/dynamodb-server";
165711
- import { join as join47 } from "path";
165792
+ import { join as join48 } from "path";
165712
165793
 
165713
165794
  // src/dev/servers/s3.ts
165714
165795
  import { createHash as createHash22 } from "crypto";
165715
165796
  import { createServer as createServer7 } from "http";
165716
- import { mkdir as mkdir8, readdir as readdir7, readFile as readFile20, rm as rm9, stat as stat8, writeFile as writeFile10 } from "fs/promises";
165717
- import { dirname as dirname21, join as join46, relative as relative9, sep as sep4 } from "path";
165797
+ import { mkdir as mkdir8, readdir as readdir8, readFile as readFile20, rm as rm10, stat as stat8, writeFile as writeFile10 } from "fs/promises";
165798
+ import { dirname as dirname21, join as join47, relative as relative9, sep as sep4 } from "path";
165718
165799
  var readBody2 = (req) => {
165719
165800
  return new Promise((resolve5, reject) => {
165720
165801
  const chunks = [];
@@ -165784,8 +165865,8 @@ var createS3Server = (props) => {
165784
165865
  res.end(xmlError("InvalidRequest", "Missing bucket name"));
165785
165866
  return;
165786
165867
  }
165787
- const bucketDir = join46(props.root, bucket);
165788
- const file2 = join46(bucketDir, ...keyParts);
165868
+ const bucketDir = join47(props.root, bucket);
165869
+ const file2 = join47(bucketDir, ...keyParts);
165789
165870
  if (relative9(bucketDir, file2).startsWith("..")) {
165790
165871
  res.writeHead(400, { "content-type": "application/xml" });
165791
165872
  res.end(xmlError("InvalidRequest", "Invalid object key"));
@@ -165797,12 +165878,12 @@ var createS3Server = (props) => {
165797
165878
  const walk2 = async (dir) => {
165798
165879
  let entries2;
165799
165880
  try {
165800
- entries2 = await readdir7(dir, { withFileTypes: true });
165881
+ entries2 = await readdir8(dir, { withFileTypes: true });
165801
165882
  } catch (_4) {
165802
165883
  return;
165803
165884
  }
165804
165885
  for (const entry of entries2) {
165805
- const path6 = join46(dir, entry.name);
165886
+ const path6 = join47(dir, entry.name);
165806
165887
  if (entry.isDirectory()) {
165807
165888
  await walk2(path6);
165808
165889
  } else {
@@ -165853,7 +165934,7 @@ var createS3Server = (props) => {
165853
165934
  return;
165854
165935
  }
165855
165936
  if (req.method === "DELETE") {
165856
- await rm9(file2, { force: true });
165937
+ await rm10(file2, { force: true });
165857
165938
  res.writeHead(204);
165858
165939
  res.end();
165859
165940
  notify("ObjectRemoved:Delete", bucket, key, 0, "");
@@ -165941,7 +166022,7 @@ var createDevContext = (props) => {
165941
166022
  const value = await props.pool.keep("store", null, async () => {
165942
166023
  const rules = [];
165943
166024
  const server = createS3Server({
165944
- root: join47(directories.output, "local", "store"),
166025
+ root: join48(directories.output, "local", "store"),
165945
166026
  region: props.appConfig.region,
165946
166027
  rules
165947
166028
  });
@@ -166010,19 +166091,67 @@ var createDevContext = (props) => {
166010
166091
  };
166011
166092
  };
166012
166093
 
166094
+ // src/dev/seed.ts
166095
+ import { spawn as spawn5 } from "child_process";
166096
+ import { isAbsolute as isAbsolute4, join as join49 } from "path";
166097
+ var createSeedRunner = (props) => {
166098
+ const seeds = props.stackConfigs.filter((stack) => stack.seed).map((stack) => ({
166099
+ name: stack.name,
166100
+ file: isAbsolute4(stack.seed) ? stack.seed : join49(directories.root, stack.seed)
166101
+ }));
166102
+ let running;
166103
+ const run = () => {
166104
+ running ??= (async () => {
166105
+ try {
166106
+ for (const entry of seeds) {
166107
+ debug(`Seeding the ${entry.name} stack`);
166108
+ await new Promise((resolve5, reject) => {
166109
+ const child = spawn5("bun", [entry.file], {
166110
+ cwd: directories.root,
166111
+ stdio: ["ignore", "pipe", "pipe"],
166112
+ env: { ...process.env, ...props.env }
166113
+ });
166114
+ const output = [];
166115
+ const capture = (chunk3) => output.push(chunk3.toString());
166116
+ child.stdout?.on("data", capture);
166117
+ child.stderr?.on("data", capture);
166118
+ child.on("error", reject);
166119
+ child.on("exit", (code) => {
166120
+ const logs = output.join("").trim();
166121
+ if (logs) {
166122
+ debug(logs);
166123
+ }
166124
+ if (code === 0) {
166125
+ resolve5();
166126
+ } else {
166127
+ reject(new Error(`The seed of the "${entry.name}" stack exited with code ${code}:
166128
+ ${logs}`));
166129
+ }
166130
+ });
166131
+ });
166132
+ }
166133
+ } finally {
166134
+ running = undefined;
166135
+ }
166136
+ })();
166137
+ return running;
166138
+ };
166139
+ return { count: seeds.length, run };
166140
+ };
166141
+
166013
166142
  // src/dev/dashboard/index.ts
166014
- var import_ioredis4 = __toESM(require_built3(), 1);
166143
+ var import_ioredis5 = __toESM(require_built3(), 1);
166015
166144
  import { DynamoDBClient as DynamoDBClient4 } from "@aws-sdk/client-dynamodb";
166016
- import { DynamoDBDocumentClient, ScanCommand } from "@aws-sdk/lib-dynamodb";
166145
+ import { DynamoDBDocumentClient, ScanCommand as ScanCommand2 } from "@aws-sdk/lib-dynamodb";
166017
166146
  import { randomUUID as randomUUID5 } from "crypto";
166018
- import { readdir as readdir8, readFile as readFile21, stat as stat9, writeFile as writeFile12 } from "fs/promises";
166147
+ import { readdir as readdir9, readFile as readFile21, stat as stat9, writeFile as writeFile12 } from "fs/promises";
166019
166148
  import { createServer as createServer8 } from "http";
166020
- import { join as join49, relative as relative10, sep as sep5 } from "path";
166149
+ import { join as join51, relative as relative10, sep as sep5 } from "path";
166021
166150
 
166022
166151
  // src/dev/worker.ts
166023
- import { spawn as spawn5 } from "child_process";
166152
+ import { spawn as spawn6 } from "child_process";
166024
166153
  import { writeFile as writeFile11 } from "fs/promises";
166025
- import { join as join48 } from "path";
166154
+ import { join as join50 } from "path";
166026
166155
  class WorkerError extends Error {
166027
166156
  name;
166028
166157
  constructor(name, message4, stack) {
@@ -166115,10 +166244,10 @@ var createBundleWorker = (props) => {
166115
166244
  throw new Error("The bundle worker never became ready.");
166116
166245
  };
166117
166246
  const start = async () => {
166118
- const entry = join48(props.buildDir, "worker.mjs");
166247
+ const entry = join50(props.buildDir, "worker.mjs");
166119
166248
  await writeFile11(entry, WORKER_ENTRY);
166120
166249
  port = await findFreePort();
166121
- child = spawn5("node", ["--enable-source-maps", entry], {
166250
+ child = spawn6("node", ["--enable-source-maps", entry], {
166122
166251
  cwd: props.buildDir,
166123
166252
  stdio: ["ignore", "pipe", "pipe"],
166124
166253
  env: {
@@ -166273,6 +166402,8 @@ var dashboardHtml = `<!doctype html>
166273
166402
  cursor: pointer;
166274
166403
  }
166275
166404
  nav button .count { margin-left: auto; }
166405
+ nav button.reseed { margin-top: auto; color: var(--muted); }
166406
+ nav button.reseed:disabled { cursor: default; }
166276
166407
  .icon {
166277
166408
  width: 15px;
166278
166409
  height: 15px;
@@ -166469,6 +166600,7 @@ const ICONS = {
166469
166600
  config: svg('<line x1="4" y1="21" x2="4" y2="14"/><line x1="4" y1="10" x2="4" y2="3"/><line x1="12" y1="21" x2="12" y2="12"/><line x1="12" y1="8" x2="12" y2="3"/><line x1="20" y1="21" x2="20" y2="16"/><line x1="20" y1="12" x2="20" y2="3"/><line x1="1" y1="14" x2="7" y2="14"/><line x1="9" y1="8" x2="15" y2="8"/><line x1="17" y1="16" x2="23" y2="16"/>'),
166470
166601
  route: svg('<circle cx="12" cy="12" r="10"/><line x1="2" y1="12" x2="22" y2="12"/><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"/>'),
166471
166602
  site: svg('<rect x="2" y="3" width="20" height="14" rx="2"/><line x1="8" y1="21" x2="16" y2="21"/><line x1="12" y1="17" x2="12" y2="21"/>'),
166603
+ seed: svg('<path d="M12 22V8"/><path d="M12 8C12 5 9 2 5 2c0 4 3 6 7 6z"/><path d="M12 12c0-3 3-6 7-6 0 4-3 6-7 6z"/>'),
166472
166604
  }
166473
166605
 
166474
166606
  const icon = kind => {
@@ -167122,6 +167254,46 @@ const render = () => {
167122
167254
  nav.append(button)
167123
167255
  }
167124
167256
 
167257
+ if (state.seeds) {
167258
+ const reseed = $('button', { className: 'reseed' }, [icon('seed'), 'Reset & seed'])
167259
+ let armed = false
167260
+ let disarm
167261
+
167262
+ reseed.onclick = async () => {
167263
+ // The reset wipes all local data, so it asks for a second
167264
+ // click before running.
167265
+ if (!armed) {
167266
+ armed = true
167267
+ reseed.lastChild.textContent = 'Click to confirm'
167268
+ disarm = setTimeout(() => {
167269
+ armed = false
167270
+ reseed.lastChild.textContent = 'Reset & seed'
167271
+ }, 3000)
167272
+ return
167273
+ }
167274
+
167275
+ clearTimeout(disarm)
167276
+ armed = false
167277
+ reseed.disabled = true
167278
+ reseed.lastChild.textContent = 'Seeding...'
167279
+
167280
+ try {
167281
+ const res = await fetch('/api/seed', { method: 'POST' })
167282
+ const data = await res.json()
167283
+ reseed.lastChild.textContent = data.ok ? 'Done' : 'Failed'
167284
+ } catch {
167285
+ reseed.lastChild.textContent = 'Failed'
167286
+ }
167287
+
167288
+ setTimeout(() => {
167289
+ reseed.disabled = false
167290
+ reseed.lastChild.textContent = 'Reset & seed'
167291
+ }, 2000)
167292
+ }
167293
+
167294
+ nav.append(reseed)
167295
+ }
167296
+
167125
167297
  const main = document.getElementById('main')
167126
167298
  main.innerHTML = ''
167127
167299
 
@@ -167201,7 +167373,8 @@ var createDashboardServer = (props) => {
167201
167373
  app: props.app,
167202
167374
  routerPorts: props.routerPorts,
167203
167375
  resources: props.resources,
167204
- routes: props.routes
167376
+ routes: props.routes,
167377
+ seeds: Boolean(props.runSeeds)
167205
167378
  }).replaceAll("<", "\\u003c");
167206
167379
  return { status: 200, body: dashboardHtml.replace("__STATE__", state), type: "text/html" };
167207
167380
  }
@@ -167244,7 +167417,7 @@ var createDashboardServer = (props) => {
167244
167417
  if (url.pathname === "/api/table") {
167245
167418
  const name = url.searchParams.get("name");
167246
167419
  try {
167247
- const result = await getDocumentClient().send(new ScanCommand({ TableName: name, Limit: 100 }));
167420
+ const result = await getDocumentClient().send(new ScanCommand2({ TableName: name, Limit: 100 }));
167248
167421
  return { status: 200, body: JSON.stringify({ items: result.Items ?? [], count: result.Count ?? 0 }) };
167249
167422
  } catch (error3) {
167250
167423
  throw new Error(`Scanning "${name}" via ${props.env.AWS_ENDPOINT_URL_DYNAMODB ?? "no dynamodb endpoint"} failed: ${error3 instanceof Error ? error3.message : String(error3)}`);
@@ -167252,7 +167425,7 @@ var createDashboardServer = (props) => {
167252
167425
  }
167253
167426
  if (url.pathname === "/api/cache") {
167254
167427
  const [host, port] = (url.searchParams.get("target") ?? "").split(":");
167255
- const redis = new import_ioredis4.Redis({ host, port: Number(port), lazyConnect: true });
167428
+ const redis = new import_ioredis5.Redis({ host, port: Number(port), lazyConnect: true });
167256
167429
  try {
167257
167430
  await redis.connect();
167258
167431
  const keyspace = await redis.info("keyspace");
@@ -167299,12 +167472,12 @@ var createDashboardServer = (props) => {
167299
167472
  const walk2 = async (dir) => {
167300
167473
  let entries2;
167301
167474
  try {
167302
- entries2 = await readdir8(dir, { withFileTypes: true });
167475
+ entries2 = await readdir9(dir, { withFileTypes: true });
167303
167476
  } catch (_4) {
167304
167477
  return;
167305
167478
  }
167306
167479
  for (const entry of entries2) {
167307
- const path6 = join49(dir, entry.name);
167480
+ const path6 = join51(dir, entry.name);
167308
167481
  if (entry.isDirectory()) {
167309
167482
  await walk2(path6);
167310
167483
  } else {
@@ -167319,6 +167492,20 @@ var createDashboardServer = (props) => {
167319
167492
  await walk2(props.storeRoot);
167320
167493
  return { status: 200, body: JSON.stringify({ files }) };
167321
167494
  }
167495
+ if (url.pathname === "/api/seed" && req.method === "POST") {
167496
+ if (!props.runSeeds) {
167497
+ return { status: 400, body: JSON.stringify({ error: "No seed files configured." }) };
167498
+ }
167499
+ try {
167500
+ await props.runSeeds();
167501
+ return { status: 200, body: JSON.stringify({ ok: true }) };
167502
+ } catch (error3) {
167503
+ return {
167504
+ status: 500,
167505
+ body: JSON.stringify({ error: error3 instanceof Error ? error3.message : String(error3) })
167506
+ };
167507
+ }
167508
+ }
167322
167509
  if (url.pathname === "/api/config") {
167323
167510
  if (req.method === "PUT") {
167324
167511
  const values2 = JSON.parse((await readBody3(req)).toString() || "{}");
@@ -167552,22 +167739,22 @@ var createLambdaServer = (props) => {
167552
167739
  };
167553
167740
 
167554
167741
  // src/dev/sdk.ts
167555
- import { readdir as readdir9, readFile as readFile22, mkdir as mkdir9, rm as rm10, symlink } from "fs/promises";
167742
+ import { readdir as readdir10, readFile as readFile22, mkdir as mkdir9, rm as rm11, symlink } from "fs/promises";
167556
167743
  import { createRequire } from "module";
167557
- import { dirname as dirname22, join as join50 } from "path";
167744
+ import { dirname as dirname22, join as join52 } from "path";
167558
167745
  var linkSdkPackages = async (buildDir, onWarn) => {
167559
- const filesDir = join50(buildDir, "files");
167746
+ const filesDir = join52(buildDir, "files");
167560
167747
  const packages = new Set;
167561
- for (const file2 of await readdir9(filesDir)) {
167748
+ for (const file2 of await readdir10(filesDir)) {
167562
167749
  if (!file2.endsWith(".mjs")) {
167563
167750
  continue;
167564
167751
  }
167565
- const code = await readFile22(join50(filesDir, file2), "utf8");
167752
+ const code = await readFile22(join52(filesDir, file2), "utf8");
167566
167753
  for (const match3 of code.matchAll(/(?:from\s*|import\()\s*["'](@aws-sdk\/[a-z0-9-]+|sharp)["']/g)) {
167567
167754
  packages.add(match3[1]);
167568
167755
  }
167569
167756
  }
167570
- const projectRequire = createRequire(join50(directories.root, "noop.js"));
167757
+ const projectRequire = createRequire(join52(directories.root, "noop.js"));
167571
167758
  const ownRequire = createRequire(import.meta.url);
167572
167759
  for (const name of packages) {
167573
167760
  try {
@@ -167581,9 +167768,9 @@ var linkSdkPackages = async (buildDir, onWarn) => {
167581
167768
  onWarn?.(`The bundle imports "${name}", which is neither a project dependency nor shipped with the cli. Add it to your project dependencies.`);
167582
167769
  continue;
167583
167770
  }
167584
- const target2 = join50(buildDir, "node_modules", name);
167771
+ const target2 = join52(buildDir, "node_modules", name);
167585
167772
  await mkdir9(dirname22(target2), { recursive: true });
167586
- await rm10(target2, { recursive: true, force: true });
167773
+ await rm11(target2, { recursive: true, force: true });
167587
167774
  await symlink(source, target2, "dir");
167588
167775
  }
167589
167776
  };
@@ -167598,12 +167785,14 @@ var startDev = async (props) => {
167598
167785
  stackConfigs,
167599
167786
  accountId: LOCAL_ACCOUNT_ID
167600
167787
  });
167601
- await mkdir10(join51(directories.output, "local"), { recursive: true });
167788
+ await mkdir10(join53(directories.output, "local"), { recursive: true });
167602
167789
  const routerPorts = {};
167603
167790
  Object.keys(appConfig.router ?? {}).forEach((id, index) => {
167604
167791
  routerPorts[id] = props.port + 1 + index;
167605
167792
  });
167793
+ const firstBoot = props.pool.peek("session") === undefined;
167606
167794
  props.pool.begin();
167795
+ await props.pool.keep("session", null, async () => ({ value: true, stop: () => {} }));
167607
167796
  const dev = createDevContext({ appConfig, stackConfigs, appId, routerPorts, log, pool: props.pool });
167608
167797
  log("Preparing the local resources...");
167609
167798
  for (const feature of features) {
@@ -167642,7 +167831,7 @@ var startDev = async (props) => {
167642
167831
  for (const [id, port] of Object.entries(routerPorts)) {
167643
167832
  env4[`ROUTER_${constantCase(id)}_ENDPOINT`] = `localhost:${port}`;
167644
167833
  }
167645
- await writeFile13(join51(directories.output, "local", "env.json"), JSON.stringify(env4, null, "\t") + `
167834
+ await writeFile13(join53(directories.output, "local", "env.json"), JSON.stringify(env4, null, "\t") + `
167646
167835
  `);
167647
167836
  const sorted = [...builders].sort((a4, b6) => Number(a4.type === "bundle") - Number(b6.type === "bundle"));
167648
167837
  const workspace = await loadWorkspace3(directories.root);
@@ -167701,6 +167890,16 @@ var startDev = async (props) => {
167701
167890
  log("Fix the error - the next invoke retries.");
167702
167891
  dirty = true;
167703
167892
  }
167893
+ const seeder = createSeedRunner({ stackConfigs, env: env4 });
167894
+ const resetData = createDataReset({ pool: props.pool, appConfig, stackConfigs });
167895
+ if (firstBoot && seeder.count > 0 && !dirty) {
167896
+ log("Seeding the local data...");
167897
+ try {
167898
+ await seeder.run();
167899
+ } catch (error3) {
167900
+ log(`Seeding failed: ${error3 instanceof Error ? error3.message : String(error3)}`);
167901
+ }
167902
+ }
167704
167903
  const routers = [];
167705
167904
  for (const [id, port] of Object.entries(routerPorts)) {
167706
167905
  routers.push(await startDevRouter({
@@ -167711,14 +167910,18 @@ var startDev = async (props) => {
167711
167910
  }
167712
167911
  const dashboardPort = props.port;
167713
167912
  const dashboard = createDashboardServer({
167913
+ runSeeds: seeder.count > 0 ? async () => {
167914
+ await resetData();
167915
+ await seeder.run();
167916
+ } : undefined,
167714
167917
  app: appConfig.name,
167715
167918
  region: appConfig.region,
167716
167919
  routerPorts,
167717
167920
  resources: dev.resources,
167718
167921
  routes: dev.routes,
167719
167922
  env: env4,
167720
- storeRoot: join51(directories.output, "local", "store"),
167721
- configFile: join51(directories.output, "local", "config.json"),
167923
+ storeRoot: join53(directories.output, "local", "store"),
167924
+ configFile: join53(directories.output, "local", "config.json"),
167722
167925
  events: dev.events
167723
167926
  });
167724
167927
  dashboard.connect(dispatch);
@@ -167740,7 +167943,7 @@ var startDev = async (props) => {
167740
167943
  dashboardPort,
167741
167944
  routerPorts,
167742
167945
  async stop() {
167743
- await rm11(join51(directories.output, "local", "env.json"), { force: true });
167946
+ await rm12(join53(directories.output, "local", "env.json"), { force: true });
167744
167947
  await watcher.close();
167745
167948
  await restartWatcher?.close();
167746
167949
  for (const router of routers) {
@@ -167804,7 +168007,7 @@ var createServerPool = () => {
167804
168007
 
167805
168008
  // src/type-gen/generate.ts
167806
168009
  import { mkdir as mkdir11, writeFile as writeFile14 } from "fs/promises";
167807
- import { dirname as dirname23, join as join52, relative as relative11 } from "path";
168010
+ import { dirname as dirname23, join as join54, relative as relative11 } from "path";
167808
168011
  var generateTypes = async (props) => {
167809
168012
  const files = [];
167810
168013
  await Promise.all(features.map((feature) => {
@@ -167812,7 +168015,7 @@ var generateTypes = async (props) => {
167812
168015
  ...props,
167813
168016
  async write(file2, data, include = false) {
167814
168017
  const code = data?.toString("utf8");
167815
- const path6 = join52(directories.types, file2);
168018
+ const path6 = join54(directories.types, file2);
167816
168019
  if (code) {
167817
168020
  if (include) {
167818
168021
  files.push(relative11(directories.root, path6));
@@ -167826,7 +168029,7 @@ var generateTypes = async (props) => {
167826
168029
  if (files.length) {
167827
168030
  const code = files.map((file2) => `/// <reference path='${file2}' />`).join(`
167828
168031
  `);
167829
- await writeFile14(join52(directories.root, `awsless.d.ts`), code);
168032
+ await writeFile14(join54(directories.root, `awsless.d.ts`), code);
167830
168033
  }
167831
168034
  };
167832
168035
 
@@ -183447,12 +183650,12 @@ var state = (program3) => {
183447
183650
 
183448
183651
  // src/cli/command/test.ts
183449
183652
  import { mkdir as mkdir12, writeFile as writeFile15 } from "fs/promises";
183450
- import { join as join54 } from "path";
183653
+ import { join as join56 } from "path";
183451
183654
 
183452
183655
  // src/test/manifest.ts
183453
- import { isAbsolute as isAbsolute4, join as join53 } from "path";
183656
+ import { isAbsolute as isAbsolute5, join as join55 } from "path";
183454
183657
  var absolute = (file2) => {
183455
- return isAbsolute4(file2) ? file2 : join53(directories.root, file2);
183658
+ return isAbsolute5(file2) ? file2 : join55(directories.root, file2);
183456
183659
  };
183457
183660
  var createTestManifest = (appConfig, stackConfigs) => {
183458
183661
  const manifest = {
@@ -183548,7 +183751,7 @@ var test2 = (program3) => {
183548
183751
  return "No tests found.";
183549
183752
  }
183550
183753
  const manifest = createTestManifest(props.appConfig, props.stackConfigs);
183551
- const manifestFile = join54(directories.output, "test", "manifest.json");
183754
+ const manifestFile = join56(directories.output, "test", "manifest.json");
183552
183755
  let redis;
183553
183756
  let killSearch;
183554
183757
  manifest.servers = {};
@@ -183575,7 +183778,7 @@ var test2 = (program3) => {
183575
183778
  await redis.ping();
183576
183779
  manifest.servers.redis = { host: "127.0.0.1", port: await redis.getPort() };
183577
183780
  }
183578
- await mkdir12(join54(directories.output, "test"), { recursive: true });
183781
+ await mkdir12(join56(directories.output, "test"), { recursive: true });
183579
183782
  await writeFile15(manifestFile, JSON.stringify(manifest));
183580
183783
  process.env.AWSLESS_TEST_MANIFEST = manifestFile;
183581
183784
  let passed = false;