@blinkk/root 3.0.3 → 3.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-JTZWI4MH.js → chunk-VQPDCDKL.js} +1256 -67
- package/dist/chunk-VQPDCDKL.js.map +7 -0
- package/dist/{chunk-DU7JUEDY.js → chunk-X2C2MEJ2.js} +3 -1
- package/dist/chunk-X2C2MEJ2.js.map +7 -0
- package/dist/cli/secrets.d.ts +9 -0
- package/dist/cli.js +1 -1
- package/dist/functions.js +1 -1
- package/dist/jsx.js +1 -1
- package/dist/render.js +1 -1
- package/dist/secrets/env-file.d.ts +44 -0
- package/dist/secrets/gcloud.d.ts +28 -0
- package/dist/secrets/hash.d.ts +11 -0
- package/dist/secrets/manifest.d.ts +60 -0
- package/dist/secrets/secrets.d.ts +118 -0
- package/dist/utils/jsonutils.d.ts +22 -0
- package/dist/utils/utils.d.ts +1 -0
- package/dist/utils.js +30 -0
- package/dist/utils.js.map +7 -0
- package/package.json +5 -1
- package/dist/chunk-DU7JUEDY.js.map +0 -7
- package/dist/chunk-JTZWI4MH.js.map +0 -7
|
@@ -96,6 +96,7 @@ var BOOLEAN_ATTRS = /* @__PURE__ */ new Set([
|
|
|
96
96
|
"default",
|
|
97
97
|
"defer",
|
|
98
98
|
"disabled",
|
|
99
|
+
"disableremoteplayback",
|
|
99
100
|
"download",
|
|
100
101
|
"draggable",
|
|
101
102
|
"formnovalidate",
|
|
@@ -127,6 +128,7 @@ var PROP_TO_ATTR = {
|
|
|
127
128
|
contentEditable: "contenteditable",
|
|
128
129
|
crossOrigin: "crossorigin",
|
|
129
130
|
dateTime: "datetime",
|
|
131
|
+
disableRemotePlayback: "disableremoteplayback",
|
|
130
132
|
encType: "enctype",
|
|
131
133
|
formAction: "formaction",
|
|
132
134
|
formEncType: "formenctype",
|
|
@@ -505,4 +507,4 @@ function noop() {
|
|
|
505
507
|
export {
|
|
506
508
|
renderJsxToString
|
|
507
509
|
};
|
|
508
|
-
//# sourceMappingURL=chunk-
|
|
510
|
+
//# sourceMappingURL=chunk-X2C2MEJ2.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/jsx/jsx-render.ts"],
|
|
4
|
+
"sourcesContent": ["/* eslint-disable n/no-extraneous-import */\nimport {options as preactOptions} from 'preact';\nimport {VNode, Fragment} from './jsx-runtime.js';\n\n/** HTML void elements (self-closing, no end tag). */\nconst VOID_ELEMENTS = new Set([\n 'area',\n 'base',\n 'br',\n 'col',\n 'embed',\n 'hr',\n 'img',\n 'input',\n 'link',\n 'meta',\n 'param',\n 'source',\n 'track',\n 'wbr',\n]);\n\n/** Tags whose text content may contain literal newlines that should not be treated as block-child indicators. */\nconst RAW_CONTENT_ELEMENTS = new Set(['pre', 'textarea', 'script', 'style']);\n\n/**\n * Standard HTML block-level elements. Also includes the `<select>` content\n * model (`select`/`optgroup`/`option`) so that each `<option>` renders on its\n * own line in pretty mode, even though those tags aren't block-level per CSS.\n */\nconst DEFAULT_BLOCK_ELEMENTS = new Set([\n 'address',\n 'article',\n 'aside',\n 'base',\n 'blockquote',\n 'body',\n 'dd',\n 'details',\n 'dialog',\n 'div',\n 'dl',\n 'dt',\n 'fieldset',\n 'figcaption',\n 'figure',\n 'footer',\n 'form',\n 'h1',\n 'h2',\n 'h3',\n 'h4',\n 'h5',\n 'h6',\n 'head',\n 'header',\n 'hgroup',\n 'hr',\n 'html',\n 'li',\n 'link',\n 'main',\n 'meta',\n 'nav',\n 'noscript',\n 'ol',\n 'optgroup',\n 'option',\n 'p',\n 'pre',\n 'script',\n 'search',\n 'section',\n 'select',\n 'style',\n 'summary',\n 'table',\n 'tbody',\n 'td',\n 'tfoot',\n 'th',\n 'thead',\n 'title',\n 'tr',\n 'ul',\n]);\n\n/**\n * Non-visual metadata and resource elements. These produce no inline rendered\n * content, so in pretty mode they always start on their own line \u2014 even inside\n * a parent with mixed text/element children, where the inline heuristic would\n * otherwise keep all siblings on a single line. (`base`/`link`/`meta` are void;\n * `script`/`style`/`title` render no visible text.)\n */\nconst ALWAYS_BLOCK_ELEMENTS = new Set([\n 'base',\n 'link',\n 'meta',\n 'script',\n 'style',\n 'title',\n]);\n\n/**\n * HTML/SVG boolean attributes.\n * When present with a truthy value, render as a minimized attribute.\n */\nconst BOOLEAN_ATTRS = new Set([\n 'allowfullscreen',\n 'async',\n 'autofocus',\n 'autoplay',\n 'capture',\n 'checked',\n 'controls',\n 'default',\n 'defer',\n 'disabled',\n 'disableremoteplayback',\n 'download',\n 'draggable',\n 'formnovalidate',\n 'hidden',\n 'inert',\n 'ismap',\n 'itemscope',\n 'loop',\n 'multiple',\n 'muted',\n 'nomodule',\n 'novalidate',\n 'open',\n 'playsinline',\n 'readonly',\n 'required',\n 'reversed',\n 'selected',\n]);\n\n/** JSX prop name -> HTML attribute name. */\nconst PROP_TO_ATTR: Record<string, string> = {\n acceptCharset: 'accept-charset',\n autoCapitalize: 'autocapitalize',\n autoComplete: 'autocomplete',\n autoFocus: 'autofocus',\n autoPlay: 'autoplay',\n charSet: 'charset',\n className: 'class',\n colSpan: 'colspan',\n contentEditable: 'contenteditable',\n crossOrigin: 'crossorigin',\n dateTime: 'datetime',\n disableRemotePlayback: 'disableremoteplayback',\n encType: 'enctype',\n formAction: 'formaction',\n formEncType: 'formenctype',\n formMethod: 'formmethod',\n formNoValidate: 'formnovalidate',\n formTarget: 'formtarget',\n frameBorder: 'frameborder',\n hrefLang: 'hreflang',\n htmlFor: 'for',\n httpEquiv: 'http-equiv',\n inputMode: 'inputmode',\n itemProp: 'itemprop',\n itemRef: 'itemref',\n itemScope: 'itemscope',\n itemType: 'itemtype',\n maxLength: 'maxlength',\n mediaGroup: 'mediagroup',\n minLength: 'minlength',\n noModule: 'nomodule',\n noValidate: 'novalidate',\n playsInline: 'playsinline',\n readOnly: 'readonly',\n referrerPolicy: 'referrerpolicy',\n rowSpan: 'rowspan',\n spellCheck: 'spellcheck',\n srcDoc: 'srcdoc',\n srcLang: 'srclang',\n srcSet: 'srcset',\n tabIndex: 'tabindex',\n useMap: 'usemap',\n\n // SVG presentation attributes (camelCase -> kebab-case).\n clipPath: 'clip-path',\n clipRule: 'clip-rule',\n colorInterpolation: 'color-interpolation',\n colorInterpolationFilters: 'color-interpolation-filters',\n dominantBaseline: 'dominant-baseline',\n fillOpacity: 'fill-opacity',\n fillRule: 'fill-rule',\n floodColor: 'flood-color',\n floodOpacity: 'flood-opacity',\n imageRendering: 'image-rendering',\n letterSpacing: 'letter-spacing',\n lightingColor: 'lighting-color',\n markerEnd: 'marker-end',\n markerMid: 'marker-mid',\n markerStart: 'marker-start',\n paintOrder: 'paint-order',\n pointerEvents: 'pointer-events',\n shapeRendering: 'shape-rendering',\n stopColor: 'stop-color',\n stopOpacity: 'stop-opacity',\n strokeDasharray: 'stroke-dasharray',\n strokeDashoffset: 'stroke-dashoffset',\n strokeLinecap: 'stroke-linecap',\n strokeLinejoin: 'stroke-linejoin',\n strokeMiterlimit: 'stroke-miterlimit',\n strokeOpacity: 'stroke-opacity',\n strokeWidth: 'stroke-width',\n textAnchor: 'text-anchor',\n textDecoration: 'text-decoration',\n textRendering: 'text-rendering',\n transformOrigin: 'transform-origin',\n vectorEffect: 'vector-effect',\n wordSpacing: 'word-spacing',\n writingMode: 'writing-mode',\n};\n\nconst AMP = '&';\nconst LT = '<';\nconst GT = '>';\nconst QUOT = '"';\n\n// Shared empty object reused as the per-component context map when no contexts\n// have ever been pushed. Components only ever read from this map, so sharing is\n// safe and avoids a per-render allocation in the common case.\nconst EMPTY_GLOBAL_CTX: Record<string, any> = {};\n\n/** Returns `true` when `value` is neither `null` nor `undefined`. */\nfunction isDef<T>(value: T | null | undefined): value is T {\n return value !== null && value !== undefined;\n}\n\nfunction escapeHtml(str: string): string {\n let result = '';\n let last = 0;\n for (let i = 0; i < str.length; i++) {\n const ch = str.charCodeAt(i);\n let escaped: string | undefined;\n if (ch === 38) escaped = AMP;\n else if (ch === 60) escaped = LT;\n else if (ch === 62) escaped = GT;\n if (escaped) {\n result += str.slice(last, i) + escaped;\n last = i + 1;\n }\n }\n if (last === 0) return str;\n return result + str.slice(last);\n}\n\nfunction escapeAttr(str: string): string {\n let result = '';\n let last = 0;\n for (let i = 0; i < str.length; i++) {\n const ch = str.charCodeAt(i);\n let escaped: string | undefined;\n if (ch === 38) escaped = AMP;\n else if (ch === 34) escaped = QUOT;\n else if (ch === 60) escaped = LT;\n else if (ch === 62) escaped = GT;\n if (escaped) {\n result += str.slice(last, i) + escaped;\n last = i + 1;\n }\n }\n if (last === 0) return str;\n return result + str.slice(last);\n}\n\nconst STYLE_KEY_CACHE = new Map<string, string>();\nconst UPPERCASE_RE = /[A-Z]/g;\n\nfunction toKebabCase(key: string): string {\n let cached = STYLE_KEY_CACHE.get(key);\n if (cached === undefined) {\n cached = key.replace(UPPERCASE_RE, (m) => '-' + m.toLowerCase());\n STYLE_KEY_CACHE.set(key, cached);\n }\n return cached;\n}\n\nfunction styleToString(style: Record<string, any>): string {\n let result = '';\n let first = true;\n for (const key in style) {\n const value = style[key];\n if (!isDef(value) || value === '') continue;\n if (first) {\n first = false;\n } else {\n result += ';';\n }\n result += `${toKebabCase(key)}:${value}`;\n }\n return result;\n}\n\nexport interface JsxRenderOptions {\n /** Render mode. `'pretty'` adds newlines around block elements; `'minimal'` outputs compact HTML. Default: `'pretty'`. */\n mode?: 'pretty' | 'minimal';\n /** Additional tag names to treat as block-level elements in pretty mode. */\n blockElements?: string[];\n}\n\n/**\n * Renders a Preact VNode tree to an HTML string.\n */\nexport function renderJsxToString(\n vnode: VNode,\n options?: JsxRenderOptions\n): string {\n const mode = options?.mode ?? 'pretty';\n const isPretty = mode === 'pretty';\n // In minimal mode `blockSet` is unused (the `isPretty` guard short-circuits\n // any `.has()` call). In pretty mode without custom block elements, reuse the\n // module-level Set instead of allocating a copy.\n let blockSet: ReadonlySet<string> = DEFAULT_BLOCK_ELEMENTS;\n if (isPretty && options?.blockElements && options.blockElements.length > 0) {\n const merged = new Set(DEFAULT_BLOCK_ELEMENTS);\n for (const el of options.blockElements) {\n merged.add(el);\n }\n blockSet = merged;\n }\n\n // Context stacks: context.__c (id) -> value[]\n let contextStacks: Map<string, any[]> | undefined;\n\n // Version counter that bumps whenever a context value is pushed or popped.\n // `buildGlobalContext` uses it to skip rebuilding when nothing changed\n // between sibling component renders (the common case).\n let ctxVersion = 0;\n let cachedGlobalCtx: Record<string, any> = EMPTY_GLOBAL_CTX;\n let cachedGlobalCtxVersion = 0;\n\n function pushCtx(contextId: string, value: any) {\n if (!contextStacks) {\n contextStacks = new Map<string, any[]>();\n }\n let stack = contextStacks.get(contextId);\n if (!stack) {\n stack = [];\n contextStacks.set(contextId, stack);\n }\n stack.push(value);\n ctxVersion++;\n }\n\n function popCtx(contextId: string) {\n const stack = contextStacks?.get(contextId);\n if (stack) {\n stack.pop();\n if (stack.length === 0) {\n contextStacks?.delete(contextId);\n }\n }\n ctxVersion++;\n }\n\n /** Builds the __n (global context) map for hooks. */\n function buildGlobalContext(): Record<string, any> {\n if (ctxVersion === cachedGlobalCtxVersion) return cachedGlobalCtx;\n if (!contextStacks || contextStacks.size === 0) {\n cachedGlobalCtx = EMPTY_GLOBAL_CTX;\n cachedGlobalCtxVersion = ctxVersion;\n return cachedGlobalCtx;\n }\n const globalCtx: Record<string, any> = {};\n for (const [contextId, stack] of contextStacks) {\n if (stack.length > 0) {\n // useContext expects provider.props.value and provider.sub().\n globalCtx[contextId] = {\n props: {value: stack[stack.length - 1]},\n sub: noop,\n };\n }\n }\n cachedGlobalCtx = globalCtx;\n cachedGlobalCtxVersion = ctxVersion;\n return globalCtx;\n }\n\n function render(node: any, inline?: boolean): string {\n if (!isDef(node) || typeof node === 'boolean') return '';\n if (typeof node === 'string') return escapeHtml(node);\n if (typeof node === 'number' || typeof node === 'bigint')\n return String(node);\n if (Array.isArray(node)) {\n let out = '';\n for (let i = 0; i < node.length; i++) {\n out += render(node[i], inline);\n }\n return out;\n }\n\n // Must be a VNode-like object.\n if (typeof node !== 'object' || !('type' in node)) return '';\n\n const {type, props} = node;\n\n // Fragment.\n if (type === Fragment) {\n return renderChildren(props?.children);\n }\n\n // Component (function or class).\n if (typeof type === 'function') {\n return renderComponent(node);\n }\n\n // HTML element.\n if (typeof type === 'string') {\n return renderElement(type, props, inline);\n }\n\n return '';\n }\n\n function renderComponent(vnode: VNode): string {\n const {type, props} = vnode;\n const fn = type as Function;\n\n // Detect context Provider.\n // Root.js local JSX runtime: Provider._isProvider === true, Provider._context\n // is the Context object with a _stack array.\n // Preact >=10.27: Provider === Context (same function). `fn.__c` is the\n // context id string (e.g. \"__cC0\").\n // Preact <10.27: Provider._contextRef (mangled `fn.__`) points to the\n // context object which has `__c` (id) and `__` (default value).\n const fnAny = fn as any;\n if (fnAny._isProvider && fnAny._context) {\n const ctx = fnAny._context;\n ctx._stack.push((props as any).value);\n const result = renderChildren(props.children);\n ctx._stack.pop();\n return result;\n }\n let contextId: string | undefined;\n if (typeof fnAny.__c === 'string' && fnAny.__c.startsWith('__cC')) {\n contextId = fnAny.__c;\n } else if (fnAny.__ && typeof fnAny.__ === 'object' && fnAny.__.__c) {\n contextId = fnAny.__.__c;\n }\n if (contextId) {\n pushCtx(contextId, (props as any).value);\n const result = renderChildren(props.children);\n popCtx(contextId);\n return result;\n }\n\n // Detect context Consumer.\n if ((fn as any).contextType) {\n const ctx = (fn as any).contextType;\n const ctxId: string = ctx.__c;\n const stack = contextStacks?.get(ctxId);\n const value =\n stack && stack.length > 0 ? stack[stack.length - 1] : ctx.__;\n if (typeof props.children === 'function') {\n return render(props.children(value));\n }\n return renderChildren(props.children);\n }\n\n // Regular component \u2014 set up a fake component instance so Preact hooks\n // (useContext, useState, useMemo, etc.) work during SSR.\n // Preact's useContext reads from `component.context[context.__c]`.\n const component: any = {\n props,\n context: buildGlobalContext(),\n state: {},\n __v: vnode, // _vnode\n __d: false, // _dirty\n __h: [], // _renderCallbacks\n __s: {}, // _nextState\n __H: null, // _hooks (initialised by hooks addon)\n };\n (vnode as any).__c = component;\n\n // Trigger Preact option hooks so the hooks addon can set currentComponent.\n (preactOptions as any).__b?.(vnode);\n (preactOptions as any).__r?.(vnode);\n\n try {\n // Class component.\n if (fn.prototype && fn.prototype.render) {\n const instance = new (fn as any)(props, component.context);\n instance.__n = component.__n;\n instance.__H = component.__H;\n (vnode as any).__c = instance;\n (preactOptions as any).__r?.(vnode);\n return render(instance.render(instance.props, instance.state));\n }\n\n // Functional component.\n const rendered = fn(props, component.context);\n return render(rendered);\n } finally {\n preactOptions.diffed?.(vnode as any);\n }\n }\n\n function renderElement(\n tag: string,\n props: Record<string, any>,\n inline?: boolean\n ): string {\n // Metadata/resource elements always break onto their own line, even within\n // mixed (text + element) content where the inline heuristic applies, since\n // they render no inline visual output.\n const isBlock =\n isPretty &&\n (ALWAYS_BLOCK_ELEMENTS.has(tag) || (!inline && blockSet.has(tag)));\n const isVoid = VOID_ELEMENTS.has(tag);\n const attrs = renderAttrs(tag, props);\n let result = '<' + tag + attrs + '>';\n\n if (isVoid) {\n if (isBlock) result += '\\n';\n return result;\n }\n\n let inner = '';\n if (isDef(props?.dangerouslySetInnerHTML?.__html)) {\n inner = props.dangerouslySetInnerHTML.__html;\n } else if (isDef(props?.children)) {\n inner = renderChildren(props.children);\n } else if (tag === 'textarea' && props) {\n // For <textarea>, render value/defaultValue as text content since\n // browsers ignore the value attribute on textarea elements.\n const textVal = props.value ?? props.defaultValue;\n if (isDef(textVal)) {\n inner = escapeHtml(String(textVal));\n }\n }\n\n if (isBlock) {\n // When inner content contains block children (indicated by newlines),\n // add a newline after the opening tag so content starts on its own line.\n // Exempt raw-content elements (pre, textarea, script, style) where\n // newlines are literal text, not block-child indicators.\n const hasBlockChildren =\n !RAW_CONTENT_ELEMENTS.has(tag) && inner.includes('\\n');\n if (hasBlockChildren) {\n result += '\\n' + inner + '</' + tag + '>\\n';\n } else {\n result += inner + '</' + tag + '>\\n';\n }\n } else {\n result += inner + '</' + tag + '>';\n }\n\n return result;\n }\n\n function renderAttrs(tag: string, props: Record<string, any>): string {\n if (!props) return '';\n let result = '';\n for (const key in props) {\n if (\n key === 'children' ||\n key === 'dangerouslySetInnerHTML' ||\n key === 'key' ||\n key === 'ref' ||\n key === '__self' ||\n key === '__source'\n ) {\n continue;\n }\n // Skip value/defaultValue on textarea \u2014 rendered as text content.\n if (tag === 'textarea' && (key === 'value' || key === 'defaultValue')) {\n continue;\n }\n\n let value = props[key];\n if (!isDef(value)) continue;\n // Skip function-valued props such as event handlers (e.g. onClick={fn}):\n // client-side handler functions can't be serialized to HTML. String\n // values like <select onChange=\"...\"> are inline HTML event attributes,\n // so they are preserved and rendered as-is.\n if (typeof value === 'function') continue;\n\n const attrName = PROP_TO_ATTR[key] || key;\n\n // For boolean attributes, `false` removes the attribute. For all other\n // attributes, `false` is stringified (e.g. data-foo=\"false\").\n if (value === false && BOOLEAN_ATTRS.has(attrName)) continue;\n\n // Boolean attributes are minimized when true; other attributes use\n // explicit string serialization (e.g. id=\"true\", data-foo=\"true\").\n if (value === true && BOOLEAN_ATTRS.has(attrName)) {\n result += ' ' + attrName;\n continue;\n }\n\n // Style objects.\n if (key === 'style' && typeof value === 'object') {\n value = styleToString(value);\n if (!value) continue;\n }\n\n result += ' ' + attrName + '=\"' + escapeAttr(String(value)) + '\"';\n }\n return result;\n }\n\n /**\n * Returns true if a child node is a text-like value (string, number).\n */\n function isTextNode(child: any): boolean {\n if (!isDef(child) || typeof child === 'boolean') return false;\n return (\n typeof child === 'string' ||\n typeof child === 'number' ||\n typeof child === 'bigint'\n );\n }\n\n /**\n * Checks if an array of children contains a mix of text nodes and elements.\n * When mixed, block elements should render inline to avoid breaking text flow.\n */\n function hasMixedContent(children: any[]): boolean {\n let hasText = false;\n let hasElement = false;\n for (const child of children) {\n if (isTextNode(child)) {\n hasText = true;\n } else if (isDef(child) && typeof child === 'object' && 'type' in child) {\n hasElement = true;\n }\n if (hasText && hasElement) return true;\n }\n return false;\n }\n\n function renderChildren(children: any): string {\n if (!isDef(children)) return '';\n if (Array.isArray(children)) {\n const inline = isPretty && hasMixedContent(children);\n let out = '';\n for (let i = 0; i < children.length; i++) {\n out += render(children[i], inline);\n }\n return out;\n }\n return render(children);\n }\n\n return render(vnode);\n}\n\nfunction noop() {}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["vnode"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
/** Registers the `root secrets …` command group. */
|
|
3
|
+
export declare function registerSecretsCommands(program: Command): void;
|
|
4
|
+
/**
|
|
5
|
+
* Runs a blocking secrets sync at the start of `root dev` so managed values are
|
|
6
|
+
* live before the server starts. Never throws and never blocks longer than
|
|
7
|
+
* {@link DEV_SYNC_TIMEOUT_MS}; failures degrade to a notice so dev still starts.
|
|
8
|
+
*/
|
|
9
|
+
export declare function syncSecretsOnDev(rootDir: string): Promise<void>;
|
package/dist/cli.js
CHANGED
package/dist/functions.js
CHANGED
package/dist/jsx.js
CHANGED
package/dist/render.js
CHANGED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reads a `.env` file, returning an empty string if it doesn't exist. Other
|
|
3
|
+
* read errors propagate.
|
|
4
|
+
*/
|
|
5
|
+
export declare function readEnvFile(envPath: string): Promise<string>;
|
|
6
|
+
/**
|
|
7
|
+
* Atomically writes `.env` content via a temp file + rename so a crash mid-write
|
|
8
|
+
* can never leave a partially written `.env`.
|
|
9
|
+
*/
|
|
10
|
+
export declare function writeEnvFile(envPath: string, content: string): Promise<void>;
|
|
11
|
+
/**
|
|
12
|
+
* Parses `.env` content into a key/value map using the same parser the CLI uses
|
|
13
|
+
* to load env vars at startup (`dotenv`), so values compared here match what the
|
|
14
|
+
* running process sees.
|
|
15
|
+
*/
|
|
16
|
+
export declare function parseEnv(content: string): Record<string, string>;
|
|
17
|
+
/**
|
|
18
|
+
* Serializes a value into a `.env`-safe, single-physical-line representation
|
|
19
|
+
* that round-trips through `dotenv.parse`.
|
|
20
|
+
*
|
|
21
|
+
* Prefers single quotes, which dotenv treats as fully literal — so backslashes,
|
|
22
|
+
* tabs, double-quotes, `#`, `=`, and spaces all survive untouched. Values that
|
|
23
|
+
* contain a single-quote or a newline fall back to double quotes, where dotenv
|
|
24
|
+
* only un-escapes `\n` and `\r`; those are escaped (collapsing multi-line values
|
|
25
|
+
* onto one line) and embedded double-quotes are escaped for parse-safety.
|
|
26
|
+
*
|
|
27
|
+
* Known limitation (inherited from dotenv): a value containing BOTH a single and
|
|
28
|
+
* a double quote, or a literal backslash adjacent to `n`/`r`, may not round-trip
|
|
29
|
+
* exactly. Such values are vanishingly rare for secrets.
|
|
30
|
+
*/
|
|
31
|
+
export declare function serializeEnvValue(value: string): string;
|
|
32
|
+
/**
|
|
33
|
+
* Upserts and/or removes the given keys in `.env` content, preserving every
|
|
34
|
+
* other line (comments, blank lines, unmanaged vars) and the file's dominant
|
|
35
|
+
* EOL.
|
|
36
|
+
*
|
|
37
|
+
* - Keys in `updates` replace an existing assignment in place (first occurrence;
|
|
38
|
+
* later duplicates of the same key are dropped) or are appended if absent.
|
|
39
|
+
* - Keys in `removals` are deleted.
|
|
40
|
+
*
|
|
41
|
+
* All managed values are written as single physical lines (see
|
|
42
|
+
* `serializeEnvValue`), so a simple per-line scan is sufficient and safe.
|
|
43
|
+
*/
|
|
44
|
+
export declare function upsertEnvVars(content: string, updates: Record<string, string>, removals?: string[]): string;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export type GcloudErrorCode = 'ENOENT' | 'NOT_FOUND' | 'ALREADY_EXISTS' | 'PERMISSION_DENIED' | 'UNAUTHENTICATED' | 'UNKNOWN';
|
|
2
|
+
/** Error thrown when a `gcloud` invocation fails, with a classified code. */
|
|
3
|
+
export declare class GcloudError extends Error {
|
|
4
|
+
code: GcloudErrorCode;
|
|
5
|
+
stderr: string;
|
|
6
|
+
constructor(code: GcloudErrorCode, message: string, stderr?: string);
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Spawns `gcloud` with the given args (no shell — args are passed as an array,
|
|
10
|
+
* so secret names and project ids can never be interpreted by a shell). Any
|
|
11
|
+
* `input` is written to stdin (used to pass secret payloads, never argv).
|
|
12
|
+
* Resolves with stdout; rejects with a {@link GcloudError} on failure.
|
|
13
|
+
*/
|
|
14
|
+
export declare function runGcloud(args: string[], options?: {
|
|
15
|
+
input?: string;
|
|
16
|
+
}): Promise<string>;
|
|
17
|
+
/**
|
|
18
|
+
* Reads the latest version of a GSM secret and parses it as a JSON object of
|
|
19
|
+
* `{ENV_NAME: value}`. A missing secret (`NOT_FOUND`) or empty payload resolves
|
|
20
|
+
* to `{}` so callers can treat "never created" the same as "empty".
|
|
21
|
+
*/
|
|
22
|
+
export declare function accessSecretJson(gsmKey: string, project: string): Promise<Record<string, string>>;
|
|
23
|
+
/**
|
|
24
|
+
* Writes a JSON `{ENV_NAME: value}` object as a new version of a GSM secret,
|
|
25
|
+
* creating the secret first if it doesn't yet exist. The payload is passed via
|
|
26
|
+
* stdin, never as a command-line argument.
|
|
27
|
+
*/
|
|
28
|
+
export declare function writeSecretJson(gsmKey: string, project: string, data: Record<string, string>): Promise<void>;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Returns a random salt (hex), generated once per local sync-state file. Storing
|
|
3
|
+
* a salt makes {@link hashValue} digests non-precomputable, so a leaked state
|
|
4
|
+
* file can't be reversed against a rainbow table of bare sha256 hashes.
|
|
5
|
+
*/
|
|
6
|
+
export declare function randomSalt(): string;
|
|
7
|
+
/**
|
|
8
|
+
* Returns the salted sha256 (hex) of a value. Used to detect local edits to a
|
|
9
|
+
* managed `.env` value without storing the plaintext in the sync state.
|
|
10
|
+
*/
|
|
11
|
+
export declare function hashValue(salt: string, value: string): string;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/** Filename of the committed, CLI-managed secrets manifest. */
|
|
2
|
+
export declare const MANIFEST_FILENAME = ".root.secrets.json";
|
|
3
|
+
/** A single managed secret's metadata (no value is ever stored here). */
|
|
4
|
+
export interface SecretEntry {
|
|
5
|
+
/** ISO-8601 UTC timestamp of when the value last changed. */
|
|
6
|
+
updatedAt: string;
|
|
7
|
+
/** Email of whoever last changed the value (best-effort). */
|
|
8
|
+
updatedBy?: string;
|
|
9
|
+
}
|
|
10
|
+
/** Optional reference to a shared manifest that this site pulls keys from. */
|
|
11
|
+
export interface ImportConfig {
|
|
12
|
+
/** Path to the shared manifest, relative to this manifest's directory. */
|
|
13
|
+
manifest: string;
|
|
14
|
+
/** Allowlist of names to import; omit or `'*'` to import all shared keys. */
|
|
15
|
+
keys?: string[] | '*';
|
|
16
|
+
}
|
|
17
|
+
/** The committed manifest schema. */
|
|
18
|
+
export interface Manifest {
|
|
19
|
+
version: number;
|
|
20
|
+
gcpProjectId: string;
|
|
21
|
+
gsmKey: string;
|
|
22
|
+
import?: ImportConfig;
|
|
23
|
+
secrets: Record<string, SecretEntry>;
|
|
24
|
+
}
|
|
25
|
+
/** A fully-resolved managed key, after following any `import`. */
|
|
26
|
+
export interface ManagedKey {
|
|
27
|
+
name: string;
|
|
28
|
+
gsmKey: string;
|
|
29
|
+
gcpProjectId: string;
|
|
30
|
+
updatedAt: string;
|
|
31
|
+
}
|
|
32
|
+
/** Resolved view of a site manifest plus its imported shared keys. */
|
|
33
|
+
export interface ResolvedSecrets {
|
|
34
|
+
rootDir: string;
|
|
35
|
+
site: Manifest;
|
|
36
|
+
shared?: Manifest;
|
|
37
|
+
keys: ManagedKey[];
|
|
38
|
+
}
|
|
39
|
+
/** Absolute path to a directory's manifest file. */
|
|
40
|
+
export declare function manifestPath(dir: string): string;
|
|
41
|
+
/** Whether a string is a valid env var name for a managed secret. */
|
|
42
|
+
export declare function isValidEnvName(name: string): boolean;
|
|
43
|
+
/** Reads and validates a manifest, returning null if the file doesn't exist. */
|
|
44
|
+
export declare function readManifest(filePath: string): Promise<Manifest | null>;
|
|
45
|
+
/**
|
|
46
|
+
* Writes a manifest with stable formatting: `secrets` keys are sorted so that
|
|
47
|
+
* setting/removing values produces minimal, readable git diffs.
|
|
48
|
+
*/
|
|
49
|
+
export declare function writeManifest(filePath: string, manifest: Manifest): Promise<void>;
|
|
50
|
+
/** Creates an empty manifest header. */
|
|
51
|
+
export declare function emptyManifest(gcpProjectId: string, gsmKey: string): Manifest;
|
|
52
|
+
/**
|
|
53
|
+
* Resolves the full set of managed keys for a site: the site manifest's own
|
|
54
|
+
* `secrets` plus any keys pulled in via `import` from a shared manifest.
|
|
55
|
+
*
|
|
56
|
+
* Returns null if the site has no manifest. Throws on validation errors:
|
|
57
|
+
* unknown imported keys, a name declared in both the site and the imported
|
|
58
|
+
* subset, or a shared manifest whose `gcpProjectId` differs from the site's.
|
|
59
|
+
*/
|
|
60
|
+
export declare function resolveManagedKeys(rootDir: string): Promise<ResolvedSecrets | null>;
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { ResolvedSecrets } from './manifest.js';
|
|
2
|
+
/** Per-machine sync state filename, kept under `<rootDir>/.root/`. */
|
|
3
|
+
export declare const STATE_FILENAME = "secrets-sync.json";
|
|
4
|
+
export interface SyncOptions {
|
|
5
|
+
rootDir: string;
|
|
6
|
+
/** When false, compute the result without writing `.env` or state. */
|
|
7
|
+
apply: boolean;
|
|
8
|
+
/** When true (pull), overwrite local values regardless of local edits. */
|
|
9
|
+
force?: boolean;
|
|
10
|
+
}
|
|
11
|
+
export interface SyncResult {
|
|
12
|
+
/** Keys whose remote value was written into `.env`. */
|
|
13
|
+
changed: string[];
|
|
14
|
+
/** Keys with a local override that was kept (no remote change). */
|
|
15
|
+
kept: string[];
|
|
16
|
+
/** Keys changed both remotely and locally; local kept, needs `pull`. */
|
|
17
|
+
conflicts: string[];
|
|
18
|
+
/** Keys whose pre-existing local value was replaced on first sync. */
|
|
19
|
+
overwritten: string[];
|
|
20
|
+
/** Keys removed from `.env` because they're no longer managed. */
|
|
21
|
+
removed: string[];
|
|
22
|
+
/** Per-gsmKey fetch failures; affected keys are left for the next run. */
|
|
23
|
+
errors: Array<{
|
|
24
|
+
gsmKey: string;
|
|
25
|
+
message: string;
|
|
26
|
+
}>;
|
|
27
|
+
/** Whether any network (gcloud) call was made. */
|
|
28
|
+
ranNetwork: boolean;
|
|
29
|
+
}
|
|
30
|
+
/** Absolute path to the per-machine sync state file for a site. */
|
|
31
|
+
export declare function localStatePath(rootDir: string): string;
|
|
32
|
+
/**
|
|
33
|
+
* Three-way merges the manifest(s), Google Cloud Secret Manager values, and the
|
|
34
|
+
* local `.env`, writing only managed keys and preserving everything else.
|
|
35
|
+
*
|
|
36
|
+
* For each managed key, "theirs" (the manifest `updatedAt`) and the local sync
|
|
37
|
+
* state decide the outcome: take remote, keep a local override, flag a conflict,
|
|
38
|
+
* or remove a no-longer-managed key. GSM is fetched at most once per gsmKey and
|
|
39
|
+
* only when a key in that blob actually changed. Fetch failures are recorded and
|
|
40
|
+
* skipped so they retry; this function never throws for network reasons.
|
|
41
|
+
*/
|
|
42
|
+
export declare function syncSecrets(options: SyncOptions): Promise<SyncResult>;
|
|
43
|
+
export interface SetSecretOptions {
|
|
44
|
+
rootDir: string;
|
|
45
|
+
/** Resolved path to the manifest the value belongs to (site or shared). */
|
|
46
|
+
manifestFilePath: string;
|
|
47
|
+
name: string;
|
|
48
|
+
value: string;
|
|
49
|
+
/** Defaults to `git config user.email`. */
|
|
50
|
+
updatedBy?: string;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Stores a value in GSM (read-modify-write of the gsmKey's JSON blob), records
|
|
54
|
+
* its name + timestamp in the manifest, and updates the local `.env` and sync
|
|
55
|
+
* state so the value is immediately usable.
|
|
56
|
+
*/
|
|
57
|
+
export declare function setSecret(options: SetSecretOptions): Promise<void>;
|
|
58
|
+
export interface RemoveSecretOptions {
|
|
59
|
+
rootDir: string;
|
|
60
|
+
manifestFilePath: string;
|
|
61
|
+
name: string;
|
|
62
|
+
}
|
|
63
|
+
/** Removes a secret from the manifest, its GSM blob, the local `.env`, and state. */
|
|
64
|
+
export declare function removeSecret(options: RemoveSecretOptions): Promise<void>;
|
|
65
|
+
export interface PushEnvOptions {
|
|
66
|
+
rootDir: string;
|
|
67
|
+
/** Resolved path to the manifest to push into (site or shared). */
|
|
68
|
+
manifestFilePath: string;
|
|
69
|
+
/** Optional allowlist of `.env` keys to push; default pushes all. */
|
|
70
|
+
only?: string[];
|
|
71
|
+
/** Defaults to `git config user.email`. */
|
|
72
|
+
updatedBy?: string;
|
|
73
|
+
/**
|
|
74
|
+
* Called with the candidate NAMES (never values) and target gsmKey before any
|
|
75
|
+
* write. Return false to abort. Omit to push without confirmation.
|
|
76
|
+
*/
|
|
77
|
+
confirm?: (names: string[], gsmKey: string) => Promise<boolean>;
|
|
78
|
+
}
|
|
79
|
+
export interface EnvPushResult {
|
|
80
|
+
/** Names written to GSM + the manifest. */
|
|
81
|
+
pushed: string[];
|
|
82
|
+
/** Names skipped, with a reason (not in `.env`, invalid, or shared). */
|
|
83
|
+
skipped: Array<{
|
|
84
|
+
name: string;
|
|
85
|
+
reason: string;
|
|
86
|
+
}>;
|
|
87
|
+
/** True if the confirm callback declined. */
|
|
88
|
+
aborted: boolean;
|
|
89
|
+
/** The gsmKey the values were (or would be) written to. */
|
|
90
|
+
gsmKey: string;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Pushes the values in the local `.env` up to Secret Manager and records them in
|
|
94
|
+
* the manifest, in a single GSM version write. Existing GSM values for the same
|
|
95
|
+
* keys are overwritten (a "force push"). Keys already provided by a shared
|
|
96
|
+
* manifest, invalid names, and (with `only`) names absent from `.env` are
|
|
97
|
+
* skipped. Secret values never leave this function.
|
|
98
|
+
*/
|
|
99
|
+
export declare function pushEnvToSecrets(options: PushEnvOptions): Promise<EnvPushResult>;
|
|
100
|
+
export type KeyStatusKind = 'in-sync' | 'remote-newer' | 'locally-edited' | 'conflict' | 'not-pulled';
|
|
101
|
+
export interface KeyStatus {
|
|
102
|
+
name: string;
|
|
103
|
+
gsmKey: string;
|
|
104
|
+
updatedAt: string;
|
|
105
|
+
kind: KeyStatusKind;
|
|
106
|
+
inEnv: boolean;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Computes the sync status of every managed key WITHOUT any network access, by
|
|
110
|
+
* comparing the manifest `updatedAt` and the local `.env` against the recorded
|
|
111
|
+
* sync state. Used by `root secrets status`.
|
|
112
|
+
*/
|
|
113
|
+
export declare function getSecretsStatus(rootDir: string): Promise<{
|
|
114
|
+
resolved: ResolvedSecrets | null;
|
|
115
|
+
keys: KeyStatus[];
|
|
116
|
+
}>;
|
|
117
|
+
/** True when a site has a manifest and sync isn't disabled via env var. */
|
|
118
|
+
export declare function isSecretsSyncEnabled(rootDir: string): Promise<boolean>;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Normalizes line endings in a string to LF (`\n`).
|
|
3
|
+
*
|
|
4
|
+
* Converts CRLF (`\r\n`) and lone CR (`\r`) to LF.
|
|
5
|
+
*/
|
|
6
|
+
export declare function normalizeLineEndings(value: string): string;
|
|
7
|
+
export interface JsonStringifyOptions {
|
|
8
|
+
/**
|
|
9
|
+
* Indentation passed through to `JSON.stringify`. Accepts a number of
|
|
10
|
+
* spaces or an indent string.
|
|
11
|
+
*/
|
|
12
|
+
indent?: number | string;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Serializes data to a JSON string with Unix (LF) line endings.
|
|
16
|
+
*
|
|
17
|
+
* Unlike `JSON.stringify()`, this:
|
|
18
|
+
* - Recursively normalizes `\r\n` and `\r` to `\n` in string values, so
|
|
19
|
+
* round-tripping through `JSON.parse` won't yield CRLF line endings.
|
|
20
|
+
* - Normalizes line endings in the resulting JSON string itself.
|
|
21
|
+
*/
|
|
22
|
+
export declare function jsonStringify(value: unknown, options?: JsonStringifyOptions): string;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './jsonutils.js';
|
package/dist/utils.js
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
// src/utils/jsonutils.ts
|
|
2
|
+
function normalizeLineEndings(value) {
|
|
3
|
+
return value.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
|
|
4
|
+
}
|
|
5
|
+
function normalizeData(value) {
|
|
6
|
+
if (typeof value === "string") {
|
|
7
|
+
return normalizeLineEndings(value);
|
|
8
|
+
}
|
|
9
|
+
if (Array.isArray(value)) {
|
|
10
|
+
return value.map(normalizeData);
|
|
11
|
+
}
|
|
12
|
+
if (value && typeof value === "object") {
|
|
13
|
+
const result = {};
|
|
14
|
+
for (const key of Object.keys(value)) {
|
|
15
|
+
result[key] = normalizeData(value[key]);
|
|
16
|
+
}
|
|
17
|
+
return result;
|
|
18
|
+
}
|
|
19
|
+
return value;
|
|
20
|
+
}
|
|
21
|
+
function jsonStringify(value, options) {
|
|
22
|
+
const normalized = normalizeData(value);
|
|
23
|
+
const serialized = JSON.stringify(normalized, null, options?.indent);
|
|
24
|
+
return normalizeLineEndings(serialized);
|
|
25
|
+
}
|
|
26
|
+
export {
|
|
27
|
+
jsonStringify,
|
|
28
|
+
normalizeLineEndings
|
|
29
|
+
};
|
|
30
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/utils/jsonutils.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Normalizes line endings in a string to LF (`\\n`).\n *\n * Converts CRLF (`\\r\\n`) and lone CR (`\\r`) to LF.\n */\nexport function normalizeLineEndings(value: string): string {\n return value.replace(/\\r\\n/g, '\\n').replace(/\\r/g, '\\n');\n}\n\nfunction normalizeData(value: unknown): unknown {\n if (typeof value === 'string') {\n return normalizeLineEndings(value);\n }\n if (Array.isArray(value)) {\n return value.map(normalizeData);\n }\n if (value && typeof value === 'object') {\n const result: Record<string, unknown> = {};\n for (const key of Object.keys(value as Record<string, unknown>)) {\n result[key] = normalizeData((value as Record<string, unknown>)[key]);\n }\n return result;\n }\n return value;\n}\n\nexport interface JsonStringifyOptions {\n /**\n * Indentation passed through to `JSON.stringify`. Accepts a number of\n * spaces or an indent string.\n */\n indent?: number | string;\n}\n\n/**\n * Serializes data to a JSON string with Unix (LF) line endings.\n *\n * Unlike `JSON.stringify()`, this:\n * - Recursively normalizes `\\r\\n` and `\\r` to `\\n` in string values, so\n * round-tripping through `JSON.parse` won't yield CRLF line endings.\n * - Normalizes line endings in the resulting JSON string itself.\n */\nexport function jsonStringify(\n value: unknown,\n options?: JsonStringifyOptions\n): string {\n const normalized = normalizeData(value);\n const serialized = JSON.stringify(normalized, null, options?.indent);\n return normalizeLineEndings(serialized);\n}\n"],
|
|
5
|
+
"mappings": ";AAKO,SAAS,qBAAqB,OAAuB;AAC1D,SAAO,MAAM,QAAQ,SAAS,IAAI,EAAE,QAAQ,OAAO,IAAI;AACzD;AAEA,SAAS,cAAc,OAAyB;AAC9C,MAAI,OAAO,UAAU,UAAU;AAC7B,WAAO,qBAAqB,KAAK;AAAA,EACnC;AACA,MAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,WAAO,MAAM,IAAI,aAAa;AAAA,EAChC;AACA,MAAI,SAAS,OAAO,UAAU,UAAU;AACtC,UAAM,SAAkC,CAAC;AACzC,eAAW,OAAO,OAAO,KAAK,KAAgC,GAAG;AAC/D,aAAO,GAAG,IAAI,cAAe,MAAkC,GAAG,CAAC;AAAA,IACrE;AACA,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAkBO,SAAS,cACd,OACA,SACQ;AACR,QAAM,aAAa,cAAc,KAAK;AACtC,QAAM,aAAa,KAAK,UAAU,YAAY,MAAM,SAAS,MAAM;AACnE,SAAO,qBAAqB,UAAU;AACxC;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@blinkk/root",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.5",
|
|
4
4
|
"author": "s@blinkk.com",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"engines": {
|
|
@@ -63,6 +63,10 @@
|
|
|
63
63
|
"./render": {
|
|
64
64
|
"types": "./dist/render/render.d.ts",
|
|
65
65
|
"import": "./dist/render.js"
|
|
66
|
+
},
|
|
67
|
+
"./utils": {
|
|
68
|
+
"types": "./dist/utils/utils.d.ts",
|
|
69
|
+
"import": "./dist/utils.js"
|
|
66
70
|
}
|
|
67
71
|
},
|
|
68
72
|
"dependencies": {
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../src/jsx/jsx-render.ts"],
|
|
4
|
-
"sourcesContent": ["/* eslint-disable n/no-extraneous-import */\nimport {options as preactOptions} from 'preact';\nimport {VNode, Fragment} from './jsx-runtime.js';\n\n/** HTML void elements (self-closing, no end tag). */\nconst VOID_ELEMENTS = new Set([\n 'area',\n 'base',\n 'br',\n 'col',\n 'embed',\n 'hr',\n 'img',\n 'input',\n 'link',\n 'meta',\n 'param',\n 'source',\n 'track',\n 'wbr',\n]);\n\n/** Tags whose text content may contain literal newlines that should not be treated as block-child indicators. */\nconst RAW_CONTENT_ELEMENTS = new Set(['pre', 'textarea', 'script', 'style']);\n\n/**\n * Standard HTML block-level elements. Also includes the `<select>` content\n * model (`select`/`optgroup`/`option`) so that each `<option>` renders on its\n * own line in pretty mode, even though those tags aren't block-level per CSS.\n */\nconst DEFAULT_BLOCK_ELEMENTS = new Set([\n 'address',\n 'article',\n 'aside',\n 'base',\n 'blockquote',\n 'body',\n 'dd',\n 'details',\n 'dialog',\n 'div',\n 'dl',\n 'dt',\n 'fieldset',\n 'figcaption',\n 'figure',\n 'footer',\n 'form',\n 'h1',\n 'h2',\n 'h3',\n 'h4',\n 'h5',\n 'h6',\n 'head',\n 'header',\n 'hgroup',\n 'hr',\n 'html',\n 'li',\n 'link',\n 'main',\n 'meta',\n 'nav',\n 'noscript',\n 'ol',\n 'optgroup',\n 'option',\n 'p',\n 'pre',\n 'script',\n 'search',\n 'section',\n 'select',\n 'style',\n 'summary',\n 'table',\n 'tbody',\n 'td',\n 'tfoot',\n 'th',\n 'thead',\n 'title',\n 'tr',\n 'ul',\n]);\n\n/**\n * Non-visual metadata and resource elements. These produce no inline rendered\n * content, so in pretty mode they always start on their own line \u2014 even inside\n * a parent with mixed text/element children, where the inline heuristic would\n * otherwise keep all siblings on a single line. (`base`/`link`/`meta` are void;\n * `script`/`style`/`title` render no visible text.)\n */\nconst ALWAYS_BLOCK_ELEMENTS = new Set([\n 'base',\n 'link',\n 'meta',\n 'script',\n 'style',\n 'title',\n]);\n\n/**\n * HTML/SVG boolean attributes.\n * When present with a truthy value, render as a minimized attribute.\n */\nconst BOOLEAN_ATTRS = new Set([\n 'allowfullscreen',\n 'async',\n 'autofocus',\n 'autoplay',\n 'capture',\n 'checked',\n 'controls',\n 'default',\n 'defer',\n 'disabled',\n 'download',\n 'draggable',\n 'formnovalidate',\n 'hidden',\n 'inert',\n 'ismap',\n 'itemscope',\n 'loop',\n 'multiple',\n 'muted',\n 'nomodule',\n 'novalidate',\n 'open',\n 'playsinline',\n 'readonly',\n 'required',\n 'reversed',\n 'selected',\n]);\n\n/** JSX prop name -> HTML attribute name. */\nconst PROP_TO_ATTR: Record<string, string> = {\n acceptCharset: 'accept-charset',\n autoCapitalize: 'autocapitalize',\n autoComplete: 'autocomplete',\n autoFocus: 'autofocus',\n autoPlay: 'autoplay',\n charSet: 'charset',\n className: 'class',\n colSpan: 'colspan',\n contentEditable: 'contenteditable',\n crossOrigin: 'crossorigin',\n dateTime: 'datetime',\n encType: 'enctype',\n formAction: 'formaction',\n formEncType: 'formenctype',\n formMethod: 'formmethod',\n formNoValidate: 'formnovalidate',\n formTarget: 'formtarget',\n frameBorder: 'frameborder',\n hrefLang: 'hreflang',\n htmlFor: 'for',\n httpEquiv: 'http-equiv',\n inputMode: 'inputmode',\n itemProp: 'itemprop',\n itemRef: 'itemref',\n itemScope: 'itemscope',\n itemType: 'itemtype',\n maxLength: 'maxlength',\n mediaGroup: 'mediagroup',\n minLength: 'minlength',\n noModule: 'nomodule',\n noValidate: 'novalidate',\n playsInline: 'playsinline',\n readOnly: 'readonly',\n referrerPolicy: 'referrerpolicy',\n rowSpan: 'rowspan',\n spellCheck: 'spellcheck',\n srcDoc: 'srcdoc',\n srcLang: 'srclang',\n srcSet: 'srcset',\n tabIndex: 'tabindex',\n useMap: 'usemap',\n\n // SVG presentation attributes (camelCase -> kebab-case).\n clipPath: 'clip-path',\n clipRule: 'clip-rule',\n colorInterpolation: 'color-interpolation',\n colorInterpolationFilters: 'color-interpolation-filters',\n dominantBaseline: 'dominant-baseline',\n fillOpacity: 'fill-opacity',\n fillRule: 'fill-rule',\n floodColor: 'flood-color',\n floodOpacity: 'flood-opacity',\n imageRendering: 'image-rendering',\n letterSpacing: 'letter-spacing',\n lightingColor: 'lighting-color',\n markerEnd: 'marker-end',\n markerMid: 'marker-mid',\n markerStart: 'marker-start',\n paintOrder: 'paint-order',\n pointerEvents: 'pointer-events',\n shapeRendering: 'shape-rendering',\n stopColor: 'stop-color',\n stopOpacity: 'stop-opacity',\n strokeDasharray: 'stroke-dasharray',\n strokeDashoffset: 'stroke-dashoffset',\n strokeLinecap: 'stroke-linecap',\n strokeLinejoin: 'stroke-linejoin',\n strokeMiterlimit: 'stroke-miterlimit',\n strokeOpacity: 'stroke-opacity',\n strokeWidth: 'stroke-width',\n textAnchor: 'text-anchor',\n textDecoration: 'text-decoration',\n textRendering: 'text-rendering',\n transformOrigin: 'transform-origin',\n vectorEffect: 'vector-effect',\n wordSpacing: 'word-spacing',\n writingMode: 'writing-mode',\n};\n\nconst AMP = '&';\nconst LT = '<';\nconst GT = '>';\nconst QUOT = '"';\n\n// Shared empty object reused as the per-component context map when no contexts\n// have ever been pushed. Components only ever read from this map, so sharing is\n// safe and avoids a per-render allocation in the common case.\nconst EMPTY_GLOBAL_CTX: Record<string, any> = {};\n\n/** Returns `true` when `value` is neither `null` nor `undefined`. */\nfunction isDef<T>(value: T | null | undefined): value is T {\n return value !== null && value !== undefined;\n}\n\nfunction escapeHtml(str: string): string {\n let result = '';\n let last = 0;\n for (let i = 0; i < str.length; i++) {\n const ch = str.charCodeAt(i);\n let escaped: string | undefined;\n if (ch === 38) escaped = AMP;\n else if (ch === 60) escaped = LT;\n else if (ch === 62) escaped = GT;\n if (escaped) {\n result += str.slice(last, i) + escaped;\n last = i + 1;\n }\n }\n if (last === 0) return str;\n return result + str.slice(last);\n}\n\nfunction escapeAttr(str: string): string {\n let result = '';\n let last = 0;\n for (let i = 0; i < str.length; i++) {\n const ch = str.charCodeAt(i);\n let escaped: string | undefined;\n if (ch === 38) escaped = AMP;\n else if (ch === 34) escaped = QUOT;\n else if (ch === 60) escaped = LT;\n else if (ch === 62) escaped = GT;\n if (escaped) {\n result += str.slice(last, i) + escaped;\n last = i + 1;\n }\n }\n if (last === 0) return str;\n return result + str.slice(last);\n}\n\nconst STYLE_KEY_CACHE = new Map<string, string>();\nconst UPPERCASE_RE = /[A-Z]/g;\n\nfunction toKebabCase(key: string): string {\n let cached = STYLE_KEY_CACHE.get(key);\n if (cached === undefined) {\n cached = key.replace(UPPERCASE_RE, (m) => '-' + m.toLowerCase());\n STYLE_KEY_CACHE.set(key, cached);\n }\n return cached;\n}\n\nfunction styleToString(style: Record<string, any>): string {\n let result = '';\n let first = true;\n for (const key in style) {\n const value = style[key];\n if (!isDef(value) || value === '') continue;\n if (first) {\n first = false;\n } else {\n result += ';';\n }\n result += `${toKebabCase(key)}:${value}`;\n }\n return result;\n}\n\nexport interface JsxRenderOptions {\n /** Render mode. `'pretty'` adds newlines around block elements; `'minimal'` outputs compact HTML. Default: `'pretty'`. */\n mode?: 'pretty' | 'minimal';\n /** Additional tag names to treat as block-level elements in pretty mode. */\n blockElements?: string[];\n}\n\n/**\n * Renders a Preact VNode tree to an HTML string.\n */\nexport function renderJsxToString(\n vnode: VNode,\n options?: JsxRenderOptions\n): string {\n const mode = options?.mode ?? 'pretty';\n const isPretty = mode === 'pretty';\n // In minimal mode `blockSet` is unused (the `isPretty` guard short-circuits\n // any `.has()` call). In pretty mode without custom block elements, reuse the\n // module-level Set instead of allocating a copy.\n let blockSet: ReadonlySet<string> = DEFAULT_BLOCK_ELEMENTS;\n if (isPretty && options?.blockElements && options.blockElements.length > 0) {\n const merged = new Set(DEFAULT_BLOCK_ELEMENTS);\n for (const el of options.blockElements) {\n merged.add(el);\n }\n blockSet = merged;\n }\n\n // Context stacks: context.__c (id) -> value[]\n let contextStacks: Map<string, any[]> | undefined;\n\n // Version counter that bumps whenever a context value is pushed or popped.\n // `buildGlobalContext` uses it to skip rebuilding when nothing changed\n // between sibling component renders (the common case).\n let ctxVersion = 0;\n let cachedGlobalCtx: Record<string, any> = EMPTY_GLOBAL_CTX;\n let cachedGlobalCtxVersion = 0;\n\n function pushCtx(contextId: string, value: any) {\n if (!contextStacks) {\n contextStacks = new Map<string, any[]>();\n }\n let stack = contextStacks.get(contextId);\n if (!stack) {\n stack = [];\n contextStacks.set(contextId, stack);\n }\n stack.push(value);\n ctxVersion++;\n }\n\n function popCtx(contextId: string) {\n const stack = contextStacks?.get(contextId);\n if (stack) {\n stack.pop();\n if (stack.length === 0) {\n contextStacks?.delete(contextId);\n }\n }\n ctxVersion++;\n }\n\n /** Builds the __n (global context) map for hooks. */\n function buildGlobalContext(): Record<string, any> {\n if (ctxVersion === cachedGlobalCtxVersion) return cachedGlobalCtx;\n if (!contextStacks || contextStacks.size === 0) {\n cachedGlobalCtx = EMPTY_GLOBAL_CTX;\n cachedGlobalCtxVersion = ctxVersion;\n return cachedGlobalCtx;\n }\n const globalCtx: Record<string, any> = {};\n for (const [contextId, stack] of contextStacks) {\n if (stack.length > 0) {\n // useContext expects provider.props.value and provider.sub().\n globalCtx[contextId] = {\n props: {value: stack[stack.length - 1]},\n sub: noop,\n };\n }\n }\n cachedGlobalCtx = globalCtx;\n cachedGlobalCtxVersion = ctxVersion;\n return globalCtx;\n }\n\n function render(node: any, inline?: boolean): string {\n if (!isDef(node) || typeof node === 'boolean') return '';\n if (typeof node === 'string') return escapeHtml(node);\n if (typeof node === 'number' || typeof node === 'bigint')\n return String(node);\n if (Array.isArray(node)) {\n let out = '';\n for (let i = 0; i < node.length; i++) {\n out += render(node[i], inline);\n }\n return out;\n }\n\n // Must be a VNode-like object.\n if (typeof node !== 'object' || !('type' in node)) return '';\n\n const {type, props} = node;\n\n // Fragment.\n if (type === Fragment) {\n return renderChildren(props?.children);\n }\n\n // Component (function or class).\n if (typeof type === 'function') {\n return renderComponent(node);\n }\n\n // HTML element.\n if (typeof type === 'string') {\n return renderElement(type, props, inline);\n }\n\n return '';\n }\n\n function renderComponent(vnode: VNode): string {\n const {type, props} = vnode;\n const fn = type as Function;\n\n // Detect context Provider.\n // Root.js local JSX runtime: Provider._isProvider === true, Provider._context\n // is the Context object with a _stack array.\n // Preact >=10.27: Provider === Context (same function). `fn.__c` is the\n // context id string (e.g. \"__cC0\").\n // Preact <10.27: Provider._contextRef (mangled `fn.__`) points to the\n // context object which has `__c` (id) and `__` (default value).\n const fnAny = fn as any;\n if (fnAny._isProvider && fnAny._context) {\n const ctx = fnAny._context;\n ctx._stack.push((props as any).value);\n const result = renderChildren(props.children);\n ctx._stack.pop();\n return result;\n }\n let contextId: string | undefined;\n if (typeof fnAny.__c === 'string' && fnAny.__c.startsWith('__cC')) {\n contextId = fnAny.__c;\n } else if (fnAny.__ && typeof fnAny.__ === 'object' && fnAny.__.__c) {\n contextId = fnAny.__.__c;\n }\n if (contextId) {\n pushCtx(contextId, (props as any).value);\n const result = renderChildren(props.children);\n popCtx(contextId);\n return result;\n }\n\n // Detect context Consumer.\n if ((fn as any).contextType) {\n const ctx = (fn as any).contextType;\n const ctxId: string = ctx.__c;\n const stack = contextStacks?.get(ctxId);\n const value =\n stack && stack.length > 0 ? stack[stack.length - 1] : ctx.__;\n if (typeof props.children === 'function') {\n return render(props.children(value));\n }\n return renderChildren(props.children);\n }\n\n // Regular component \u2014 set up a fake component instance so Preact hooks\n // (useContext, useState, useMemo, etc.) work during SSR.\n // Preact's useContext reads from `component.context[context.__c]`.\n const component: any = {\n props,\n context: buildGlobalContext(),\n state: {},\n __v: vnode, // _vnode\n __d: false, // _dirty\n __h: [], // _renderCallbacks\n __s: {}, // _nextState\n __H: null, // _hooks (initialised by hooks addon)\n };\n (vnode as any).__c = component;\n\n // Trigger Preact option hooks so the hooks addon can set currentComponent.\n (preactOptions as any).__b?.(vnode);\n (preactOptions as any).__r?.(vnode);\n\n try {\n // Class component.\n if (fn.prototype && fn.prototype.render) {\n const instance = new (fn as any)(props, component.context);\n instance.__n = component.__n;\n instance.__H = component.__H;\n (vnode as any).__c = instance;\n (preactOptions as any).__r?.(vnode);\n return render(instance.render(instance.props, instance.state));\n }\n\n // Functional component.\n const rendered = fn(props, component.context);\n return render(rendered);\n } finally {\n preactOptions.diffed?.(vnode as any);\n }\n }\n\n function renderElement(\n tag: string,\n props: Record<string, any>,\n inline?: boolean\n ): string {\n // Metadata/resource elements always break onto their own line, even within\n // mixed (text + element) content where the inline heuristic applies, since\n // they render no inline visual output.\n const isBlock =\n isPretty &&\n (ALWAYS_BLOCK_ELEMENTS.has(tag) || (!inline && blockSet.has(tag)));\n const isVoid = VOID_ELEMENTS.has(tag);\n const attrs = renderAttrs(tag, props);\n let result = '<' + tag + attrs + '>';\n\n if (isVoid) {\n if (isBlock) result += '\\n';\n return result;\n }\n\n let inner = '';\n if (isDef(props?.dangerouslySetInnerHTML?.__html)) {\n inner = props.dangerouslySetInnerHTML.__html;\n } else if (isDef(props?.children)) {\n inner = renderChildren(props.children);\n } else if (tag === 'textarea' && props) {\n // For <textarea>, render value/defaultValue as text content since\n // browsers ignore the value attribute on textarea elements.\n const textVal = props.value ?? props.defaultValue;\n if (isDef(textVal)) {\n inner = escapeHtml(String(textVal));\n }\n }\n\n if (isBlock) {\n // When inner content contains block children (indicated by newlines),\n // add a newline after the opening tag so content starts on its own line.\n // Exempt raw-content elements (pre, textarea, script, style) where\n // newlines are literal text, not block-child indicators.\n const hasBlockChildren =\n !RAW_CONTENT_ELEMENTS.has(tag) && inner.includes('\\n');\n if (hasBlockChildren) {\n result += '\\n' + inner + '</' + tag + '>\\n';\n } else {\n result += inner + '</' + tag + '>\\n';\n }\n } else {\n result += inner + '</' + tag + '>';\n }\n\n return result;\n }\n\n function renderAttrs(tag: string, props: Record<string, any>): string {\n if (!props) return '';\n let result = '';\n for (const key in props) {\n if (\n key === 'children' ||\n key === 'dangerouslySetInnerHTML' ||\n key === 'key' ||\n key === 'ref' ||\n key === '__self' ||\n key === '__source'\n ) {\n continue;\n }\n // Skip value/defaultValue on textarea \u2014 rendered as text content.\n if (tag === 'textarea' && (key === 'value' || key === 'defaultValue')) {\n continue;\n }\n\n let value = props[key];\n if (!isDef(value)) continue;\n // Skip function-valued props such as event handlers (e.g. onClick={fn}):\n // client-side handler functions can't be serialized to HTML. String\n // values like <select onChange=\"...\"> are inline HTML event attributes,\n // so they are preserved and rendered as-is.\n if (typeof value === 'function') continue;\n\n const attrName = PROP_TO_ATTR[key] || key;\n\n // For boolean attributes, `false` removes the attribute. For all other\n // attributes, `false` is stringified (e.g. data-foo=\"false\").\n if (value === false && BOOLEAN_ATTRS.has(attrName)) continue;\n\n // Boolean attributes are minimized when true; other attributes use\n // explicit string serialization (e.g. id=\"true\", data-foo=\"true\").\n if (value === true && BOOLEAN_ATTRS.has(attrName)) {\n result += ' ' + attrName;\n continue;\n }\n\n // Style objects.\n if (key === 'style' && typeof value === 'object') {\n value = styleToString(value);\n if (!value) continue;\n }\n\n result += ' ' + attrName + '=\"' + escapeAttr(String(value)) + '\"';\n }\n return result;\n }\n\n /**\n * Returns true if a child node is a text-like value (string, number).\n */\n function isTextNode(child: any): boolean {\n if (!isDef(child) || typeof child === 'boolean') return false;\n return (\n typeof child === 'string' ||\n typeof child === 'number' ||\n typeof child === 'bigint'\n );\n }\n\n /**\n * Checks if an array of children contains a mix of text nodes and elements.\n * When mixed, block elements should render inline to avoid breaking text flow.\n */\n function hasMixedContent(children: any[]): boolean {\n let hasText = false;\n let hasElement = false;\n for (const child of children) {\n if (isTextNode(child)) {\n hasText = true;\n } else if (isDef(child) && typeof child === 'object' && 'type' in child) {\n hasElement = true;\n }\n if (hasText && hasElement) return true;\n }\n return false;\n }\n\n function renderChildren(children: any): string {\n if (!isDef(children)) return '';\n if (Array.isArray(children)) {\n const inline = isPretty && hasMixedContent(children);\n let out = '';\n for (let i = 0; i < children.length; i++) {\n out += render(children[i], inline);\n }\n return out;\n }\n return render(children);\n }\n\n return render(vnode);\n}\n\nfunction noop() {}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["vnode"]
|
|
7
|
-
}
|