@opengeni/vaults 3.1.2 → 3.2.2

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/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/splice/index.ts","../src/splice/posix.ts","../src/splice/stream.ts","../src/splice/powershell.ts"],"sourcesContent":["/**\n * Shell splice contract (design §10B.1.4). F1 owns the signatures; W1\n * implements the dialect-aware bodies. Each reference in a command becomes a\n * per-command environment variable (`${OPENGENI_SECRET_<n>}` on POSIX,\n * `${env:OPENGENI_SECRET_<n>}` on PowerShell). Literal bodies (quoted heredocs,\n * `@'…'@` here-strings) are rewritten into their expanding form with the body\n * escaped, so no value is ever placed in command text.\n */\nimport { SecretReferenceError, type SecretTextToken } from \"@opengeni/contracts\";\nimport { PosixSplicer } from \"./posix\";\nimport { PowerShellSplicer } from \"./powershell\";\nimport { BindingTable, streamFromTokens } from \"./stream\";\n\nexport type ShellDialect = \"posix\" | \"powershell\" | \"cmd\" | \"fish\" | \"unknown\";\nexport interface SecretExecBinding {\n /** Environment variable name, e.g. OPENGENI_SECRET_0. */\n envName: string;\n /** `referenceKey(ref)` of the bound reference. */\n key: string;\n /** Always false: every context is spliced as an expansion (no literal fallback). */\n literal: boolean;\n /** Always null (kept for the F1 contract shape). */\n sentinel: string | null;\n}\nexport interface ShellSpliceResult {\n text: string;\n bindings: SecretExecBinding[];\n}\n\nexport const SECRET_EXEC_ENV_PREFIX = \"OPENGENI_SECRET_\";\n\n/**\n * Rewrites `tokens` (from `tokenizeSecretText(text)`) into a command that\n * reads each reference from its own env var, shell-aware (see `posix.ts` and\n * `powershell.ts` for the context tables). Throws\n * `SecretReferenceError(unsupported_shell)` for cmd, fish and unknown shells\n * when the command holds a reference. Escapes are already removed by the\n * tokenizer, so the result is rebuilt from `tokens` and `_text` is unused.\n * Pure: no values are involved.\n */\nexport function spliceShellCommand(\n _text: string,\n dialect: ShellDialect,\n tokens: readonly SecretTextToken[],\n): ShellSpliceResult {\n const references = tokens.filter((token) => token.type === \"reference\");\n const items = streamFromTokens(tokens);\n if (references.length === 0) {\n return { text: items.join(\"\"), bindings: [] };\n }\n if (dialect !== \"posix\" && dialect !== \"powershell\") {\n throw new SecretReferenceError(\n references.map((token) => ({\n raw: token.type === \"reference\" ? token.reference.raw : \"\",\n code: \"unsupported_shell\" as const,\n message:\n dialect === \"cmd\"\n ? 'secret references cannot be used safely in cmd.exe; run the command with shell \"powershell\" instead, or pass the value as a file with {{secretfile:…}}'\n : `secret references are not supported in ${dialect} shells; run the command with shell \"sh\" or \"bash\" (or \"powershell\" on Windows), or pass the value as a file with {{secretfile:…}}`,\n })),\n null,\n );\n }\n const table = new BindingTable(SECRET_EXEC_ENV_PREFIX);\n const text =\n dialect === \"posix\"\n ? new PosixSplicer(items, table).run()\n : new PowerShellSplicer(items, table).run();\n return { text, bindings: table.bindings };\n}\n\n/** Pick the splice dialect for a shell path or name on a given OS. */\nexport function dialectFromShell(\n shell: string | null,\n os: \"linux\" | \"darwin\" | \"windows\" | \"unknown\",\n): ShellDialect {\n if (shell === null || shell.trim() === \"\") {\n if (os === \"windows\") return \"powershell\";\n if (os === \"linux\" || os === \"darwin\") return \"posix\";\n return \"unknown\";\n }\n const base = shell\n .trim()\n .split(/[\\\\/]/)\n .pop()!\n .toLowerCase()\n .replace(/\\.exe$/, \"\");\n if ([\"sh\", \"bash\", \"dash\", \"zsh\", \"ksh\", \"mksh\", \"ash\", \"busybox\"].includes(base)) return \"posix\";\n if (base === \"pwsh\" || base === \"powershell\") return \"powershell\";\n if (base === \"cmd\") return \"cmd\";\n if (base === \"fish\") return \"fish\";\n return \"unknown\";\n}\n","/**\n * POSIX (sh, bash, dash, zsh, ksh) splice. A lexical scanner tracks the quoting\n * context at each reference and emits the variable expansion that yields the\n * value as exactly one word with no further interpretation:\n *\n * | context | emission |\n * |-----------------------------|----------------------------------|\n * | unquoted word | `\"${V}\"` |\n * | double quotes, `$(` in `\"` | `${V}` |\n * | single quotes | `'\"${V}\"'` (close, splice, reopen) |\n * | ANSI-C `$'…'` | `'\"${V}\"$'` |\n * | unquoted heredoc body | `${V}` |\n * | quoted heredoc body | made unquoted, body escaped, `${V}` |\n * | `$( )`, backticks | recurse with the same rules |\n * | comment | reference text kept as written |\n *\n * Nested shells (`bash -c '…'`, `ssh host '…'`, `eval`) re-parse the text the\n * outer shell produced, so a value spliced into their argument is lexed again.\n * The robust idioms pass the value by name instead (`V={{secret:X}} bash -c\n * '… \"$V\" …'`, `printf %s {{secret:X}} | ssh host 'read -r V; …'`); the\n * variables are exported, so inner shells inherit them.\n */\nimport { SecretReferenceError, type SecretReference } from \"@opengeni/contracts\";\nimport { BindingTable, isReference, type StreamItem } from \"./stream\";\n\nconst WORD_BREAK = new Set([\" \", \"\\t\", \"\\n\", \";\", \"&\", \"|\", \"(\", \")\", \"<\", \">\"]);\n\ninterface PendingHeredoc {\n delimiter: string;\n quoted: boolean;\n stripTabs: boolean;\n /** Offsets of the delimiter word as copied into `out`, so a quoted\n * delimiter can be rewritten unquoted once its body is known. */\n wordStart: number;\n wordEnd: number;\n}\n\n/** Reserved words after which a command (and so `case`/`esac`) can follow. */\nconst COMMAND_KEYWORDS = new Set([\n \"then\",\n \"do\",\n \"else\",\n \"elif\",\n \"if\",\n \"while\",\n \"until\",\n \"!\",\n \"{\",\n \"time\",\n]);\n\n/** Delimiters that are a single plain word once unquoted. */\nconst PLAIN_DELIMITER = /^[A-Za-z0-9_][A-Za-z0-9_.-]*$/;\n\ntype Closer = \")\" | \"`\" | null;\n\nexport class PosixSplicer {\n private index = 0;\n private out = \"\";\n private readonly pending: PendingHeredoc[] = [];\n\n constructor(\n private readonly items: readonly StreamItem[],\n private readonly table: BindingTable,\n ) {}\n\n run(): string {\n this.command(null, false);\n // Unbalanced closers at top level are copied verbatim; the shell reports them.\n while (this.index < this.items.length) {\n this.copyCurrent();\n this.command(null, false);\n }\n return this.out;\n }\n\n private peek(offset = 0): StreamItem | undefined {\n return this.items[this.index + offset];\n }\n\n private copyCurrent(): void {\n const item = this.items[this.index];\n this.index += 1;\n if (item === undefined) return;\n this.out += isReference(item) ? item.raw : item;\n }\n\n private env(reference: SecretReference): string {\n return this.table.env(reference);\n }\n\n private unsupported(reference: SecretReference, message: string): never {\n throw new SecretReferenceError([{ raw: reference.raw, code: \"unsupported_shell\", message }]);\n }\n\n /** `$` right before a reference would join the expansion (`$$` is the PID). */\n private rejectDollarBeforeReference(): void {\n const next = this.peek(1);\n if (isReference(next)) {\n this.unsupported(\n next,\n `a secret reference right after \"$\" is ambiguous; quote the \"$\" ('$') or separate it from ${next.raw}`,\n );\n }\n }\n\n /**\n * True when the output so far ends where a command starts: the scope start,\n * after a separator, or after a reserved word that takes a command.\n */\n private atCommandStart(scopeStart: number, cases: number): boolean {\n let cursor = this.out.length - 1;\n while (cursor >= scopeStart && (this.out[cursor] === \" \" || this.out[cursor] === \"\\t\")) {\n cursor -= 1;\n }\n if (cursor < scopeStart) return true;\n const last = this.out[cursor]!;\n if (\";&|\\n(\".includes(last)) return true;\n if (last === \")\") return cases > 0;\n let start = cursor;\n while (start > scopeStart && /[A-Za-z!{]/.test(this.out[start - 1]!)) start -= 1;\n const before = start > scopeStart ? this.out[start - 1]! : \"\\n\";\n return (\n COMMAND_KEYWORDS.has(this.out.slice(start, cursor + 1)) &&\n (WORD_BREAK.has(before) || before === \"\\n\")\n );\n }\n\n /** True when the next items spell `word` as a whole word. */\n private keywordAhead(word: string): boolean {\n for (let offset = 0; offset < word.length; offset += 1) {\n if (this.peek(offset) !== word[offset]) return false;\n }\n const after = this.peek(word.length);\n return after === undefined || (typeof after === \"string\" && WORD_BREAK.has(after));\n }\n\n /**\n * After `$((` or `((` has been copied: arithmetic, copied through its `))`.\n * Arithmetic re-evaluates expanded text (array subscripts run commands), so\n * a value is never spliced there.\n */\n private arithmetic(): void {\n let depth = 0;\n while (this.index < this.items.length) {\n const item = this.peek()!;\n if (isReference(item)) {\n this.unsupported(\n item,\n `secret references cannot be used inside (( )) arithmetic; assign it first (N={{secret:…}}) and use \"$N\"`,\n );\n }\n if (item === \"(\") depth += 1;\n else if (item === \")\") {\n if (depth === 0 && this.peek(1) === \")\") {\n this.copyCurrent();\n this.copyCurrent();\n return;\n }\n depth -= 1;\n }\n this.copyCurrent();\n }\n }\n\n /** At `$`: `$((` arithmetic or `$(` substitution; false when neither. */\n private dollarParen(): boolean {\n if (this.peek(1) !== \"(\") return false;\n this.copyCurrent();\n this.copyCurrent();\n if (this.peek() === \"(\") {\n this.copyCurrent();\n this.arithmetic();\n } else {\n this.substitution();\n }\n return true;\n }\n\n /** A command list: top level, `$( … )` or a backtick substitution. */\n private command(closer: Closer, insideDoubleQuotedBackticks: boolean): void {\n let depth = 0;\n // Open `case … esac` statements: their pattern `)` closes nothing.\n let cases = 0;\n let wordStart = true;\n const scopeStart = this.out.length;\n while (this.index < this.items.length) {\n const item = this.peek()!;\n if (isReference(item)) {\n const name = this.env(item);\n this.out += insideDoubleQuotedBackticks ? `\\\\\"\\${${name}}\\\\\"` : `\"\\${${name}}\"`;\n this.index += 1;\n wordStart = false;\n continue;\n }\n if (\n wordStart &&\n (this.keywordAhead(\"case\") || this.keywordAhead(\"esac\")) &&\n this.atCommandStart(scopeStart, cases)\n ) {\n cases = Math.max(0, cases + (item === \"c\" ? 1 : -1));\n for (let copied = 0; copied < 4; copied += 1) this.copyCurrent();\n wordStart = false;\n continue;\n }\n if (item === \")\" && depth === 0 && cases > 0) {\n this.copyCurrent();\n wordStart = true;\n continue;\n }\n if (closer === \")\" && item === \")\" && depth === 0) return;\n if (closer === \"`\" && item === \"`\") return;\n switch (item) {\n case \"\\\\\": {\n this.copyCurrent();\n if (this.peek() === \"\\n\") {\n this.copyCurrent();\n } else if (this.index < this.items.length) {\n const next = this.peek()!;\n if (isReference(next)) {\n // `\\` before a reference: the backslash escapes nothing useful.\n const name = this.env(next);\n this.out += `\"\\${${name}}\"`;\n this.index += 1;\n } else {\n this.copyCurrent();\n }\n }\n wordStart = false;\n continue;\n }\n case \"'\": {\n this.copyCurrent();\n this.singleQuoted();\n wordStart = false;\n continue;\n }\n case '\"': {\n this.copyCurrent();\n this.doubleQuoted();\n wordStart = false;\n continue;\n }\n case \"$\": {\n this.rejectDollarBeforeReference();\n if (this.peek(1) === \"'\") {\n this.copyCurrent();\n this.copyCurrent();\n this.ansiQuoted();\n } else if (!this.dollarParen()) {\n this.copyCurrent();\n }\n wordStart = false;\n continue;\n }\n case \"`\": {\n this.copyCurrent();\n this.command(\"`\", false);\n if (this.peek() === \"`\") this.copyCurrent();\n wordStart = false;\n continue;\n }\n case \"(\":\n if (wordStart && this.peek(1) === \"(\") {\n // `(( … ))` arithmetic command.\n this.copyCurrent();\n this.copyCurrent();\n this.arithmetic();\n wordStart = false;\n continue;\n }\n depth += 1;\n this.copyCurrent();\n wordStart = true;\n continue;\n case \")\":\n depth -= 1;\n this.copyCurrent();\n wordStart = true;\n continue;\n case \"#\":\n if (wordStart) {\n this.comment();\n continue;\n }\n this.copyCurrent();\n continue;\n case \"<\":\n if (this.peek(1) === \"<\" && this.peek(2) !== \"<\") {\n this.heredocOperator();\n wordStart = true;\n continue;\n }\n if (this.peek(1) === \"<\" && this.peek(2) === \"<\") {\n // Here-string: copy the operator; its word is lexed normally.\n this.copyCurrent();\n this.copyCurrent();\n this.copyCurrent();\n wordStart = true;\n continue;\n }\n this.copyCurrent();\n wordStart = true;\n continue;\n case \"\\n\":\n this.copyCurrent();\n this.heredocBodies();\n wordStart = true;\n continue;\n default:\n this.copyCurrent();\n wordStart = WORD_BREAK.has(item);\n }\n }\n }\n\n /** After `$(` has been copied: the command list, then its `)`. */\n private substitution(): void {\n this.command(\")\", false);\n if (this.peek() === \")\") this.copyCurrent();\n }\n\n private comment(): void {\n while (this.index < this.items.length && this.peek() !== \"\\n\") this.copyCurrent();\n }\n\n private singleQuoted(): void {\n while (this.index < this.items.length) {\n const item = this.peek()!;\n if (isReference(item)) {\n this.out += `'\"\\${${this.env(item)}}\"'`;\n this.index += 1;\n continue;\n }\n this.copyCurrent();\n if (item === \"'\") return;\n }\n }\n\n private ansiQuoted(): void {\n while (this.index < this.items.length) {\n const item = this.peek()!;\n if (isReference(item)) {\n this.out += `'\"\\${${this.env(item)}}\"$'`;\n this.index += 1;\n continue;\n }\n this.copyCurrent();\n if (item === \"\\\\\") {\n if (this.index < this.items.length && !isReference(this.peek())) this.copyCurrent();\n continue;\n }\n if (item === \"'\") return;\n }\n }\n\n private doubleQuoted(): void {\n while (this.index < this.items.length) {\n const item = this.peek()!;\n if (isReference(item)) {\n this.out += `\\${${this.env(item)}}`;\n this.index += 1;\n continue;\n }\n if (item === \"\\\\\") {\n this.copyCurrent();\n if (this.index < this.items.length && !isReference(this.peek())) this.copyCurrent();\n continue;\n }\n if (item === \"$\") {\n this.rejectDollarBeforeReference();\n if (this.dollarParen()) continue;\n }\n if (item === \"`\") {\n this.copyCurrent();\n this.command(\"`\", true);\n if (this.peek() === \"`\") this.copyCurrent();\n continue;\n }\n this.copyCurrent();\n if (item === '\"') return;\n }\n }\n\n /** `<<` / `<<-`, optional blanks, then the delimiter word. Copied verbatim. */\n private heredocOperator(): void {\n this.copyCurrent();\n this.copyCurrent();\n let stripTabs = false;\n if (this.peek() === \"-\") {\n stripTabs = true;\n this.copyCurrent();\n }\n while (this.peek() === \" \" || this.peek() === \"\\t\") this.copyCurrent();\n const wordStart = this.out.length;\n let delimiter = \"\";\n let quoted = false;\n while (this.index < this.items.length) {\n const item = this.peek()!;\n if (isReference(item)) break;\n if (item === \"'\" || item === '\"') {\n quoted = true;\n const quote = item;\n this.copyCurrent();\n while (this.index < this.items.length && this.peek() !== quote) {\n const inner = this.peek()!;\n if (isReference(inner)) break;\n delimiter += inner;\n this.copyCurrent();\n }\n if (this.peek() === quote) this.copyCurrent();\n continue;\n }\n if (item === \"\\\\\") {\n quoted = true;\n this.copyCurrent();\n const next = this.peek();\n if (typeof next === \"string\") {\n delimiter += next;\n this.copyCurrent();\n }\n continue;\n }\n if (WORD_BREAK.has(item)) break;\n delimiter += item;\n this.copyCurrent();\n }\n if (delimiter.length > 0) {\n this.pending.push({ delimiter, quoted, stripTabs, wordStart, wordEnd: this.out.length });\n }\n }\n\n /** Called right after a newline: consume every queued heredoc body in order. */\n private heredocBodies(): void {\n while (this.pending.length > 0) {\n const heredoc = this.pending.shift()!;\n this.heredocBody(heredoc);\n }\n }\n\n private lineMatchesDelimiter(heredoc: PendingHeredoc): number | null {\n let cursor = this.index;\n let line = \"\";\n while (cursor < this.items.length) {\n const item = this.items[cursor]!;\n if (isReference(item)) return null;\n if (item === \"\\n\") break;\n line += item;\n cursor += 1;\n }\n const candidate = heredoc.stripTabs ? line.replace(/^\\t+/, \"\") : line;\n return candidate === heredoc.delimiter ? cursor : null;\n }\n\n /** True when a reference occurs before the body's delimiter line. */\n private bodyHasReference(heredoc: PendingHeredoc): boolean {\n const saved = this.index;\n try {\n while (this.index < this.items.length) {\n const end = this.lineMatchesDelimiter(heredoc);\n if (end !== null) return false;\n while (this.index < this.items.length) {\n const item = this.items[this.index]!;\n this.index += 1;\n if (isReference(item)) return true;\n if (item === \"\\n\") break;\n }\n }\n return false;\n } finally {\n this.index = saved;\n }\n }\n\n /**\n * A quoted heredoc keeps its body literal, so a value cannot be expanded\n * there. When the body holds a reference, rewrite the delimiter unquoted and\n * escape the body's `\\`, `$` and backquote, which yields the same literal\n * text plus a `${V}` expansion that is never re-parsed.\n */\n private unquoteDelimiter(heredoc: PendingHeredoc): void {\n if (!PLAIN_DELIMITER.test(heredoc.delimiter)) {\n throw new SecretReferenceError([\n {\n raw: \"\",\n code: \"unsupported_shell\",\n message: `secret references cannot be used inside a quoted heredoc whose delimiter is not a plain word (${JSON.stringify(heredoc.delimiter)}); use a plain delimiter such as <<'EOF', an unquoted heredoc, or {{secretfile:…}}`,\n },\n ]);\n }\n const delta = heredoc.delimiter.length - (heredoc.wordEnd - heredoc.wordStart);\n this.out =\n this.out.slice(0, heredoc.wordStart) + heredoc.delimiter + this.out.slice(heredoc.wordEnd);\n for (const later of this.pending) {\n later.wordStart += delta;\n later.wordEnd += delta;\n }\n }\n\n private heredocBody(heredoc: PendingHeredoc): void {\n let escapeBody = false;\n if (heredoc.quoted && this.bodyHasReference(heredoc)) {\n this.unquoteDelimiter(heredoc);\n escapeBody = true;\n }\n while (this.index < this.items.length) {\n const end = this.lineMatchesDelimiter(heredoc);\n if (end !== null) {\n while (this.index < end) this.copyCurrent();\n if (this.peek() === \"\\n\") this.copyCurrent();\n return;\n }\n if (escapeBody) this.escapedHeredocLine();\n else this.heredocLine(heredoc.quoted);\n }\n }\n\n /** A former quoted-heredoc line: literal text escaped, references expanded. */\n private escapedHeredocLine(): void {\n while (this.index < this.items.length) {\n const item = this.peek()!;\n this.index += 1;\n if (isReference(item)) {\n this.out += `\\${${this.env(item)}}`;\n continue;\n }\n this.out += item === \"\\\\\" || item === \"$\" || item === \"`\" ? `\\\\${item}` : item;\n if (item === \"\\n\") return;\n }\n }\n\n /** One body line (through its newline). */\n private heredocLine(quoted: boolean): void {\n while (this.index < this.items.length) {\n const item = this.peek()!;\n if (isReference(item)) {\n // A quoted body with references was rewritten by heredocBody; here\n // only an unquoted body can hold one.\n this.out += `\\${${this.env(item)}}`;\n this.index += 1;\n continue;\n }\n if (!quoted) {\n if (item === \"\\\\\") {\n this.copyCurrent();\n if (this.index < this.items.length && !isReference(this.peek())) this.copyCurrent();\n continue;\n }\n if (item === \"$\") {\n this.rejectDollarBeforeReference();\n if (this.dollarParen()) continue;\n }\n if (item === \"`\") {\n this.copyCurrent();\n this.command(\"`\", false);\n if (this.peek() === \"`\") this.copyCurrent();\n continue;\n }\n }\n this.copyCurrent();\n if (item === \"\\n\") return;\n }\n }\n}\n","/**\n * The splice scanners walk one virtual stream in which literal text is split\n * into characters (code points) and each secret reference is one opaque item.\n * References never take part in shell lexing: the scanner only asks \"which\n * lexical context am I in?\" when it meets one.\n */\nimport { referenceKey, type SecretReference, type SecretTextToken } from \"@opengeni/contracts\";\n\nexport type StreamItem = string | SecretReference;\n\nexport function isReference(item: StreamItem | undefined): item is SecretReference {\n return typeof item === \"object\" && item !== null;\n}\n\n/** Literal text keeps escapes removed by the tokenizer; invalid candidates stay verbatim. */\nexport function streamFromTokens(tokens: readonly SecretTextToken[]): StreamItem[] {\n const items: StreamItem[] = [];\n for (const token of tokens) {\n if (token.type === \"reference\") {\n items.push(token.reference);\n continue;\n }\n const text = token.type === \"text\" ? token.value : token.raw;\n for (const character of text) items.push(character);\n }\n return items;\n}\n\nexport interface SpliceBinding {\n envName: string;\n key: string;\n literal: boolean;\n sentinel: string | null;\n}\n\n/**\n * Allocates one env binding per distinct reference (deduplicated by\n * `referenceKey`). Every context is spliced as an expansion, so bindings are\n * never literal; `literal`/`sentinel` remain in the contract for adapters.\n */\nexport class BindingTable {\n readonly bindings: SpliceBinding[] = [];\n private readonly byKey = new Map<string, SpliceBinding>();\n\n constructor(private readonly envPrefix: string) {}\n\n env(reference: SecretReference): string {\n const key = referenceKey(reference);\n const existing = this.byKey.get(key);\n if (existing) return existing.envName;\n const binding: SpliceBinding = {\n envName: `${this.envPrefix}${this.bindings.length}`,\n key,\n literal: false,\n sentinel: null,\n };\n this.byKey.set(key, binding);\n this.bindings.push(binding);\n return binding.envName;\n }\n}\n","/**\n * PowerShell (Windows PowerShell 5.1 and pwsh 7) splice. References become\n * `${env:V}` expansions; PowerShell never re-parses an expanded value, so the\n * value is inert in every expandable context.\n *\n * | context | emission |\n * |----------------------------------|--------------------------------------------|\n * | unquoted (argument or expression) | `${env:V}` |\n * | `\"…\"` (and curly “ ” „) | `${env:V}` |\n * | `'…'` (and curly ‘ ’ ‚ ‛) | whole string rewritten as `\"…\"` with `` ` ``, `$` and double quotes escaped |\n * | `@\"…\"@` here-string | `${env:V}` |\n * | `@'…'@` here-string | rewritten as `@\"…\"@` with `` ` `` and `$` escaped, then `${env:V}` |\n * | `$( … )` | recurse |\n * | `#` and `<# … #>` comments | reference text kept as written |\n */\nimport { SecretReferenceError, type SecretReference } from \"@opengeni/contracts\";\nimport { BindingTable, isReference, type StreamItem } from \"./stream\";\n\nconst SINGLE_QUOTES = new Set([\"'\", \"\\u2018\", \"\\u2019\", \"\\u201a\", \"\\u201b\"]);\nconst DOUBLE_QUOTES = new Set(['\"', \"\\u201c\", \"\\u201d\", \"\\u201e\"]);\nconst TOKEN_BREAK = new Set([\" \", \"\\t\", \"\\r\", \"\\n\", \";\", \"|\", \"&\", \"(\", \")\", \"{\", \"}\", \",\"]);\n\nexport class PowerShellSplicer {\n private index = 0;\n private out = \"\";\n\n constructor(\n private readonly items: readonly StreamItem[],\n private readonly table: BindingTable,\n ) {}\n\n run(): string {\n this.code(false);\n while (this.index < this.items.length) {\n this.copyCurrent();\n this.code(false);\n }\n return this.out;\n }\n\n private peek(offset = 0): StreamItem | undefined {\n return this.items[this.index + offset];\n }\n\n private copyCurrent(): void {\n const item = this.items[this.index];\n this.index += 1;\n if (item === undefined) return;\n this.out += isReference(item) ? item.raw : item;\n }\n\n private expansion(reference: SecretReference): string {\n return `\\${env:${this.table.env(reference)}}`;\n }\n\n /**\n * `--%` passes the rest of the line to the native command verbatim, so an\n * expansion there would arrive as literal text. Refuse references in it.\n */\n private stopParsing(): void {\n while (this.index < this.items.length) {\n const item = this.peek()!;\n if (isReference(item)) {\n throw new SecretReferenceError([\n {\n raw: item.raw,\n code: \"unsupported_shell\",\n message:\n \"secret references cannot follow --% (PowerShell passes that text verbatim); pass the value as a normal argument or with {{secretfile:…}}\",\n },\n ]);\n }\n if (item === \"\\n\" || item === \"|\") return;\n this.copyCurrent();\n }\n }\n\n /** Script code; `nested` stops at the `)` closing a `$(`. */\n private code(nested: boolean): void {\n let depth = 0;\n let tokenStart = true;\n while (this.index < this.items.length) {\n const item = this.peek()!;\n if (isReference(item)) {\n this.out += this.expansion(item);\n this.index += 1;\n tokenStart = false;\n continue;\n }\n if (nested && item === \")\" && depth === 0) return;\n if (item === \"`\") {\n this.copyCurrent();\n if (this.index < this.items.length && !isReference(this.peek())) this.copyCurrent();\n tokenStart = false;\n continue;\n }\n if (tokenStart && item === \"-\" && this.peek(1) === \"-\" && this.peek(2) === \"%\") {\n this.stopParsing();\n tokenStart = true;\n continue;\n }\n if (item === \"<\" && this.peek(1) === \"#\") {\n this.blockComment();\n tokenStart = true;\n continue;\n }\n if (item === \"#\" && tokenStart) {\n while (this.index < this.items.length && this.peek() !== \"\\n\") this.copyCurrent();\n continue;\n }\n if (item === \"@\" && (this.peek(1) === '\"' || this.peek(1) === \"'\")) {\n if (this.hereStringStartsHere()) {\n this.hereString(this.peek(1) === '\"');\n tokenStart = false;\n continue;\n }\n }\n if (SINGLE_QUOTES.has(item)) {\n this.singleQuoted();\n tokenStart = false;\n continue;\n }\n if (DOUBLE_QUOTES.has(item)) {\n this.copyCurrent();\n this.doubleQuoted();\n tokenStart = false;\n continue;\n }\n if (item === \"$\" && this.peek(1) === \"(\") {\n this.copyCurrent();\n this.copyCurrent();\n this.code(true);\n if (this.peek() === \")\") this.copyCurrent();\n tokenStart = false;\n continue;\n }\n if (item === \"(\") depth += 1;\n if (item === \")\") depth -= 1;\n this.copyCurrent();\n tokenStart = TOKEN_BREAK.has(item);\n }\n }\n\n private blockComment(): void {\n while (this.index < this.items.length) {\n if (this.peek() === \"#\" && this.peek(1) === \">\") {\n this.copyCurrent();\n this.copyCurrent();\n return;\n }\n this.copyCurrent();\n }\n }\n\n /** `@\"` / `@'` opens a here-string only when followed by a newline. */\n private hereStringStartsHere(): boolean {\n let cursor = this.index + 2;\n while (this.items[cursor] === \" \" || this.items[cursor] === \"\\t\") cursor += 1;\n if (this.items[cursor] === \"\\r\") cursor += 1;\n return this.items[cursor] === \"\\n\";\n }\n\n /** True when a reference occurs before the here-string's terminator line. */\n private hereStringHasReference(quote: string): boolean {\n let lineStart = false;\n for (let cursor = this.index + 2; cursor < this.items.length; cursor += 1) {\n const item = this.items[cursor];\n if (isReference(item)) return true;\n if (lineStart && item === quote && this.items[cursor + 1] === \"@\") return false;\n lineStart = item === \"\\n\";\n }\n return false;\n }\n\n private hereString(expandable: boolean): void {\n const quote = expandable ? '\"' : \"'\";\n if (!expandable && this.hereStringHasReference(quote)) {\n this.literalHereStringAsExpandable();\n return;\n }\n this.copyCurrent();\n this.copyCurrent();\n let lineStart = false;\n while (this.index < this.items.length) {\n const item = this.peek()!;\n if (isReference(item)) {\n this.out += this.expansion(item);\n this.index += 1;\n lineStart = false;\n continue;\n }\n if (lineStart && item === quote && this.peek(1) === \"@\") {\n this.copyCurrent();\n this.copyCurrent();\n return;\n }\n if (expandable && item === \"`\") {\n this.copyCurrent();\n if (this.index < this.items.length && !isReference(this.peek())) this.copyCurrent();\n lineStart = false;\n continue;\n }\n if (expandable && item === \"$\" && this.peek(1) === \"(\") {\n this.copyCurrent();\n this.copyCurrent();\n this.code(true);\n if (this.peek() === \")\") this.copyCurrent();\n lineStart = false;\n continue;\n }\n this.copyCurrent();\n lineStart = item === \"\\n\";\n }\n }\n\n /**\n * `@'…'@` keeps its body literal. When it holds a reference, emit it as\n * `@\"…\"@` with every backtick and `$` escaped (and a line-initial `\"`, which\n * could otherwise close the string), so the text is unchanged and the\n * reference becomes an expansion that is never re-parsed.\n */\n private literalHereStringAsExpandable(): void {\n this.index += 2;\n this.out += '@\"';\n let lineStart = false;\n while (this.index < this.items.length) {\n const item = this.peek()!;\n this.index += 1;\n if (isReference(item)) {\n this.out += this.expansion(item);\n lineStart = false;\n continue;\n }\n if (lineStart && item === \"'\" && this.peek() === \"@\") {\n this.index += 1;\n this.out += '\"@';\n return;\n }\n if (item === \"`\" || item === \"$\") this.out += `\\`${item}`;\n else if (lineStart && item === '\"') this.out += '`\"';\n else this.out += item;\n lineStart = item === \"\\n\";\n }\n }\n\n private doubleQuoted(): void {\n while (this.index < this.items.length) {\n const item = this.peek()!;\n if (isReference(item)) {\n this.out += this.expansion(item);\n this.index += 1;\n continue;\n }\n if (item === \"`\") {\n this.copyCurrent();\n if (this.index < this.items.length && !isReference(this.peek())) this.copyCurrent();\n continue;\n }\n if (item === \"$\" && this.peek(1) === \"(\") {\n this.copyCurrent();\n this.copyCurrent();\n this.code(true);\n if (this.peek() === \")\") this.copyCurrent();\n continue;\n }\n if (DOUBLE_QUOTES.has(item)) {\n // A doubled quote is an escaped quote inside the string.\n const next = this.peek(1);\n if (typeof next === \"string\" && DOUBLE_QUOTES.has(next)) {\n this.copyCurrent();\n this.copyCurrent();\n continue;\n }\n this.copyCurrent();\n return;\n }\n this.copyCurrent();\n }\n }\n\n /**\n * A verbatim string cannot expand anything, so a string holding a reference\n * is re-emitted as an equivalent expandable string. Strings without\n * references are copied byte for byte.\n */\n private singleQuoted(): void {\n const start = this.index;\n let cursor = this.index + 1;\n let hasReference = false;\n let closed = false;\n while (cursor < this.items.length) {\n const item = this.items[cursor]!;\n if (isReference(item)) {\n hasReference = true;\n cursor += 1;\n continue;\n }\n if (SINGLE_QUOTES.has(item)) {\n const next = this.items[cursor + 1];\n if (typeof next === \"string\" && SINGLE_QUOTES.has(next)) {\n cursor += 2;\n continue;\n }\n closed = true;\n cursor += 1;\n break;\n }\n cursor += 1;\n }\n if (!hasReference || !closed) {\n while (this.index < cursor) {\n const item = this.peek()!;\n if (isReference(item)) {\n this.out += this.expansion(item);\n this.index += 1;\n } else {\n this.copyCurrent();\n }\n }\n return;\n }\n let rewritten = '\"';\n let position = start + 1;\n const end = cursor - 1;\n while (position < end) {\n const item = this.items[position]!;\n if (isReference(item)) {\n rewritten += this.expansion(item);\n position += 1;\n continue;\n }\n if (SINGLE_QUOTES.has(item)) {\n // Only doubled quotes can appear here: they stand for one quote.\n rewritten += item;\n position += 2;\n continue;\n }\n if (item === \"`\" || item === \"$\" || DOUBLE_QUOTES.has(item)) {\n rewritten += `\\`${item}`;\n position += 1;\n continue;\n }\n rewritten += item;\n position += 1;\n }\n rewritten += '\"';\n this.out += rewritten;\n this.index = cursor;\n }\n}\n"],"mappings":"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","names":["SecretReferenceError","SecretReferenceError","SecretReferenceError","SecretReferenceError"]}
1
+ {"version":3,"sources":["../src/provider-pages.ts","../src/provider-capabilities.ts","../src/remote-provider.ts","../src/splice/index.ts","../src/splice/posix.ts","../src/splice/stream.ts","../src/splice/powershell.ts"],"sourcesContent":["import { VAULT_LIMITS } from \"@opengeni/contracts\";\nimport {\n VaultProviderError,\n type ProviderItemMeta,\n type ProviderPage,\n type ProviderPageRequest,\n type ProviderVault,\n type VaultProvider,\n type VaultProviderContext,\n} from \"./provider\";\n\nexport const PROVIDER_PAGE_SIZE = 100;\nexport const PROVIDER_MAX_PAGES = 100;\n\nfunction incomplete(): never {\n // Do not echo untrusted cursors, item names or response bodies in errors.\n throw new VaultProviderError(\n \"provider_inventory_incomplete\",\n \"The provider inventory could not be read completely. The previous inventory was kept.\",\n );\n}\n\n/**\n * A bounded provider inventory and what it proves (external vaults §8).\n */\nexport interface ProviderInventory<T> {\n items: T[];\n /**\n * Whether the listing also proves which items are absent. It does when it\n * was one response (a single page or a legacy array listing), or when\n * every page carried the same provider snapshot token. Offset or position\n * cursors without a snapshot can skip an existing item that moved across\n * a page boundary while the pages were read (an earlier item was deleted\n * meanwhile), so such a multi-page listing proves only what it contains.\n * Never remove, or report as missing, anything absent from an inventory\n * that is not consistent.\n */\n consistent: boolean;\n}\n\nexport interface ProviderPageTraversal<T> {\n page: (request: ProviderPageRequest) => Promise<ProviderPage<T>>;\n identity: (item: T) => string;\n maxItems: number;\n signal?: AbortSignal;\n}\n\n/**\n * A full traversal or a refusal (`provider_inventory_incomplete`), never a\n * prefix presented as the whole. A caller may remove items absent from it\n * only when it is `consistent`.\n */\nexport async function traverseProviderPages<T>(\n input: ProviderPageTraversal<T>,\n): Promise<ProviderInventory<T>> {\n if (!Number.isSafeInteger(input.maxItems) || input.maxItems < 1 || input.maxItems > 10_000)\n incomplete();\n const items: T[] = [];\n const ids = new Set<string>();\n const cursors = new Set<string>();\n let cursor: string | undefined;\n let snapshot: string | null | undefined;\n for (let count = 0; count < PROVIDER_MAX_PAGES; count++) {\n input.signal?.throwIfAborted();\n const limit = Math.min(PROVIDER_PAGE_SIZE, input.maxItems - items.length);\n if (limit < 1) incomplete();\n const page = await input.page({\n limit,\n ...(cursor !== undefined ? { cursor } : {}),\n ...(snapshot != null ? { snapshot } : {}),\n });\n input.signal?.throwIfAborted();\n if (\n !page ||\n !Array.isArray(page.items) ||\n page.items.length > limit ||\n (page.snapshot !== null &&\n (typeof page.snapshot !== \"string\" ||\n page.snapshot.length === 0 ||\n page.snapshot.length > 1024)) ||\n (page.nextCursor !== null &&\n (typeof page.nextCursor !== \"string\" ||\n page.nextCursor.length === 0 ||\n page.nextCursor.length > 1024))\n )\n incomplete();\n if (snapshot !== undefined && page.snapshot !== snapshot) incomplete();\n snapshot = page.snapshot;\n if (page.freshness && page.freshness.state !== \"current\") incomplete();\n for (const item of page.items) {\n const id = input.identity(item);\n if (typeof id !== \"string\" || id.length === 0 || id.length > 300 || ids.has(id)) incomplete();\n ids.add(id);\n items.push(item);\n }\n // One page is one response; later pages are consistent only under the\n // same snapshot (a changed snapshot was refused above).\n if (page.nextCursor === null) return { items, consistent: count === 0 || snapshot !== null };\n if (items.length >= input.maxItems || cursors.has(page.nextCursor)) incomplete();\n cursors.add(page.nextCursor);\n cursor = page.nextCursor;\n }\n return incomplete();\n}\n\n/**\n * Enumeration: everything a complete bounded traversal listed, or a refusal.\n * It does not say whether absence is proven; use `traverseProviderPages`\n * before removing anything that is not listed.\n */\nexport async function collectProviderPages<T>(input: ProviderPageTraversal<T>): Promise<T[]> {\n return (await traverseProviderPages(input)).items;\n}\n\nfunction validateLegacyInventory<T>(items: T[], identity: (item: T) => string, max: number): T[] {\n if (!Array.isArray(items) || items.length > max) incomplete();\n const ids = new Set<string>();\n for (const item of items) {\n const id = identity(item);\n if (typeof id !== \"string\" || !id || id.length > 300 || ids.has(id)) incomplete();\n ids.add(id);\n }\n return items;\n}\n\n/**\n * The provider's vaults and whether absence is proven. Legacy array\n * providers remain compatible (one response is consistent); new remote\n * providers page natively.\n */\nexport async function readProviderVaultInventory(\n provider: VaultProvider,\n ctx: VaultProviderContext,\n): Promise<ProviderInventory<ProviderVault>> {\n const identity = (vault: ProviderVault) => vault.externalVaultId;\n if (provider.listVaultPage) {\n return traverseProviderPages({\n page: async (page) => {\n const result = await provider.listVaultPage!(ctx, page);\n if (result.freshness) ctx.onFreshness?.(result.freshness);\n return result;\n },\n identity,\n maxItems: VAULT_LIMITS.vaultsPerOwnerScope,\n ...(ctx.signal ? { signal: ctx.signal } : {}),\n });\n }\n ctx.signal?.throwIfAborted();\n const items = await provider.listVaults(ctx);\n ctx.signal?.throwIfAborted();\n return {\n items: validateLegacyInventory(items, identity, VAULT_LIMITS.vaultsPerOwnerScope),\n consistent: true,\n };\n}\n\n/** Enumeration of the provider's vaults (discovery and linking). */\nexport async function listProviderVaults(\n provider: VaultProvider,\n ctx: VaultProviderContext,\n): Promise<ProviderVault[]> {\n return (await readProviderVaultInventory(provider, ctx)).items;\n}\n\n/**\n * A provider vault's item metadata and whether absence is proven: only a\n * consistent inventory may replace a mirror.\n */\nexport async function readProviderItemInventory(\n provider: VaultProvider,\n ctx: VaultProviderContext,\n externalVaultId: string,\n): Promise<ProviderInventory<ProviderItemMeta>> {\n const identity = (item: ProviderItemMeta) => item.externalItemId;\n if (provider.listItemPage) {\n return traverseProviderPages({\n page: async (page) => {\n const result = await provider.listItemPage!(ctx, externalVaultId, page);\n if (result.freshness) ctx.onFreshness?.(result.freshness);\n return result;\n },\n identity,\n maxItems: VAULT_LIMITS.itemsPerVault,\n ...(ctx.signal ? { signal: ctx.signal } : {}),\n });\n }\n ctx.signal?.throwIfAborted();\n const items = await provider.listItems(ctx, externalVaultId);\n ctx.signal?.throwIfAborted();\n return {\n items: validateLegacyInventory(items, identity, VAULT_LIMITS.itemsPerVault),\n consistent: true,\n };\n}\n\n/**\n * Enumeration of a provider vault's item metadata. It does not prove which\n * items are absent; mirror replacement uses `readProviderItemInventory`.\n */\nexport async function listProviderItems(\n provider: VaultProvider,\n ctx: VaultProviderContext,\n externalVaultId: string,\n): Promise<ProviderItemMeta[]> {\n return (await readProviderItemInventory(provider, ctx, externalVaultId)).items;\n}\n","import type { VaultProviderOperations } from \"@opengeni/contracts\";\nimport type { ProviderVault, VaultProviderCapabilities } from \"./provider\";\n\n/** Preserve the published legacy port, while new adapters declare exact operations. */\nexport function providerOperations(\n capabilities: VaultProviderCapabilities,\n vault?: Pick<ProviderVault, \"operations\" | \"writeAccess\">,\n): VaultProviderOperations {\n const base: VaultProviderOperations = capabilities.operations ?? {\n createItemTypes: capabilities.write ? [\"login\", \"api_key\", \"note\"] : [],\n updateItem: capabilities.write,\n removeField: capabilities.write,\n archiveItem: capabilities.write,\n archiveKind: capabilities.write ? \"archive\" : \"none\",\n deleteItem: false,\n restoreItem: false,\n readFiles: capabilities.files,\n writeFiles: false,\n createTotp: capabilities.write && capabilities.totp,\n updateTotp: capabilities.write && capabilities.totp,\n createVault: capabilities.createVault,\n restoreFieldHistory: false,\n };\n const override = vault?.operations;\n // An upstream vault may narrow its adapter's abilities, never widen them.\n const operations: VaultProviderOperations = {\n createItemTypes: base.createItemTypes.filter(\n (type) => type !== \"passkey\" && (!override || override.createItemTypes.includes(type)),\n ),\n updateItem: base.updateItem && (override?.updateItem ?? true),\n removeField: base.removeField && (override?.removeField ?? true),\n archiveItem: base.archiveItem && (override?.archiveItem ?? true),\n archiveKind: base.archiveKind,\n deleteItem: false,\n restoreItem: base.restoreItem && (override?.restoreItem ?? true),\n readFiles: base.readFiles && (override?.readFiles ?? true),\n writeFiles: base.writeFiles && (override?.writeFiles ?? true),\n createTotp: base.createTotp && (override?.createTotp ?? true),\n updateTotp: base.updateTotp && (override?.updateTotp ?? true),\n createVault: base.createVault && (override?.createVault ?? true),\n restoreFieldHistory: base.restoreFieldHistory && (override?.restoreFieldHistory ?? true),\n };\n if (override && override.archiveKind !== base.archiveKind) operations.archiveItem = false;\n if (operations.archiveKind === \"none\") operations.archiveItem = false;\n if (!operations.archiveItem) operations.archiveKind = \"none\";\n operations.removeField &&= operations.updateItem;\n operations.updateTotp &&= operations.updateItem;\n operations.createTotp &&= operations.createItemTypes.length > 0;\n if (vault?.writeAccess !== \"read_only\" && capabilities.write) return operations;\n return {\n ...operations,\n createItemTypes: [],\n updateItem: false,\n removeField: false,\n archiveItem: false,\n archiveKind: \"none\",\n restoreItem: false,\n writeFiles: false,\n createTotp: false,\n updateTotp: false,\n createVault: false,\n restoreFieldHistory: false,\n };\n}\n","/**\n * Generic remote vault provider over the signed `opengeni.vault.v1` protocol.\n *\n * The HTTP transport is injected: the API and worker supply their DNS-pinned,\n * HTTPS-only, no-redirect egress. This adapter only signs exact request\n * bytes, enforces the response byte cap again, verifies the response MAC and\n * strictly parses the operation result. It never retries a mutation: any\n * response that cannot be verified after a write may have been applied and is\n * reported as `provider_outcome_unknown`.\n */\nimport {\n VAULT_LIMITS,\n VAULT_PROVIDER_WIRE_LIMITS,\n VAULT_PROVIDER_WIRE_RESPONSE_SIGNATURE_HEADER,\n VAULT_PROVIDER_WIRE_VERSION,\n VaultProviderWireRequest,\n parseTotpInput,\n parseVaultProviderWireResponse,\n vaultProviderWireResponseKey,\n vaultProviderWireUtf8Bytes,\n type SecretMaterial,\n type VaultProviderFreshness,\n type VaultProviderOperations,\n type VaultProviderWireFreshness,\n type VaultProviderWireItemMeta,\n type VaultProviderWireOperation,\n type VaultProviderWireOperationName,\n type VaultProviderWireResult,\n type VaultProviderWireVault,\n type VaultProviderWireWriteField,\n} from \"@opengeni/contracts\";\nimport {\n OPENGENI_SIGNATURE_HEADER,\n signOpenGeniPayload,\n verifyOpenGeniSignature,\n} from \"@opengeni/contracts/workspace-integration-wire\";\nimport {\n VaultProviderError,\n type ProviderCallOperation,\n type ProviderFieldValue,\n type ProviderItemMeta,\n type ProviderPage,\n type ProviderPageRequest,\n type ProviderVault,\n type ProviderWriteItem,\n type VaultProvider,\n type VaultProviderCapabilities,\n type VaultProviderContext,\n type VaultProviderErrorCode,\n} from \"./provider\";\nimport { collectProviderPages } from \"./provider-pages\";\n\nexport type RemoteVaultProviderKind = \"external\" | \"bitwarden\";\n\n/** Case-insensitive header lookup, satisfied by `Headers`. */\nexport interface RemoteVaultHeaders {\n get(name: string): string | null;\n}\n\nexport interface RemoteVaultHttpRequest {\n url: string;\n method: \"POST\";\n headers: Readonly<Record<string, string>>;\n /** Send exactly these bytes; the signature covers them. */\n body: string;\n /** Hard deadline for connect, send and the complete response body. */\n timeoutMs: number;\n /** Fail instead of reading more response body bytes than this. */\n maxResponseBytes: number;\n signal?: AbortSignal;\n}\n\nexport interface RemoteVaultHttpResponse {\n status: number;\n headers: RemoteVaultHeaders;\n body: string;\n}\n\n/**\n * Bounded HTTP egress for remote vault calls. Implementations must refuse\n * redirects, enforce `timeoutMs` and `maxResponseBytes`, and apply the\n * deployment's endpoint policy (HTTPS, DNS pinning, private-address refusal).\n */\nexport interface RemoteVaultTransport {\n post(request: RemoteVaultHttpRequest): Promise<RemoteVaultHttpResponse>;\n}\n\nexport type RemoteVaultTransportFailure =\n | \"refused\"\n | \"network\"\n | \"timeout\"\n | \"redirect\"\n | \"too_large\"\n | \"aborted\";\n\n/**\n * Transport failure. Set `requestSent: false` only when the transport knows\n * no request bytes left the process (for example a refused DNS policy);\n * otherwise a failed mutation is reported as an unknown outcome.\n */\nexport class RemoteVaultTransportError extends Error {\n readonly failure: RemoteVaultTransportFailure;\n readonly requestSent: boolean;\n constructor(failure: RemoteVaultTransportFailure, requestSent: boolean) {\n super(`remote vault transport failed: ${failure}`);\n this.name = \"RemoteVaultTransportError\";\n this.failure = failure;\n this.requestSent = requestSent;\n }\n}\n\nexport type RemoteVaultFetch = (\n url: string,\n init: {\n method: \"POST\";\n headers: Record<string, string>;\n body: string;\n redirect: \"manual\";\n signal: AbortSignal;\n },\n) => Promise<{\n status: number;\n type?: string;\n headers: RemoteVaultHeaders;\n body: ReadableStream<Uint8Array> | null;\n}>;\n\n/**\n * Adapts a fetch-compatible function (for example the deployment's pinned\n * fetch) to the bounded transport: manual redirects are refused, the whole\n * exchange shares one deadline and the body is read with a byte cap.\n */\nexport function createFetchRemoteVaultTransport(fetchImpl: RemoteVaultFetch): RemoteVaultTransport {\n return {\n async post(request) {\n const controller = new AbortController();\n let failure: RemoteVaultTransportFailure | null = null;\n const timer = setTimeout(() => {\n failure = \"timeout\";\n controller.abort();\n }, request.timeoutMs);\n const onAbort = () => {\n failure ??= \"aborted\";\n controller.abort();\n };\n request.signal?.addEventListener(\"abort\", onAbort, { once: true });\n if (request.signal?.aborted) onAbort();\n try {\n let response: Awaited<ReturnType<RemoteVaultFetch>>;\n try {\n response = await fetchImpl(request.url, {\n method: \"POST\",\n headers: { ...request.headers },\n body: request.body,\n redirect: \"manual\",\n signal: controller.signal,\n });\n } catch {\n throw new RemoteVaultTransportError(failure ?? \"network\", true);\n }\n if (\n response.type === \"opaqueredirect\" ||\n (response.status >= 300 && response.status < 400)\n ) {\n await response.body?.cancel().catch(() => {});\n throw new RemoteVaultTransportError(\"redirect\", true);\n }\n const chunks: Uint8Array[] = [];\n let total = 0;\n const reader = response.body?.getReader();\n if (reader) {\n try {\n for (;;) {\n const { done, value } = await reader.read();\n if (done) break;\n total += value.byteLength;\n if (total > request.maxResponseBytes) {\n await reader.cancel().catch(() => {});\n throw new RemoteVaultTransportError(\"too_large\", true);\n }\n chunks.push(value);\n }\n } catch (error) {\n if (error instanceof RemoteVaultTransportError) throw error;\n throw new RemoteVaultTransportError(failure ?? \"network\", true);\n }\n }\n const bytes = new Uint8Array(total);\n let offset = 0;\n for (const chunk of chunks) {\n bytes.set(chunk, offset);\n offset += chunk.byteLength;\n }\n return {\n status: response.status,\n headers: response.headers,\n body: new TextDecoder(\"utf-8\", { fatal: false }).decode(bytes),\n };\n } finally {\n clearTimeout(timer);\n request.signal?.removeEventListener(\"abort\", onAbort);\n }\n },\n };\n}\n\nexport interface RemoteVaultProviderOptions {\n provider: RemoteVaultProviderKind;\n /** Registered endpoint. HTTPS only unless `allowInsecureHttp` (local/test). */\n endpoint: string;\n /** Per-connection secret; signs requests and derives the response key. */\n signingSecret: string;\n transport: RemoteVaultTransport;\n /** The Opengeni connection id; must match `ctx.connectionId` when both exist. */\n connectionId?: string;\n /**\n * Operations verified by the last describe (stored with the connection), so\n * a fresh instance can answer `capabilities()` without a call. Without it,\n * and before `validate`, the provider is read-only.\n */\n operations?: VaultProviderOperations;\n timeoutMs?: number;\n allowInsecureHttp?: boolean;\n now?: () => number;\n newRequestId?: () => string;\n}\n\nexport interface RemoteVaultValidation {\n accountName: string | null;\n accountId: string;\n operations: VaultProviderOperations;\n capabilities: { totp: boolean; files: boolean };\n}\n\nexport interface RemoteVaultProvider extends VaultProvider {\n readonly id: RemoteVaultProviderKind;\n validate(ctx: VaultProviderContext): Promise<RemoteVaultValidation>;\n listVaultPage(\n ctx: VaultProviderContext,\n page: ProviderPageRequest,\n ): Promise<ProviderPage<ProviderVault>>;\n listItemPage(\n ctx: VaultProviderContext,\n externalVaultId: string,\n page: ProviderPageRequest,\n ): Promise<ProviderPage<ProviderItemMeta>>;\n /** Deliberate upstream refresh. Returns the receiver's freshness. */\n refresh(ctx: VaultProviderContext): Promise<VaultProviderFreshness | null>;\n}\n\n/** Operations a remote connection can never perform through this protocol. */\nexport const REMOTE_VAULT_READ_ONLY_OPERATIONS: VaultProviderOperations = Object.freeze({\n createItemTypes: [],\n updateItem: false,\n removeField: false,\n archiveItem: false,\n archiveKind: \"none\",\n deleteItem: false,\n restoreItem: false,\n readFiles: false,\n writeFiles: false,\n createTotp: false,\n updateTotp: false,\n createVault: false,\n restoreFieldHistory: false,\n}) as VaultProviderOperations;\n\n/** Clamp a described operation set to what the v1 wire can express. */\nexport function remoteVaultOperations(\n operations: VaultProviderOperations,\n): VaultProviderOperations {\n const createItemTypes = operations.createItemTypes.filter(\n (type) => type !== \"passkey\" && type !== \"file\",\n );\n const archiveItem = operations.archiveItem && operations.archiveKind !== \"none\";\n return {\n createItemTypes,\n updateItem: operations.updateItem,\n removeField: operations.removeField && operations.updateItem,\n archiveItem,\n archiveKind: archiveItem ? operations.archiveKind : \"none\",\n deleteItem: false,\n restoreItem: false,\n readFiles: operations.readFiles,\n writeFiles: false,\n createTotp: operations.createTotp && createItemTypes.length > 0,\n updateTotp: operations.updateTotp && operations.updateItem,\n createVault: false,\n restoreFieldHistory: false,\n };\n}\n\nconst SAFE_MESSAGES: Record<VaultProviderErrorCode, string> = {\n provider_auth_invalid: \"The remote vault rejected Opengeni's credentials.\",\n provider_auth_expired: \"The remote vault needs to be reconnected.\",\n provider_rate_limited: \"The remote vault is rate limiting requests. Try again later.\",\n provider_unavailable: \"The remote vault is unavailable.\",\n provider_conflict: \"The item changed in the remote vault. Reload it and try again.\",\n provider_not_found: \"The remote vault item or field was not found.\",\n provider_permission_denied: \"The remote vault does not allow this operation.\",\n provider_locked: \"The remote vault is locked. Unlock it where it runs, then refresh.\",\n provider_inventory_incomplete:\n \"The remote vault inventory could not be read completely. The previous inventory was kept.\",\n provider_outcome_unknown:\n \"The remote vault did not confirm the change. It may or may not have been saved; check the vault before trying again.\",\n};\n\nfunction fail(code: VaultProviderErrorCode, retryAfterMs?: number): never {\n throw new VaultProviderError(code, SAFE_MESSAGES[code], retryAfterMs);\n}\n\nconst UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\n// oxlint-disable-next-line no-control-regex\nconst CONTROL = /[\\u0000-\\u001f\\u007f-\\u009f]/;\n\nfunction validEndpoint(endpoint: string, allowInsecureHttp: boolean): string {\n let url: URL;\n try {\n url = new URL(endpoint);\n } catch {\n return fail(\"provider_unavailable\");\n }\n const schemeOk = url.protocol === \"https:\" || (allowInsecureHttp && url.protocol === \"http:\");\n if (!schemeOk || url.username || url.password || url.hash || endpoint.length > 2_048) {\n fail(\"provider_unavailable\");\n }\n return url.toString();\n}\n\nfunction decodeBase64(base64: string): Uint8Array {\n const binary = atob(base64);\n const bytes = new Uint8Array(binary.length);\n for (let index = 0; index < binary.length; index += 1) bytes[index] = binary.charCodeAt(index);\n return bytes;\n}\n\nfunction retryAfterHeader(headers: RemoteVaultHeaders): number | undefined {\n const value = headers.get(\"retry-after\");\n if (!value || !/^\\d{1,6}$/.test(value.trim())) return undefined;\n return Math.min(Number(value.trim()) * 1000, 86_400_000);\n}\n\nfunction toProviderItem(item: VaultProviderWireItemMeta): ProviderItemMeta {\n return {\n externalItemId: item.externalItemId,\n name: item.name,\n type: item.type,\n websites: [...item.websites],\n fields: item.fields.map((field) => ({\n externalFieldId: field.externalFieldId,\n name: field.name,\n kind: field.kind,\n })),\n version: item.version,\n updatedAt: item.updatedAt,\n };\n}\n\nfunction toProviderVault(vault: VaultProviderWireVault): ProviderVault {\n return {\n externalVaultId: vault.externalVaultId,\n name: vault.name,\n contentVersion: vault.contentVersion,\n itemCount: vault.itemCount,\n writeAccess: vault.writeAccess,\n ...(vault.operations ? { operations: remoteVaultOperations(vault.operations) } : {}),\n };\n}\n\n/**\n * Create a provider for one registered remote connection. Construction\n * validates the endpoint and secret; no request is sent until a method runs.\n */\nexport function createRemoteVaultProvider(\n options: RemoteVaultProviderOptions,\n): RemoteVaultProvider {\n if (options.provider !== \"external\" && options.provider !== \"bitwarden\") {\n fail(\"provider_unavailable\");\n }\n const endpoint = validEndpoint(options.endpoint, options.allowInsecureHttp === true);\n if (\n typeof options.signingSecret !== \"string\" ||\n options.signingSecret.length < 32 ||\n options.signingSecret.length > 4_096\n ) {\n fail(\"provider_auth_invalid\");\n }\n if (options.connectionId !== undefined && !UUID.test(options.connectionId)) {\n fail(\"provider_unavailable\");\n }\n const timeoutMs = Math.min(\n Math.max(Math.trunc(options.timeoutMs ?? VAULT_PROVIDER_WIRE_LIMITS.defaultTimeoutMs), 1_000),\n VAULT_PROVIDER_WIRE_LIMITS.maxTimeoutMs,\n );\n const now = options.now ?? (() => Date.now());\n const newRequestId = options.newRequestId ?? (() => crypto.randomUUID());\n const responseKey = vaultProviderWireResponseKey(options.signingSecret);\n let described: RemoteVaultValidation | null = null;\n\n function currentOperations(): VaultProviderOperations {\n if (described) return described.operations;\n if (options.operations) return remoteVaultOperations(options.operations);\n return REMOTE_VAULT_READ_ONLY_OPERATIONS;\n }\n\n function connectionIdFor(ctx: VaultProviderContext): string {\n const fromCtx = ctx.connectionId;\n if (fromCtx && options.connectionId && fromCtx !== options.connectionId) {\n fail(\"provider_permission_denied\");\n }\n const id = fromCtx ?? options.connectionId;\n if (!id || !UUID.test(id)) fail(\"provider_unavailable\");\n return id.toLowerCase();\n }\n\n function freshnessFrom(wire: VaultProviderWireFreshness | null): VaultProviderFreshness | null {\n if (!wire) return null;\n return {\n state: wire.state,\n lastCheckedAt: new Date(now()).toISOString(),\n sourceSyncedAt: wire.sourceSyncedAt,\n source: wire.source,\n errorCode: wire.errorCode,\n retryAt: wire.retryAt,\n };\n }\n\n async function call<Op extends VaultProviderWireOperationName>(\n ctx: VaultProviderContext,\n budget: ProviderCallOperation,\n operation: Extract<VaultProviderWireOperation, { op: Op }>,\n ): Promise<{ result: VaultProviderWireResult<Op>; freshness: VaultProviderFreshness | null }> {\n const mutation = operation.op === \"write_item\" || operation.op === \"archive_item\";\n // Never send an unauthorized or unattributed request.\n if (!ctx.authority) fail(\"provider_permission_denied\");\n const connectionId = connectionIdFor(ctx);\n ctx.signal?.throwIfAborted();\n ctx.budget.take(budget);\n const requestId = newRequestId();\n const { accountId, workspaceId, subjectId, connectionWorkspaceId } = ctx.authority;\n const parsed = VaultProviderWireRequest.safeParse({\n version: VAULT_PROVIDER_WIRE_VERSION,\n type: \"request\",\n requestId,\n sentAt: new Date(now()).toISOString(),\n provider: options.provider,\n connectionId,\n authority: {\n accountId,\n workspaceId,\n subjectId,\n connectionWorkspaceId,\n ...(ctx.authority.sessionId ? { sessionId: ctx.authority.sessionId } : {}),\n ...(ctx.authority.turnId ? { turnId: ctx.authority.turnId } : {}),\n ...(ctx.authority.attemptId ? { attemptId: ctx.authority.attemptId } : {}),\n ...(ctx.authority.siteId ? { siteId: ctx.authority.siteId } : {}),\n },\n operation,\n });\n // An unrepresentable request is refused locally; nothing was sent.\n if (!parsed.success) fail(\"provider_unavailable\");\n const body = JSON.stringify(parsed.data);\n if (vaultProviderWireUtf8Bytes(body) > VAULT_PROVIDER_WIRE_LIMITS.maxRequestBytes) {\n fail(\"provider_unavailable\");\n }\n const signature = await signOpenGeniPayload(\n options.signingSecret,\n body,\n Math.floor(now() / 1000),\n );\n const unverified = (code: VaultProviderErrorCode, retryAfterMs?: number): never =>\n mutation ? fail(\"provider_outcome_unknown\") : fail(code, retryAfterMs);\n\n let response: RemoteVaultHttpResponse;\n try {\n response = await options.transport.post({\n url: endpoint,\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\",\n accept: \"application/json\",\n [OPENGENI_SIGNATURE_HEADER]: signature,\n },\n body,\n timeoutMs,\n maxResponseBytes: VAULT_PROVIDER_WIRE_LIMITS.maxResponseBytes,\n ...(ctx.signal ? { signal: ctx.signal } : {}),\n });\n } catch (error) {\n if (error instanceof RemoteVaultTransportError && !error.requestSent) {\n fail(\"provider_unavailable\");\n }\n if (mutation) fail(\"provider_outcome_unknown\");\n ctx.signal?.throwIfAborted();\n return fail(\"provider_unavailable\");\n }\n if (\n typeof response?.body !== \"string\" ||\n vaultProviderWireUtf8Bytes(response.body) > VAULT_PROVIDER_WIRE_LIMITS.maxResponseBytes\n ) {\n return unverified(\"provider_unavailable\");\n }\n if (response.status !== 200) {\n // Unsigned status: never trusted as an outcome for a mutation.\n if (response.status === 401 || response.status === 403) {\n return unverified(\"provider_auth_invalid\");\n }\n if (response.status === 429) {\n return unverified(\"provider_rate_limited\", retryAfterHeader(response.headers));\n }\n return unverified(\"provider_unavailable\");\n }\n const verified = await verifyOpenGeniSignature({\n secret: responseKey,\n body: response.body,\n signature: response.headers.get(VAULT_PROVIDER_WIRE_RESPONSE_SIGNATURE_HEADER),\n toleranceSeconds: VAULT_PROVIDER_WIRE_LIMITS.signatureToleranceSeconds,\n nowSeconds: Math.floor(now() / 1000),\n });\n if (!verified) return unverified(\"provider_unavailable\");\n let json: unknown;\n try {\n json = JSON.parse(response.body);\n } catch {\n return unverified(\"provider_unavailable\");\n }\n const envelope = parseVaultProviderWireResponse(json, { requestId, op: operation.op as Op });\n if (!envelope) return unverified(\"provider_unavailable\");\n const freshness = freshnessFrom(envelope.freshness);\n if (!envelope.ok) {\n if (freshness) ctx.onFreshness?.(freshness);\n fail(envelope.error.code, envelope.error.retryAfterMs ?? undefined);\n }\n return { result: envelope.result as VaultProviderWireResult<Op>, freshness };\n }\n\n function readContext(ctx: VaultProviderContext) {\n const epoch = ctx.cacheEpoch;\n const cacheEpoch =\n typeof epoch === \"string\" &&\n epoch.length > 0 &&\n epoch.length <= VAULT_PROVIDER_WIRE_LIMITS.cacheEpochMaxChars &&\n !CONTROL.test(epoch)\n ? epoch\n : null;\n return { forceRefresh: ctx.forceRefresh === true, cacheEpoch };\n }\n\n function wirePage(page: ProviderPageRequest) {\n const limit = Math.trunc(page.limit);\n if (!Number.isSafeInteger(limit) || limit < 1) fail(\"provider_inventory_incomplete\");\n return {\n limit: Math.min(limit, VAULT_PROVIDER_WIRE_LIMITS.pageSizeMax),\n ...(page.cursor !== undefined ? { cursor: page.cursor } : {}),\n ...(page.snapshot !== undefined ? { snapshot: page.snapshot } : {}),\n };\n }\n\n function idempotencyKey(ctx: VaultProviderContext): string {\n const key = ctx.idempotencyKey;\n if (\n typeof key === \"string\" &&\n key.length > 0 &&\n key.length <= VAULT_PROVIDER_WIRE_LIMITS.idempotencyKeyMaxChars &&\n !CONTROL.test(key)\n ) {\n return key;\n }\n return crypto.randomUUID();\n }\n\n const provider: RemoteVaultProvider = {\n id: options.provider,\n\n capabilities(): VaultProviderCapabilities {\n const operations = currentOperations();\n return {\n write:\n operations.createItemTypes.length > 0 || operations.updateItem || operations.archiveItem,\n createVault: false,\n totp: described?.capabilities.totp ?? (operations.createTotp || operations.updateTotp),\n files: operations.readFiles,\n groupGrants: false,\n passkeys: false,\n operations,\n };\n },\n\n async validate(ctx) {\n const { result, freshness } = await call(ctx, \"admin\", { op: \"describe\" });\n if (freshness) ctx.onFreshness?.(freshness);\n const validation: RemoteVaultValidation = {\n accountId: result.accountId,\n accountName: result.accountName,\n operations: remoteVaultOperations(result.operations),\n capabilities: { ...result.capabilities },\n };\n validation.operations.readFiles &&= validation.capabilities.files;\n if (!validation.capabilities.totp) {\n validation.operations.createTotp = false;\n validation.operations.updateTotp = false;\n }\n described = validation;\n return {\n ...validation,\n operations: { ...validation.operations },\n capabilities: { ...validation.capabilities },\n };\n },\n\n async listVaultPage(ctx, page) {\n const request = wirePage(page);\n const { result, freshness } = await call(ctx, \"list\", {\n op: \"list_vaults\",\n page: request,\n ...readContext(ctx),\n });\n if (result.items.length > request.limit) fail(\"provider_inventory_incomplete\");\n return {\n items: result.items.map(toProviderVault),\n nextCursor: result.nextCursor,\n snapshot: result.snapshot,\n ...(freshness ? { freshness } : {}),\n };\n },\n\n async listItemPage(ctx, externalVaultId, page) {\n const request = wirePage(page);\n const { result, freshness } = await call(ctx, \"list\", {\n op: \"list_items\",\n externalVaultId,\n page: request,\n ...readContext(ctx),\n });\n if (result.items.length > request.limit) fail(\"provider_inventory_incomplete\");\n return {\n items: result.items.map(toProviderItem),\n nextCursor: result.nextCursor,\n snapshot: result.snapshot,\n ...(freshness ? { freshness } : {}),\n };\n },\n\n // Compatibility: a complete bounded traversal or a refusal, never a prefix.\n async listVaults(ctx) {\n return collectProviderPages({\n page: async (page) => {\n const result = await provider.listVaultPage(ctx, page);\n if (result.freshness) ctx.onFreshness?.(result.freshness);\n return result;\n },\n identity: (vault) => vault.externalVaultId,\n maxItems: VAULT_LIMITS.vaultsPerOwnerScope,\n ...(ctx.signal ? { signal: ctx.signal } : {}),\n });\n },\n\n async listItems(ctx, externalVaultId) {\n return collectProviderPages({\n page: async (page) => {\n const result = await provider.listItemPage(ctx, externalVaultId, page);\n if (result.freshness) ctx.onFreshness?.(result.freshness);\n return result;\n },\n identity: (item) => item.externalItemId,\n maxItems: VAULT_LIMITS.itemsPerVault,\n ...(ctx.signal ? { signal: ctx.signal } : {}),\n });\n },\n\n async readFields(ctx, externalVaultId, externalItemId, externalFieldIds) {\n if (externalFieldIds.length === 0) return [];\n if (\n externalFieldIds.length > VAULT_PROVIDER_WIRE_LIMITS.readFieldsMax ||\n new Set(externalFieldIds).size !== externalFieldIds.length\n ) {\n fail(\"provider_not_found\");\n }\n const { result, freshness } = await call(ctx, \"read\", {\n op: \"read_fields\",\n externalVaultId,\n externalItemId,\n externalFieldIds: [...externalFieldIds],\n ...readContext(ctx),\n });\n if (freshness) ctx.onFreshness?.(freshness);\n // Exactly the requested ids, each once: never accept unrequested values.\n const byId = new Map(result.fields.map((field) => [field.externalFieldId, field]));\n if (\n result.fields.length !== externalFieldIds.length ||\n externalFieldIds.some((id) => !byId.has(id))\n ) {\n fail(\"provider_unavailable\");\n }\n const values: ProviderFieldValue[] = [];\n for (const externalFieldId of externalFieldIds) {\n const wire = byId.get(externalFieldId)!.value;\n let material: SecretMaterial;\n if (wire.type === \"text\") {\n material = { type: \"text\", value: wire.value };\n } else if (wire.type === \"totp\") {\n try {\n material = { type: \"totp\", params: parseTotpInput(wire.value) };\n } catch {\n return fail(\"provider_unavailable\");\n }\n } else {\n let bytes: Uint8Array;\n try {\n bytes = decodeBase64(wire.base64);\n } catch {\n return fail(\"provider_unavailable\");\n }\n if (bytes.byteLength > VAULT_LIMITS.fileValueMaxBytes) fail(\"provider_unavailable\");\n material = { type: \"bytes\", value: bytes };\n }\n values.push({ externalFieldId, material });\n }\n return values;\n },\n\n async writeItem(ctx, externalVaultId, item: ProviderWriteItem) {\n const operations = currentOperations();\n const update = item.externalItemId !== undefined;\n const type = item.type;\n if (type === \"passkey\") return fail(\"provider_permission_denied\");\n if (update ? !operations.updateItem : !operations.createItemTypes.includes(item.type)) {\n fail(\"provider_permission_denied\");\n }\n if (\n item.fields.some((field) => field.kind === \"file\" && field.value !== undefined) ||\n (update && !operations.removeField && item.fields.some((field) => field.remove)) ||\n (item.fields.some((field) => field.kind === \"totp\" && field.value !== undefined) &&\n !(update ? operations.updateTotp : operations.createTotp))\n ) {\n fail(\"provider_permission_denied\");\n }\n const fields: VaultProviderWireWriteField[] = item.fields.map((field) => ({\n ...(field.externalFieldId !== undefined ? { externalFieldId: field.externalFieldId } : {}),\n name: field.name,\n kind: field.kind,\n ...(field.value !== undefined ? { value: field.value } : {}),\n ...(field.remove ? { remove: true as const } : {}),\n }));\n const { result, freshness } = await call(ctx, \"write\", {\n op: \"write_item\",\n externalVaultId,\n item: {\n ...(update ? { externalItemId: item.externalItemId } : {}),\n ...(item.expectedVersion !== undefined ? { expectedVersion: item.expectedVersion } : {}),\n name: item.name,\n type,\n websites: [...item.websites],\n fields,\n },\n idempotencyKey: idempotencyKey(ctx),\n });\n if (freshness) ctx.onFreshness?.(freshness);\n // A confirmed write that names another item cannot be trusted as this write.\n if (update && result.item.externalItemId !== item.externalItemId) {\n fail(\"provider_outcome_unknown\");\n }\n return toProviderItem(result.item);\n },\n\n async archiveItem(ctx, externalVaultId, externalItemId) {\n if (!currentOperations().archiveItem) fail(\"provider_permission_denied\");\n const { freshness } = await call(ctx, \"write\", {\n op: \"archive_item\",\n externalVaultId,\n externalItemId,\n idempotencyKey: idempotencyKey(ctx),\n });\n if (freshness) ctx.onFreshness?.(freshness);\n },\n\n async refresh(ctx) {\n const { freshness } = await call(ctx, \"admin\", { op: \"refresh\" });\n if (freshness) ctx.onFreshness?.(freshness);\n return freshness;\n },\n };\n return provider;\n}\n","/**\n * Shell splice contract (design §10B.1.4). F1 owns the signatures; W1\n * implements the dialect-aware bodies. Each reference in a command becomes a\n * per-command environment variable (`${OPENGENI_SECRET_<n>}` on POSIX,\n * `${env:OPENGENI_SECRET_<n>}` on PowerShell). Literal bodies (quoted heredocs,\n * `@'…'@` here-strings) are rewritten into their expanding form with the body\n * escaped, so no value is ever placed in command text.\n */\nimport { SecretReferenceError, type SecretTextToken } from \"@opengeni/contracts\";\nimport { PosixSplicer } from \"./posix\";\nimport { PowerShellSplicer } from \"./powershell\";\nimport { BindingTable, streamFromTokens } from \"./stream\";\n\nexport type ShellDialect = \"posix\" | \"powershell\" | \"cmd\" | \"fish\" | \"unknown\";\nexport interface SecretExecBinding {\n /** Environment variable name, e.g. OPENGENI_SECRET_0. */\n envName: string;\n /** `referenceKey(ref)` of the bound reference. */\n key: string;\n /** Always false: every context is spliced as an expansion (no literal fallback). */\n literal: boolean;\n /** Always null (kept for the F1 contract shape). */\n sentinel: string | null;\n}\nexport interface ShellSpliceResult {\n text: string;\n bindings: SecretExecBinding[];\n}\n\nexport const SECRET_EXEC_ENV_PREFIX = \"OPENGENI_SECRET_\";\n\n/**\n * Rewrites `tokens` (from `tokenizeSecretText(text)`) into a command that\n * reads each reference from its own env var, shell-aware (see `posix.ts` and\n * `powershell.ts` for the context tables). Throws\n * `SecretReferenceError(unsupported_shell)` for cmd, fish and unknown shells\n * when the command holds a reference. Escapes are already removed by the\n * tokenizer, so the result is rebuilt from `tokens` and `_text` is unused.\n * Pure: no values are involved.\n */\nexport function spliceShellCommand(\n _text: string,\n dialect: ShellDialect,\n tokens: readonly SecretTextToken[],\n): ShellSpliceResult {\n const references = tokens.filter((token) => token.type === \"reference\");\n const items = streamFromTokens(tokens);\n if (references.length === 0) {\n return { text: items.join(\"\"), bindings: [] };\n }\n if (dialect !== \"posix\" && dialect !== \"powershell\") {\n throw new SecretReferenceError(\n references.map((token) => ({\n raw: token.type === \"reference\" ? token.reference.raw : \"\",\n code: \"unsupported_shell\" as const,\n message:\n dialect === \"cmd\"\n ? 'secret references cannot be used safely in cmd.exe; run the command with shell \"powershell\" instead, or pass the value as a file with {{secretfile:…}}'\n : `secret references are not supported in ${dialect} shells; run the command with shell \"sh\" or \"bash\" (or \"powershell\" on Windows), or pass the value as a file with {{secretfile:…}}`,\n })),\n null,\n );\n }\n const table = new BindingTable(SECRET_EXEC_ENV_PREFIX);\n const text =\n dialect === \"posix\"\n ? new PosixSplicer(items, table).run()\n : new PowerShellSplicer(items, table).run();\n return { text, bindings: table.bindings };\n}\n\n/** Pick the splice dialect for a shell path or name on a given OS. */\nexport function dialectFromShell(\n shell: string | null,\n os: \"linux\" | \"darwin\" | \"windows\" | \"unknown\",\n): ShellDialect {\n if (shell === null || shell.trim() === \"\") {\n if (os === \"windows\") return \"powershell\";\n if (os === \"linux\" || os === \"darwin\") return \"posix\";\n return \"unknown\";\n }\n const base = shell\n .trim()\n .split(/[\\\\/]/)\n .pop()!\n .toLowerCase()\n .replace(/\\.exe$/, \"\");\n if ([\"sh\", \"bash\", \"dash\", \"zsh\", \"ksh\", \"mksh\", \"ash\", \"busybox\"].includes(base)) return \"posix\";\n if (base === \"pwsh\" || base === \"powershell\") return \"powershell\";\n if (base === \"cmd\") return \"cmd\";\n if (base === \"fish\") return \"fish\";\n return \"unknown\";\n}\n","/**\n * POSIX (sh, bash, dash, zsh, ksh) splice. A lexical scanner tracks the quoting\n * context at each reference and emits the variable expansion that yields the\n * value as exactly one word with no further interpretation:\n *\n * | context | emission |\n * |-----------------------------|----------------------------------|\n * | unquoted word | `\"${V}\"` |\n * | double quotes, `$(` in `\"` | `${V}` |\n * | single quotes | `'\"${V}\"'` (close, splice, reopen) |\n * | ANSI-C `$'…'` | `'\"${V}\"$'` |\n * | unquoted heredoc body | `${V}` |\n * | quoted heredoc body | made unquoted, body escaped, `${V}` |\n * | `$( )`, backticks | recurse with the same rules |\n * | comment | reference text kept as written |\n *\n * Nested shells (`bash -c '…'`, `ssh host '…'`, `eval`) re-parse the text the\n * outer shell produced, so a value spliced into their argument is lexed again.\n * The robust idioms pass the value by name instead (`V={{secret:X}} bash -c\n * '… \"$V\" …'`, `printf %s {{secret:X}} | ssh host 'read -r V; …'`); the\n * variables are exported, so inner shells inherit them.\n */\nimport { SecretReferenceError, type SecretReference } from \"@opengeni/contracts\";\nimport { BindingTable, isReference, type StreamItem } from \"./stream\";\n\nconst WORD_BREAK = new Set([\" \", \"\\t\", \"\\n\", \";\", \"&\", \"|\", \"(\", \")\", \"<\", \">\"]);\n\ninterface PendingHeredoc {\n delimiter: string;\n quoted: boolean;\n stripTabs: boolean;\n /** Offsets of the delimiter word as copied into `out`, so a quoted\n * delimiter can be rewritten unquoted once its body is known. */\n wordStart: number;\n wordEnd: number;\n}\n\n/** Reserved words after which a command (and so `case`/`esac`) can follow. */\nconst COMMAND_KEYWORDS = new Set([\n \"then\",\n \"do\",\n \"else\",\n \"elif\",\n \"if\",\n \"while\",\n \"until\",\n \"!\",\n \"{\",\n \"time\",\n]);\n\n/** Delimiters that are a single plain word once unquoted. */\nconst PLAIN_DELIMITER = /^[A-Za-z0-9_][A-Za-z0-9_.-]*$/;\n\ntype Closer = \")\" | \"`\" | null;\n\nexport class PosixSplicer {\n private index = 0;\n private out = \"\";\n private readonly pending: PendingHeredoc[] = [];\n\n constructor(\n private readonly items: readonly StreamItem[],\n private readonly table: BindingTable,\n ) {}\n\n run(): string {\n this.command(null, false);\n // Unbalanced closers at top level are copied verbatim; the shell reports them.\n while (this.index < this.items.length) {\n this.copyCurrent();\n this.command(null, false);\n }\n return this.out;\n }\n\n private peek(offset = 0): StreamItem | undefined {\n return this.items[this.index + offset];\n }\n\n private copyCurrent(): void {\n const item = this.items[this.index];\n this.index += 1;\n if (item === undefined) return;\n this.out += isReference(item) ? item.raw : item;\n }\n\n private env(reference: SecretReference): string {\n return this.table.env(reference);\n }\n\n private unsupported(reference: SecretReference, message: string): never {\n throw new SecretReferenceError([{ raw: reference.raw, code: \"unsupported_shell\", message }]);\n }\n\n /** `$` right before a reference would join the expansion (`$$` is the PID). */\n private rejectDollarBeforeReference(): void {\n const next = this.peek(1);\n if (isReference(next)) {\n this.unsupported(\n next,\n `a secret reference right after \"$\" is ambiguous; quote the \"$\" ('$') or separate it from ${next.raw}`,\n );\n }\n }\n\n /**\n * True when the output so far ends where a command starts: the scope start,\n * after a separator, or after a reserved word that takes a command.\n */\n private atCommandStart(scopeStart: number, cases: number): boolean {\n let cursor = this.out.length - 1;\n while (cursor >= scopeStart && (this.out[cursor] === \" \" || this.out[cursor] === \"\\t\")) {\n cursor -= 1;\n }\n if (cursor < scopeStart) return true;\n const last = this.out[cursor]!;\n if (\";&|\\n(\".includes(last)) return true;\n if (last === \")\") return cases > 0;\n let start = cursor;\n while (start > scopeStart && /[A-Za-z!{]/.test(this.out[start - 1]!)) start -= 1;\n const before = start > scopeStart ? this.out[start - 1]! : \"\\n\";\n return (\n COMMAND_KEYWORDS.has(this.out.slice(start, cursor + 1)) &&\n (WORD_BREAK.has(before) || before === \"\\n\")\n );\n }\n\n /** True when the next items spell `word` as a whole word. */\n private keywordAhead(word: string): boolean {\n for (let offset = 0; offset < word.length; offset += 1) {\n if (this.peek(offset) !== word[offset]) return false;\n }\n const after = this.peek(word.length);\n return after === undefined || (typeof after === \"string\" && WORD_BREAK.has(after));\n }\n\n /**\n * After `$((` or `((` has been copied: arithmetic, copied through its `))`.\n * Arithmetic re-evaluates expanded text (array subscripts run commands), so\n * a value is never spliced there.\n */\n private arithmetic(): void {\n let depth = 0;\n while (this.index < this.items.length) {\n const item = this.peek()!;\n if (isReference(item)) {\n this.unsupported(\n item,\n `secret references cannot be used inside (( )) arithmetic; assign it first (N={{secret:…}}) and use \"$N\"`,\n );\n }\n if (item === \"(\") depth += 1;\n else if (item === \")\") {\n if (depth === 0 && this.peek(1) === \")\") {\n this.copyCurrent();\n this.copyCurrent();\n return;\n }\n depth -= 1;\n }\n this.copyCurrent();\n }\n }\n\n /** At `$`: `$((` arithmetic or `$(` substitution; false when neither. */\n private dollarParen(): boolean {\n if (this.peek(1) !== \"(\") return false;\n this.copyCurrent();\n this.copyCurrent();\n if (this.peek() === \"(\") {\n this.copyCurrent();\n this.arithmetic();\n } else {\n this.substitution();\n }\n return true;\n }\n\n /** A command list: top level, `$( … )` or a backtick substitution. */\n private command(closer: Closer, insideDoubleQuotedBackticks: boolean): void {\n let depth = 0;\n // Open `case … esac` statements: their pattern `)` closes nothing.\n let cases = 0;\n let wordStart = true;\n const scopeStart = this.out.length;\n while (this.index < this.items.length) {\n const item = this.peek()!;\n if (isReference(item)) {\n const name = this.env(item);\n this.out += insideDoubleQuotedBackticks ? `\\\\\"\\${${name}}\\\\\"` : `\"\\${${name}}\"`;\n this.index += 1;\n wordStart = false;\n continue;\n }\n if (\n wordStart &&\n (this.keywordAhead(\"case\") || this.keywordAhead(\"esac\")) &&\n this.atCommandStart(scopeStart, cases)\n ) {\n cases = Math.max(0, cases + (item === \"c\" ? 1 : -1));\n for (let copied = 0; copied < 4; copied += 1) this.copyCurrent();\n wordStart = false;\n continue;\n }\n if (item === \")\" && depth === 0 && cases > 0) {\n this.copyCurrent();\n wordStart = true;\n continue;\n }\n if (closer === \")\" && item === \")\" && depth === 0) return;\n if (closer === \"`\" && item === \"`\") return;\n switch (item) {\n case \"\\\\\": {\n this.copyCurrent();\n if (this.peek() === \"\\n\") {\n this.copyCurrent();\n } else if (this.index < this.items.length) {\n const next = this.peek()!;\n if (isReference(next)) {\n // `\\` before a reference: the backslash escapes nothing useful.\n const name = this.env(next);\n this.out += `\"\\${${name}}\"`;\n this.index += 1;\n } else {\n this.copyCurrent();\n }\n }\n wordStart = false;\n continue;\n }\n case \"'\": {\n this.copyCurrent();\n this.singleQuoted();\n wordStart = false;\n continue;\n }\n case '\"': {\n this.copyCurrent();\n this.doubleQuoted();\n wordStart = false;\n continue;\n }\n case \"$\": {\n this.rejectDollarBeforeReference();\n if (this.peek(1) === \"'\") {\n this.copyCurrent();\n this.copyCurrent();\n this.ansiQuoted();\n } else if (!this.dollarParen()) {\n this.copyCurrent();\n }\n wordStart = false;\n continue;\n }\n case \"`\": {\n this.copyCurrent();\n this.command(\"`\", false);\n if (this.peek() === \"`\") this.copyCurrent();\n wordStart = false;\n continue;\n }\n case \"(\":\n if (wordStart && this.peek(1) === \"(\") {\n // `(( … ))` arithmetic command.\n this.copyCurrent();\n this.copyCurrent();\n this.arithmetic();\n wordStart = false;\n continue;\n }\n depth += 1;\n this.copyCurrent();\n wordStart = true;\n continue;\n case \")\":\n depth -= 1;\n this.copyCurrent();\n wordStart = true;\n continue;\n case \"#\":\n if (wordStart) {\n this.comment();\n continue;\n }\n this.copyCurrent();\n continue;\n case \"<\":\n if (this.peek(1) === \"<\" && this.peek(2) !== \"<\") {\n this.heredocOperator();\n wordStart = true;\n continue;\n }\n if (this.peek(1) === \"<\" && this.peek(2) === \"<\") {\n // Here-string: copy the operator; its word is lexed normally.\n this.copyCurrent();\n this.copyCurrent();\n this.copyCurrent();\n wordStart = true;\n continue;\n }\n this.copyCurrent();\n wordStart = true;\n continue;\n case \"\\n\":\n this.copyCurrent();\n this.heredocBodies();\n wordStart = true;\n continue;\n default:\n this.copyCurrent();\n wordStart = WORD_BREAK.has(item);\n }\n }\n }\n\n /** After `$(` has been copied: the command list, then its `)`. */\n private substitution(): void {\n this.command(\")\", false);\n if (this.peek() === \")\") this.copyCurrent();\n }\n\n private comment(): void {\n while (this.index < this.items.length && this.peek() !== \"\\n\") this.copyCurrent();\n }\n\n private singleQuoted(): void {\n while (this.index < this.items.length) {\n const item = this.peek()!;\n if (isReference(item)) {\n this.out += `'\"\\${${this.env(item)}}\"'`;\n this.index += 1;\n continue;\n }\n this.copyCurrent();\n if (item === \"'\") return;\n }\n }\n\n private ansiQuoted(): void {\n while (this.index < this.items.length) {\n const item = this.peek()!;\n if (isReference(item)) {\n this.out += `'\"\\${${this.env(item)}}\"$'`;\n this.index += 1;\n continue;\n }\n this.copyCurrent();\n if (item === \"\\\\\") {\n if (this.index < this.items.length && !isReference(this.peek())) this.copyCurrent();\n continue;\n }\n if (item === \"'\") return;\n }\n }\n\n private doubleQuoted(): void {\n while (this.index < this.items.length) {\n const item = this.peek()!;\n if (isReference(item)) {\n this.out += `\\${${this.env(item)}}`;\n this.index += 1;\n continue;\n }\n if (item === \"\\\\\") {\n this.copyCurrent();\n if (this.index < this.items.length && !isReference(this.peek())) this.copyCurrent();\n continue;\n }\n if (item === \"$\") {\n this.rejectDollarBeforeReference();\n if (this.dollarParen()) continue;\n }\n if (item === \"`\") {\n this.copyCurrent();\n this.command(\"`\", true);\n if (this.peek() === \"`\") this.copyCurrent();\n continue;\n }\n this.copyCurrent();\n if (item === '\"') return;\n }\n }\n\n /** `<<` / `<<-`, optional blanks, then the delimiter word. Copied verbatim. */\n private heredocOperator(): void {\n this.copyCurrent();\n this.copyCurrent();\n let stripTabs = false;\n if (this.peek() === \"-\") {\n stripTabs = true;\n this.copyCurrent();\n }\n while (this.peek() === \" \" || this.peek() === \"\\t\") this.copyCurrent();\n const wordStart = this.out.length;\n let delimiter = \"\";\n let quoted = false;\n while (this.index < this.items.length) {\n const item = this.peek()!;\n if (isReference(item)) break;\n if (item === \"'\" || item === '\"') {\n quoted = true;\n const quote = item;\n this.copyCurrent();\n while (this.index < this.items.length && this.peek() !== quote) {\n const inner = this.peek()!;\n if (isReference(inner)) break;\n delimiter += inner;\n this.copyCurrent();\n }\n if (this.peek() === quote) this.copyCurrent();\n continue;\n }\n if (item === \"\\\\\") {\n quoted = true;\n this.copyCurrent();\n const next = this.peek();\n if (typeof next === \"string\") {\n delimiter += next;\n this.copyCurrent();\n }\n continue;\n }\n if (WORD_BREAK.has(item)) break;\n delimiter += item;\n this.copyCurrent();\n }\n if (delimiter.length > 0) {\n this.pending.push({ delimiter, quoted, stripTabs, wordStart, wordEnd: this.out.length });\n }\n }\n\n /** Called right after a newline: consume every queued heredoc body in order. */\n private heredocBodies(): void {\n while (this.pending.length > 0) {\n const heredoc = this.pending.shift()!;\n this.heredocBody(heredoc);\n }\n }\n\n private lineMatchesDelimiter(heredoc: PendingHeredoc): number | null {\n let cursor = this.index;\n let line = \"\";\n while (cursor < this.items.length) {\n const item = this.items[cursor]!;\n if (isReference(item)) return null;\n if (item === \"\\n\") break;\n line += item;\n cursor += 1;\n }\n const candidate = heredoc.stripTabs ? line.replace(/^\\t+/, \"\") : line;\n return candidate === heredoc.delimiter ? cursor : null;\n }\n\n /** True when a reference occurs before the body's delimiter line. */\n private bodyHasReference(heredoc: PendingHeredoc): boolean {\n const saved = this.index;\n try {\n while (this.index < this.items.length) {\n const end = this.lineMatchesDelimiter(heredoc);\n if (end !== null) return false;\n while (this.index < this.items.length) {\n const item = this.items[this.index]!;\n this.index += 1;\n if (isReference(item)) return true;\n if (item === \"\\n\") break;\n }\n }\n return false;\n } finally {\n this.index = saved;\n }\n }\n\n /**\n * A quoted heredoc keeps its body literal, so a value cannot be expanded\n * there. When the body holds a reference, rewrite the delimiter unquoted and\n * escape the body's `\\`, `$` and backquote, which yields the same literal\n * text plus a `${V}` expansion that is never re-parsed.\n */\n private unquoteDelimiter(heredoc: PendingHeredoc): void {\n if (!PLAIN_DELIMITER.test(heredoc.delimiter)) {\n throw new SecretReferenceError([\n {\n raw: \"\",\n code: \"unsupported_shell\",\n message: `secret references cannot be used inside a quoted heredoc whose delimiter is not a plain word (${JSON.stringify(heredoc.delimiter)}); use a plain delimiter such as <<'EOF', an unquoted heredoc, or {{secretfile:…}}`,\n },\n ]);\n }\n const delta = heredoc.delimiter.length - (heredoc.wordEnd - heredoc.wordStart);\n this.out =\n this.out.slice(0, heredoc.wordStart) + heredoc.delimiter + this.out.slice(heredoc.wordEnd);\n for (const later of this.pending) {\n later.wordStart += delta;\n later.wordEnd += delta;\n }\n }\n\n private heredocBody(heredoc: PendingHeredoc): void {\n let escapeBody = false;\n if (heredoc.quoted && this.bodyHasReference(heredoc)) {\n this.unquoteDelimiter(heredoc);\n escapeBody = true;\n }\n while (this.index < this.items.length) {\n const end = this.lineMatchesDelimiter(heredoc);\n if (end !== null) {\n while (this.index < end) this.copyCurrent();\n if (this.peek() === \"\\n\") this.copyCurrent();\n return;\n }\n if (escapeBody) this.escapedHeredocLine();\n else this.heredocLine(heredoc.quoted);\n }\n }\n\n /** A former quoted-heredoc line: literal text escaped, references expanded. */\n private escapedHeredocLine(): void {\n while (this.index < this.items.length) {\n const item = this.peek()!;\n this.index += 1;\n if (isReference(item)) {\n this.out += `\\${${this.env(item)}}`;\n continue;\n }\n this.out += item === \"\\\\\" || item === \"$\" || item === \"`\" ? `\\\\${item}` : item;\n if (item === \"\\n\") return;\n }\n }\n\n /** One body line (through its newline). */\n private heredocLine(quoted: boolean): void {\n while (this.index < this.items.length) {\n const item = this.peek()!;\n if (isReference(item)) {\n // A quoted body with references was rewritten by heredocBody; here\n // only an unquoted body can hold one.\n this.out += `\\${${this.env(item)}}`;\n this.index += 1;\n continue;\n }\n if (!quoted) {\n if (item === \"\\\\\") {\n this.copyCurrent();\n if (this.index < this.items.length && !isReference(this.peek())) this.copyCurrent();\n continue;\n }\n if (item === \"$\") {\n this.rejectDollarBeforeReference();\n if (this.dollarParen()) continue;\n }\n if (item === \"`\") {\n this.copyCurrent();\n this.command(\"`\", false);\n if (this.peek() === \"`\") this.copyCurrent();\n continue;\n }\n }\n this.copyCurrent();\n if (item === \"\\n\") return;\n }\n }\n}\n","/**\n * The splice scanners walk one virtual stream in which literal text is split\n * into characters (code points) and each secret reference is one opaque item.\n * References never take part in shell lexing: the scanner only asks \"which\n * lexical context am I in?\" when it meets one.\n */\nimport { referenceKey, type SecretReference, type SecretTextToken } from \"@opengeni/contracts\";\n\nexport type StreamItem = string | SecretReference;\n\nexport function isReference(item: StreamItem | undefined): item is SecretReference {\n return typeof item === \"object\" && item !== null;\n}\n\n/** Literal text keeps escapes removed by the tokenizer; invalid candidates stay verbatim. */\nexport function streamFromTokens(tokens: readonly SecretTextToken[]): StreamItem[] {\n const items: StreamItem[] = [];\n for (const token of tokens) {\n if (token.type === \"reference\") {\n items.push(token.reference);\n continue;\n }\n const text = token.type === \"text\" ? token.value : token.raw;\n for (const character of text) items.push(character);\n }\n return items;\n}\n\nexport interface SpliceBinding {\n envName: string;\n key: string;\n literal: boolean;\n sentinel: string | null;\n}\n\n/**\n * Allocates one env binding per distinct reference (deduplicated by\n * `referenceKey`). Every context is spliced as an expansion, so bindings are\n * never literal; `literal`/`sentinel` remain in the contract for adapters.\n */\nexport class BindingTable {\n readonly bindings: SpliceBinding[] = [];\n private readonly byKey = new Map<string, SpliceBinding>();\n\n constructor(private readonly envPrefix: string) {}\n\n env(reference: SecretReference): string {\n const key = referenceKey(reference);\n const existing = this.byKey.get(key);\n if (existing) return existing.envName;\n const binding: SpliceBinding = {\n envName: `${this.envPrefix}${this.bindings.length}`,\n key,\n literal: false,\n sentinel: null,\n };\n this.byKey.set(key, binding);\n this.bindings.push(binding);\n return binding.envName;\n }\n}\n","/**\n * PowerShell (Windows PowerShell 5.1 and pwsh 7) splice. References become\n * `${env:V}` expansions; PowerShell never re-parses an expanded value, so the\n * value is inert in every expandable context.\n *\n * | context | emission |\n * |----------------------------------|--------------------------------------------|\n * | unquoted (argument or expression) | `${env:V}` |\n * | `\"…\"` (and curly “ ” „) | `${env:V}` |\n * | `'…'` (and curly ‘ ’ ‚ ‛) | whole string rewritten as `\"…\"` with `` ` ``, `$` and double quotes escaped |\n * | `@\"…\"@` here-string | `${env:V}` |\n * | `@'…'@` here-string | rewritten as `@\"…\"@` with `` ` `` and `$` escaped, then `${env:V}` |\n * | `$( … )` | recurse |\n * | `#` and `<# … #>` comments | reference text kept as written |\n */\nimport { SecretReferenceError, type SecretReference } from \"@opengeni/contracts\";\nimport { BindingTable, isReference, type StreamItem } from \"./stream\";\n\nconst SINGLE_QUOTES = new Set([\"'\", \"\\u2018\", \"\\u2019\", \"\\u201a\", \"\\u201b\"]);\nconst DOUBLE_QUOTES = new Set(['\"', \"\\u201c\", \"\\u201d\", \"\\u201e\"]);\nconst TOKEN_BREAK = new Set([\" \", \"\\t\", \"\\r\", \"\\n\", \";\", \"|\", \"&\", \"(\", \")\", \"{\", \"}\", \",\"]);\n\nexport class PowerShellSplicer {\n private index = 0;\n private out = \"\";\n\n constructor(\n private readonly items: readonly StreamItem[],\n private readonly table: BindingTable,\n ) {}\n\n run(): string {\n this.code(false);\n while (this.index < this.items.length) {\n this.copyCurrent();\n this.code(false);\n }\n return this.out;\n }\n\n private peek(offset = 0): StreamItem | undefined {\n return this.items[this.index + offset];\n }\n\n private copyCurrent(): void {\n const item = this.items[this.index];\n this.index += 1;\n if (item === undefined) return;\n this.out += isReference(item) ? item.raw : item;\n }\n\n private expansion(reference: SecretReference): string {\n return `\\${env:${this.table.env(reference)}}`;\n }\n\n /**\n * `--%` passes the rest of the line to the native command verbatim, so an\n * expansion there would arrive as literal text. Refuse references in it.\n */\n private stopParsing(): void {\n while (this.index < this.items.length) {\n const item = this.peek()!;\n if (isReference(item)) {\n throw new SecretReferenceError([\n {\n raw: item.raw,\n code: \"unsupported_shell\",\n message:\n \"secret references cannot follow --% (PowerShell passes that text verbatim); pass the value as a normal argument or with {{secretfile:…}}\",\n },\n ]);\n }\n if (item === \"\\n\" || item === \"|\") return;\n this.copyCurrent();\n }\n }\n\n /** Script code; `nested` stops at the `)` closing a `$(`. */\n private code(nested: boolean): void {\n let depth = 0;\n let tokenStart = true;\n while (this.index < this.items.length) {\n const item = this.peek()!;\n if (isReference(item)) {\n this.out += this.expansion(item);\n this.index += 1;\n tokenStart = false;\n continue;\n }\n if (nested && item === \")\" && depth === 0) return;\n if (item === \"`\") {\n this.copyCurrent();\n if (this.index < this.items.length && !isReference(this.peek())) this.copyCurrent();\n tokenStart = false;\n continue;\n }\n if (tokenStart && item === \"-\" && this.peek(1) === \"-\" && this.peek(2) === \"%\") {\n this.stopParsing();\n tokenStart = true;\n continue;\n }\n if (item === \"<\" && this.peek(1) === \"#\") {\n this.blockComment();\n tokenStart = true;\n continue;\n }\n if (item === \"#\" && tokenStart) {\n while (this.index < this.items.length && this.peek() !== \"\\n\") this.copyCurrent();\n continue;\n }\n if (item === \"@\" && (this.peek(1) === '\"' || this.peek(1) === \"'\")) {\n if (this.hereStringStartsHere()) {\n this.hereString(this.peek(1) === '\"');\n tokenStart = false;\n continue;\n }\n }\n if (SINGLE_QUOTES.has(item)) {\n this.singleQuoted();\n tokenStart = false;\n continue;\n }\n if (DOUBLE_QUOTES.has(item)) {\n this.copyCurrent();\n this.doubleQuoted();\n tokenStart = false;\n continue;\n }\n if (item === \"$\" && this.peek(1) === \"(\") {\n this.copyCurrent();\n this.copyCurrent();\n this.code(true);\n if (this.peek() === \")\") this.copyCurrent();\n tokenStart = false;\n continue;\n }\n if (item === \"(\") depth += 1;\n if (item === \")\") depth -= 1;\n this.copyCurrent();\n tokenStart = TOKEN_BREAK.has(item);\n }\n }\n\n private blockComment(): void {\n while (this.index < this.items.length) {\n if (this.peek() === \"#\" && this.peek(1) === \">\") {\n this.copyCurrent();\n this.copyCurrent();\n return;\n }\n this.copyCurrent();\n }\n }\n\n /** `@\"` / `@'` opens a here-string only when followed by a newline. */\n private hereStringStartsHere(): boolean {\n let cursor = this.index + 2;\n while (this.items[cursor] === \" \" || this.items[cursor] === \"\\t\") cursor += 1;\n if (this.items[cursor] === \"\\r\") cursor += 1;\n return this.items[cursor] === \"\\n\";\n }\n\n /** True when a reference occurs before the here-string's terminator line. */\n private hereStringHasReference(quote: string): boolean {\n let lineStart = false;\n for (let cursor = this.index + 2; cursor < this.items.length; cursor += 1) {\n const item = this.items[cursor];\n if (isReference(item)) return true;\n if (lineStart && item === quote && this.items[cursor + 1] === \"@\") return false;\n lineStart = item === \"\\n\";\n }\n return false;\n }\n\n private hereString(expandable: boolean): void {\n const quote = expandable ? '\"' : \"'\";\n if (!expandable && this.hereStringHasReference(quote)) {\n this.literalHereStringAsExpandable();\n return;\n }\n this.copyCurrent();\n this.copyCurrent();\n let lineStart = false;\n while (this.index < this.items.length) {\n const item = this.peek()!;\n if (isReference(item)) {\n this.out += this.expansion(item);\n this.index += 1;\n lineStart = false;\n continue;\n }\n if (lineStart && item === quote && this.peek(1) === \"@\") {\n this.copyCurrent();\n this.copyCurrent();\n return;\n }\n if (expandable && item === \"`\") {\n this.copyCurrent();\n if (this.index < this.items.length && !isReference(this.peek())) this.copyCurrent();\n lineStart = false;\n continue;\n }\n if (expandable && item === \"$\" && this.peek(1) === \"(\") {\n this.copyCurrent();\n this.copyCurrent();\n this.code(true);\n if (this.peek() === \")\") this.copyCurrent();\n lineStart = false;\n continue;\n }\n this.copyCurrent();\n lineStart = item === \"\\n\";\n }\n }\n\n /**\n * `@'…'@` keeps its body literal. When it holds a reference, emit it as\n * `@\"…\"@` with every backtick and `$` escaped (and a line-initial `\"`, which\n * could otherwise close the string), so the text is unchanged and the\n * reference becomes an expansion that is never re-parsed.\n */\n private literalHereStringAsExpandable(): void {\n this.index += 2;\n this.out += '@\"';\n let lineStart = false;\n while (this.index < this.items.length) {\n const item = this.peek()!;\n this.index += 1;\n if (isReference(item)) {\n this.out += this.expansion(item);\n lineStart = false;\n continue;\n }\n if (lineStart && item === \"'\" && this.peek() === \"@\") {\n this.index += 1;\n this.out += '\"@';\n return;\n }\n if (item === \"`\" || item === \"$\") this.out += `\\`${item}`;\n else if (lineStart && item === '\"') this.out += '`\"';\n else this.out += item;\n lineStart = item === \"\\n\";\n }\n }\n\n private doubleQuoted(): void {\n while (this.index < this.items.length) {\n const item = this.peek()!;\n if (isReference(item)) {\n this.out += this.expansion(item);\n this.index += 1;\n continue;\n }\n if (item === \"`\") {\n this.copyCurrent();\n if (this.index < this.items.length && !isReference(this.peek())) this.copyCurrent();\n continue;\n }\n if (item === \"$\" && this.peek(1) === \"(\") {\n this.copyCurrent();\n this.copyCurrent();\n this.code(true);\n if (this.peek() === \")\") this.copyCurrent();\n continue;\n }\n if (DOUBLE_QUOTES.has(item)) {\n // A doubled quote is an escaped quote inside the string.\n const next = this.peek(1);\n if (typeof next === \"string\" && DOUBLE_QUOTES.has(next)) {\n this.copyCurrent();\n this.copyCurrent();\n continue;\n }\n this.copyCurrent();\n return;\n }\n this.copyCurrent();\n }\n }\n\n /**\n * A verbatim string cannot expand anything, so a string holding a reference\n * is re-emitted as an equivalent expandable string. Strings without\n * references are copied byte for byte.\n */\n private singleQuoted(): void {\n const start = this.index;\n let cursor = this.index + 1;\n let hasReference = false;\n let closed = false;\n while (cursor < this.items.length) {\n const item = this.items[cursor]!;\n if (isReference(item)) {\n hasReference = true;\n cursor += 1;\n continue;\n }\n if (SINGLE_QUOTES.has(item)) {\n const next = this.items[cursor + 1];\n if (typeof next === \"string\" && SINGLE_QUOTES.has(next)) {\n cursor += 2;\n continue;\n }\n closed = true;\n cursor += 1;\n break;\n }\n cursor += 1;\n }\n if (!hasReference || !closed) {\n while (this.index < cursor) {\n const item = this.peek()!;\n if (isReference(item)) {\n this.out += this.expansion(item);\n this.index += 1;\n } else {\n this.copyCurrent();\n }\n }\n return;\n }\n let rewritten = '\"';\n let position = start + 1;\n const end = cursor - 1;\n while (position < end) {\n const item = this.items[position]!;\n if (isReference(item)) {\n rewritten += this.expansion(item);\n position += 1;\n continue;\n }\n if (SINGLE_QUOTES.has(item)) {\n // Only doubled quotes can appear here: they stand for one quote.\n rewritten += item;\n position += 2;\n continue;\n }\n if (item === \"`\" || item === \"$\" || DOUBLE_QUOTES.has(item)) {\n rewritten += `\\`${item}`;\n position += 1;\n continue;\n }\n rewritten += item;\n position += 1;\n }\n rewritten += '\"';\n this.out += rewritten;\n this.index = cursor;\n }\n}\n"],"mappings":"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","names":["VAULT_LIMITS","VAULT_LIMITS","SecretReferenceError","SecretReferenceError","SecretReferenceError","SecretReferenceError"]}
@@ -0,0 +1,4 @@
1
+ import type { VaultProviderOperations } from "@opengeni/contracts";
2
+ import type { ProviderVault, VaultProviderCapabilities } from "./provider.js";
3
+ /** Preserve the published legacy port, while new adapters declare exact operations. */
4
+ export declare function providerOperations(capabilities: VaultProviderCapabilities, vault?: Pick<ProviderVault, "operations" | "writeAccess">): VaultProviderOperations;
@@ -0,0 +1,56 @@
1
+ import { type ProviderItemMeta, type ProviderPage, type ProviderPageRequest, type ProviderVault, type VaultProvider, type VaultProviderContext } from "./provider.js";
2
+ export declare const PROVIDER_PAGE_SIZE = 100;
3
+ export declare const PROVIDER_MAX_PAGES = 100;
4
+ /**
5
+ * A bounded provider inventory and what it proves (external vaults §8).
6
+ */
7
+ export interface ProviderInventory<T> {
8
+ items: T[];
9
+ /**
10
+ * Whether the listing also proves which items are absent. It does when it
11
+ * was one response (a single page or a legacy array listing), or when
12
+ * every page carried the same provider snapshot token. Offset or position
13
+ * cursors without a snapshot can skip an existing item that moved across
14
+ * a page boundary while the pages were read (an earlier item was deleted
15
+ * meanwhile), so such a multi-page listing proves only what it contains.
16
+ * Never remove, or report as missing, anything absent from an inventory
17
+ * that is not consistent.
18
+ */
19
+ consistent: boolean;
20
+ }
21
+ export interface ProviderPageTraversal<T> {
22
+ page: (request: ProviderPageRequest) => Promise<ProviderPage<T>>;
23
+ identity: (item: T) => string;
24
+ maxItems: number;
25
+ signal?: AbortSignal;
26
+ }
27
+ /**
28
+ * A full traversal or a refusal (`provider_inventory_incomplete`), never a
29
+ * prefix presented as the whole. A caller may remove items absent from it
30
+ * only when it is `consistent`.
31
+ */
32
+ export declare function traverseProviderPages<T>(input: ProviderPageTraversal<T>): Promise<ProviderInventory<T>>;
33
+ /**
34
+ * Enumeration: everything a complete bounded traversal listed, or a refusal.
35
+ * It does not say whether absence is proven; use `traverseProviderPages`
36
+ * before removing anything that is not listed.
37
+ */
38
+ export declare function collectProviderPages<T>(input: ProviderPageTraversal<T>): Promise<T[]>;
39
+ /**
40
+ * The provider's vaults and whether absence is proven. Legacy array
41
+ * providers remain compatible (one response is consistent); new remote
42
+ * providers page natively.
43
+ */
44
+ export declare function readProviderVaultInventory(provider: VaultProvider, ctx: VaultProviderContext): Promise<ProviderInventory<ProviderVault>>;
45
+ /** Enumeration of the provider's vaults (discovery and linking). */
46
+ export declare function listProviderVaults(provider: VaultProvider, ctx: VaultProviderContext): Promise<ProviderVault[]>;
47
+ /**
48
+ * A provider vault's item metadata and whether absence is proven: only a
49
+ * consistent inventory may replace a mirror.
50
+ */
51
+ export declare function readProviderItemInventory(provider: VaultProvider, ctx: VaultProviderContext, externalVaultId: string): Promise<ProviderInventory<ProviderItemMeta>>;
52
+ /**
53
+ * Enumeration of a provider vault's item metadata. It does not prove which
54
+ * items are absent; mirror replacement uses `readProviderItemInventory`.
55
+ */
56
+ export declare function listProviderItems(provider: VaultProvider, ctx: VaultProviderContext, externalVaultId: string): Promise<ProviderItemMeta[]>;
@@ -1,4 +1,4 @@
1
- import type { ConnectionCredentialsPort, SecretMaterial, VaultFieldKind, VaultItemType, VaultSource } from "@opengeni/contracts";
1
+ import type { ConnectionCredentialsPort, SecretMaterial, VaultFieldKind, VaultItemType, VaultSource, VaultProviderOperations, VaultProviderFreshness } from "@opengeni/contracts";
2
2
  export interface VaultProviderCapabilities {
3
3
  write: boolean;
4
4
  createVault: boolean;
@@ -7,12 +7,16 @@ export interface VaultProviderCapabilities {
7
7
  groupGrants: boolean;
8
8
  /** Passkeys live only in Opengeni-hosted vaults (D20). */
9
9
  passkeys: false;
10
+ /** Additive: older in-process providers retain the legacy capability flags. */
11
+ operations?: VaultProviderOperations;
10
12
  }
11
13
  export interface ProviderVault {
12
14
  externalVaultId: string;
13
15
  name: string;
14
16
  contentVersion: string | null;
15
17
  itemCount: number | null;
18
+ writeAccess?: "read_only" | "read_write" | "unknown";
19
+ operations?: VaultProviderOperations;
16
20
  }
17
21
  export interface ProviderFieldMeta {
18
22
  externalFieldId: string;
@@ -56,15 +60,63 @@ export interface VaultProviderContext {
56
60
  connectionId: string | null;
57
61
  budget: ProviderCallBudget;
58
62
  signal?: AbortSignal;
63
+ /** Trusted native scope, supplied by the authorized registry, never model arguments. */
64
+ authority?: VaultProviderAuthority;
65
+ /** Last successful mirror-check identity; changes invalidate attempt value caches. */
66
+ cacheEpoch?: string | null;
67
+ /** Recheck upstream, without retrying a mutation or bypassing provider throttling. */
68
+ forceRefresh?: boolean;
69
+ /** Stable caller operation identity when available. No automatic replay is implied. */
70
+ idempotencyKey?: string;
71
+ /** Runtime-only observation; never supplied by an agent or persisted with values. */
72
+ onFreshness?: (freshness: VaultProviderFreshness) => void;
73
+ }
74
+ export interface VaultProviderAuthority {
75
+ accountId: string;
76
+ workspaceId: string;
77
+ subjectId: string | null;
78
+ /** Where the encrypted connection is owned, not a replacement for the calling workspace. */
79
+ connectionWorkspaceId: string;
80
+ sessionId?: string;
81
+ turnId?: string;
82
+ attemptId?: string;
83
+ siteId?: string;
84
+ }
85
+ export interface ProviderPageRequest {
86
+ cursor?: string;
87
+ limit: number;
88
+ snapshot?: string;
89
+ }
90
+ export interface ProviderPage<T> {
91
+ items: T[];
92
+ nextCursor: string | null;
93
+ /**
94
+ * Null only when upstream cannot supply snapshot consistency. A single page
95
+ * needs none, but a multi-page listing without a snapshot proves only what
96
+ * it contains: Opengeni lists it for discovery, yet never replaces a mirror
97
+ * from it (that would drop items skipped while the pages were read). Every
98
+ * page of one listing carries the same snapshot.
99
+ */
100
+ snapshot: string | null;
101
+ freshness?: VaultProviderFreshness;
59
102
  }
60
103
  export interface VaultProvider {
61
- readonly id: "onepassword" | "host" | "fake";
104
+ readonly id: Exclude<VaultSource, "opengeni"> | "fake";
62
105
  capabilities(): VaultProviderCapabilities;
63
106
  validate(ctx: VaultProviderContext): Promise<{
64
107
  accountName: string | null;
108
+ /** Stable identity, when supplied by the upstream account or bridge. */
109
+ accountId?: string;
65
110
  }>;
111
+ /**
112
+ * One complete response, trusted as a consistent inventory. An adapter
113
+ * that pages upstream should implement `listVaultPage`/`listItemPage`, so
114
+ * page consistency is checked, rather than join pages here.
115
+ */
66
116
  listVaults(ctx: VaultProviderContext): Promise<ProviderVault[]>;
67
117
  listItems(ctx: VaultProviderContext, externalVaultId: string): Promise<ProviderItemMeta[]>;
118
+ listVaultPage?(ctx: VaultProviderContext, page: ProviderPageRequest): Promise<ProviderPage<ProviderVault>>;
119
+ listItemPage?(ctx: VaultProviderContext, externalVaultId: string, page: ProviderPageRequest): Promise<ProviderPage<ProviderItemMeta>>;
68
120
  readFields(ctx: VaultProviderContext, externalVaultId: string, externalItemId: string, externalFieldIds: readonly string[]): Promise<ProviderFieldValue[]>;
69
121
  writeItem(ctx: VaultProviderContext, externalVaultId: string, item: ProviderWriteItem): Promise<ProviderItemMeta>;
70
122
  archiveItem(ctx: VaultProviderContext, externalVaultId: string, externalItemId: string): Promise<void>;
@@ -81,7 +133,7 @@ export declare const VAULT_PROVIDER_ERROR_CODES: readonly ["provider_auth_invali
81
133
  * write into a 1Password vault the service account can only read). The vault
82
134
  * service reports `vault_read_only` for writes, `vault_permission_denied` otherwise.
83
135
  */
84
- "provider_permission_denied"];
136
+ "provider_permission_denied", "provider_locked", "provider_inventory_incomplete", "provider_outcome_unknown"];
85
137
  export type VaultProviderErrorCode = (typeof VAULT_PROVIDER_ERROR_CODES)[number];
86
138
  export declare class VaultProviderError extends Error {
87
139
  readonly code: VaultProviderErrorCode;
@@ -113,6 +165,10 @@ export interface VaultProviderRegistry {
113
165
  export declare function createVaultProviderRegistry(factories: {
114
166
  onepassword?: (connectionId: string | null) => Promise<VaultProvider>;
115
167
  host?: () => Promise<VaultProvider>;
168
+ external?: (connectionId: string | null) => Promise<VaultProvider>;
169
+ protonpass?: (connectionId: string | null) => Promise<VaultProvider>;
170
+ keeper?: (connectionId: string | null) => Promise<VaultProvider>;
171
+ bitwarden?: (connectionId: string | null) => Promise<VaultProvider>;
116
172
  }): VaultProviderRegistry;
117
173
  /** A registry with no providers: every provider vault is unavailable. */
118
174
  export declare const EMPTY_VAULT_PROVIDER_REGISTRY: VaultProviderRegistry;