@awsless/cli 0.0.46-local.10 → 0.0.46-local.12

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
@@ -150257,16 +150257,6 @@ var bootstrapAwsless = async (props) => {
150257
150257
  // src/config/load/load.ts
150258
150258
  import { basename as basename2, dirname as dirname5, join as join13 } from "path";
150259
150259
 
150260
- // src/feature/config/schema.ts
150261
- var ConfigNameSchema = exports_external.string().regex(/^[a-z0-9-]+$/, "Invalid config name");
150262
- var ConfigsSchema = exports_external.array(ConfigNameSchema).optional().describe("Define the config values for your app.");
150263
- var ConfigFileSchema = exports_external.record(ConfigNameSchema, exports_external.union([
150264
- exports_external.string().describe("A committed default value for the local dev environment."),
150265
- exports_external.object({
150266
- secret: exports_external.literal(true).describe("Pulled from ssm into memory on local dev boot, never stored locally.")
150267
- }).describe("A secret config value.")
150268
- ])).describe("The config values of your app.");
150269
-
150270
150260
  // src/config/schema/config-ref.ts
150271
150261
  var ConfigRefSchema = exports_external.string().regex(/^config:[a-z0-9-]+$/, "Invalid config reference");
150272
150262
  var isConfigRef = (value) => {
@@ -150335,6 +150325,10 @@ var AuthDefaultSchema = exports_external.record(ResourceIdSchema, exports_extern
150335
150325
  }).default({}).describe("Specifies the validity duration for every JWT token.")
150336
150326
  })).default({}).describe("Define the authenticatable users in your app.");
150337
150327
 
150328
+ // src/feature/config/schema.ts
150329
+ var ConfigNameSchema = exports_external.string().regex(/^[a-z0-9-]+$/, "Invalid config name");
150330
+ var ConfigsSchema = exports_external.array(ConfigNameSchema).optional().describe("Define the config values for your app.");
150331
+
150338
150332
  // src/feature/domain/schema.ts
150339
150333
  var DomainNameSchema = exports_external.string().regex(/[a-z\-\_\.]/g, "Invalid domain name").describe("Enter a fully qualified domain name, for example, www.example.com. You can optionally include a trailing dot. If you omit the trailing dot, Amazon Route 53 assumes that the domain name that you specify is fully qualified. This means that Route 53 treats www.example.com (without a trailing dot) and www.example.com. (with a trailing dot) as identical.");
150340
150334
  var DNSTypeSchema = exports_external.enum(["A", "AAAA", "CAA", "CNAME", "DS", "MX", "NAPTR", "NS", "PTR", "SOA", "SPF", "SRV", "TXT"]).describe("The DNS record type.");
@@ -152488,32 +152482,8 @@ var loadAppConfig = async (options) => {
152488
152482
  debug("Validate app config file");
152489
152483
  const app = await validateConfig(AppSchema, appConfig.file, appConfig.data);
152490
152484
  app.stage = options.stage;
152491
- await loadConfigFile(app, root3, options.stage);
152492
152485
  return app;
152493
152486
  };
152494
- var loadConfigFile = async (app, root3, stage) => {
152495
- const ext2 = ["config.json", "config.jsonc", "config.json5"];
152496
- const files = await glob(ext2, { cwd: root3 });
152497
- const file2 = ext2.find((name) => files.includes(name));
152498
- if (!file2) {
152499
- return;
152500
- }
152501
- debug("Load config file:", color2.info(file2));
152502
- const config = await readConfigWithStage(join13(root3, file2), stage);
152503
- const entries2 = await validateConfig(ConfigFileSchema, config.file, config.data);
152504
- const defaults2 = {};
152505
- const secrets = [];
152506
- for (const [name, value] of Object.entries(entries2)) {
152507
- if (typeof value === "string") {
152508
- defaults2[name] = value;
152509
- } else {
152510
- secrets.push(name);
152511
- }
152512
- }
152513
- app.configs = [...new Set([...app.configs ?? [], ...Object.keys(entries2)])].sort();
152514
- app.configDefaults = defaults2;
152515
- app.configSecrets = secrets;
152516
- };
152517
152487
  var loadStackConfigs = async (options) => {
152518
152488
  debug("Load stacks config files");
152519
152489
  const ext2 = "{json,jsonc,json5}";
@@ -154801,9 +154771,7 @@ var createSsmServer = (props) => {
154801
154771
  let closeServer;
154802
154772
  let log;
154803
154773
  const warned2 = new Set;
154804
- let defaults2 = {};
154805
154774
  let pulled = {};
154806
- let secrets = new Set;
154807
154775
  const loadValues = async () => {
154808
154776
  try {
154809
154777
  return JSON.parse(await readFile12(props.file, "utf8"));
@@ -154816,9 +154784,7 @@ var createSsmServer = (props) => {
154816
154784
  log = logFn;
154817
154785
  },
154818
154786
  setValues(next) {
154819
- defaults2 = next.defaults;
154820
154787
  pulled = next.pulled;
154821
- secrets = next.secrets;
154822
154788
  },
154823
154789
  async listen(port = 0) {
154824
154790
  server = createServer2((req, res) => {
@@ -154839,12 +154805,12 @@ var createSsmServer = (props) => {
154839
154805
  const parameters = [];
154840
154806
  for (const name of Names ?? []) {
154841
154807
  const key = name.split("/").at(-1);
154842
- const value = values[key] ?? defaults2[key] ?? pulled[key];
154808
+ const value = values[key] ?? pulled[key];
154843
154809
  if (typeof value === "string") {
154844
154810
  parameters.push({ Name: name, Type: "SecureString", Value: value });
154845
154811
  } else if (!warned2.has(key)) {
154846
154812
  warned2.add(key);
154847
- log?.(secrets.has(key) ? `The "${key}" config secret has no value - the ssm pull didn't provide one. Set it with "awsless config set ${key}" or override it on the dashboard.` : `The "${key}" config has no local value yet. Set it on the dashboard or add a default in config.jsonc`);
154813
+ log?.(`The "${key}" config has no value - the ssm pull didn't provide one. Set it with "awsless config set ${key}" or on the dashboard.`);
154848
154814
  }
154849
154815
  }
154850
154816
  res.writeHead(200, { "content-type": "application/x-amz-json-1.1" });
@@ -155030,10 +154996,9 @@ var configFeature = defineFeature({
155030
154996
  if (names.size === 0) {
155031
154997
  return;
155032
154998
  }
155033
- const secrets = new Set(ctx.appConfig.configSecrets ?? []);
155034
154999
  for (const name of names) {
155035
155000
  ctx.addEnv(`CONFIG_${constantCase(name)}`, name);
155036
- ctx.registerResource({ kind: "config", id: name, detail: secrets.has(name) ? "secret" : "" });
155001
+ ctx.registerResource({ kind: "config", id: name });
155037
155002
  }
155038
155003
  const file2 = join18(directories.output, "local", "config.json");
155039
155004
  const { server, port } = await ctx.keep("shim:ssm", file2, async () => {
@@ -155042,38 +155007,31 @@ var configFeature = defineFeature({
155042
155007
  return { value: { server: server2, port: port2 }, stop: () => server2.stop() };
155043
155008
  });
155044
155009
  ctx.addEnv("AWS_ENDPOINT_URL_SSM", `http://127.0.0.1:${port}`);
155045
- let pulled = {};
155046
- if (secrets.size > 0) {
155047
- pulled = await ctx.keep("config:pull", [...secrets].sort().join(","), async () => {
155048
- const values = {};
155049
- try {
155050
- ctx.log(`Pulling ${secrets.size} config secret${secrets.size === 1 ? "" : "s"} from SSM...`);
155051
- const credentials2 = await getCredentials(ctx.appConfig.profile);
155052
- const store = new SsmStore({ credentials: credentials2, appConfig: ctx.appConfig });
155053
- let timer;
155054
- const all5 = await Promise.race([
155055
- store.list(),
155056
- new Promise((_3, reject) => {
155057
- timer = setTimeout(() => reject(new Error("the pull timed out after 15s")), 15000);
155058
- })
155059
- ]).finally(() => clearTimeout(timer));
155060
- for (const name of secrets) {
155061
- if (typeof all5[name] === "string") {
155062
- values[name] = all5[name];
155063
- }
155010
+ const pulled = await ctx.keep("config:pull", [...names].sort().join(","), async () => {
155011
+ const values = {};
155012
+ try {
155013
+ ctx.log(`Pulling ${names.size} config value${names.size === 1 ? "" : "s"} from SSM...`);
155014
+ const credentials2 = await getCredentials(ctx.appConfig.profile);
155015
+ const store = new SsmStore({ credentials: credentials2, appConfig: ctx.appConfig });
155016
+ let timer;
155017
+ const all5 = await Promise.race([
155018
+ store.list(),
155019
+ new Promise((_3, reject) => {
155020
+ timer = setTimeout(() => reject(new Error("the pull timed out after 15s")), 15000);
155021
+ })
155022
+ ]).finally(() => clearTimeout(timer));
155023
+ for (const name of names) {
155024
+ if (typeof all5[name] === "string") {
155025
+ values[name] = all5[name];
155064
155026
  }
155065
- } catch (error3) {
155066
- debug("Config secret pull failed", error3);
155067
- ctx.log(`Couldn't pull the config secrets from SSM (${error3 instanceof Error ? error3.message : String(error3)}) - secret-backed features will fail when called.`);
155068
155027
  }
155069
- return { value: values, stop: () => {} };
155070
- });
155071
- }
155072
- server.setValues({
155073
- defaults: ctx.appConfig.configDefaults ?? {},
155074
- pulled,
155075
- secrets
155028
+ } catch (error3) {
155029
+ debug("Config pull failed", error3);
155030
+ ctx.log(`Couldn't pull the config values from SSM (${error3 instanceof Error ? error3.message : String(error3)}) - set them on the dashboard instead.`);
155031
+ }
155032
+ return { value: values, stop: () => {} };
155076
155033
  });
155034
+ server.setValues({ pulled });
155077
155035
  ctx.restartOnChange(file2);
155078
155036
  ctx.registerServer({
155079
155037
  name: "config",
@@ -165859,7 +165817,7 @@ var watchConfig = async (options, resolve5, reject) => {
165859
165817
  await loadAppConfig(options);
165860
165818
  debug("Start watching...");
165861
165819
  const ext2 = "{json,jsonc,json5}";
165862
- const watcher = $watch([`app.${ext2}`, `config.${ext2}`, `**/stack.${ext2}`, `**/*.stack.${ext2}`], {
165820
+ const watcher = $watch([`app.${ext2}`, `**/stack.${ext2}`, `**/*.stack.${ext2}`], {
165863
165821
  cwd: directories.root,
165864
165822
  ignored: ["**/node_modules/**", "**/dist/**"],
165865
165823
  awaitWriteFinish: true
@@ -167191,24 +167149,18 @@ const configPanel = async (main) => {
167191
167149
  const names = [...new Set(state.resources.filter(r => r.kind === 'config').map(r => r.id))].sort()
167192
167150
  const data = await api('/api/config')
167193
167151
  const values = data.values ?? {}
167194
- const defaults = data.defaults ?? {}
167195
- const secrets = new Set(data.secrets ?? [])
167152
+ const pulled = new Set(data.pulled ?? [])
167196
167153
 
167197
167154
  const inputs = new Map()
167198
167155
  const form = $('div', { className: 'config-form' })
167199
167156
 
167200
167157
  for (const name of names) {
167201
- // An empty input falls through to the committed default or the
167202
- // pulled ssm secret - the placeholder shows which one carries.
167203
- const placeholder = secrets.has(name)
167204
- ? 'pulled from ssm'
167205
- : defaults[name] !== undefined ? 'default: ' + defaults[name] : 'not set'
167206
-
167158
+ // An empty input falls through to the value pulled from ssm on
167159
+ // boot - the placeholder shows whether the pull provided one.
167207
167160
  const input = $('input', {
167208
167161
  value: values[name] ?? '',
167209
- placeholder,
167162
+ placeholder: pulled.has(name) ? 'pulled from ssm' : 'not set',
167210
167163
  spellcheck: false,
167211
- ...(secrets.has(name) ? { type: 'password' } : {}),
167212
167164
  })
167213
167165
  inputs.set(name, input)
167214
167166
  form.append($('label', { className: 'field' }, [$('span', { className: 'name' }, name), input]))
@@ -167655,8 +167607,7 @@ var createDashboardServer = (props) => {
167655
167607
  status: 200,
167656
167608
  body: JSON.stringify({
167657
167609
  values,
167658
- defaults: props.configMeta?.defaults ?? {},
167659
- secrets: props.configMeta?.secrets ?? []
167610
+ pulled: props.configPulled ?? []
167660
167611
  })
167661
167612
  };
167662
167613
  }
@@ -167917,10 +167868,14 @@ var linkSdkPackages = async (buildDir, onWarn) => {
167917
167868
  };
167918
167869
 
167919
167870
  // src/dev/index.ts
167871
+ var breakdown = (timings) => {
167872
+ const slow = timings.filter(([, ms]) => ms >= 100).sort((a4, b6) => b6[1] - a4[1]);
167873
+ return slow.map(([name, ms]) => `${name} ${ms < 1000 ? `${Math.round(ms)}ms` : `${(ms / 1000).toFixed(1)}s`}`).join(", ");
167874
+ };
167920
167875
  var LOCAL_ACCOUNT_ID = "000000000000";
167921
167876
  var startDev = async (props) => {
167922
167877
  const log = props.onLog ?? (() => {});
167923
- const phase = props.phase ?? (async ({ start }, fn) => (log(start), fn()));
167878
+ const phase = props.phase ?? (async ({ start }, fn) => (log(start), fn(() => {})));
167924
167879
  const { appConfig, stackConfigs } = props;
167925
167880
  const { builders, appId } = createApp({
167926
167881
  appConfig,
@@ -167939,10 +167894,17 @@ var startDev = async (props) => {
167939
167894
  const dev = createDevContext({ appConfig, stackConfigs, appId, routerPorts, log, pool: props.pool });
167940
167895
  const bundleName = getBundleFunctionName(appConfig.name);
167941
167896
  const buildDir = getBuildPath("bundle", bundleName, ".");
167942
- const { env: env4, lambda } = await phase({ start: "Preparing the local resources...", done: "Prepared the local resources" }, async () => {
167897
+ const { env: env4, lambda } = await phase({ start: "Preparing the local resources...", done: "Prepared the local resources" }, async (detail) => {
167898
+ const timings = [];
167943
167899
  for (const feature of features) {
167944
- await feature.onDev?.(dev.context);
167900
+ if (!feature.onDev) {
167901
+ continue;
167902
+ }
167903
+ const started = Date.now();
167904
+ await feature.onDev(dev.context);
167905
+ timings.push([feature.name, Date.now() - started]);
167945
167906
  }
167907
+ detail(breakdown(timings));
167946
167908
  props.pool.retain("blocked");
167947
167909
  props.pool.retain("lambda");
167948
167910
  await props.pool.sweep();
@@ -168041,10 +168003,14 @@ var startDev = async (props) => {
168041
168003
  log
168042
168004
  });
168043
168005
  lambda.connect(dispatch, reportFailure);
168044
- await phase({ start: "Starting the local servers...", done: "Started the local servers" }, async () => {
168006
+ await phase({ start: "Starting the local servers...", done: "Started the local servers" }, async (detail) => {
168007
+ const timings = [];
168045
168008
  for (const server of dev.servers) {
168009
+ const started = Date.now();
168046
168010
  await server.start({ dispatch, log, reportFailure, env: env4 });
168011
+ timings.push([server.name, Date.now() - started]);
168047
168012
  }
168013
+ detail(breakdown(timings));
168048
168014
  });
168049
168015
  await phase({ start: "Starting the bundle worker...", done: "Started the bundle worker" }, async () => {
168050
168016
  try {
@@ -168087,10 +168053,7 @@ var startDev = async (props) => {
168087
168053
  env: env4,
168088
168054
  storeRoot: join53(directories.output, "local", "store"),
168089
168055
  configFile: join53(directories.output, "local", "config.json"),
168090
- configMeta: {
168091
- defaults: appConfig.configDefaults ?? {},
168092
- secrets: appConfig.configSecrets ?? []
168093
- },
168056
+ configPulled: Object.keys(props.pool.peek("config:pull") ?? {}),
168094
168057
  events: dev.events
168095
168058
  });
168096
168059
  dashboard.connect(dispatch);
@@ -168238,13 +168201,14 @@ var dev = (program3) => {
168238
168201
  let logger = (message4) => logs_exports.step(message4);
168239
168202
  const phase = async (titles, fn) => {
168240
168203
  const time2 = createTimer();
168204
+ let detail = "";
168241
168205
  return logs_exports.task({
168242
168206
  initialMessage: titles.start,
168243
168207
  errorMessage: `${titles.start.replace(/\.\.\.$/, "")} failed.`,
168244
168208
  task: ({ updateMessage, updateSuccessMessage }) => {
168245
168209
  logger = updateMessage;
168246
- return fn().then((result) => {
168247
- updateSuccessMessage(`${titles.done} in ${time2()}`);
168210
+ return fn((text2) => detail = text2).then((result) => {
168211
+ updateSuccessMessage(`${titles.done} in ${time2()}${detail ? color2.dim(` (${detail})`) : ""}`);
168248
168212
  return result;
168249
168213
  }).finally(() => {
168250
168214
  logger = (message4) => logs_exports.step(message4);
@@ -168359,7 +168323,7 @@ import { DynamoDBClient as DynamoDBClient6, dynamoDBClient } from "@awsless/dyna
168359
168323
 
168360
168324
  // ../../node_modules/.pnpm/@aws-sdk+client-iot-data-plane@3.1023.0_aws-crt@1.30.0_supports-color@8.1.1_/node_modules/@aws-sdk/client-iot-data-plane/dist-es/IoTDataPlaneClient.js
168361
168325
  var import_core50 = __toESM(require_dist_cjs2(), 1);
168362
- var import_schema68 = __toESM(require_schema(), 1);
168326
+ var import_schema67 = __toESM(require_schema(), 1);
168363
168327
 
168364
168328
  // ../../node_modules/.pnpm/@aws-sdk+client-iot-data-plane@3.1023.0_aws-crt@1.30.0_supports-color@8.1.1_/node_modules/@aws-sdk/client-iot-data-plane/dist-es/auth/httpAuthSchemeProvider.js
168365
168329
  var import_httpAuthSchemes4 = __toESM(require_httpAuthSchemes(), 1);
@@ -168565,7 +168529,7 @@ var defaultEndpointResolver3 = (endpointParams, context = {}) => {
168565
168529
  customEndpointFunctions.aws = awsEndpointFunctions;
168566
168530
 
168567
168531
  // ../../node_modules/.pnpm/@aws-sdk+client-iot-data-plane@3.1023.0_aws-crt@1.30.0_supports-color@8.1.1_/node_modules/@aws-sdk/client-iot-data-plane/dist-es/schemas/schemas_0.js
168568
- var import_schema67 = __toESM(require_schema(), 1);
168532
+ var import_schema66 = __toESM(require_schema(), 1);
168569
168533
 
168570
168534
  // ../../node_modules/.pnpm/@aws-sdk+client-iot-data-plane@3.1023.0_aws-crt@1.30.0_supports-color@8.1.1_/node_modules/@aws-sdk/client-iot-data-plane/dist-es/models/IoTDataPlaneServiceException.js
168571
168535
  class IoTDataPlaneServiceException extends ServiceException {
@@ -168795,10 +168759,10 @@ var _xamcd = "x-amz-mqtt5-correlation-data";
168795
168759
  var _xampfi = "x-amz-mqtt5-payload-format-indicator";
168796
168760
  var _xamup = "x-amz-mqtt5-user-properties";
168797
168761
  var n03 = "com.amazonaws.iotdataplane";
168798
- var _s_registry3 = import_schema67.TypeRegistry.for(_s3);
168762
+ var _s_registry3 = import_schema66.TypeRegistry.for(_s3);
168799
168763
  var IoTDataPlaneServiceException$ = [-3, _s3, "IoTDataPlaneServiceException", 0, [], []];
168800
168764
  _s_registry3.registerError(IoTDataPlaneServiceException$, IoTDataPlaneServiceException);
168801
- var n0_registry3 = import_schema67.TypeRegistry.for(n03);
168765
+ var n0_registry3 = import_schema66.TypeRegistry.for(n03);
168802
168766
  var ConflictException$ = [
168803
168767
  -3,
168804
168768
  n03,
@@ -169234,7 +169198,7 @@ class IoTDataPlaneClient extends Client {
169234
169198
  const _config_7 = resolveHttpAuthSchemeConfig3(_config_6);
169235
169199
  const _config_8 = resolveRuntimeExtensions3(_config_7, configuration?.extensions || []);
169236
169200
  this.config = _config_8;
169237
- this.middlewareStack.use(import_schema68.getSchemaSerdePlugin(this.config));
169201
+ this.middlewareStack.use(import_schema67.getSchemaSerdePlugin(this.config));
169238
169202
  this.middlewareStack.use(getUserAgentPlugin(this.config));
169239
169203
  this.middlewareStack.use(getRetryPlugin(this.config));
169240
169204
  this.middlewareStack.use(getContentLengthPlugin(this.config));
@@ -381,7 +381,7 @@ var topicHandler = (event, routes) => {
381
381
  return type === "topic" && id === topicId;
382
382
  });
383
383
  if (!subscribers.length) {
384
- throw new Error(`Unknown bundle topic: ${topicId}`);
384
+ return [];
385
385
  }
386
386
  if (subscribers.length === 1) {
387
387
  return asyncRoute(subscribers[0], event);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@awsless/cli",
3
- "version": "0.0.46-local.10",
3
+ "version": "0.0.46-local.12",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -42,15 +42,15 @@
42
42
  "@awsless/ts-file-cache": "^0.0.16"
43
43
  },
44
44
  "peerDependencies": {
45
- "@awsless/dynamodb": "^0.3.22",
46
- "@awsless/duration": "^0.0.4",
47
45
  "@awsless/big-float": "^0.1.7",
46
+ "@awsless/duration": "^0.0.4",
48
47
  "@awsless/json": "^0.0.11",
49
- "@awsless/s3": "^0.0.22",
48
+ "@awsless/dynamodb": "^0.3.22",
50
49
  "@awsless/lambda": "^0.0.47",
51
50
  "@awsless/validate": "^0.1.7",
52
- "awsless": "^0.0.15-local.3",
53
- "@awsless/weak-cache": "^0.0.1"
51
+ "@awsless/s3": "^0.0.22",
52
+ "@awsless/weak-cache": "^0.0.1",
53
+ "awsless": "^0.0.15-local.3"
54
54
  },
55
55
  "devDependencies": {
56
56
  "@aws-sdk/client-cloudformation": "^3.369.0",
@@ -120,24 +120,24 @@
120
120
  "zip-a-folder": "^3.1.6",
121
121
  "zod": "^3.24.2",
122
122
  "zod-to-json-schema": "^3.24.3",
123
- "@awsless/big-float": "^0.1.7",
123
+ "@awsless/clui": "^0.0.9",
124
124
  "@awsless/cloudwatch": "^0.0.1",
125
+ "@awsless/big-float": "^0.1.7",
125
126
  "@awsless/duration": "^0.0.4",
126
- "@awsless/clui": "^0.0.9",
127
127
  "@awsless/iot": "^0.0.5",
128
- "@awsless/lambda": "^0.0.47",
129
- "@awsless/open-search": "^0.0.24",
130
128
  "@awsless/dynamodb": "^0.3.22",
131
- "@awsless/redis": "^0.1.13",
132
- "@awsless/scheduler": "^0.0.5",
133
- "@awsless/s3": "^0.0.22",
129
+ "@awsless/lambda": "^0.0.47",
134
130
  "@awsless/json": "^0.0.11",
135
- "@awsless/sqs": "^0.0.24",
131
+ "@awsless/s3": "^0.0.22",
132
+ "@awsless/scheduler": "^0.0.5",
133
+ "@awsless/redis": "^0.1.13",
134
+ "@awsless/sns": "^0.0.11",
135
+ "@awsless/open-search": "^0.0.24",
136
136
  "@awsless/size": "^0.0.2",
137
+ "@awsless/sqs": "^0.0.24",
138
+ "@awsless/validate": "^0.1.7",
137
139
  "@awsless/weak-cache": "^0.0.1",
138
- "@awsless/sns": "^0.0.11",
139
140
  "awsless": "^0.0.15-local.3",
140
- "@awsless/validate": "^0.1.7",
141
141
  "@awsless/ssm": "^0.0.8"
142
142
  },
143
143
  "scripts": {