/** * @vitest-environment node */ import { spawnSync } from 'node:child_process' import { hasPython3, PYTHON_SKIP_REASON } from '@sim/testing/environment' import { afterEach, describe, expect, it } from 'vitest' import { analyzeCodePlaceholders, type CodePlaceholderRuntimeBinding, compileCodePlaceholders, } from '@/lib/execution/code-placeholders' import { CodeLanguage } from '@/lib/execution/languages' const installedGlobals = new Set() async function executeJavaScript( code: string, bindings: ReadonlyArray<{ name: string; value: string }>, runtimeBindings: readonly CodePlaceholderRuntimeBinding[] = [] ): Promise { for (const binding of bindings) { Object.defineProperty(globalThis, binding.name, { configurable: true, value: binding.value, writable: true, }) installedGlobals.add(binding.name) } for (const binding of runtimeBindings) { const templateObjects: unknown[] = [] const value = Object.freeze({ RegExp, freeze: Object.freeze.bind(Object), defineProperty: Object.defineProperty.bind(Object), template: (index: number, create: () => unknown) => templateObjects[index] ?? (templateObjects[index] = create()), }) Object.defineProperty(globalThis, binding.name, { configurable: true, value, writable: false, }) installedGlobals.add(binding.name) } return new Function(`return (async () => {\n${code}\n})()`)() } function executeShell( code: string, bindings: ReadonlyArray<{ name: string; value: string }> ): string { const result = spawnSync('/bin/bash', ['-c', code], { encoding: 'utf8', env: { ...process.env, ...Object.fromEntries(bindings.map(({ name, value }) => [name, value])), }, }) if (result.error) throw result.error if (result.status !== 0) throw new Error(result.stderr) return result.stdout } function executePython( code: string, bindings: ReadonlyArray<{ name: string; value: string }> ): string { const prologue = [ 'import os as _sim_test_os', ...bindings.map(({ name }) => `${name} = _sim_test_os.environ[${JSON.stringify(name)}]`), ].join('\n') const result = spawnSync('python3', ['-c', `${prologue}\n${code}`], { encoding: 'utf8', env: { ...process.env, ...Object.fromEntries(bindings.map(({ name, value }) => [name, value])), }, }) if (result.error) throw result.error if (result.status !== 0) throw new Error(result.stderr) return result.stdout } afterEach(() => { for (const name of installedGlobals) Reflect.deleteProperty(globalThis, name) installedGlobals.clear() }) describe('code placeholder compiler', () => { it('preserves bare, quoted, embedded, template, string types, and one-pass JavaScript values', async () => { const value = 'a"\\\n{{OTHER}}' const compiled = await compileCodePlaceholders({ code: [ 'const bare = {{KEY}}', 'const quoted = "{{KEY}}"', 'const embedded = "Bearer {{KEY}}"', 'const template = `Token {{KEY}}`', 'return { bare, quoted, embedded, template, numeric: {{NUM}}, boolean: {{BOOL}} }', ].join('\n'), language: CodeLanguage.JavaScript, environmentVariables: { KEY: value, NUM: '123', BOOL: 'true', OTHER: 'must-not-resolve' }, }) expect(compiled.code).not.toContain(value) expect(compiled.code).not.toContain('__var_') expect(compiled.resolvedSecretNames).toEqual(['KEY', 'NUM', 'BOOL']) await expect( executeJavaScript(compiled.code, compiled.bindings, compiled.runtimeBindings) ).resolves.toEqual({ bare: value, quoted: value, embedded: `Bearer ${value}`, template: `Token ${value}`, numeric: '123', boolean: 'true', }) }) it('compiles JavaScript regex literals without escaping the bound pattern', async () => { const compiled = await compileCodePlaceholders({ code: [ 'const RegExp = null', 'const matcher = /^{{PATTERN}}$/im', 'return [matcher.flags, matcher.test("aZZb")]', ].join('\n'), language: CodeLanguage.JavaScript, environmentVariables: { PATTERN: 'a.+b' }, }) expect(compiled.runtimeBindings).toEqual([ expect.objectContaining({ kind: 'javascript-runtime' }), ]) expect(compiled.code).not.toContain('a.+b') await expect( executeJavaScript(compiled.code, compiled.bindings, compiled.runtimeBindings) ).resolves.toEqual(['im', true]) }) it('captures the JavaScript regex intrinsic before user code mutates its prototype', async () => { const compiled = await compileCodePlaceholders({ code: [ 'const originalConstructor = RegExp.prototype.constructor', 'RegExp.prototype.constructor = null', 'try {', ' return /^{{PATTERN}}$/.test("secret")', '} finally {', ' RegExp.prototype.constructor = originalConstructor', '}', ].join('\n'), language: CodeLanguage.JavaScript, environmentVariables: { PATTERN: 'secret' }, }) await expect( executeJavaScript(compiled.code, compiled.bindings, compiled.runtimeBindings) ).resolves.toBe(true) }) it('rejects resolved placeholders in a static import without exposing the value', async () => { const secret = 'must-not-appear-in-the-diagnostic' const error = await compileCodePlaceholders({ code: 'import value from "{{MODULE}}"', language: CodeLanguage.JavaScript, environmentVariables: { MODULE: secret }, }).catch((caught) => caught) expect(error).toBeInstanceOf(Error) expect(String(error)).toContain('is not supported') expect(String(error)).not.toContain(secret) }) it('preserves tagged-template cooked, raw, substitution, and receiver semantics', async () => { const secret = 'quote"\\\n{{OTHER}}' const compiled = await compileCodePlaceholders({ code: [ 'let calls = 0', 'const receiver = {', ' tag(strings, value) {', ' return {', ' cooked: [...strings],', ' raw: [...strings.raw],', ' value,', ' calls,', ' receiver: this === receiver,', ' frozen: ({}).constructor.isFrozen(strings) && ({}).constructor.isFrozen(strings.raw),', ' }', ' },', '}', 'const Object = null', 'return receiver.tag`line\\n{{KEY}}:$' + '{++calls}:\\x41{{KEY}}`', ].join('\n'), language: CodeLanguage.JavaScript, environmentVariables: { KEY: secret, OTHER: 'must-not-resolve' }, }) expect(compiled.code).not.toContain(secret) await expect( executeJavaScript(compiled.code, compiled.bindings, compiled.runtimeBindings) ).resolves.toEqual({ cooked: [`line\n${secret}:`, `:A${secret}`], raw: [`line\\n${secret}:`, `:\\x41${secret}`], value: 1, calls: 1, receiver: true, frozen: true, }) }) it('round-trips source-sensitive string and tagged-template characters', async () => { const sourceText = `${String.fromCharCode(0x2028, 0x2029)}` const secret = `secret"\\\n${sourceText}` const literalText = `before ${sourceText} {{KEY}} after` const compiled = await compileCodePlaceholders({ code: [ `const quoted = ${JSON.stringify(literalText)}`, 'const tag = (strings) => ({ cooked: strings[0], raw: strings.raw[0] })', `const tagged = tag\`${literalText}\``, 'return { quoted, tagged }', ].join('\n'), language: CodeLanguage.JavaScript, environmentVariables: { KEY: secret }, }) const expected = `before ${sourceText} ${secret} after` expect(compiled.code).toContain('\\u003c/script\\u003e') expect(compiled.code).toContain('\\u2028\\u2029') expect(compiled.code).not.toContain('') expect(compiled.code).not.toContain(String.fromCharCode(0x2028)) expect(compiled.code).not.toContain(String.fromCharCode(0x2029)) expect(compiled.code).not.toContain(secret) await expect( executeJavaScript(compiled.code, compiled.bindings, compiled.runtimeBindings) ).resolves.toEqual({ quoted: expected, tagged: { cooked: expected, raw: expected }, }) }) it('leaves JavaScript comments and missing placeholders untouched', async () => { const code = [ '// {{COMMENT}}', 'const missing = "{{MISSING}}"', 'const mixed = "{{MISSING}}/{{KEY}}"', 'const reverseMixed = "{{KEY}}/{{LONG_MISSING}}"', 'const template = `{{MISSING}}/{{KEY}}`', 'return { key: {{KEY}}, mixed, reverseMixed, template }', ].join('\n') const compiled = await compileCodePlaceholders({ code, language: CodeLanguage.JavaScript, environmentVariables: { COMMENT: 'hidden', KEY: 'ok' }, }) expect(compiled.code).toContain('// {{COMMENT}}') expect(compiled.code).toContain('"{{MISSING}}"') expect(compiled.resolvedSecretNames).toEqual(['KEY']) await expect(executeJavaScript(compiled.code, compiled.bindings)).resolves.toEqual({ key: 'ok', mixed: '{{MISSING}}/ok', reverseMixed: 'ok/{{LONG_MISSING}}', template: '{{MISSING}}/ok', }) }) it('keeps opaque binding names collision-free and applies env-over-param precedence', async () => { const compiled = await compileCodePlaceholders({ code: 'return [{{A-B}}, {{A_B}}, {{__proto__}}]', language: CodeLanguage.JavaScript, params: Object.fromEntries([ ['A-B', 1], ['A_B', false], ['__proto__', 'param'], ]), environmentVariables: Object.fromEntries([ ['A-B', 'env'], ['A_B', 'two'], ['__proto__', 'safe'], ]), reservedNames: ['__sim_code_0_binding_0'], }) expect(new Set(compiled.bindings.map((binding) => binding.name)).size).toBe(3) expect(compiled.bindings.every((binding) => !binding.name.includes('A_B'))).toBe(true) await expect(executeJavaScript(compiled.code, compiled.bindings)).resolves.toEqual([ 'env', 'two', 'safe', ]) }) it('produces identical compiler artifacts for identical inputs', async () => { const input = { code: [ 'const existing = __sim_code_0_binding_0', 'const quoted = "Bearer {{TOKEN}}"', 'const matcher = /^{{PATTERN}}$/i', 'return [existing, quoted, matcher.source, {{MISSING}}]', ].join('\n'), language: CodeLanguage.JavaScript, environmentVariables: { TOKEN: 'secret', PATTERN: 'a.+b' }, reservedNames: ['__sim_code_1_runtime_0'], } as const const first = await compileCodePlaceholders(input) const second = await compileCodePlaceholders(input) expect(second).toEqual(first) }) it('keeps variable-length JavaScript parser sentinels scoped to their own syntax nodes', async () => { const compiled = await compileCodePlaceholders({ code: 'const short = {{A}}; const long = "{{LONGER}}"; return [short, long]', language: CodeLanguage.JavaScript, environmentVariables: { A: 'short-value', LONGER: 'long-value' }, }) await expect(executeJavaScript(compiled.code, compiled.bindings)).resolves.toEqual([ 'short-value', 'long-value', ]) }) it('keeps decoded JavaScript tokens and regex comment syntax collision-free', async () => { const compiled = await compileCodePlaceholders({ code: [ "const \\u005f\\u005fsim_code_0_binding_0 = 'shadow'", 'const slash = /[//]/', 'const tag = (strings) => strings[1]', 'return [\\u005f\\u005fsim_code_0_binding_0, slash.test("/"), tag`head$' + '{1}\\x2400000\\x24{{KEY}}`]', ].join('\n'), language: CodeLanguage.JavaScript, environmentVariables: { KEY: 'secret' }, }) expect(compiled.bindings[0].name).not.toBe('__sim_code_0_binding_0') await expect( executeJavaScript(compiled.code, compiled.bindings, compiled.runtimeBindings) ).resolves.toEqual(['shadow', true, '$00000$secret']) }) it('preserves tagged-template precedence when the tag result is constructed', async () => { const compiled = await compileCodePlaceholders({ code: [ 'function Tag(strings) {', ' if (new.target) throw new Error("tag was constructed")', ' return class Result { constructor() { this.value = strings[0] } }', '}', 'const instance = new Tag`{{KEY}}`', 'return [instance.constructor.name, instance.value]', ].join('\n'), language: CodeLanguage.JavaScript, environmentVariables: { KEY: 'secret' }, }) await expect( executeJavaScript(compiled.code, compiled.bindings, compiled.runtimeBindings) ).resolves.toEqual(['Result', 'secret']) }) it('rejects JavaScript placeholders used as write targets', async () => { for (const code of [ '{{KEY}} = 1', '{{KEY}}++', 'for ({{KEY}} of []) {}', '({ x: {{KEY}} } = { x: 1 })', '[{{KEY}}] = [1]', 'for ({ x: {{KEY}} } of []) {}', '({ {{KEY}} } = {})', ]) { await expect( compileCodePlaceholders({ code, language: CodeLanguage.JavaScript, environmentVariables: { KEY: 'secret' }, }) ).rejects.toThrow('is not supported') } const computedKey = await compileCodePlaceholders({ code: 'let target; ({ [{{KEY}}]: target } = { secret: 7 }); return target', language: CodeLanguage.JavaScript, environmentVariables: { KEY: 'secret' }, }) await expect(executeJavaScript(computedKey.code, computedKey.bindings)).resolves.toBe(7) }) it('uses unshadowable JavaScript bindings in optional access and destructuring keys', async () => { const compiled = await compileCodePlaceholders({ code: [ 'const globalThis = {}', 'const object = { field: 7 }', 'const missing = null', 'const { "{{KEY}}": picked } = object', 'return [{{KEY}}, object?.{{KEY}}, missing?.{{KEY}}, picked]', ].join('\n'), language: CodeLanguage.JavaScript, environmentVariables: { KEY: 'field' }, }) await expect(executeJavaScript(compiled.code, compiled.bindings)).resolves.toEqual([ 'field', 7, undefined, 7, ]) }) it('keeps template interpolation active after an odd source backslash', async () => { const oneBackslash = await compileCodePlaceholders({ code: 'return `\\{{KEY}}`', language: CodeLanguage.JavaScript, environmentVariables: { KEY: 'secret' }, }) const twoBackslashes = await compileCodePlaceholders({ code: 'return `\\\\{{KEY}}`', language: CodeLanguage.JavaScript, environmentVariables: { KEY: 'secret' }, }) await expect(executeJavaScript(oneBackslash.code, oneBackslash.bindings)).resolves.toBe( 'secret' ) await expect(executeJavaScript(twoBackslashes.code, twoBackslashes.bindings)).resolves.toBe( '\\secret' ) expect(oneBackslash.code).not.toContain(`\\\${${oneBackslash.bindings[0].name}}`) }) it('leaves JavaScript shebang placeholders untouched', async () => { const compiled = await compileCodePlaceholders({ code: '#!/usr/bin/env node {{COMMENT}}\nconst value = {{KEY}}', language: CodeLanguage.JavaScript, environmentVariables: { COMMENT: 'hidden', KEY: 'visible-at-runtime-only' }, }) expect(compiled.code).toContain('#!/usr/bin/env node {{COMMENT}}') expect(compiled.code).not.toContain('visible-at-runtime-only') expect(compiled.resolvedSecretNames).toEqual(['KEY']) }) it('rejects malformed JavaScript instead of repairing it during placeholder compilation', async () => { await expect( compileCodePlaceholders({ code: 'return "unterminated {{KEY}}', language: CodeLanguage.JavaScript, environmentVariables: { KEY: 'secret' }, }) ).rejects.toThrow('Invalid JavaScript syntax: Unterminated string literal') const compiled = await compileCodePlaceholders({ code: 'return {{KEY}}', language: CodeLanguage.JavaScript, environmentVariables: { KEY: 'secret' }, }) await expect(executeJavaScript(compiled.code, compiled.bindings)).resolves.toBe('secret') }) it('keeps matching secret names and values out of source in JavaScript and Python', async () => { const javascript = await compileCodePlaceholders({ code: 'return {{Test}}', language: CodeLanguage.JavaScript, environmentVariables: { Test: 'Test' }, }) const python = await compileCodePlaceholders({ code: 'def read():\n return {{Test}}\nprint(read())', language: CodeLanguage.Python, environmentVariables: { Test: 'Test' }, }) expect(javascript.code).not.toContain('Test') expect(python.code).not.toContain('Test') await expect(executeJavaScript(javascript.code, javascript.bindings)).resolves.toBe('Test') expect(executePython(python.code, python.bindings)).toBe('Test\n') }) it('preserves placeholders in Annex B HTML comments and normalizes them for modules', async () => { const compiled = await compileCodePlaceholders({ code: [ ' {{CLOSE_COMMENT}}', 'return [value, matcher.test("