firebase-tools 11.1.0 → 11.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. package/lib/accountExporter.js +11 -4
  2. package/lib/accountImporter.js +5 -6
  3. package/lib/appdistribution/client.js +7 -9
  4. package/lib/auth.js +3 -5
  5. package/lib/checkValidTargetFilters.js +28 -18
  6. package/lib/commands/database-profile.js +2 -3
  7. package/lib/commands/database-push.js +2 -3
  8. package/lib/commands/database-remove.js +1 -2
  9. package/lib/commands/database-set.js +1 -2
  10. package/lib/commands/deploy.js +5 -6
  11. package/lib/commands/ext-dev-emulators-exec.js +1 -1
  12. package/lib/commands/ext-dev-emulators-start.js +1 -1
  13. package/lib/commands/ext-dev-list.js +6 -7
  14. package/lib/commands/ext-info.js +12 -13
  15. package/lib/commands/ext.js +2 -3
  16. package/lib/commands/functions-delete.js +1 -7
  17. package/lib/commands/open.js +5 -6
  18. package/lib/commands/serve.js +3 -5
  19. package/lib/commands/use.js +2 -3
  20. package/lib/config.js +4 -3
  21. package/lib/deploy/database/prepare.js +2 -3
  22. package/lib/deploy/extensions/secrets.js +3 -3
  23. package/lib/deploy/functions/build.js +3 -2
  24. package/lib/deploy/functions/ensure.js +1 -11
  25. package/lib/deploy/functions/prepare.js +3 -13
  26. package/lib/deploy/functions/prepareFunctionsUpload.js +2 -3
  27. package/lib/deploy/functions/release/fabricator.js +0 -1
  28. package/lib/deploy/functions/release/index.js +1 -5
  29. package/lib/deploy/functions/runtimes/discovery/index.js +18 -3
  30. package/lib/deploy/functions/runtimes/discovery/v1alpha1.js +3 -2
  31. package/lib/deploy/functions/runtimes/golang/index.js +2 -22
  32. package/lib/deploy/functions/runtimes/node/index.js +3 -7
  33. package/lib/deploy/functions/runtimes/node/parseTriggers.js +1 -1
  34. package/lib/deploy/lifecycleHooks.js +7 -10
  35. package/lib/deploy/storage/prepare.js +1 -1
  36. package/lib/emulator/auth/index.js +1 -1
  37. package/lib/emulator/auth/operations.js +336 -64
  38. package/lib/emulator/auth/server.js +2 -2
  39. package/lib/emulator/auth/state.js +32 -7
  40. package/lib/emulator/commandUtils.js +1 -1
  41. package/lib/emulator/constants.js +1 -1
  42. package/lib/emulator/controller.js +6 -5
  43. package/lib/emulator/databaseEmulator.js +2 -2
  44. package/lib/emulator/download.js +1 -1
  45. package/lib/emulator/events/types.js +2 -3
  46. package/lib/emulator/firestoreEmulator.js +2 -2
  47. package/lib/emulator/functionsEmulator.js +27 -37
  48. package/lib/emulator/functionsEmulatorRuntime.js +7 -7
  49. package/lib/emulator/hostingEmulator.js +1 -1
  50. package/lib/emulator/hub.js +1 -1
  51. package/lib/emulator/loggingEmulator.js +1 -1
  52. package/lib/emulator/pubsubEmulator.js +1 -1
  53. package/lib/emulator/storage/crc.js +4 -4
  54. package/lib/emulator/storage/index.js +1 -1
  55. package/lib/emulator/types.js +1 -1
  56. package/lib/extensions/askUserForConsent.js +1 -2
  57. package/lib/extensions/askUserForParam.js +15 -18
  58. package/lib/extensions/emulator/optionsHelper.js +4 -4
  59. package/lib/extensions/extensionsApi.js +1 -22
  60. package/lib/extensions/extensionsHelper.js +6 -6
  61. package/lib/extensions/listExtensions.js +9 -10
  62. package/lib/extensions/manifest.js +2 -2
  63. package/lib/extensions/resolveSource.js +11 -7
  64. package/lib/extensions/secretsUtils.js +3 -3
  65. package/lib/extensions/types.js +24 -0
  66. package/lib/extensions/updateHelper.js +1 -1
  67. package/lib/extensions/utils.js +1 -2
  68. package/lib/extensions/warnings.js +3 -3
  69. package/lib/firestore/encodeFirestoreValue.js +11 -8
  70. package/lib/fsAsync.js +3 -3
  71. package/lib/functionsConfig.js +17 -14
  72. package/lib/functionsConfigClone.js +10 -12
  73. package/lib/gcp/cloudfunctions.js +2 -15
  74. package/lib/gcp/rules.js +1 -1
  75. package/lib/gcp/runtimeconfig.js +2 -2
  76. package/lib/hosting/proxy.js +1 -1
  77. package/lib/init/features/hosting/github.js +1 -1
  78. package/lib/init/features/hosting/index.js +2 -2
  79. package/lib/localFunction.js +4 -4
  80. package/lib/previews.js +1 -1
  81. package/lib/profileReport.js +10 -10
  82. package/lib/prompt.js +1 -2
  83. package/lib/rc.js +1 -1
  84. package/lib/rulesDeploy.js +2 -2
  85. package/lib/serve/index.js +4 -5
  86. package/lib/utils.js +30 -6
  87. package/npm-shrinkwrap.json +2 -2
  88. package/package.json +10 -9
@@ -10,7 +10,7 @@ const logger_1 = require("../../../logger");
10
10
  const INDEX_TEMPLATE = fs.readFileSync(__dirname + "/../../../../templates/init/hosting/index.html", "utf8");
11
11
  const MISSING_TEMPLATE = fs.readFileSync(__dirname + "/../../../../templates/init/hosting/404.html", "utf8");
12
12
  const DEFAULT_IGNORES = ["firebase.json", "**/.*", "**/node_modules/**"];
13
- async function doSetup(setup, config, options) {
13
+ async function doSetup(setup, config) {
14
14
  setup.hosting = {};
15
15
  logger_1.logger.info();
16
16
  logger_1.logger.info(`Your ${clc.bold("public")} directory is the folder (relative to your project directory) that`);
@@ -51,7 +51,7 @@ async function doSetup(setup, config, options) {
51
51
  const response = await c.get("/firebasejs/releases.json");
52
52
  await config.askWriteProjectFile(`${setup.hosting.public}/index.html`, INDEX_TEMPLATE.replace(/{{VERSION}}/g, response.body.current.version));
53
53
  if (setup.hosting.github) {
54
- return (0, github_1.initGitHub)(setup, config, options);
54
+ return (0, github_1.initGitHub)(setup);
55
55
  }
56
56
  }
57
57
  exports.doSetup = doSetup;
@@ -38,13 +38,13 @@ LocalFunction.prototype._substituteParams = function (resource, params) {
38
38
  return resource.replace(wildcardRegex, function (wildcard) {
39
39
  var wildcardNoBraces = wildcard.slice(1, -1);
40
40
  var sub = _.get(params, wildcardNoBraces);
41
- return sub || wildcardNoBraces + _.random(1, 9);
41
+ return sub || wildcardNoBraces + utils.randomInt(1, 9);
42
42
  });
43
43
  };
44
44
  LocalFunction.prototype._constructCallableFunc = function (data, opts) {
45
45
  opts = opts || {};
46
46
  var headers = {};
47
- if (_.has(opts, "instanceIdToken")) {
47
+ if (opts.instanceIdToken) {
48
48
  headers["Firebase-Instance-ID-Token"] = opts.instanceIdToken;
49
49
  }
50
50
  return request.post({
@@ -134,7 +134,7 @@ LocalFunction.prototype._call = function (data, opts) {
134
134
  }
135
135
  else if (this.eventTrigger) {
136
136
  if (this._isDatabaseFunc(this.eventTrigger)) {
137
- operationType = _.last(this.eventTrigger.eventType.split("."));
137
+ operationType = utils.last(this.eventTrigger.eventType.split("."));
138
138
  switch (operationType) {
139
139
  case "create":
140
140
  dataPayload = {
@@ -159,7 +159,7 @@ LocalFunction.prototype._call = function (data, opts) {
159
159
  this.controller.call(this.name, dataPayload, opts);
160
160
  }
161
161
  else if (this._isFirestoreFunc(this.eventTrigger)) {
162
- operationType = _.last(this.eventTrigger.eventType.split("."));
162
+ operationType = utils.last(this.eventTrigger.eventType.split("."));
163
163
  switch (operationType) {
164
164
  case "create":
165
165
  dataPayload = {
package/lib/previews.js CHANGED
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.previews = void 0;
4
4
  const lodash_1 = require("lodash");
5
5
  const configstore_1 = require("./configstore");
6
- exports.previews = Object.assign({ rtdbrules: false, ext: false, extdev: false, rtdbmanagement: false, golang: false, deletegcfartifacts: false, artifactregistry: false, emulatoruisnapshot: false, frameworkawareness: false, functionsparams: false }, configstore_1.configstore.get("previews"));
6
+ exports.previews = Object.assign({ rtdbrules: false, ext: false, extdev: false, rtdbmanagement: false, golang: false, deletegcfartifacts: false, emulatoruisnapshot: false, frameworkawareness: false, functionsparams: false }, configstore_1.configstore.get("previews"));
7
7
  if (process.env.FIREBASE_CLI_PREVIEWS) {
8
8
  process.env.FIREBASE_CLI_PREVIEWS.split(",").forEach((feature) => {
9
9
  if ((0, lodash_1.has)(exports.previews, feature)) {
@@ -62,7 +62,7 @@ function formatBytes(bytes) {
62
62
  }
63
63
  exports.formatBytes = formatBytes;
64
64
  function extractReadableIndex(query) {
65
- if (_.has(query, "orderBy")) {
65
+ if (query.orderBy) {
66
66
  return query.orderBy;
67
67
  }
68
68
  const indexPath = _.get(query, "index.path");
@@ -96,13 +96,13 @@ class ProfileReport {
96
96
  if (!data.unIndexed) {
97
97
  return;
98
98
  }
99
- if (!_.has(this.state.unindexed, path)) {
99
+ if (!this.state.unindexed.path) {
100
100
  this.state.unindexed[path] = {};
101
101
  }
102
102
  const pathNode = this.state.unindexed[path];
103
103
  const query = data.querySet[0];
104
104
  const index = JSON.stringify(query.index);
105
- if (!_.has(pathNode, index)) {
105
+ if (!pathNode[index]) {
106
106
  pathNode[index] = {
107
107
  times: 0,
108
108
  query: query,
@@ -132,7 +132,7 @@ class ProfileReport {
132
132
  }
133
133
  }
134
134
  collectSpeed(data, path, opType) {
135
- if (!_.has(opType, path)) {
135
+ if (!opType[path]) {
136
136
  opType[path] = {
137
137
  times: 0,
138
138
  millis: 0,
@@ -155,7 +155,7 @@ class ProfileReport {
155
155
  }
156
156
  }
157
157
  collectBandwidth(bytes, path, direction) {
158
- if (!_.has(direction, path)) {
158
+ if (!direction[path]) {
159
159
  direction[path] = {
160
160
  times: 0,
161
161
  bytes: 0,
@@ -239,7 +239,7 @@ class ProfileReport {
239
239
  if (!this.options.collapse) {
240
240
  return pathedObject;
241
241
  }
242
- const allSegments = _.keys(pathedObject).map((path) => {
242
+ const allSegments = Object.keys(pathedObject).map((path) => {
243
243
  return path.split("/").filter((s) => {
244
244
  return s !== "";
245
245
  });
@@ -302,9 +302,9 @@ class ProfileReport {
302
302
  };
303
303
  });
304
304
  });
305
- const paths = _.keys(unindexed);
305
+ const paths = Object.keys(unindexed);
306
306
  paths.forEach((path) => {
307
- const indices = _.keys(unindexed[path]);
307
+ const indices = Object.keys(unindexed[path]);
308
308
  indices.forEach((index) => {
309
309
  const data = unindexed[path][index];
310
310
  const row = [path, extractReadableIndex(data.query), formatNumber(data.times)];
@@ -327,7 +327,7 @@ class ProfileReport {
327
327
  times: b1.times + b2.times,
328
328
  };
329
329
  });
330
- const paths = _.orderBy(_.keys(data), [(p) => data[p].bytes], ["desc"]);
330
+ const paths = _.orderBy(Object.keys(data), [(p) => data[p].bytes], ["desc"]);
331
331
  paths.forEach((path) => {
332
332
  const bandwidth = data[path];
333
333
  const row = [
@@ -392,7 +392,7 @@ class ProfileReport {
392
392
  rejected: s1.rejected + s2.rejected,
393
393
  };
394
394
  });
395
- let paths = _.keys(data);
395
+ let paths = Object.keys(data);
396
396
  paths = _.orderBy(paths, (path) => {
397
397
  const speed = data[path];
398
398
  return speed.millis / speed.times;
package/lib/prompt.js CHANGED
@@ -2,7 +2,6 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.promptOnce = exports.prompt = void 0;
4
4
  const inquirer = require("inquirer");
5
- const _ = require("lodash");
6
5
  const error_1 = require("./error");
7
6
  async function prompt(options, questions) {
8
7
  const prompts = [];
@@ -12,7 +11,7 @@ async function prompt(options, questions) {
12
11
  }
13
12
  }
14
13
  if (prompts.length && options.nonInteractive) {
15
- const missingOptions = _.uniq(_.map(prompts, "name")).join(", ");
14
+ const missingOptions = Array.from(new Set(prompts.map((p) => p.name))).join(", ");
16
15
  throw new error_1.FirebaseError(`Missing required options (${missingOptions}) while running in non-interactive mode`, {
17
16
  children: prompts,
18
17
  });
package/lib/rc.js CHANGED
@@ -93,7 +93,7 @@ class RC {
93
93
  }
94
94
  }
95
95
  const existing = this.target(project, type, targetName);
96
- const list = _.uniq(existing.concat(resources)).sort();
96
+ const list = Array.from(new Set(existing.concat(resources))).sort();
97
97
  this.set(["targets", project, type, targetName], list);
98
98
  this.save();
99
99
  return changed;
@@ -91,8 +91,8 @@ class RulesDeploy {
91
91
  }, this.options);
92
92
  if (confirm) {
93
93
  const releases = await gcp.rules.listAllReleases(this.options.project);
94
- const unreleased = _.reject(history, (ruleset) => {
95
- return !!releases.find((release) => release.rulesetName === ruleset.name);
94
+ const unreleased = history.filter((ruleset) => {
95
+ return !releases.find((release) => release.rulesetName === ruleset.name);
96
96
  });
97
97
  const entriesToDelete = unreleased.reverse().slice(0, RULESETS_TO_GC);
98
98
  for (const entry of entriesToDelete) {
@@ -1,7 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.serve = void 0;
4
- const _ = require("lodash");
5
4
  const logger_1 = require("../logger");
6
5
  const frameworks_1 = require("../frameworks");
7
6
  const previews_1 = require("../previews");
@@ -11,23 +10,23 @@ const TARGETS = {
11
10
  functions: new FunctionsServer(),
12
11
  };
13
12
  async function serve(options) {
14
- const targetNames = options.targets;
13
+ const targetNames = options.targets || [];
15
14
  options.port = parseInt(options.port, 10);
16
15
  if (previews_1.previews.frameworkawareness &&
17
16
  targetNames.includes("hosting") &&
18
17
  [].concat(options.config.get("hosting")).some((it) => it.source)) {
19
18
  await (0, frameworks_1.prepareFrameworks)(targetNames, options, options);
20
19
  }
21
- await Promise.all(_.map(targetNames, (targetName) => {
20
+ await Promise.all(targetNames.map((targetName) => {
22
21
  return TARGETS[targetName].start(options);
23
22
  }));
24
- await Promise.all(_.map(targetNames, (targetName) => {
23
+ await Promise.all(targetNames.map((targetName) => {
25
24
  return TARGETS[targetName].connect();
26
25
  }));
27
26
  await new Promise((resolve) => {
28
27
  process.on("SIGINT", () => {
29
28
  logger_1.logger.info("Shutting down...");
30
- return Promise.all(_.map(targetNames, (targetName) => {
29
+ Promise.all(targetNames.map((targetName) => {
31
30
  return TARGETS[targetName].stop(options);
32
31
  }))
33
32
  .then(resolve)
package/lib/utils.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.cloneDeep = exports.groupBy = exports.assertIsStringOrUndefined = exports.assertIsNumber = exports.assertIsString = exports.assertDefined = exports.thirtyDaysFromNow = exports.isRunningInWSL = exports.isCloudEnvironment = exports.datetimeString = exports.createDestroyer = exports.promiseWithSpinner = exports.setupLoggers = exports.tryParse = exports.tryStringify = exports.promiseProps = exports.promiseWhile = exports.promiseAllSettled = exports.getFunctionsEventProvider = exports.endpoint = exports.makeActiveProject = exports.streamToString = exports.stringToStream = exports.explainStdin = exports.allSettled = exports.reject = exports.logLabeledError = exports.logLabeledWarning = exports.logWarning = exports.logLabeledBullet = exports.logBullet = exports.logLabeledSuccess = exports.logSuccess = exports.addSubdomain = exports.addDatabaseNamespace = exports.getDatabaseViewDataUrl = exports.getDatabaseUrl = exports.envOverride = exports.getInheritedOption = exports.consoleUrl = exports.envOverrides = void 0;
3
+ exports.randomInt = exports.debounce = exports.last = exports.cloneDeep = exports.groupBy = exports.assertIsStringOrUndefined = exports.assertIsNumber = exports.assertIsString = exports.assertDefined = exports.thirtyDaysFromNow = exports.isRunningInWSL = exports.isCloudEnvironment = exports.datetimeString = exports.createDestroyer = exports.promiseWithSpinner = exports.setupLoggers = exports.tryParse = exports.tryStringify = exports.promiseProps = exports.promiseWhile = exports.promiseAllSettled = exports.getFunctionsEventProvider = exports.endpoint = exports.makeActiveProject = exports.streamToString = exports.stringToStream = exports.explainStdin = exports.allSettled = exports.reject = exports.logLabeledError = exports.logLabeledWarning = exports.logWarning = exports.logLabeledBullet = exports.logBullet = exports.logLabeledSuccess = exports.logSuccess = exports.addSubdomain = exports.addDatabaseNamespace = exports.getDatabaseViewDataUrl = exports.getDatabaseUrl = exports.envOverride = exports.getInheritedOption = exports.consoleUrl = exports.envOverrides = void 0;
4
4
  const _ = require("lodash");
5
5
  const url = require("url");
6
6
  const clc = require("cli-color");
@@ -28,7 +28,7 @@ exports.consoleUrl = consoleUrl;
28
28
  function getInheritedOption(options, key) {
29
29
  let target = options;
30
30
  while (target) {
31
- if (_.has(target, key)) {
31
+ if (target[key] !== undefined) {
32
32
  return target[key];
33
33
  }
34
34
  target = target.parent;
@@ -184,13 +184,13 @@ function makeActiveProject(projectDir, newActive) {
184
184
  }
185
185
  exports.makeActiveProject = makeActiveProject;
186
186
  function endpoint(parts) {
187
- return `/${_.join(parts, "/")}`;
187
+ return `/${parts.join("/")}`;
188
188
  }
189
189
  exports.endpoint = endpoint;
190
190
  function getFunctionsEventProvider(eventType) {
191
191
  const parts = eventType.split("/");
192
192
  if (parts.length > 1) {
193
- const provider = _.last(parts[1].split("."));
193
+ const provider = last(parts[1].split("."));
194
194
  return _.capitalize(provider);
195
195
  }
196
196
  if (eventType.match(/google.pubsub/)) {
@@ -218,7 +218,7 @@ function getFunctionsEventProvider(eventType) {
218
218
  }
219
219
  exports.getFunctionsEventProvider = getFunctionsEventProvider;
220
220
  function promiseAllSettled(promises) {
221
- const wrappedPromises = _.map(promises, async (p) => {
221
+ const wrappedPromises = promises.map(async (p) => {
222
222
  try {
223
223
  const val = await Promise.resolve(p);
224
224
  return { state: "fulfilled", value: val };
@@ -250,7 +250,7 @@ async function promiseWhile(action, check, interval = 2500) {
250
250
  exports.promiseWhile = promiseWhile;
251
251
  async function promiseProps(obj) {
252
252
  const resultObj = {};
253
- const promises = _.keys(obj).map(async (key) => {
253
+ const promises = Object.keys(obj).map(async (key) => {
254
254
  const r = await Promise.resolve(obj[key]);
255
255
  resultObj[key] = r;
256
256
  });
@@ -435,3 +435,27 @@ function cloneDeep(obj) {
435
435
  return cloneObject(obj);
436
436
  }
437
437
  exports.cloneDeep = cloneDeep;
438
+ function last(arr) {
439
+ if (!Array.isArray(arr)) {
440
+ return;
441
+ }
442
+ return arr[arr.length - 1];
443
+ }
444
+ exports.last = last;
445
+ function debounce(fn, delay, { leading } = {}) {
446
+ let timer;
447
+ return (...args) => {
448
+ if (!timer && leading) {
449
+ fn(...args);
450
+ }
451
+ clearTimeout(timer);
452
+ timer = setTimeout(() => fn(...args), delay);
453
+ };
454
+ }
455
+ exports.debounce = debounce;
456
+ function randomInt(min, max) {
457
+ min = Math.floor(min);
458
+ max = Math.ceil(max) + 1;
459
+ return Math.floor(Math.random() * (max - min) + min);
460
+ }
461
+ exports.randomInt = randomInt;
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "firebase-tools",
3
- "version": "11.1.0",
3
+ "version": "11.2.0",
4
4
  "lockfileVersion": 2,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "firebase-tools",
9
- "version": "11.1.0",
9
+ "version": "11.2.0",
10
10
  "license": "MIT",
11
11
  "dependencies": {
12
12
  "@google-cloud/pubsub": "^3.0.1",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "firebase-tools",
3
- "version": "11.1.0",
3
+ "version": "11.2.0",
4
4
  "description": "Command-Line Interface for Firebase",
5
5
  "main": "./lib/index.js",
6
6
  "bin": {
@@ -23,15 +23,16 @@
23
23
  "mocha": "nyc mocha 'src/test/**/*.{ts,js}'",
24
24
  "prepare": "npm run clean && npm run build -- --build tsconfig.publish.json",
25
25
  "test": "npm run lint:quiet && npm run test:compile && npm run mocha",
26
- "test:client-integration": "./scripts/client-integration-tests/run.sh",
26
+ "test:client-integration": "bash ./scripts/client-integration-tests/run.sh",
27
27
  "test:compile": "tsc --project tsconfig.compile.json",
28
- "test:emulator": "./scripts/emulator-tests/run.sh",
29
- "test:extensions-deploy": "./scripts/extensions-deploy-tests/run.sh",
30
- "test:extensions-emulator": "./scripts/extensions-emulator-tests/run.sh",
31
- "test:hosting": "./scripts/hosting-tests/run.sh",
32
- "test:triggers-end-to-end": "./scripts/triggers-end-to-end-tests/run.sh",
33
- "test:storage-deploy": "./scripts/storage-deploy-tests/run.sh",
34
- "test:storage-emulator-integration": "./scripts/storage-emulator-integration/run.sh"
28
+ "test:emulator": "bash ./scripts/emulator-tests/run.sh",
29
+ "test:import-export": "bash ./scripts/emulator-import-export-tests/run.sh",
30
+ "test:extensions-deploy": "bash ./scripts/extensions-deploy-tests/run.sh",
31
+ "test:extensions-emulator": "bash ./scripts/extensions-emulator-tests/run.sh",
32
+ "test:hosting": "bash ./scripts/hosting-tests/run.sh",
33
+ "test:triggers-end-to-end": "bash ./scripts/triggers-end-to-end-tests/run.sh",
34
+ "test:storage-deploy": "bash ./scripts/storage-deploy-tests/run.sh",
35
+ "test:storage-emulator-integration": "bash ./scripts/storage-emulator-integration/run.sh"
35
36
  },
36
37
  "files": [
37
38
  "lib",