wawesome 0.0.9 → 0.0.10

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 (3) hide show
  1. package/README.md +15 -0
  2. package/dist/index.mjs +45 -20
  3. package/package.json +2 -1
package/README.md CHANGED
@@ -200,6 +200,21 @@ Every project directory includes a `wawesome-function.json` file generated durin
200
200
  `app` is the App this Function is deployed into, and it is client-facing — every deploy from this
201
201
  directory is scoped to it.
202
202
 
203
+ ### Reserved headers
204
+
205
+ `x-wawesome-*` belongs to the platform in both directions. It is stripped off the request before your
206
+ handler sees it, and off your response before the caller does — so **do not name a header of your own
207
+ on that prefix**: it is dropped silently rather than rejected, and you will not get an error telling
208
+ you why it vanished.
209
+
210
+ Three headers arrive or leave on it, and the stripping is what makes them worth trusting:
211
+
212
+ | Header | Direction | What it means |
213
+ | --- | --- | --- |
214
+ | `x-wawesome-forwarded-prefix` | inbound | The mount that was stripped from the path. Join it to the path you observe to rebuild the caller's URL. |
215
+ | `x-wawesome-invocation-id` | outbound | The id of this run — the key to fetch its logs with `npx wawesome logs --invocation <id>`. |
216
+ | `x-wawesome-error` | outbound | Present only when the platform failed, never when your Function did. Its *absence* means the status on the wire is yours. |
217
+
203
218
  ### Local Development / Gateway Overrides
204
219
 
205
220
  If you are running a local gateway or self-hosted instance, you can configure your CLI Gateway URL using any of the
package/dist/index.mjs CHANGED
@@ -161,7 +161,7 @@ async function buildJs(entryInput, options) {
161
161
  * that has to name this version — `--version`, the dependency a scaffolded
162
162
  * project pins — reads it here, so a release bumps one file.
163
163
  */
164
- const CLI_VERSION = "0.0.9";
164
+ const CLI_VERSION = "0.0.10";
165
165
  //#endregion
166
166
  //#region src/prompt.ts
167
167
  /**
@@ -335,10 +335,6 @@ async function renameTenantSlug(creds, slug) {
335
335
  });
336
336
  return result;
337
337
  }
338
- /** The address a deployed Function answers on, for a workspace and app. */
339
- function publicInvokeUrl(gatewayUrl, tenantSlug, appSlug, functionName) {
340
- return `${gatewayUrl}/v1/s/${encodeURIComponent(tenantSlug)}/apps/${encodeURIComponent(appSlug)}/functions/${encodeURIComponent(functionName)}/invoke`;
341
- }
342
338
  //#endregion
343
339
  //#region src/auth.ts
344
340
  /**
@@ -548,6 +544,20 @@ async function whoami() {
548
544
  console.log(` Gateway: ${creds.gateway_url}\n`);
549
545
  }
550
546
  //#endregion
547
+ //#region ../shared/public-address.ts
548
+ const INVOCATION_PREFIX = "/x";
549
+ const SUBTREE_NOTE = "Every path beneath this address reaches the Function.";
550
+ function mountBase(origin, tenantSlug) {
551
+ return `${origin.replace(/\/+$/, "")}${INVOCATION_PREFIX}/${encodeURIComponent(tenantSlug)}`;
552
+ }
553
+ function publicAddress(origin, tenantSlug, appSlug, functionSlug) {
554
+ return `${mountBase(origin, tenantSlug)}/${encodeURIComponent(appSlug)}/${encodeURIComponent(functionSlug)}`;
555
+ }
556
+ /** The same address with the app and function still to be chosen. */
557
+ function publicAddressTemplate(origin, tenantSlug) {
558
+ return `${mountBase(origin, tenantSlug)}/<app>/<function>`;
559
+ }
560
+ //#endregion
551
561
  //#region src/deploy.ts
552
562
  /**
553
563
  * Deploy a function: build → upload JS to gateway → promote.
@@ -644,10 +654,10 @@ async function deploy(entryInput, options) {
644
654
  }
645
655
  process.exit(1);
646
656
  }
647
- let invokeUrl = null;
657
+ let address = null;
648
658
  try {
649
659
  const { slug } = await resolveWorkspace(creds);
650
- invokeUrl = publicInvokeUrl(creds.gateway_url, slug, app, funcName);
660
+ address = publicAddress(creds.gateway_url, slug, app, funcName);
651
661
  } catch (err) {
652
662
  if (isVerbose) console.log(`[wawesome:verbose] Could not resolve the workspace address: ${err instanceof Error ? err.message : err}`);
653
663
  }
@@ -657,13 +667,16 @@ async function deploy(entryInput, options) {
657
667
  console.log(`\n App: ${app}`);
658
668
  console.log(` Function: ${funcName}`);
659
669
  if (version !== void 0) console.log(` Version: ${version}`);
660
- if (invokeUrl) console.log(`\n URL: \x1b[36m${invokeUrl}\x1b[0m`);
670
+ if (address) {
671
+ console.log(`\n URL: \x1b[36m${address}\x1b[0m`);
672
+ console.log(` ${SUBTREE_NOTE}`);
673
+ }
661
674
  console.log("======================================================\n");
662
675
  return {
663
676
  app,
664
677
  functionName: funcName,
665
678
  version,
666
- invokeUrl
679
+ address
667
680
  };
668
681
  }
669
682
  //#endregion
@@ -1014,11 +1027,9 @@ function alignCliDependency(dir, version) {
1014
1027
  const file = path.join(dir, PACKAGE_FILE);
1015
1028
  const pkg = readJson(file);
1016
1029
  const wanted = `^${version}`;
1017
- for (const field of ["dependencies", "devDependencies"]) {
1030
+ for (const { field, range } of declaredCliRanges(pkg)) {
1031
+ if (range === wanted) continue;
1018
1032
  const deps = pkg[field];
1019
- if (!isRecord(deps)) continue;
1020
- const current = deps[CLI_PACKAGE];
1021
- if (typeof current !== "string" || current === wanted) continue;
1022
1033
  writeJson(file, {
1023
1034
  ...pkg,
1024
1035
  [field]: {
@@ -1027,12 +1038,22 @@ function alignCliDependency(dir, version) {
1027
1038
  }
1028
1039
  });
1029
1040
  return {
1030
- from: current,
1041
+ from: range,
1031
1042
  to: wanted
1032
1043
  };
1033
1044
  }
1034
1045
  return null;
1035
1046
  }
1047
+ /** Where a template declares the CLI, and at which range. */
1048
+ function declaredCliRanges(pkg) {
1049
+ return ["dependencies", "devDependencies"].flatMap((field) => {
1050
+ const deps = pkg[field];
1051
+ return isRecord(deps) && typeof deps[CLI_PACKAGE] === "string" ? [{
1052
+ field,
1053
+ range: deps[CLI_PACKAGE]
1054
+ }] : [];
1055
+ });
1056
+ }
1036
1057
  function isRecord(value) {
1037
1058
  return typeof value === "object" && value !== null && !Array.isArray(value);
1038
1059
  }
@@ -1066,9 +1087,9 @@ function collidingPaths(dir, relativePaths) {
1066
1087
  * not be resolved the message still prints, with the placeholder left visible
1067
1088
  * rather than a confident "undefined".
1068
1089
  */
1069
- function renderPostDeploy(postDeploy, invokeUrl) {
1070
- if (!invokeUrl) return postDeploy;
1071
- return postDeploy.split("{{url}}").join(invokeUrl);
1090
+ function renderPostDeploy(postDeploy, address) {
1091
+ if (!address) return postDeploy;
1092
+ return postDeploy.split("{{url}}").join(address);
1072
1093
  }
1073
1094
  /**
1074
1095
  * Normalise arbitrary input into a legal DNS label, returning an empty string
@@ -1509,7 +1530,8 @@ const MAX_RENAME_ATTEMPTS = 3;
1509
1530
  /** Show the address the Function will answer on, once it is deployed. */
1510
1531
  function announceUrl(creds, slug, appSlug, functionName) {
1511
1532
  console.log("\n[wawesome] Your Function will answer on:\n");
1512
- console.log(` \x1b[36m${publicInvokeUrl(creds.gateway_url, slug, appSlug, functionName)}\x1b[0m\n`);
1533
+ console.log(` \x1b[36m${publicAddress(creds.gateway_url, slug, appSlug, functionName)}\x1b[0m`);
1534
+ console.log(` ${SUBTREE_NOTE}\n`);
1513
1535
  }
1514
1536
  /**
1515
1537
  * Show the URL, and offer to fix the workspace address while it can still be fixed.
@@ -1697,7 +1719,7 @@ async function initFromTemplate(templateName, options) {
1697
1719
  verbose: options.verbose
1698
1720
  });
1699
1721
  if (manifest.post_deploy) {
1700
- console.log(renderPostDeploy(manifest.post_deploy, result.invokeUrl));
1722
+ console.log(renderPostDeploy(manifest.post_deploy, result.address));
1701
1723
  console.log("");
1702
1724
  }
1703
1725
  }
@@ -2465,7 +2487,10 @@ async function showWorkspace(options) {
2465
2487
  console.log(` Name: ${tenant.name}`);
2466
2488
  console.log(` Address: ${tenant.tenant_slug}`);
2467
2489
  console.log(` Tenant: ${tenant.id}`);
2468
- if (options.verbose) console.log(` Invoke: ${creds.gateway_url}/v1/s/${tenant.tenant_slug}/apps/<app>/functions/<function>/invoke`);
2490
+ if (options.verbose) {
2491
+ console.log(` URLs: ${publicAddressTemplate(creds.gateway_url, tenant.tenant_slug)}`);
2492
+ console.log(` ${SUBTREE_NOTE}`);
2493
+ }
2469
2494
  if (tenant.slug_locked) console.log("\n 🔒 The address is fixed — a Function version has been promoted and live URLs carry it.");
2470
2495
  else {
2471
2496
  console.log("\n The address can still be changed: \x1B[36mwawesome workspace rename <name>\x1B[0m");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wawesome",
3
- "version": "0.0.9",
3
+ "version": "0.0.10",
4
4
  "description": "CLI tool for building and deploying serverless functions on wawesome.io platform",
5
5
  "type": "module",
6
6
  "bin": {
@@ -16,6 +16,7 @@
16
16
  "build": "tsdown",
17
17
  "dev": "tsdown --watch",
18
18
  "test": "vitest run",
19
+ "test:templates": "vitest run --config vitest.live.config.ts",
19
20
  "check": "publint --pack npm",
20
21
  "changeset": "changeset"
21
22
  },