@awsless/cli 0.0.46-local.46 → 0.0.46-local.48

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
@@ -152830,8 +152830,7 @@ var createAuthAdmin = (props) => {
152830
152830
  describePool(id) {
152831
152831
  const pool = getPool(id);
152832
152832
  return {
152833
- groups: pool.groups,
152834
- password: pool.password
152833
+ groups: pool.groups
152835
152834
  };
152836
152835
  },
152837
152836
  async listUsers(id) {
@@ -153542,9 +153541,14 @@ for (const name in env) {
153542
153541
  process.env[name] ??= env[name]
153543
153542
  }
153544
153543
 
153545
- const { createBundle } = await import(${JSON.stringify(runtime)})
153544
+ const runtime = await import(${JSON.stringify(runtime)})
153546
153545
 
153547
- export default createBundle({
153546
+ // The local dev worker tags console output with the active route. A
153547
+ // lazy accessor instead of a re-export, since a static re-export would
153548
+ // hoist the runtime import above the env application.
153549
+ export const getCurrentRoute = () => runtime.getCurrentRoute?.()
153550
+
153551
+ export default runtime.createBundle({
153548
153552
  ${entries2.join(`
153549
153553
  `)}
153550
153554
  })
@@ -166622,11 +166626,37 @@ class WorkerError extends Error {
166622
166626
  }
166623
166627
  }
166624
166628
  var WORKER_ENTRY = `import { createServer } from 'node:http'
166629
+ import { format } from 'node:util'
166625
166630
 
166626
166631
  let handler
166632
+ let getCurrentRoute = () => undefined
166633
+
166634
+ // Console output is tagged with the active bundle route (invisible
166635
+ // \\x1f markers), so the dev cli can attribute every log line to the
166636
+ // function that wrote it - accurate even under concurrent requests,
166637
+ // since the route comes from the bundle's async context.
166638
+ const patchConsole = (method, stream) => {
166639
+ console[method] = (...args) => {
166640
+ const route = getCurrentRoute() ?? ''
166641
+ const text = format(...args)
166642
+
166643
+ for (const line of text.split('\\n')) {
166644
+ stream.write('\\x1f' + route + '\\x1f' + line + '\\n')
166645
+ }
166646
+ }
166647
+ }
166648
+
166649
+ patchConsole('log', process.stdout)
166650
+ patchConsole('info', process.stdout)
166651
+ patchConsole('debug', process.stdout)
166652
+ patchConsole('warn', process.stderr)
166653
+ patchConsole('error', process.stderr)
166627
166654
 
166628
166655
  try {
166629
- handler = (await import('./files/index.mjs')).default
166656
+ const bundle = await import('./files/index.mjs')
166657
+
166658
+ handler = bundle.default
166659
+ getCurrentRoute = bundle.getCurrentRoute ?? getCurrentRoute
166630
166660
  } catch (error) {
166631
166661
  // Keep module load failures readable, instead of node dumping the
166632
166662
  // whole minified line that threw.
@@ -166716,12 +166746,25 @@ var createBundleWorker = (props) => {
166716
166746
  }
166717
166747
  });
166718
166748
  const capture = (stream2) => (chunk3) => {
166719
- process[stream2].write(chunk3);
166720
166749
  for (const raw of chunk3.toString().split(`
166721
166750
  `)) {
166722
- const line = stripAnsi2(raw);
166723
- if (line.trim() !== "") {
166724
- props.onOutput?.(line, stream2);
166751
+ if (raw === "") {
166752
+ continue;
166753
+ }
166754
+ let line = raw;
166755
+ let route;
166756
+ if (raw.startsWith("\x1F")) {
166757
+ const end = raw.indexOf("\x1F", 1);
166758
+ if (end > 0) {
166759
+ route = raw.slice(1, end) || undefined;
166760
+ line = raw.slice(end + 1);
166761
+ }
166762
+ }
166763
+ process[stream2].write((route ? `[${route}] ` : "") + line + `
166764
+ `);
166765
+ const clean = stripAnsi2(line);
166766
+ if (clean.trim() !== "") {
166767
+ props.onOutput?.(clean, stream2, route);
166725
166768
  }
166726
166769
  }
166727
166770
  };
@@ -166832,6 +166875,7 @@ var dashboardHtml = `<!doctype html>
166832
166875
  }
166833
166876
  .logs .line { display: flex; gap: 8px; padding: 1px 0; }
166834
166877
  .logs .time { color: var(--muted); flex-shrink: 0; }
166878
+ .logs .route { color: var(--accent); max-width: 220px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
166835
166879
  .logs .text { white-space: pre-wrap; word-break: break-word; }
166836
166880
  .logs .line.error .text { color: var(--bad); }
166837
166881
  .config-form { display: flex; flex-direction: column; gap: 8px; max-width: 520px; }
@@ -166999,6 +167043,15 @@ var dashboardHtml = `<!doctype html>
166999
167043
  cursor: pointer;
167000
167044
  }
167001
167045
  button.primary:disabled { opacity: 0.5; cursor: wait; }
167046
+ button.secondary {
167047
+ background: var(--panel);
167048
+ color: var(--text);
167049
+ border: 1px solid var(--border);
167050
+ border-radius: 6px;
167051
+ padding: 6px 16px;
167052
+ font: inherit;
167053
+ cursor: pointer;
167054
+ }
167002
167055
  pre.result {
167003
167056
  background: var(--panel);
167004
167057
  border: 1px solid var(--border);
@@ -167067,7 +167120,7 @@ const GROUPS = [
167067
167120
  ['config', 'Config'],
167068
167121
  ['auth', 'Auth'],
167069
167122
  ['email', 'Emails'],
167070
- ['worker', 'Worker'],
167123
+ ['worker', 'Logs'],
167071
167124
  ['route', 'Routes'],
167072
167125
  ]
167073
167126
 
@@ -167185,11 +167238,23 @@ window.addEventListener('popstate', applyLocation)
167185
167238
  // Detail panels
167186
167239
 
167187
167240
  const invokePanel = (main, r) => {
167241
+ // The last payload survives reloads & panel switches, so a hand
167242
+ // crafted event never gets lost. The envelope only prefills the
167243
+ // first visit.
167244
+ const storageKey = 'invoke-payload:' + r.kind + ':' + (r.stack ?? '-') + ':' + r.id
167188
167245
  const placeholder = JSON.stringify(r.envelope ?? {}, null, 2)
167189
- const input = $('textarea', { value: placeholder, spellcheck: false })
167246
+ const input = $('textarea', { value: localStorage.getItem(storageKey) ?? placeholder, spellcheck: false })
167190
167247
  const status = $('span', { className: 'status' })
167191
167248
  const result = $('pre', { className: 'result', hidden: true })
167192
167249
  const run = $('button', { className: 'primary', textContent: r.kind === 'topic' ? 'Publish' : 'Invoke' })
167250
+ const reset = $('button', { className: 'secondary', textContent: 'Reset' })
167251
+
167252
+ input.oninput = () => localStorage.setItem(storageKey, input.value)
167253
+
167254
+ reset.onclick = () => {
167255
+ localStorage.removeItem(storageKey)
167256
+ input.value = placeholder
167257
+ }
167193
167258
 
167194
167259
  run.onclick = async () => {
167195
167260
  run.disabled = true
@@ -167215,9 +167280,14 @@ const invokePanel = (main, r) => {
167215
167280
 
167216
167281
  main.append(
167217
167282
  input,
167218
- $('div', { className: 'actions' }, [run, status]),
167283
+ $('div', { className: 'actions' }, [run, reset, status]),
167219
167284
  result,
167220
167285
  )
167286
+
167287
+ // The resource's own console output, filtered from the worker feed.
167288
+ if (r.routeKey) {
167289
+ cleanupPanel = attachLogFeed(main, 'worker', r.routeKey)
167290
+ }
167221
167291
  }
167222
167292
 
167223
167293
  const pubsubPanel = (main, r) => {
@@ -167341,8 +167411,10 @@ const rpcPanel = (main, r) => {
167341
167411
  // A terminal-style view streaming a resource's live event channel,
167342
167412
  // like the dev server output of a site. The bus replays the recent
167343
167413
  // lines, so the boot output shows even when the panel opens later.
167344
- const attachLogFeed = (main, channel) => {
167345
- main.append($('h3', {}, 'Logs'))
167414
+ const attachLogFeed = (main, channel, route, title = 'Logs') => {
167415
+ if (title) {
167416
+ main.append($('h3', {}, title))
167417
+ }
167346
167418
 
167347
167419
  const feed = $('div', { className: 'logs' }, $('p', { className: 'empty' }, 'Waiting for output...'))
167348
167420
  main.append(feed)
@@ -167352,9 +167424,16 @@ const attachLogFeed = (main, channel) => {
167352
167424
  source.onmessage = message => {
167353
167425
  const data = JSON.parse(message.data)
167354
167426
 
167427
+ // A route filter shows only the lines of one resource, like the
167428
+ // function panel showing its own console output.
167429
+ if (route && data.route !== route) {
167430
+ return
167431
+ }
167432
+
167355
167433
  feed.querySelector('.empty')?.remove()
167356
167434
  feed.append($('div', { className: 'line' + (data.error ? ' error' : '') }, [
167357
167435
  $('span', { className: 'time' }, new Date(data.date).toLocaleTimeString()),
167436
+ !route && data.route ? $('span', { className: 'route' }, data.route) : '',
167358
167437
  $('span', { className: 'text' }, data.line),
167359
167438
  ]))
167360
167439
 
@@ -167839,6 +167918,10 @@ const renderResource = main => {
167839
167918
  if (r.kind === 'store') return storePanel(main, r)
167840
167919
  if (r.kind === 'config') return configPanel(main)
167841
167920
  if (r.kind === 'auth') return authPanel(main, r)
167921
+ if (r.kind === 'worker') {
167922
+ cleanupPanel = attachLogFeed(main, 'worker')
167923
+ return
167924
+ }
167842
167925
  if (r.kind === 'route' || r.kind === 'site') {
167843
167926
  const url = r.url ?? r.detail
167844
167927
  main.append($('p', {}, $('a', { href: url, target: '_blank', style: 'color: var(--accent)' }, url)))
@@ -167872,6 +167955,13 @@ const renderList = main => {
167872
167955
  return emailPanel(main)
167873
167956
  }
167874
167957
 
167958
+ // The worker page streams the bundle worker output directly,
167959
+ // instead of listing its single resource.
167960
+ if (view.kind === 'worker') {
167961
+ cleanupPanel = attachLogFeed(main, 'worker', undefined, null)
167962
+ return
167963
+ }
167964
+
167875
167965
  const matches = r => {
167876
167966
  if (filter.stack && r.stack !== filter.stack) return false
167877
167967
  if (!filter.query) return true
@@ -167959,7 +168049,7 @@ const render = () => {
167959
168049
  const button = $('button', { className: view.kind === kind ? 'active' : '' }, [
167960
168050
  icon(kind),
167961
168051
  title,
167962
- kind === 'email' ? '' : $('span', { className: 'count' }, String(count)),
168052
+ kind === 'email' || kind === 'worker' ? '' : $('span', { className: 'count' }, String(count)),
167963
168053
  ])
167964
168054
  button.onclick = () => selectKind(kind)
167965
168055
  nav.append(button)
@@ -168634,14 +168724,14 @@ var startDev = async (props) => {
168634
168724
  workspace = await loadWorkspace3(directories.root);
168635
168725
  await buildAll();
168636
168726
  });
168637
- const emitWorkerLine = (line, error3 = false) => {
168638
- dev.events.emit("worker", { date: Date.now(), line, error: error3 });
168727
+ const emitWorkerLine = (line, error3 = false, route) => {
168728
+ dev.events.emit("worker", { date: Date.now(), line, error: error3, route });
168639
168729
  };
168640
168730
  const worker = createBundleWorker({
168641
168731
  buildDir,
168642
168732
  env: env4,
168643
168733
  functionName: bundleName,
168644
- onOutput: (line, stream2) => emitWorkerLine(line, stream2 === "stderr")
168734
+ onOutput: (line, stream2, route) => emitWorkerLine(line, stream2 === "stderr", route)
168645
168735
  });
168646
168736
  dev.resources.push({
168647
168737
  kind: "worker",
@@ -168729,7 +168819,7 @@ var startDev = async (props) => {
168729
168819
  const detail = error3 instanceof Error ? error3.stack ?? error3.message : String(error3);
168730
168820
  process.stderr.write(`Route ${routeKey} failed: ${detail}
168731
168821
  `);
168732
- emitWorkerLine(`Route ${routeKey} failed: ${detail}`, true);
168822
+ emitWorkerLine(`Route ${routeKey} failed: ${detail}`, true, routeKey);
168733
168823
  }
168734
168824
  }));
168735
168825
  }
@@ -406,6 +406,7 @@ var topicHandler = (event, routes) => {
406
406
  };
407
407
 
408
408
  // src/feature/bundle/server/handle.ts
409
+ import { getCurrentRoute as getCurrentRoute2 } from "awsless";
409
410
  var createBundle = (handlers) => {
410
411
  const routes = Object.keys(handlers);
411
412
  setBundleRoutes(routes);
@@ -504,5 +505,6 @@ var createBundle = (handlers) => {
504
505
  };
505
506
  };
506
507
  export {
508
+ getCurrentRoute2 as getCurrentRoute,
507
509
  createBundle
508
510
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@awsless/cli",
3
- "version": "0.0.46-local.46",
3
+ "version": "0.0.46-local.48",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -43,14 +43,14 @@
43
43
  },
44
44
  "peerDependencies": {
45
45
  "@awsless/big-float": "^0.1.7",
46
- "@awsless/dynamodb": "^0.3.22",
47
46
  "@awsless/duration": "^0.0.4",
47
+ "@awsless/json": "^0.0.11",
48
+ "@awsless/dynamodb": "^0.3.22",
48
49
  "@awsless/s3": "^0.0.22",
49
- "@awsless/lambda": "^0.0.47",
50
50
  "@awsless/weak-cache": "^0.0.1",
51
- "@awsless/json": "^0.0.11",
52
- "@awsless/validate": "^0.1.7",
53
- "awsless": "^0.0.15-local.11"
51
+ "@awsless/lambda": "^0.0.47",
52
+ "awsless": "^0.0.15-local.12",
53
+ "@awsless/validate": "^0.1.8"
54
54
  },
55
55
  "devDependencies": {
56
56
  "@aws-sdk/client-cloudformation": "^3.369.0",
@@ -120,25 +120,25 @@
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/clui": "^0.0.9",
124
123
  "@awsless/big-float": "^0.1.7",
124
+ "@awsless/clui": "^0.0.9",
125
+ "@awsless/cloudwatch": "^0.0.1",
125
126
  "@awsless/duration": "^0.0.4",
126
- "@awsless/lambda": "^0.0.47",
127
127
  "@awsless/dynamodb": "^0.3.22",
128
- "@awsless/open-search": "^0.0.26",
129
128
  "@awsless/iot": "^0.0.5",
130
- "@awsless/cloudwatch": "^0.0.1",
131
129
  "@awsless/json": "^0.0.11",
132
130
  "@awsless/redis": "^0.1.13",
133
- "@awsless/s3": "^0.0.22",
134
- "@awsless/sqs": "^0.0.24",
131
+ "@awsless/lambda": "^0.0.47",
135
132
  "@awsless/size": "^0.0.2",
133
+ "@awsless/s3": "^0.0.22",
134
+ "@awsless/open-search": "^0.0.26",
136
135
  "@awsless/scheduler": "^0.0.5",
136
+ "@awsless/sqs": "^0.0.24",
137
137
  "@awsless/sns": "^0.0.11",
138
- "@awsless/validate": "^0.1.7",
139
- "awsless": "^0.0.15-local.11",
138
+ "awsless": "^0.0.15-local.12",
139
+ "@awsless/ssm": "^0.0.8",
140
140
  "@awsless/weak-cache": "^0.0.1",
141
- "@awsless/ssm": "^0.0.8"
141
+ "@awsless/validate": "^0.1.8"
142
142
  },
143
143
  "scripts": {
144
144
  "test": "bun cli/build-handlers.ts && pnpm vitest",