@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,47 @@
|
|
|
1
|
+
import type { Context } from "hono";
|
|
2
|
+
import type { Env } from "./types";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Build the header set the customer-functions service binding expects on every
|
|
6
|
+
* proxied request. Shared by `proxyToFunctions` (proxy.ts) and `proxyMcp`
|
|
7
|
+
* (mcp-proxy.ts), which inject the identical trusted context.
|
|
8
|
+
*
|
|
9
|
+
* Clones the inbound request headers (so the visitor's `Cookie` — including the
|
|
10
|
+
* Docs MCP `__lid`/`__sid` set during the OAuth authorize flow — round-trips to
|
|
11
|
+
* the origin), then stamps the trusted values the origin relies on:
|
|
12
|
+
* - `companyId` — the per-site tenant id (trusted; baked into this worker).
|
|
13
|
+
* - `preview` — whether this is a preview build.
|
|
14
|
+
* - `turnstileSecretKey` — forwarded for the origin's Turnstile checks.
|
|
15
|
+
* - `originUrl` — the visitor-facing request URL.
|
|
16
|
+
* - `x-real-ip` — the client IP. Cloudflare delivers it to this Worker as
|
|
17
|
+
* `cf-connecting-ip` (Miniflare sets `127.0.0.1` for local `wrangler dev`);
|
|
18
|
+
* customer-functions' middleware reads it under the `x-real-ip` name.
|
|
19
|
+
* `Headers.set` overwrites any client-supplied value, so it is not spoofable.
|
|
20
|
+
*/
|
|
21
|
+
export function buildProxyHeaders(c: Context<{ Bindings: Env }>): Headers {
|
|
22
|
+
const headers = new Headers(c.req.raw.headers);
|
|
23
|
+
headers.set("companyId", c.env.COMPANY_ID);
|
|
24
|
+
headers.set("preview", String(c.env.PREVIEW_SITE));
|
|
25
|
+
headers.set("turnstileSecretKey", c.env.TURNSTILE_SECRET_KEY);
|
|
26
|
+
headers.set("originUrl", c.req.url);
|
|
27
|
+
headers.set("x-real-ip", c.req.header("cf-connecting-ip") ?? "");
|
|
28
|
+
return headers;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Dispatch a proxied request to customer-functions (#284).
|
|
33
|
+
*
|
|
34
|
+
* Production path: the `FUNCTIONS` service binding. Local-dev override: when
|
|
35
|
+
* `FUNCTIONS_ORIGIN` is set, the request is re-targeted at that origin (keeping
|
|
36
|
+
* the inbound path + query) and sent via global `fetch`, bypassing wrangler's
|
|
37
|
+
* cross-`wrangler dev` registry. Both branches are identical except the target —
|
|
38
|
+
* same `init` (method/headers/body/redirect), so callers share one request shape.
|
|
39
|
+
*/
|
|
40
|
+
export function fetchFunctions(c: Context<{ Bindings: Env }>, init: RequestInit): Promise<Response> {
|
|
41
|
+
if (c.env.FUNCTIONS_ORIGIN) {
|
|
42
|
+
const inbound = new URL(c.req.url);
|
|
43
|
+
const target = new URL(inbound.pathname + inbound.search, c.env.FUNCTIONS_ORIGIN);
|
|
44
|
+
return fetch(new Request(target, init));
|
|
45
|
+
}
|
|
46
|
+
return c.env.FUNCTIONS.fetch(new Request(c.req.url, init));
|
|
47
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Entitlement tier ladder for edge gating (#329).
|
|
3
|
+
*
|
|
4
|
+
* Lives in the worker because the worker is the constrained side: it is a
|
|
5
|
+
* standalone hono-only bundle (the build copies its `src/` + an isolated
|
|
6
|
+
* package.json with only `hono` into the customer site repo) and so CANNOT
|
|
7
|
+
* import `@leed/*` — `hasFeature` and `FEATURE_MIN_TIER` are unreachable here.
|
|
8
|
+
* The same reason `constants.ts` and the `DocResource` mirror live in this
|
|
9
|
+
* directory.
|
|
10
|
+
*
|
|
11
|
+
* So the tier is baked into the worker as `ENTITLEMENT_TIER` and compared here.
|
|
12
|
+
* The ladder itself is duplicated, which is safe — it is four values that define
|
|
13
|
+
* the pricing model — but the per-feature MINIMUM below is exactly the kind of
|
|
14
|
+
* value that moves. `tierDrift.test.ts` on the site-management side (which CAN
|
|
15
|
+
* import both) asserts these constants still match `FEATURE_MIN_TIER`, so a
|
|
16
|
+
* change to the catalog fails a test instead of silently un-gating a customer.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
/** Ordered low → high. Mirrors `TIER_RANK` in `@leed/data-types` featureCatalog. */
|
|
20
|
+
export const TIER_RANK: Record<string, number> = {
|
|
21
|
+
free: 0,
|
|
22
|
+
starter: 1,
|
|
23
|
+
growth: 2,
|
|
24
|
+
enterprise: 3,
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
/** Minimum tier for live docs search — mirrors `FEATURE_MIN_TIER.docsLiveSearch`. */
|
|
28
|
+
export const DOCS_LIVE_SEARCH_MIN_TIER = "starter";
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Whether `tier` reaches `minimum` on the ladder.
|
|
32
|
+
*
|
|
33
|
+
* FAIL-CLOSED on anything unrecognized, matching `hasFeature`: an unknown or
|
|
34
|
+
* missing tier meets no paid minimum. The one caller compensates for the
|
|
35
|
+
* "missing" case deliberately — see the guard in `index.ts`.
|
|
36
|
+
*/
|
|
37
|
+
export function meetsTier(tier: string | undefined, minimum: string): boolean {
|
|
38
|
+
if (!tier || !Object.hasOwn(TIER_RANK, tier)) return false;
|
|
39
|
+
return TIER_RANK[tier] >= TIER_RANK[minimum];
|
|
40
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vendored mirror of the Docs MCP `DocResource` (#284).
|
|
3
|
+
*
|
|
4
|
+
* The canonical Zod schema lives with the Docs MCP server at
|
|
5
|
+
* `apps/customer-functions/src/mcp/docResource.ts`. This worker is a standalone
|
|
6
|
+
* hono-only bundle — the build copies its `src/` + an isolated package.json
|
|
7
|
+
* (only `hono`) into the customer site repo, and wrangler runs `bun install`
|
|
8
|
+
* against that package.json — so it CANNOT import any `@leed/*` workspace
|
|
9
|
+
* package. The Docs MCP hydration only needs the shape to fill `content`, so this
|
|
10
|
+
* hand-written interface is kept intentionally in sync with the canonical Zod
|
|
11
|
+
* schema. Keep the two structurally compatible.
|
|
12
|
+
*/
|
|
13
|
+
export interface DocResource {
|
|
14
|
+
pageId?: string;
|
|
15
|
+
path: string;
|
|
16
|
+
url: string;
|
|
17
|
+
title?: string;
|
|
18
|
+
setId?: string;
|
|
19
|
+
content?: string;
|
|
20
|
+
error?: string;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/** The content-bearing tool-response envelope the site-worker hydrates. */
|
|
24
|
+
export interface DocResourcesPayload {
|
|
25
|
+
resources: DocResource[];
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export interface Env {
|
|
29
|
+
ASSETS: Fetcher;
|
|
30
|
+
FUNCTIONS: Fetcher;
|
|
31
|
+
/**
|
|
32
|
+
* Local-dev override (#284). When set (only in devMode wrangler configs),
|
|
33
|
+
* proxied requests go to this origin via global `fetch` instead of the
|
|
34
|
+
* `FUNCTIONS` service binding. Works around wrangler's cross-`wrangler dev`
|
|
35
|
+
* registry not reliably linking `customer-functions-dev` locally. Never
|
|
36
|
+
* emitted for public/preview builds — production keeps the service binding.
|
|
37
|
+
*/
|
|
38
|
+
FUNCTIONS_ORIGIN?: string;
|
|
39
|
+
COMPANY_ID: string;
|
|
40
|
+
VALID_ORIGINS: string;
|
|
41
|
+
PREVIEW_SITE: boolean;
|
|
42
|
+
TURNSTILE_SECRET_KEY: string;
|
|
43
|
+
/**
|
|
44
|
+
* Per-customer MCP entitlement (#284, #294). Boolean wrangler var, baked
|
|
45
|
+
* into the generated wrangler config from the company's `entitlements.mcp`.
|
|
46
|
+
* When false the site-worker short-circuits AT THE EDGE both the `/mcp` +
|
|
47
|
+
* OAuth surface (the request never reaches customer-functions; customer-
|
|
48
|
+
* functions keeps its own `entitlements.mcp` check as defense-in-depth) and
|
|
49
|
+
* the `/.well-known/webmcp` + `/.well-known/agent.json` surfaces (404).
|
|
50
|
+
*/
|
|
51
|
+
MCP_ENABLED: boolean;
|
|
52
|
+
/**
|
|
53
|
+
* The company's entitlement tier (#329) — `free` | `starter` | `growth` |
|
|
54
|
+
* `enterprise`. Baked so the edge can gate on the SAME tier ladder the rest of
|
|
55
|
+
* the platform uses, rather than a per-feature boolean per gate.
|
|
56
|
+
*
|
|
57
|
+
* Optional: a worker generated before this var existed carries no tier, and
|
|
58
|
+
* must DEFER to customer-functions rather than 404 its own search — so the
|
|
59
|
+
* guard checks for absence explicitly instead of relying on fail-closed
|
|
60
|
+
* `meetsTier`.
|
|
61
|
+
*/
|
|
62
|
+
ENTITLEMENT_TIER?: string;
|
|
63
|
+
/**
|
|
64
|
+
* Commit SHA baked into this worker version at build time. Emitted on
|
|
65
|
+
* every response as `X-Site-Version` so `curl -I` against a customer
|
|
66
|
+
* site reveals which commit is currently live.
|
|
67
|
+
*/
|
|
68
|
+
SITE_VERSION: string;
|
|
69
|
+
/**
|
|
70
|
+
* Plaintext "true"/"false" — when "true" the workers.dev hostname is
|
|
71
|
+
* gated and any request hitting it without the CMS proxy header is 301'd
|
|
72
|
+
* to PRIMARY_DOMAIN. Emitted as "true" on public builds once the custom
|
|
73
|
+
* domain becomes active (preview builds always emit "false" — they
|
|
74
|
+
* disable workers.dev outright instead). #266
|
|
75
|
+
*/
|
|
76
|
+
REDIRECT_TO_PRIMARY_DOMAIN: string;
|
|
77
|
+
/**
|
|
78
|
+
* Canonical custom domain — destination for the workers.dev redirect.
|
|
79
|
+
* Same value as the route hostname in wrangler.jsonc for this Worker.
|
|
80
|
+
*/
|
|
81
|
+
PRIMARY_DOMAIN: string;
|
|
82
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auxiliary worker standing in for the `customer-functions` service binding in
|
|
3
|
+
* the customer-site-worker workerd integration test (#284). Plain JS because the
|
|
4
|
+
* workers-pool loads auxiliary `scriptPath` modules without TS transformation.
|
|
5
|
+
*
|
|
6
|
+
* Routes:
|
|
7
|
+
* - `/mcp/oauth/authorize` — mirrors the production OAuth authorize grant:
|
|
8
|
+
* reads the forwarded body and answers with a 302 → client `redirect_uri`,
|
|
9
|
+
* echoing the body back on `X-Forwarded-Body` so the proxy test can confirm
|
|
10
|
+
* it forwarded the body intact.
|
|
11
|
+
* - `/__302` / `/__follow_target` — a real redirect boundary used by the
|
|
12
|
+
* mechanism test to prove WHY the proxy must buffer the request body: a
|
|
13
|
+
* `fetch(..., { redirect: "follow" })` whose body is a one-time-use stream
|
|
14
|
+
* throws "encountered a redirect requiring the body to be retransmitted" on
|
|
15
|
+
* the 302, while a buffered (ArrayBuffer) body replays cleanly.
|
|
16
|
+
*
|
|
17
|
+
* Reached through the customer-site-worker's real `FUNCTIONS` service binding,
|
|
18
|
+
* so the proxy's `FUNCTIONS.fetch(... redirect: "manual")` call crosses the
|
|
19
|
+
* genuine workerd subrequest boundary the node-pool unit tests mock away.
|
|
20
|
+
*/
|
|
21
|
+
export default {
|
|
22
|
+
async fetch(request) {
|
|
23
|
+
const url = new URL(request.url);
|
|
24
|
+
|
|
25
|
+
if (url.pathname === "/mcp/oauth/authorize") {
|
|
26
|
+
const forwarded = await request.text();
|
|
27
|
+
return new Response(null, {
|
|
28
|
+
status: 302,
|
|
29
|
+
headers: {
|
|
30
|
+
Location: "https://client.example.com/cb?code=abc&state=xyz",
|
|
31
|
+
"X-Forwarded-Body": forwarded,
|
|
32
|
+
},
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
if (url.pathname === "/__302") {
|
|
37
|
+
return new Response(null, { status: 302, headers: { Location: "/__follow_target" } });
|
|
38
|
+
}
|
|
39
|
+
if (url.pathname === "/__follow_target") {
|
|
40
|
+
// Reached only after workerd follows the 302 above (a 302 of a POST
|
|
41
|
+
// becomes a bodyless GET per the fetch spec). Its presence proves the
|
|
42
|
+
// followed-redirect path completed without the body-retransmit throw.
|
|
43
|
+
return new Response("ok", { headers: { "X-Replayed": "1" } });
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
return new Response(JSON.stringify({ jsonrpc: "2.0", id: 1, result: { ok: true } }), {
|
|
47
|
+
headers: { "content-type": "application/json" },
|
|
48
|
+
});
|
|
49
|
+
},
|
|
50
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ESNext",
|
|
4
|
+
"module": "ESNext",
|
|
5
|
+
"moduleResolution": "bundler",
|
|
6
|
+
"lib": ["ESNext"],
|
|
7
|
+
"types": ["@cloudflare/workers-types"],
|
|
8
|
+
"strict": true,
|
|
9
|
+
"skipLibCheck": true,
|
|
10
|
+
"esModuleInterop": true,
|
|
11
|
+
"forceConsistentCasingInFileNames": true
|
|
12
|
+
},
|
|
13
|
+
"include": ["src/**/*.ts"],
|
|
14
|
+
// Co-located tests (run by vitest, excluded from the customer bundle by the
|
|
15
|
+
// build's copy filter) pull in test-only virtual modules like `cloudflare:test`
|
|
16
|
+
// that this production-bundle tsconfig has no types for. Keep them out of this
|
|
17
|
+
// project's typecheck — the test suites are typechecked by vitest. (#284)
|
|
18
|
+
"exclude": ["src/**/*.test.ts", "src/**/*.spec.ts"]
|
|
19
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { cloudflareTest } from "@cloudflare/vitest-plugin";
|
|
2
|
+
import { defineConfig } from "vitest/config";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Workers-pool (Miniflare / workerd) config for the customer-site-worker (#284).
|
|
6
|
+
*
|
|
7
|
+
* The existing `mcp-proxy.test.ts` unit tests run in the NODE pool with a
|
|
8
|
+
* hand-built `env` whose `FUNCTIONS.fetch` is a plain `vi.fn()` — so they never
|
|
9
|
+
* exercise workerd's real subrequest machinery and PASSED even while the live
|
|
10
|
+
* proxy threw the "one-time-use body … requiring the body to be retransmitted"
|
|
11
|
+
* error on the OAuth-302. This config boots the actual worker (`src/index.ts`)
|
|
12
|
+
* in workerd; the `FUNCTIONS` binding is a real auxiliary mock worker
|
|
13
|
+
* (`test/functions-mock.worker.js`) that answers the OAuth authorize grant with
|
|
14
|
+
* the 302 → client `redirect_uri`, so the `.worker.test` suite drives the proxy
|
|
15
|
+
* across the genuine service-binding boundary. The node-pool tests are
|
|
16
|
+
* untouched: the site-management root config excludes the `.worker.test` glob.
|
|
17
|
+
*/
|
|
18
|
+
export default defineConfig({
|
|
19
|
+
plugins: [
|
|
20
|
+
cloudflareTest({
|
|
21
|
+
main: "./src/index.ts",
|
|
22
|
+
// No wrangler.jsonc lives in this dir (the production config is generated
|
|
23
|
+
// per-customer by the wrangler generator at build time), so the worker is
|
|
24
|
+
// configured inline here.
|
|
25
|
+
miniflare: {
|
|
26
|
+
compatibilityDate: "2026-04-07",
|
|
27
|
+
serviceBindings: {
|
|
28
|
+
// The customer-functions stand-in (see test/functions-mock.worker.js).
|
|
29
|
+
FUNCTIONS: "functions-mock",
|
|
30
|
+
// ASSETS is only consulted on page-resources hydration, never on a 302.
|
|
31
|
+
ASSETS: async () => new Response("should-not-be-called", { status: 404 }),
|
|
32
|
+
},
|
|
33
|
+
bindings: {
|
|
34
|
+
COMPANY_ID: "co-test",
|
|
35
|
+
VALID_ORIGINS: JSON.stringify(["https://docs.example.com"]),
|
|
36
|
+
PREVIEW_SITE: false,
|
|
37
|
+
TURNSTILE_SECRET_KEY: "ts-test",
|
|
38
|
+
SITE_VERSION: "abcdef0",
|
|
39
|
+
REDIRECT_TO_PRIMARY_DOMAIN: "false",
|
|
40
|
+
PRIMARY_DOMAIN: "docs.example.com",
|
|
41
|
+
MCP_ENABLED: true,
|
|
42
|
+
},
|
|
43
|
+
workers: [
|
|
44
|
+
{
|
|
45
|
+
name: "functions-mock",
|
|
46
|
+
modules: true,
|
|
47
|
+
scriptPath: "./test/functions-mock.worker.js",
|
|
48
|
+
compatibilityDate: "2026-04-07",
|
|
49
|
+
},
|
|
50
|
+
],
|
|
51
|
+
},
|
|
52
|
+
}),
|
|
53
|
+
],
|
|
54
|
+
test: {
|
|
55
|
+
name: "customer-site-worker-workers",
|
|
56
|
+
include: ["src/**/*.worker.test.ts"],
|
|
57
|
+
globals: true,
|
|
58
|
+
testTimeout: 30000,
|
|
59
|
+
teardownTimeout: 5000,
|
|
60
|
+
},
|
|
61
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
node .husky/valid-commit-msg.mjs "$1"
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
node .husky/valid-command.mjs "commit"
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
node .husky/valid-command.mjs "push"
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { execSync as shell } from "node:child_process";
|
|
2
|
+
import { red, yellow } from "./colors.mjs";
|
|
3
|
+
|
|
4
|
+
const args = process.argv.slice(2);
|
|
5
|
+
const [command] = args;
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* We use git to see if the leed.invoked flag was set.
|
|
9
|
+
*/
|
|
10
|
+
let invokedByScript = false;
|
|
11
|
+
try {
|
|
12
|
+
invokedByScript = shell("git config --get leed.invoked").toString().trim();
|
|
13
|
+
} catch (_e) {
|
|
14
|
+
// any exit code other than zero is caught
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* If it was not invoked by our application, we spit out an error
|
|
19
|
+
* and the application help command.
|
|
20
|
+
*/
|
|
21
|
+
if (invokedByScript !== "true") {
|
|
22
|
+
console.error(red(`\n\tYou cannot '${command}' directly, please use:\n`));
|
|
23
|
+
if (command === "commit") {
|
|
24
|
+
console.error(yellow(`\t\tleed site commit -m "update details"\n`));
|
|
25
|
+
} else if (command === "push") {
|
|
26
|
+
console.error(yellow(`\t\tleed site push\n`));
|
|
27
|
+
}
|
|
28
|
+
process.exit(18); // Exit with error code to block the commit
|
|
29
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import { red, yellow } from "./colors.mjs";
|
|
3
|
+
|
|
4
|
+
// Read the commit message from the file passed by Git
|
|
5
|
+
const commitMessageFile = process.argv[2];
|
|
6
|
+
const commitMessage = fs.readFileSync(commitMessageFile, "utf-8").trim();
|
|
7
|
+
|
|
8
|
+
const startMsg = "@leed/site-management=>";
|
|
9
|
+
const pos = commitMessage.indexOf(startMsg);
|
|
10
|
+
if (pos > -1) {
|
|
11
|
+
const data = commitMessage.substring(startMsg.length);
|
|
12
|
+
const json = JSON.parse(data);
|
|
13
|
+
if (json.userId && json.version && json.message) {
|
|
14
|
+
process.exit(0);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
console.error(red("\n\tYou cannot commit directly to this repo, please use:\n"));
|
|
19
|
+
console.error(yellow(`\t\tleed site commit -m "reason for update"\n`));
|
|
20
|
+
process.exit(18); // Exit with error code to block the commit
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "2.0.0",
|
|
3
|
+
"_description": "VS Code Tasks to simplify execution of the application",
|
|
4
|
+
"command": "leed",
|
|
5
|
+
"tasks": [
|
|
6
|
+
{
|
|
7
|
+
"label": "Run Webserver",
|
|
8
|
+
"type": "shell",
|
|
9
|
+
"args": ["site", "build", "--serve"],
|
|
10
|
+
"problemMatcher": [],
|
|
11
|
+
"group": {
|
|
12
|
+
"kind": "build",
|
|
13
|
+
"isDefault": true
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"label": "Build",
|
|
18
|
+
"type": "shell",
|
|
19
|
+
"args": ["site", "build"],
|
|
20
|
+
"problemMatcher": [],
|
|
21
|
+
"group": {
|
|
22
|
+
"kind": "build",
|
|
23
|
+
"isDefault": true
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"label": "Build (debug)",
|
|
28
|
+
"type": "shell",
|
|
29
|
+
"args": ["site", "build", "-d"],
|
|
30
|
+
"problemMatcher": [],
|
|
31
|
+
"group": {
|
|
32
|
+
"kind": "build",
|
|
33
|
+
"isDefault": true
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
"label": "Site Validation",
|
|
38
|
+
"type": "shell",
|
|
39
|
+
"args": ["site", "validate"],
|
|
40
|
+
"problemMatcher": [],
|
|
41
|
+
"group": {
|
|
42
|
+
"kind": "build",
|
|
43
|
+
"isDefault": true
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
"label": "Site Validation - Reset (Dry-Run)",
|
|
48
|
+
"type": "shell",
|
|
49
|
+
"args": ["site", "validate", "-r", "--dry-run"],
|
|
50
|
+
"problemMatcher": [],
|
|
51
|
+
"group": {
|
|
52
|
+
"kind": "build",
|
|
53
|
+
"isDefault": true
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
"label": "Site Validation - Reset",
|
|
58
|
+
"type": "shell",
|
|
59
|
+
"args": ["site", "validate", "-r"],
|
|
60
|
+
"problemMatcher": [],
|
|
61
|
+
"group": {
|
|
62
|
+
"kind": "build",
|
|
63
|
+
"isDefault": true
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
"label": "Commit Changes",
|
|
68
|
+
"type": "shell",
|
|
69
|
+
"args": ["site", "commit", "-m ${input:commitMsg}"],
|
|
70
|
+
"problemMatcher": []
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
"label": "Push to Staging",
|
|
74
|
+
"type": "shell",
|
|
75
|
+
"args": ["site", "push"],
|
|
76
|
+
"problemMatcher": []
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
"label": "Pull Latest from Staging",
|
|
80
|
+
"type": "shell",
|
|
81
|
+
"command": "git pull",
|
|
82
|
+
"problemMatcher": []
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
"label": "Login",
|
|
86
|
+
"type": "shell",
|
|
87
|
+
"args": ["auth", "login", "--browser"],
|
|
88
|
+
"problemMatcher": []
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
"label": "Logout",
|
|
92
|
+
"type": "shell",
|
|
93
|
+
"args": ["auth", "logout"],
|
|
94
|
+
"problemMatcher": []
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
"label": "Auth Status",
|
|
98
|
+
"type": "shell",
|
|
99
|
+
"args": ["auth", "status"],
|
|
100
|
+
"problemMatcher": []
|
|
101
|
+
}
|
|
102
|
+
],
|
|
103
|
+
"inputs": [
|
|
104
|
+
{
|
|
105
|
+
"id": "commitMsg",
|
|
106
|
+
"type": "promptString",
|
|
107
|
+
"description": "Enter a commit message",
|
|
108
|
+
"default": "update site content"
|
|
109
|
+
}
|
|
110
|
+
]
|
|
111
|
+
}
|