@leed-ai/cli 0.0.0-stage → 6.19.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.
- package/LICENSE.md +57 -0
- package/README.md +125 -2
- package/dist/LICENSE.md +57 -0
- package/dist/acorn-DAgDT1om.js +5087 -0
- package/dist/angular-l0_4PK8N.js +3598 -0
- package/dist/authShared-Dray38Ls.js +1161 -0
- package/dist/babel-CJeRQd5u.js +10038 -0
- package/dist/buildResults-tiq1nugP.js +21180 -0
- package/dist/chunk-1VJ9lAw7.js +42 -0
- package/dist/cliAuth-38JjD6hw.js +15 -0
- package/dist/env-B0bHiXJJ.js +29 -0
- package/dist/errors-CqKamGCu.js +481 -0
- package/dist/estree-E8WG8UHj.js +6930 -0
- package/dist/flow-6xaRIbPQ.js +52255 -0
- package/dist/glimmer-aJPjsfbT.js +7272 -0
- package/dist/graphql-mcgtPEiZ.js +1901 -0
- package/dist/html--eeea3Kl.js +6553 -0
- package/dist/leed.eleventy.mjs +6525 -0
- package/dist/leed.mjs +88952 -0
- package/dist/leed.sources.json +798 -0
- package/dist/leedLogger-Zkada5aO.js +78 -0
- package/dist/markdown-D73jNKwx.js +6836 -0
- package/dist/meriyah-CMp1nDDW.js +8932 -0
- package/dist/package.json +101 -0
- package/dist/postcss-h4fBr2Fn.js +6760 -0
- package/dist/prettier-CwFSKxfN.js +16821 -0
- package/dist/static/customer-site-worker/package.json +9 -0
- package/dist/static/customer-site-worker/src/assetsHydration.ts +55 -0
- package/dist/static/customer-site-worker/src/constants.ts +20 -0
- package/dist/static/customer-site-worker/src/cors.ts +120 -0
- package/dist/static/customer-site-worker/src/index.ts +242 -0
- package/dist/static/customer-site-worker/src/mcp-proxy.ts +98 -0
- package/dist/static/customer-site-worker/src/proxy.ts +92 -0
- package/dist/static/customer-site-worker/src/proxyHeaders.ts +47 -0
- package/dist/static/customer-site-worker/src/tier.ts +40 -0
- package/dist/static/customer-site-worker/src/types.ts +82 -0
- package/dist/static/customer-site-worker/test/functions-mock.worker.js +50 -0
- package/dist/static/customer-site-worker/tsconfig.json +19 -0
- package/dist/static/customer-site-worker/vitest.workers.config.ts +61 -0
- package/dist/static/install/husky/colors.mjs +5 -0
- package/dist/static/install/husky/hooks/commit-msg +1 -0
- package/dist/static/install/husky/hooks/pre-commit +1 -0
- package/dist/static/install/husky/hooks/pre-push +1 -0
- package/dist/static/install/husky/valid-command.mjs +29 -0
- package/dist/static/install/husky/valid-commit-msg.mjs +20 -0
- package/dist/static/install/package.json +10 -0
- package/dist/static/install/packages.txt +4 -0
- package/dist/static/install/tasks.json +111 -0
- package/dist/static/javascript/detectIncognito.js +195 -0
- package/dist/static/javascript/documentation.js +2781 -0
- package/dist/static/javascript/fp/fp.esm.js +2896 -0
- package/dist/static/javascript/fp/fp.js +3067 -0
- package/dist/static/javascript/live-search.js +986 -0
- package/dist/static/javascript/lunr-search.js +843 -0
- package/dist/static/javascript/timeme.js +451 -0
- package/dist/static/javascript/tracker/webmcp.js +67 -0
- package/dist/static/javascript/tracker/whisper.js +1 -0
- package/dist/static/javascript/utilities.js +819 -0
- package/dist/static/javascript/versions.json +74 -0
- package/dist/static/javascript/zoomable.js +488 -0
- package/dist/static/site/_data/eleventyComputed.js +228 -0
- package/dist/static/site/_data/leed-form-data.json +253 -0
- package/dist/static/site/_includes/leed/api/bits/array-type.hbs +24 -0
- package/dist/static/site/_includes/leed/api/bits/badges.hbs +9 -0
- package/dist/static/site/_includes/leed/api/bits/description.hbs +9 -0
- package/dist/static/site/_includes/leed/api/bits/examples.hbs +42 -0
- package/dist/static/site/_includes/leed/api/bits/scopes.hbs +28 -0
- package/dist/static/site/_includes/leed/api/object.hbs +110 -0
- package/dist/static/site/_includes/leed/api/parameters.hbs +11 -0
- package/dist/static/site/_includes/leed/api/property.hbs +153 -0
- package/dist/static/site/_includes/leed/api/request-body.hbs +51 -0
- package/dist/static/site/_includes/leed/api/responses.hbs +89 -0
- package/dist/static/site/_includes/leed/api/security-constraints.hbs +59 -0
- package/dist/static/site/_includes/leed/api/security.hbs +75 -0
- package/dist/static/site/_includes/leed/components/pagination.hbs +45 -0
- package/dist/static/site/_includes/leed/components/scroll-status-indicator-horizontal.hbs +22 -0
- package/dist/static/site/_includes/leed/docs/alpha/api.hbs +6 -0
- package/dist/static/site/_includes/leed/docs/alpha/base.hbs +26 -0
- package/dist/static/site/_includes/leed/docs/alpha/documentation.hbs +7 -0
- package/dist/static/site/_includes/leed/docs/api-article.hbs +75 -0
- package/dist/static/site/_includes/leed/docs/bravo/api.hbs +5 -0
- package/dist/static/site/_includes/leed/docs/bravo/base.hbs +31 -0
- package/dist/static/site/_includes/leed/docs/bravo/documentation.hbs +7 -0
- package/dist/static/site/_includes/leed/docs/charlie/api.hbs +6 -0
- package/dist/static/site/_includes/leed/docs/charlie/base.hbs +27 -0
- package/dist/static/site/_includes/leed/docs/charlie/documentation.hbs +10 -0
- package/dist/static/site/_includes/leed/docs/doc-article.hbs +40 -0
- package/dist/static/site/_includes/leed/docs/docs-footer.hbs +35 -0
- package/dist/static/site/_includes/leed/docs/docs-header.hbs +59 -0
- package/dist/static/site/_includes/leed/docs/document-search-modal.hbs +36 -0
- package/dist/static/site/_includes/leed/docs/document-search.hbs +23 -0
- package/dist/static/site/_includes/leed/docs/footer.hbs +12 -0
- package/dist/static/site/_includes/leed/docs/header/brand.hbs +19 -0
- package/dist/static/site/_includes/leed/docs/header/chrome.hbs +33 -0
- package/dist/static/site/_includes/leed/docs/header/compact.hbs +19 -0
- package/dist/static/site/_includes/leed/docs/header/cta.hbs +15 -0
- package/dist/static/site/_includes/leed/docs/header/nav.hbs +18 -0
- package/dist/static/site/_includes/leed/docs/header/top-search.hbs +15 -0
- package/dist/static/site/_includes/leed/docs/mini-bar.hbs +53 -0
- package/dist/static/site/_includes/leed/docs/pagination.hbs +19 -0
- package/dist/static/site/_includes/leed/docs/shell.hbs +56 -0
- package/dist/static/site/_includes/leed/docs/sidebar.hbs +52 -0
- package/dist/static/site/_includes/leed/docs/social-icons.hbs +81 -0
- package/dist/static/site/_includes/leed/docs/style.hbs +17 -0
- package/dist/static/site/_includes/leed/docs/toc.hbs +7 -0
- package/dist/static/site/_includes/leed/form.hbs +266 -0
- package/dist/static/site/_includes/leed/head.hbs +67 -0
- package/dist/static/site/_includes/leed/menu/builder.hbs +35 -0
- package/dist/static/site/_includes/leed/menu/item.hbs +67 -0
- package/dist/static/site/_includes/leed/menu/link.hbs +59 -0
- package/dist/static/site/_includes/leed/metadata/ogCard.hbs +40 -0
- package/dist/static/site/_includes/leed/metadata/siteMetadata.hbs +24 -0
- package/dist/static/site/_includes/leed/metadata/twitterCard.hbs +34 -0
- package/dist/static/site/_includes/leed/popup-video.hbs +21 -0
- package/dist/static/site/_includes/leed/stub-template.hbs +17 -0
- package/dist/static/site/_includes/leed/unsubscribe-form.hbs +30 -0
- package/dist/static/site/_layouts/leed-documentation.hbs +12 -0
- package/dist/static/site/leed-feed-atom.hbs +42 -0
- package/dist/static/site/leed-feed-json.hbs +56 -0
- package/dist/static/site/leed-feed-rss.hbs +39 -0
- package/dist/static/site/leed-headers.hbs +38 -0
- package/dist/static/site/leed-redirects.hbs +10 -0
- package/dist/static/site/leed-sitemap-pageType.hbs +28 -0
- package/dist/static/site/leed-sitemap.hbs +19 -0
- package/dist/static/site/leed-unsubscribe.hbs +44 -0
- package/dist/static/site/leed-unsubscribed.hbs +40 -0
- package/dist/static/tailwind/components/alerts.css +132 -0
- package/dist/static/tailwind/components/api-methods.css +39 -0
- package/dist/static/tailwind/components/breadcrumbs.css +31 -0
- package/dist/static/tailwind/components/code.css +88 -0
- package/dist/static/tailwind/components/collapsible.css +38 -0
- package/dist/static/tailwind/components/document-search.css +222 -0
- package/dist/static/tailwind/components/form.css +185 -0
- package/dist/static/tailwind/components/kbd.css +7 -0
- package/dist/static/tailwind/components/pagination.css +81 -0
- package/dist/static/tailwind/components/scroll-status-indicator.css +5 -0
- package/dist/static/tailwind/components/tab-groups.css +117 -0
- package/dist/static/tailwind/components/tables.css +0 -0
- package/dist/static/tailwind/components/toc.css +60 -0
- package/dist/static/tailwind/components.css +248 -0
- package/dist/static/tailwind/defaults.css +260 -0
- package/dist/static/tailwind/docs/api.css +701 -0
- package/dist/static/tailwind/docs/components/blockquote.css +5 -0
- package/dist/static/tailwind/docs/components/button.css +11 -0
- package/dist/static/tailwind/docs/components/docs-pagination.css +71 -0
- package/dist/static/tailwind/docs/components/mobile-bar.css +83 -0
- package/dist/static/tailwind/docs/components/navigation.css +279 -0
- package/dist/static/tailwind/docs/components/table.css +54 -0
- package/dist/static/tailwind/docs/components.css +6 -0
- package/dist/static/tailwind/docs/docs.css +427 -0
- package/dist/static/tailwind/docs/layouts/alpha.css +108 -0
- package/dist/static/tailwind/docs/layouts/bravo.css +218 -0
- package/dist/static/tailwind/docs/layouts/charlie.css +105 -0
- package/dist/static/tailwind/docs/layouts.css +3 -0
- package/dist/static/tailwind/docs/themes/amber.css +113 -0
- package/dist/static/tailwind/docs/themes/blue.css +94 -0
- package/dist/static/tailwind/docs/themes/cyan.css +111 -0
- package/dist/static/tailwind/docs/themes/emerald.css +111 -0
- package/dist/static/tailwind/docs/themes/fuchsia.css +111 -0
- package/dist/static/tailwind/docs/themes/green.css +95 -0
- package/dist/static/tailwind/docs/themes/indigo.css +111 -0
- package/dist/static/tailwind/docs/themes/lime.css +111 -0
- package/dist/static/tailwind/docs/themes/orange.css +111 -0
- package/dist/static/tailwind/docs/themes/pink.css +111 -0
- package/dist/static/tailwind/docs/themes/purple.css +111 -0
- package/dist/static/tailwind/docs/themes/red.css +111 -0
- package/dist/static/tailwind/docs/themes/rose.css +111 -0
- package/dist/static/tailwind/docs/themes/sky.css +111 -0
- package/dist/static/tailwind/docs/themes/teal.css +111 -0
- package/dist/static/tailwind/docs/themes/violet.css +111 -0
- package/dist/static/tailwind/docs/themes/yellow.css +111 -0
- package/dist/static/tailwind/docs/themes.css +84 -0
- package/dist/static/tailwind/font-awesome/free-7.3.1/brands.css +2455 -0
- package/dist/static/tailwind/font-awesome/free-7.3.1/fontawesome.css +8997 -0
- package/dist/static/tailwind/font-awesome/free-7.3.1/fonts.css +45 -0
- package/dist/static/tailwind/font-awesome/free-7.3.1/icons.json +2608 -0
- package/dist/static/tailwind/font-awesome/free-7.3.1.css +3 -0
- package/dist/static/tailwind/font-awesome/pro-7.0.0/brands.css +2215 -0
- package/dist/static/tailwind/font-awesome/pro-7.0.0/fontawesome.css +19281 -0
- package/dist/static/tailwind/font-awesome/pro-7.0.0/fonts.css +445 -0
- package/dist/static/tailwind/font-awesome/pro-7.0.0.css +3 -0
- package/dist/static/tailwind/font-awesome/pro-7.3.1/brands.css +2455 -0
- package/dist/static/tailwind/font-awesome/pro-7.3.1/fontawesome.css +20365 -0
- package/dist/static/tailwind/font-awesome/pro-7.3.1/fonts.css +589 -0
- package/dist/static/tailwind/font-awesome/pro-7.3.1.css +3 -0
- package/dist/static/tailwind/fonts/all.css +6 -0
- package/dist/static/tailwind/fonts/config.jsonc +31 -0
- package/dist/static/tailwind/fonts/geist-mono.css +142 -0
- package/dist/static/tailwind/fonts/geist.css +142 -0
- package/dist/static/tailwind/fonts/inter.css +215 -0
- package/dist/static/tailwind/fonts/jetbrains-mono.css +126 -0
- package/dist/static/tailwind/fonts/noto-sans.css +134 -0
- package/dist/static/tailwind/fonts/open-sans.css +89 -0
- package/dist/static/tailwind/highlighters.css +14 -0
- package/dist/static/tailwind/hljs/README.md +53 -0
- package/dist/static/tailwind/hljs/a11y.css +96 -0
- package/dist/static/tailwind/hljs/atom-fruit.css +90 -0
- package/dist/static/tailwind/hljs/atom-one.css +164 -0
- package/dist/static/tailwind/hljs/default.css +164 -0
- package/dist/static/tailwind/hljs/github.css +101 -0
- package/dist/static/tailwind/hljs/google-code.css +112 -0
- package/dist/static/tailwind/hljs/grayscale.css +115 -0
- package/dist/static/tailwind/hljs/gruvbox-hard.css +115 -0
- package/dist/static/tailwind/hljs/gruvbox-medium.css +115 -0
- package/dist/static/tailwind/hljs/gruvbox-soft.css +115 -0
- package/dist/static/tailwind/hljs/papercolor.css +120 -0
- package/dist/static/tailwind/hljs/qt-creator.css +91 -0
- package/dist/static/tailwind/hljs/summerfruit.css +115 -0
- package/dist/static/tailwind/hljs/tomorrow.css +115 -0
- package/dist/static/tailwind/leed.css +170 -0
- package/dist/static/tailwind/site-tokens.reference.css +105 -0
- package/dist/static/tailwind/utils/icons.css +102 -0
- package/dist/static/tailwind/utils/utilities.css +105 -0
- package/dist/static/templates/pages/PAGE.hbs +27 -0
- package/dist/static/templates/pages/PAGE_LAYOUT.hbs +19 -0
- package/dist/static/templates/pages/PAGE_TYPE_INDEX.hbs +89 -0
- package/dist/static/templates/pages/PAGINATED_PAGE_TYPE_ITEM.hbs +52 -0
- package/dist/static/templates/pages/PAGINATED_PAGE_TYPE_LIST.hbs +39 -0
- package/dist/static/templates/pages/PAGINATED_PAGE_TYPE_PAGINATION.hbs +11 -0
- package/dist/static/templates/raw-content/.ci/build.sh +58 -0
- package/dist/static/templates/raw-content/README.md +179 -0
- package/dist/static/templates/raw-content/_gitignore +50 -0
- package/dist/static/templates/raw-content/src/404.hbs +21 -0
- package/dist/static/templates/raw-content/src/_data/autolink.json +1 -0
- package/dist/static/templates/raw-content/src/_data/ctaList.json +1 -0
- package/dist/static/templates/raw-content/src/_data/leedForms.json +1 -0
- package/dist/static/templates/raw-content/src/_data/menu.json +1 -0
- package/dist/static/templates/raw-content/src/_includes/footer.hbs +18 -0
- package/dist/static/templates/raw-content/src/_includes/header-includes.hbs +25 -0
- package/dist/static/templates/raw-content/src/_includes/header.hbs +5 -0
- package/dist/static/templates/raw-content/src/_includes/site-template.hbs +23 -0
- package/dist/static/templates/raw-content/src/_includes/unsubscribe-DISABLED.hbs +17 -0
- package/dist/static/templates/raw-content/src/_includes/unsubscribed-DISABLED.hbs +13 -0
- package/dist/static/templates/raw-content/src/_layouts/empty.hbs +2 -0
- package/dist/static/templates/raw-content/src/index.hbs +21 -0
- package/dist/static/templates/raw-content/src/robots.hbs +9 -0
- package/dist/static/templates/raw-content/tailwind/site/base.css +44 -0
- package/dist/static/templates/raw-content/tailwind/site.config.css +3 -0
- package/dist/static/templates/sandbox/_gitignore +50 -0
- package/dist/static/templates/sandbox/identity.json +1 -0
- package/dist/static/templates/sandbox/src/404.hbs +21 -0
- package/dist/static/templates/sandbox/src/_data/autolink.json +1 -0
- package/dist/static/templates/sandbox/src/_data/ctaList.json +1 -0
- package/dist/static/templates/sandbox/src/_data/labelList.json +9 -0
- package/dist/static/templates/sandbox/src/_data/leedForms.json +20 -0
- package/dist/static/templates/sandbox/src/_data/menu.json +19 -0
- package/dist/static/templates/sandbox/src/_data/pageTypeList.json +14 -0
- package/dist/static/templates/sandbox/src/_data/searchIndexList.json +1 -0
- package/dist/static/templates/sandbox/src/_data/userList.json +11 -0
- package/dist/static/templates/sandbox/src/_includes/footer.hbs +18 -0
- package/dist/static/templates/sandbox/src/_includes/header-includes.hbs +25 -0
- package/dist/static/templates/sandbox/src/_includes/header.hbs +5 -0
- package/dist/static/templates/sandbox/src/_includes/site-template.hbs +23 -0
- package/dist/static/templates/sandbox/src/_layouts/empty.hbs +2 -0
- package/dist/static/templates/sandbox/src/index.hbs +20 -0
- package/dist/static/templates/sandbox/src/robots.hbs +9 -0
- package/dist/static/templates/sandbox/src/src.11tydata.json +39 -0
- package/dist/static/templates/sandbox/tailwind/site/base.css +44 -0
- package/dist/static/templates/sandbox/tailwind/site.config.css +3 -0
- package/dist/thrown-sukVkp_1.js +113 -0
- package/dist/typescript-D4T0V_Hn.js +23004 -0
- package/dist/yaml-9wR8GxF_.js +5236 -0
- package/package.json +157 -4
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SPDX-FileCopyrightText: © 2024-2025 Leed, Inc.
|
|
3
|
+
* SPDX-License-Identifier: LicenseRef-Leed-EULA
|
|
4
|
+
*/
|
|
5
|
+
//#region \0rolldown/runtime.js
|
|
6
|
+
var __create = Object.create;
|
|
7
|
+
var __defProp = Object.defineProperty;
|
|
8
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
9
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
10
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
11
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
12
|
+
var __esmMin = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
13
|
+
var __commonJSMin = (cb, mod) => () => (mod || (cb((mod = { exports: {} }).exports, mod), cb = null), mod.exports);
|
|
14
|
+
var __exportAll = (all, no_symbols) => {
|
|
15
|
+
let target = {};
|
|
16
|
+
for (var name in all) __defProp(target, name, {
|
|
17
|
+
get: all[name],
|
|
18
|
+
enumerable: true
|
|
19
|
+
});
|
|
20
|
+
if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
|
|
21
|
+
return target;
|
|
22
|
+
};
|
|
23
|
+
var __copyProps = (to, from, except, desc) => {
|
|
24
|
+
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
25
|
+
key = keys[i];
|
|
26
|
+
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
|
|
27
|
+
get: ((k) => from[k]).bind(null, key),
|
|
28
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
return to;
|
|
32
|
+
};
|
|
33
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
34
|
+
value: mod,
|
|
35
|
+
enumerable: true
|
|
36
|
+
}) : target, mod));
|
|
37
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, { get: (a, b) => (typeof require !== "undefined" ? require : a)[b] }) : x)(function(x) {
|
|
38
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
39
|
+
throw Error("Calling `require` for \"" + x + "\" in an environment that doesn't expose the `require` function. See https://rolldown.rs/in-depth/bundling-cjs#require-external-modules for more details.");
|
|
40
|
+
});
|
|
41
|
+
//#endregion
|
|
42
|
+
export { __toESM as a, __require as i, __esmMin as n, __exportAll as r, __commonJSMin as t };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SPDX-FileCopyrightText: © 2024-2025 Leed, Inc.
|
|
3
|
+
* SPDX-License-Identifier: LicenseRef-Leed-EULA
|
|
4
|
+
*/
|
|
5
|
+
import { r as __exportAll } from "./chunk-1VJ9lAw7.js";
|
|
6
|
+
import { z } from "zod";
|
|
7
|
+
//#region ../../libs/data-types/src/auth/schemas/cliAuth.ts
|
|
8
|
+
var cliAuth_exports = /* @__PURE__ */ __exportAll({ CliRefreshResponse: () => CliRefreshResponse });
|
|
9
|
+
z.object({ accessToken: z.string().min(1).describe("The current (possibly expired) session token to refresh") });
|
|
10
|
+
const CliRefreshResponse = z.object({
|
|
11
|
+
accessToken: z.string().describe("Session token to use from now on: the same token until it is renewed, then its successor"),
|
|
12
|
+
expiresIn: z.number().describe("Seconds until the returned token expires")
|
|
13
|
+
});
|
|
14
|
+
//#endregion
|
|
15
|
+
export { cliAuth_exports as n, CliRefreshResponse as t };
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SPDX-FileCopyrightText: © 2024-2025 Leed, Inc.
|
|
3
|
+
* SPDX-License-Identifier: LicenseRef-Leed-EULA
|
|
4
|
+
*/
|
|
5
|
+
import { r as __exportAll } from "./chunk-1VJ9lAw7.js";
|
|
6
|
+
import { z } from "zod";
|
|
7
|
+
//#region ../../libs/data-types/src/schema/env.ts
|
|
8
|
+
var env_exports = /* @__PURE__ */ __exportAll({
|
|
9
|
+
CMS_BASE_URLS: () => CMS_BASE_URLS,
|
|
10
|
+
EnvName: () => EnvName,
|
|
11
|
+
cmsBaseUrl: () => cmsBaseUrl
|
|
12
|
+
});
|
|
13
|
+
const EnvName = z.enum([
|
|
14
|
+
"production",
|
|
15
|
+
"staging",
|
|
16
|
+
"dev"
|
|
17
|
+
]);
|
|
18
|
+
/** CMS app base URLs by environment. Use `cmsBaseUrl(env)` for resolved URL with env var override. */
|
|
19
|
+
const CMS_BASE_URLS = {
|
|
20
|
+
production: "https://app.leed.ai",
|
|
21
|
+
staging: "https://staging.app.leed.ai",
|
|
22
|
+
dev: "http://localhost:8787"
|
|
23
|
+
};
|
|
24
|
+
/** Resolve the CMS base URL for an environment, with `LEED_CMS_URL` env var override. */
|
|
25
|
+
function cmsBaseUrl(env) {
|
|
26
|
+
return process.env.LEED_CMS_URL || CMS_BASE_URLS[env] || CMS_BASE_URLS.production;
|
|
27
|
+
}
|
|
28
|
+
//#endregion
|
|
29
|
+
export { cmsBaseUrl as n, env_exports as r, EnvName as t };
|
|
@@ -0,0 +1,481 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SPDX-FileCopyrightText: © 2024-2025 Leed, Inc.
|
|
3
|
+
* SPDX-License-Identifier: LicenseRef-Leed-EULA
|
|
4
|
+
*/
|
|
5
|
+
//#region src/cli/output/documentStrings.ts
|
|
6
|
+
/**
|
|
7
|
+
* One walk over every string a document will actually serialize (#334).
|
|
8
|
+
*
|
|
9
|
+
* `emit()` applies two whole-document string transforms before it writes:
|
|
10
|
+
* credential redaction (`./redact.ts`) and ANSI stripping (`./ansi.ts`). Both
|
|
11
|
+
* are "rewrite every string anywhere in the value", and both have to agree
|
|
12
|
+
* exactly about which strings those are — a boxed `String`, a class instance's
|
|
13
|
+
* own enumerable properties, a `toJSON` bearer, a cycle. Getting that set wrong
|
|
14
|
+
* is how the original credential leak happened, so it is written once here and
|
|
15
|
+
* the two transforms are parameters.
|
|
16
|
+
*
|
|
17
|
+
* Extracted from `redactDocument`, whose behavior it is verbatim;
|
|
18
|
+
* `redactionSweep.test.ts` and `redact.test.ts` are its coverage.
|
|
19
|
+
*/
|
|
20
|
+
/**
|
|
21
|
+
* The primitive behind a boxed `String`, or null for anything else.
|
|
22
|
+
*
|
|
23
|
+
* `JSON.stringify` writes `new String(url)` as the URL, not as the `{"0":"h",
|
|
24
|
+
* "1":"t",…}` its own enumerable properties would produce — so walking those
|
|
25
|
+
* properties would rewrite nothing that gets serialized. It needs the same
|
|
26
|
+
* treatment a bare string gets, on its primitive.
|
|
27
|
+
*/
|
|
28
|
+
function boxedStringValue(value) {
|
|
29
|
+
return Object.prototype.toString.call(value) === "[object String]" ? String(value) : null;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Whether `JSON.stringify` will serialize `value` through its own `toJSON`
|
|
33
|
+
* rather than from its properties — a `Date`, or anything that declares one.
|
|
34
|
+
*
|
|
35
|
+
* Such a value is returned as it came. Its own enumerable properties are NOT
|
|
36
|
+
* what the serializer writes, so rewriting them would change the object without
|
|
37
|
+
* changing the document, and there is no way to rewrite what `toJSON` returns
|
|
38
|
+
* that leaves the value still usable by a renderer — replacing a `Date` with a
|
|
39
|
+
* string breaks the first `.toISOString()` that touches it. See the residual
|
|
40
|
+
* edge noted below.
|
|
41
|
+
*/
|
|
42
|
+
function hasToJson(value) {
|
|
43
|
+
return typeof value.toJSON === "function";
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* `value` with every string in it, at any depth, run through `transform`.
|
|
47
|
+
*
|
|
48
|
+
* **It walks what `JSON.stringify` will actually serialize**, which is the
|
|
49
|
+
* whole point of a backstop: the own enumerable properties of any object the
|
|
50
|
+
* serializer will write as an object, arrays by their elements, boxed strings
|
|
51
|
+
* by their primitive. Restricting the walk to *plain* objects was a hole in
|
|
52
|
+
* exactly the shape `./redact.ts` was written for — a simple-git `GitError` is
|
|
53
|
+
* a class instance, and the token lives on its own enumerable `task.commands`,
|
|
54
|
+
* which the serializer writes out and the walk skipped straight past.
|
|
55
|
+
*
|
|
56
|
+
* The one thing it does not walk is a `toJSON`-bearing value, because that is
|
|
57
|
+
* the one case where own enumerable properties are not what gets serialized.
|
|
58
|
+
* **Residual edge:** a `toJSON` that itself returns a string the caller wanted
|
|
59
|
+
* rewritten is therefore left alone. Nothing in the CLI has one — `Date` is the
|
|
60
|
+
* only such value it produces — and closing it would mean replacing the value
|
|
61
|
+
* with its JSON projection, which breaks every renderer that calls a method on
|
|
62
|
+
* it.
|
|
63
|
+
*
|
|
64
|
+
* A non-plain object is rebuilt as a plain one, so what comes out serializes
|
|
65
|
+
* byte-for-byte as the input would have, minus whatever `transform` removed.
|
|
66
|
+
* That rebuild loses the prototype and any non-enumerable property (an
|
|
67
|
+
* `Error`'s `message` and `stack`) — but it happens ONLY when something below
|
|
68
|
+
* actually changed. On every other value the original object is returned
|
|
69
|
+
* unchanged, so the common case allocates nothing and the value `emit()` hands
|
|
70
|
+
* a renderer is identical.
|
|
71
|
+
*
|
|
72
|
+
* `open` is the set of objects on the current path, and it is not an
|
|
73
|
+
* optimization: a payload can be circular, and `emit()` runs this BEFORE
|
|
74
|
+
* `JSON.stringify` — so an unguarded walk turns "the caller handed us a cyclic
|
|
75
|
+
* result" into a `RangeError` thrown out of `emit()` itself, which is the one
|
|
76
|
+
* thing `emit()` promises never to do. A node already on the path is returned
|
|
77
|
+
* as it came; the serializer that follows refuses the cycle anyway and
|
|
78
|
+
* `emit()` answers with its substituted failure envelope, so no document
|
|
79
|
+
* carrying the unwalked subtree is ever written.
|
|
80
|
+
*/
|
|
81
|
+
function mapDocumentStrings(value, transform, open = /* @__PURE__ */ new WeakSet()) {
|
|
82
|
+
if (typeof value === "string") return transform(value);
|
|
83
|
+
if (typeof value !== "object" || value === null) return value;
|
|
84
|
+
if (open.has(value)) return value;
|
|
85
|
+
const isArray = Array.isArray(value);
|
|
86
|
+
if (!isArray) {
|
|
87
|
+
const boxed = boxedStringValue(value);
|
|
88
|
+
if (boxed !== null) {
|
|
89
|
+
const mapped = transform(boxed);
|
|
90
|
+
return mapped === boxed ? value : new String(mapped);
|
|
91
|
+
}
|
|
92
|
+
if (hasToJson(value)) return value;
|
|
93
|
+
}
|
|
94
|
+
open.add(value);
|
|
95
|
+
try {
|
|
96
|
+
let changed = false;
|
|
97
|
+
const walk = (item) => {
|
|
98
|
+
const mapped = mapDocumentStrings(item, transform, open);
|
|
99
|
+
if (mapped !== item) changed = true;
|
|
100
|
+
return mapped;
|
|
101
|
+
};
|
|
102
|
+
if (isArray) {
|
|
103
|
+
const next = value.map(walk);
|
|
104
|
+
return changed ? next : value;
|
|
105
|
+
}
|
|
106
|
+
const next = {};
|
|
107
|
+
for (const [key, item] of Object.entries(value)) next[key] = walk(item);
|
|
108
|
+
return changed ? next : value;
|
|
109
|
+
} finally {
|
|
110
|
+
open.delete(value);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
//#endregion
|
|
114
|
+
//#region src/cli/output/redact.ts
|
|
115
|
+
/**
|
|
116
|
+
* Credential redaction at the one place documents leave the CLI (#333).
|
|
117
|
+
*
|
|
118
|
+
* `leed site init` used to build the raw-content clone URL with the freshly
|
|
119
|
+
* issued GitLab token embedded in it — `https://access-token:<token>@gitlab.com/…`
|
|
120
|
+
* — because that URL was also what got persisted as the checkout's `origin`, and
|
|
121
|
+
* every later `leed site push` / `leed site commit` authenticated with it. The
|
|
122
|
+
* token therefore appeared in the argv of the git commands the CLI ran, and
|
|
123
|
+
* simple-git parks that argv on the error it throws as an OWN ENUMERABLE
|
|
124
|
+
* `task.commands` property. Anything that renders such an error as a value —
|
|
125
|
+
* `util.format`, `util.inspect`, `console.error(err)` — prints own enumerable
|
|
126
|
+
* properties, so the token came out with it.
|
|
127
|
+
*
|
|
128
|
+
* #413 removed that URL: the token lives in `~/.config/leed/auth.json` and
|
|
129
|
+
* reaches git through config environment variables, so argv is clean by
|
|
130
|
+
* construction. **That moved the leak surface rather than closing this
|
|
131
|
+
* module.** Three shapes have to be matched now, not one:
|
|
132
|
+
*
|
|
133
|
+
* - `URL_USERINFO`, kept as the backstop for a checkout that has not been
|
|
134
|
+
* migrated yet — its `origin` still carries userinfo, and git prints the
|
|
135
|
+
* remote URL in plenty of its own messages;
|
|
136
|
+
* - `GITLAB_TOKEN`, the bare `glpat-…` shape, which is what a token looks like
|
|
137
|
+
* once it is not in a URL — in a `git credential` transcript, in an
|
|
138
|
+
* `auth.json` path a user pasted, or in a CMS response a command echoed;
|
|
139
|
+
* - `AUTHORIZATION_VALUE`, the header the config environment carries, which
|
|
140
|
+
* `simple-git` itself logs with `logger("%O", spawnOptions)` under
|
|
141
|
+
* `DEBUG=simple-git`.
|
|
142
|
+
*
|
|
143
|
+
* Without the last two this module would silently stop covering anything the
|
|
144
|
+
* moment the URL form went away.
|
|
145
|
+
*
|
|
146
|
+
* On its own that was a line on a terminal. Under `--json` it became a field of
|
|
147
|
+
* a document written to stdout for a machine to capture, parse, persist and
|
|
148
|
+
* forward — `data.repositoryError` and `warnings[0]` on the `site.init`
|
|
149
|
+
* envelope. Log-read access is a far wider circle than repo-write access, and
|
|
150
|
+
* the token stays valid: every failure that produces one of those strings (a
|
|
151
|
+
* half-created directory, an aborted earlier init, a removed remote, a clone
|
|
152
|
+
* that failed on the network) is unrelated to whether the token still works.
|
|
153
|
+
*
|
|
154
|
+
* Two rules, and this module is the second:
|
|
155
|
+
*
|
|
156
|
+
* 1. Never render a git error OBJECT into a reported string. Take its
|
|
157
|
+
* `message`. `initRepository.ts` is where that is done.
|
|
158
|
+
* 2. Redact anyway, at the boundary — because rule 1 is a convention and one
|
|
159
|
+
* unwrapped `simpleGit(...).remote(["set-url", …])` reintroduces the
|
|
160
|
+
* vulnerability. `emit()` is that boundary: every document the CLI emits,
|
|
161
|
+
* from a command leaf, from a Commander `_exit`, or from `emit()`'s own
|
|
162
|
+
* substituted failure envelope, is written by it and nothing else.
|
|
163
|
+
*
|
|
164
|
+
* The redaction runs on the PARSED value, before either projection, so the
|
|
165
|
+
* human render and the JSON payload are redacted by the same pass and cannot
|
|
166
|
+
* disagree about it.
|
|
167
|
+
*
|
|
168
|
+
* ## What the guarantee covers, and where it stops
|
|
169
|
+
*
|
|
170
|
+
* It covers **the document** — every field of every envelope the CLI writes,
|
|
171
|
+
* under `--json` and in the human render alike, because both are projections of
|
|
172
|
+
* the value this module has already walked.
|
|
173
|
+
*
|
|
174
|
+
* It does **not** cover **stderr passthrough**. The output of a program the CLI
|
|
175
|
+
* drives — wrangler, Eleventy, git — is streamed to stderr as it arrives
|
|
176
|
+
* (`./subprocess.ts`, `./streams.ts`), never buffered into a field, and never
|
|
177
|
+
* routed through `emit()`. Nothing redacts it. That is deliberate: it is
|
|
178
|
+
* diagnostic narration for the person watching, it is what the program itself
|
|
179
|
+
* chose to print, and interposing on a live stream would mean holding output
|
|
180
|
+
* back to look for a `//user:password@` that could straddle two chunks. The
|
|
181
|
+
* machine-readable document on stdout is the surface with the guarantee; the
|
|
182
|
+
* narration on stderr is not, and no future reader should assume otherwise.
|
|
183
|
+
*
|
|
184
|
+
* The one place an invocation IS reconstructed into a field —
|
|
185
|
+
* `externalCommandDetails` in `./errors.ts`, which prints the argv git was run
|
|
186
|
+
* with — redacts at the point it builds the string, as well as here.
|
|
187
|
+
*
|
|
188
|
+
* URL userinfo: the `user:password@` (or bare `token@`) between `//` and the
|
|
189
|
+
* host.
|
|
190
|
+
*
|
|
191
|
+
* Neither half may contain `/`, whitespace or a second `@`, which is what stops
|
|
192
|
+
* it matching an `@` that merely appears somewhere in a path — `//host/a@b` has
|
|
193
|
+
* a `/` before the `@` and is left alone. An `scp`-form remote
|
|
194
|
+
* (`git@gitlab.com:leed-ai/x.git`) has no `//` and carries no secret, so it is
|
|
195
|
+
* likewise untouched.
|
|
196
|
+
*
|
|
197
|
+
* The user half also excludes `:`, which the password half does not. Without
|
|
198
|
+
* that it is greedy enough to swallow the separator — `//access-token:<token>@`
|
|
199
|
+
* matched as a username of `access-token:<token>` and no password at all, which
|
|
200
|
+
* still redacted the secret but reported the wrong shape.
|
|
201
|
+
*/
|
|
202
|
+
const URL_USERINFO = /\/\/([^/\s@:]*)(:[^/\s@]*)?@/g;
|
|
203
|
+
/** What a redacted `user:password@` reads as. */
|
|
204
|
+
const REDACTED_USERINFO = "//***:***@";
|
|
205
|
+
/** What a redacted bare `token@` reads as. */
|
|
206
|
+
const REDACTED_USER = "//***@";
|
|
207
|
+
/**
|
|
208
|
+
* A GitLab access token outside any URL: the `glpat-` prefix and its payload.
|
|
209
|
+
*
|
|
210
|
+
* The prefix is the whole anchor, and it is enough — GitLab stamps it on every
|
|
211
|
+
* personal and project access token, and nothing else in this CLI's output is
|
|
212
|
+
* shaped like it. The prefix is KEPT in the replacement, because a reader needs
|
|
213
|
+
* to know that what was removed was a repository token rather than a session
|
|
214
|
+
* cookie or a password.
|
|
215
|
+
*/
|
|
216
|
+
const GITLAB_TOKEN = /glpat-[A-Za-z0-9_-]+/g;
|
|
217
|
+
/** What a redacted bare `glpat-…` token reads as. */
|
|
218
|
+
const REDACTED_TOKEN = "glpat-***";
|
|
219
|
+
/**
|
|
220
|
+
* An `Authorization` header carrying an actual credential.
|
|
221
|
+
*
|
|
222
|
+
* **Anchored on the credential, not on the header name.** `redactDocument`
|
|
223
|
+
* walks every string of every emitted document, and `leed import openapi`
|
|
224
|
+
* legitimately handles specs that *describe* an `Authorization` header — a
|
|
225
|
+
* matcher that ate from the word `Authorization:` to the end of the line would
|
|
226
|
+
* redact the user's own API documentation. Requiring `Basic` or `Bearer`
|
|
227
|
+
* followed by at least one credential character means a prose mention, or a
|
|
228
|
+
* placeholder like `Authorization: Bearer <token>`, is left exactly as it is.
|
|
229
|
+
*
|
|
230
|
+
* The scheme is kept in the replacement for the same reason the `glpat-` prefix
|
|
231
|
+
* is: it says what was removed.
|
|
232
|
+
*
|
|
233
|
+
* **Horizontal whitespace only.** `\s` matches newlines, so an
|
|
234
|
+
* `Authorization: Basic` ending a line — a truncated log, a header printed with
|
|
235
|
+
* no value — reached across the break and ate the first token-shaped word on
|
|
236
|
+
* the NEXT line, which is someone else's output. Failing safe is still
|
|
237
|
+
* corrupting, so the classes are `[ \t]`.
|
|
238
|
+
*/
|
|
239
|
+
const AUTHORIZATION_VALUE = /(Authorization:[ \t]*(?:Basic|Bearer)[ \t]+)[A-Za-z0-9+/=._~-]+/gi;
|
|
240
|
+
/**
|
|
241
|
+
* `text` with every credential shape it contains replaced by `***`.
|
|
242
|
+
*
|
|
243
|
+
* A URL keeps its shape — scheme, host, path — because that is the part a
|
|
244
|
+
* reader needs to understand what failed. Only the secret goes, and the same
|
|
245
|
+
* goes for a token's prefix and a header's scheme.
|
|
246
|
+
*/
|
|
247
|
+
function redactCredentials(text) {
|
|
248
|
+
return text.replace(URL_USERINFO, (_match, _user, password) => password === void 0 ? REDACTED_USER : REDACTED_USERINFO).replace(GITLAB_TOKEN, REDACTED_TOKEN).replace(AUTHORIZATION_VALUE, (_match, scheme) => `${scheme}***`);
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* `value` with every string in it, at any depth, run through
|
|
252
|
+
* `redactCredentials`.
|
|
253
|
+
*
|
|
254
|
+
* The walk itself lives in `./documentStrings.ts`, shared with the ANSI sweep
|
|
255
|
+
* in `./ansi.ts`: both transforms must agree exactly about which strings a
|
|
256
|
+
* document contains — a boxed `String`, a class instance's own enumerable
|
|
257
|
+
* properties, a `toJSON` bearer, a cycle — and that set is where the original
|
|
258
|
+
* leak hid. See that module for what is and is not walked, and for the
|
|
259
|
+
* residual `toJSON` edge.
|
|
260
|
+
*/
|
|
261
|
+
function redactDocument(value) {
|
|
262
|
+
return mapDocumentStrings(value, redactCredentials);
|
|
263
|
+
}
|
|
264
|
+
//#endregion
|
|
265
|
+
//#region src/cli/output/errors.ts
|
|
266
|
+
/**
|
|
267
|
+
* The bridge between thrown errors and the `--json` envelope (#333 Phase 2).
|
|
268
|
+
*
|
|
269
|
+
* `CliUserError` is the CLI's one deliberate, user-facing throw. Folding it
|
|
270
|
+
* into the shared error catalog means a single thrown error renders correctly
|
|
271
|
+
* in BOTH modes: `src/cli/index.ts` prints its message and hint as text, and
|
|
272
|
+
* `cliErrorFrom` turns the same instance into the envelope's `error` object
|
|
273
|
+
* with a machine-readable `code`.
|
|
274
|
+
*
|
|
275
|
+
* Nothing here changes the wording of any message — only its shape.
|
|
276
|
+
*/
|
|
277
|
+
/**
|
|
278
|
+
* The code a `CliUserError` carries when its throw site does not name one.
|
|
279
|
+
*
|
|
280
|
+
* It is the code for exactly one situation: the options or arguments supplied
|
|
281
|
+
* cannot be used — a bad flag value, a file named by a flag that is missing or
|
|
282
|
+
* of the wrong kind. It is NOT a catch-all. Every throw site whose remedy is
|
|
283
|
+
* something other than "fix your arguments" — cd into a site checkout, log in
|
|
284
|
+
* again, stage a set first — names its own code, because that code
|
|
285
|
+
* is the branch an agent takes and a wrong one sends it down the wrong path.
|
|
286
|
+
*/
|
|
287
|
+
const DEFAULT_USER_ERROR_CODE = "invalid_arguments";
|
|
288
|
+
/** The code used for any error that is not a deliberate, user-facing one. */
|
|
289
|
+
const UNEXPECTED_ERROR_CODE = "internal_error";
|
|
290
|
+
/** The code for a fault in the environment the CLI is running in, not in the CLI. */
|
|
291
|
+
const EXTERNAL_COMMAND_ERROR_CODE = "external_command_failed";
|
|
292
|
+
/**
|
|
293
|
+
* simple-git's own error classes, by constructor name.
|
|
294
|
+
*
|
|
295
|
+
* Every command that touches a repository reaches git through simple-git, and
|
|
296
|
+
* everything it throws — git absent from PATH, the directory not a repository,
|
|
297
|
+
* a command that exited non-zero — arrives here as one of these. `name` is no
|
|
298
|
+
* use: they all inherit `"Error"` from `Error.prototype`, so the constructor is
|
|
299
|
+
* what identifies them. `TaskConfigurationError` is deliberately absent: that
|
|
300
|
+
* one means the CLI called simple-git wrongly, which IS an internal fault.
|
|
301
|
+
*/
|
|
302
|
+
const GIT_ERROR_CONSTRUCTORS = new Set([
|
|
303
|
+
"GitError",
|
|
304
|
+
"GitConstructError",
|
|
305
|
+
"GitPluginError",
|
|
306
|
+
"GitResponseError"
|
|
307
|
+
]);
|
|
308
|
+
/**
|
|
309
|
+
* Markers of an external fault in a message, for anything that reaches us
|
|
310
|
+
* without its class intact — a bundler that renamed a constructor, an error
|
|
311
|
+
* re-thrown as a plain `Error` carrying a subprocess's own words.
|
|
312
|
+
*
|
|
313
|
+
* `fatal:` and `error:` are git's, at the start of a line; `spawn … ENOENT` is
|
|
314
|
+
* Node's for a program that could not be started at all.
|
|
315
|
+
*/
|
|
316
|
+
const EXTERNAL_FAULT_RE = /^fatal: |^error: |\bspawn\b[^\n]*\bENOENT\b/m;
|
|
317
|
+
/**
|
|
318
|
+
* Node's own prefix on an `execSync`/`exec` failure: `Command failed: <cmd>`,
|
|
319
|
+
* followed by whatever the child wrote to stderr.
|
|
320
|
+
*
|
|
321
|
+
* `leed self-update` is why this is here. It drives `bun pm view` and `bun
|
|
322
|
+
* install -g` through `execSync`, and a registry that cannot be reached throws
|
|
323
|
+
* a plain `Error` whose message begins with this prefix — no git error class,
|
|
324
|
+
* no `fatal:`, no `spawn ENOENT`. It was therefore reported as
|
|
325
|
+
* `internal_error`, "an unexpected fault in the CLI itself", for a failure
|
|
326
|
+
* entirely in the caller's network or registry configuration: an agent that
|
|
327
|
+
* branched on that code would file a bug against the CLI instead of checking
|
|
328
|
+
* its own connectivity.
|
|
329
|
+
*/
|
|
330
|
+
const SUBPROCESS_PREFIX_RE = /^Command failed: (.*)$/m;
|
|
331
|
+
/**
|
|
332
|
+
* Whether `thrown` came back from a child process the CLI started.
|
|
333
|
+
*
|
|
334
|
+
* `status` is the child's exit code, set by `execSync` and `spawnSync` on the
|
|
335
|
+
* error they throw; a genuine internal fault does not carry one. The message
|
|
336
|
+
* prefix is the fallback for anything that lost its extra properties on the way
|
|
337
|
+
* here — a re-throw, a bundler, a `structuredClone`.
|
|
338
|
+
*/
|
|
339
|
+
function isSubprocessFailure(thrown) {
|
|
340
|
+
const status = thrown.status;
|
|
341
|
+
if (typeof status === "number" || typeof status === "string") return true;
|
|
342
|
+
return SUBPROCESS_PREFIX_RE.test(thrown.message);
|
|
343
|
+
}
|
|
344
|
+
/**
|
|
345
|
+
* Whether `thrown` is a program the CLI drives failing, rather than the CLI
|
|
346
|
+
* failing.
|
|
347
|
+
*
|
|
348
|
+
* The distinction is the whole reason `external_command_failed` exists. "git
|
|
349
|
+
* is not installed" and "this is not a git repository" reached `site validate`,
|
|
350
|
+
* `site commit` and `site upload` as `internal_error`, which tells an agent the
|
|
351
|
+
* CLI is broken and there is nothing it can do — when in fact the remedy is
|
|
352
|
+
* entirely in the caller's environment, and git has usually printed it.
|
|
353
|
+
*/
|
|
354
|
+
function isExternalCommandFailure(thrown) {
|
|
355
|
+
if (!(thrown instanceof Error)) return false;
|
|
356
|
+
if (GIT_ERROR_CONSTRUCTORS.has(thrown.constructor?.name ?? "")) return true;
|
|
357
|
+
if (isSubprocessFailure(thrown)) return true;
|
|
358
|
+
return EXTERNAL_FAULT_RE.test(thrown.message);
|
|
359
|
+
}
|
|
360
|
+
/** The invocation behind `thrown`, when the thrower recorded one. */
|
|
361
|
+
function failingInvocation(thrown) {
|
|
362
|
+
const commands = thrown.task?.commands;
|
|
363
|
+
if (Array.isArray(commands) && commands.length > 0) return `git ${commands.join(" ")}`;
|
|
364
|
+
return SUBPROCESS_PREFIX_RE.exec(thrown.message)?.[1]?.trim();
|
|
365
|
+
}
|
|
366
|
+
/** Whatever the child wrote, when it is carried separately from the message. */
|
|
367
|
+
function subprocessOutput(thrown) {
|
|
368
|
+
const stderr = thrown.stderr;
|
|
369
|
+
const text = typeof stderr === "string" ? stderr : stderr instanceof Uint8Array ? Buffer.from(stderr).toString() : "";
|
|
370
|
+
return text.trim().length > 0 ? text.trim() : void 0;
|
|
371
|
+
}
|
|
372
|
+
/**
|
|
373
|
+
* The message with Node's own `Command failed: <cmd>` line taken off.
|
|
374
|
+
*
|
|
375
|
+
* The invocation on that line is reported as `details`' first line already;
|
|
376
|
+
* leaving it in the body prints it twice, once as the CLI's framing and once as
|
|
377
|
+
* Node's, with the child's actual words below both.
|
|
378
|
+
*/
|
|
379
|
+
function withoutSubprocessPrefix(message) {
|
|
380
|
+
const lines = message.split("\n");
|
|
381
|
+
if (!SUBPROCESS_PREFIX_RE.test(lines[0] ?? "")) return message.trim();
|
|
382
|
+
return lines.slice(1).join("\n").trim();
|
|
383
|
+
}
|
|
384
|
+
/**
|
|
385
|
+
* `error.details` for a failure of a program the CLI drives.
|
|
386
|
+
*
|
|
387
|
+
* The enum entry for `external_command_failed` tells a consumer to read
|
|
388
|
+
* `error.details` — so it has to BE there. It was not: the codes assigned by
|
|
389
|
+
* hand (`site push`'s fetch and push failures) carried an extract, while every
|
|
390
|
+
* failure that arrived by being thrown carried git's output in `message` and no
|
|
391
|
+
* `details` at all, leaving an agent that followed the documented advice
|
|
392
|
+
* holding `undefined`.
|
|
393
|
+
*
|
|
394
|
+
* What it carries is the fullest form of the program's own words the CLI has:
|
|
395
|
+
* the exact invocation, when the thrower recorded one, then that program's
|
|
396
|
+
* output. The invocation is the part `message` never has, and it is what turns
|
|
397
|
+
* "fatal: ambiguous argument 'origin/staging..HEAD'" into something a caller
|
|
398
|
+
* can act on without guessing which command produced it.
|
|
399
|
+
*
|
|
400
|
+
* **It is also the one place that deliberately reconstructs an argv**, and the
|
|
401
|
+
* CLI's git argv carries the raw-content access token inside the remote URL —
|
|
402
|
+
* `git remote set-url origin https://access-token:<token>@gitlab.com/…`. So the
|
|
403
|
+
* reconstruction is redacted here, at the point it is built, as well as at
|
|
404
|
+
* `emit()`'s boundary. Two layers because this one is the specific hazard and
|
|
405
|
+
* that one is the general guarantee.
|
|
406
|
+
*
|
|
407
|
+
* Both layers are about the DOCUMENT. The same program's output streamed live
|
|
408
|
+
* to stderr — `./subprocess.ts` — passes through neither and is not redacted;
|
|
409
|
+
* that boundary is written up in `./redact.ts`.
|
|
410
|
+
*/
|
|
411
|
+
function externalCommandDetails(thrown) {
|
|
412
|
+
if (!(thrown instanceof Error)) return void 0;
|
|
413
|
+
const invocation = failingInvocation(thrown);
|
|
414
|
+
const output = subprocessOutput(thrown) ?? withoutSubprocessPrefix(thrown.message);
|
|
415
|
+
if (output.length === 0) return invocation ? redactCredentials(`$ ${invocation}`) : void 0;
|
|
416
|
+
return redactCredentials(invocation ? `$ ${invocation}\n\n${output}` : output);
|
|
417
|
+
}
|
|
418
|
+
/**
|
|
419
|
+
* Whether `value` is a user-facing CLI error.
|
|
420
|
+
*
|
|
421
|
+
* Tested by `name` rather than `instanceof`: the CLI is bundled, and tests
|
|
422
|
+
* re-import modules through `vi.resetModules()`, either of which can produce
|
|
423
|
+
* two distinct `CliUserError` constructors for the same conceptual class.
|
|
424
|
+
* `name` survives both. This is the same check `index.ts` has always made.
|
|
425
|
+
*/
|
|
426
|
+
function isCliUserError(value) {
|
|
427
|
+
return value instanceof Error && value.name === "CliUserError";
|
|
428
|
+
}
|
|
429
|
+
/**
|
|
430
|
+
* Convert anything thrown into the envelope's `error` object.
|
|
431
|
+
*
|
|
432
|
+
* A `CliUserError` keeps its code, message, hint and `next` steps. A failure of a program the
|
|
433
|
+
* CLI drives is `external_command_failed` — the message is that program's, and
|
|
434
|
+
* the remedy is in the caller's environment. Anything else is an internal
|
|
435
|
+
* fault: its message is preserved for the reader, but the code is
|
|
436
|
+
* `internal_error` because the CLI has no idea what actually went wrong.
|
|
437
|
+
*/
|
|
438
|
+
function cliErrorFrom(thrown, details) {
|
|
439
|
+
if (isCliUserError(thrown)) {
|
|
440
|
+
const error = {
|
|
441
|
+
code: thrown.code,
|
|
442
|
+
message: thrown.message,
|
|
443
|
+
...thrown.hint ? { hint: thrown.hint } : {},
|
|
444
|
+
...thrown.next && thrown.next.length > 0 ? { next: [...thrown.next] } : {},
|
|
445
|
+
...blockedRequestOfError(thrown)
|
|
446
|
+
};
|
|
447
|
+
return details === void 0 ? error : {
|
|
448
|
+
...error,
|
|
449
|
+
details
|
|
450
|
+
};
|
|
451
|
+
}
|
|
452
|
+
const code = codeForFault(thrown);
|
|
453
|
+
const resolved = details ?? (code === "external_command_failed" ? externalCommandDetails(thrown) : void 0);
|
|
454
|
+
const error = {
|
|
455
|
+
code,
|
|
456
|
+
message: messageOf(thrown)
|
|
457
|
+
};
|
|
458
|
+
return resolved === void 0 ? error : {
|
|
459
|
+
...error,
|
|
460
|
+
details: resolved
|
|
461
|
+
};
|
|
462
|
+
}
|
|
463
|
+
/**
|
|
464
|
+
* A thrown `request_blocked` error's details (#463), when it carries them (`notifyBuildResult.ts`'s
|
|
465
|
+
* `BuildResultRefusal`): the envelope promises `error.request` with that code.
|
|
466
|
+
*/
|
|
467
|
+
function blockedRequestOfError(thrown) {
|
|
468
|
+
const { request } = thrown;
|
|
469
|
+
return thrown.code === "request_blocked" && request ? { request } : {};
|
|
470
|
+
}
|
|
471
|
+
/** `external_command_failed` for a driven program's fault, else `internal_error`. */
|
|
472
|
+
function codeForFault(thrown) {
|
|
473
|
+
return isExternalCommandFailure(thrown) ? EXTERNAL_COMMAND_ERROR_CODE : UNEXPECTED_ERROR_CODE;
|
|
474
|
+
}
|
|
475
|
+
function messageOf(thrown) {
|
|
476
|
+
if (thrown instanceof Error) return thrown.message;
|
|
477
|
+
if (typeof thrown === "string") return thrown;
|
|
478
|
+
return String(thrown);
|
|
479
|
+
}
|
|
480
|
+
//#endregion
|
|
481
|
+
export { isCliUserError as a, redactDocument as c, externalCommandDetails as i, mapDocumentStrings as l, EXTERNAL_COMMAND_ERROR_CODE as n, isExternalCommandFailure as o, cliErrorFrom as r, redactCredentials as s, DEFAULT_USER_ERROR_CODE as t };
|