alef 0.19.9

Opinionated polyglot binding generator for Rust libraries
Documentation
{{ header }}import { spawn } from 'child_process';
import { resolve } from 'path';

let serverProcess;

export async function setup() {
  // Pre-initialize the wasm-bindgen module. Published wasm packages built with
  // wasm-bindgen (non-wasm-pack-nodejs) export a default async `init()` that
  // must be awaited before any wasm export is callable. Without this, the first
  // test that touches a wasm export fails with
  // "Cannot read properties of undefined (reading '__wbindgen_add_to_stack_pointer')".
  // If the module does not export `init` (e.g. a self-initializing wasm-pack
  // --target nodejs CJS bundle), this import resolves to `undefined` and the
  // conditional is a no-op.
  try {
    const wasmModule = await import('{{ pkg_name }}');
    const init = wasmModule.default ?? wasmModule.init;
    if (typeof init === 'function') {
      await init();
    }
  } catch {
    // Module may not export a top-level init — continue anyway.
  }

  // Honor a pre-set MOCK_SERVER_URL: when the test runner (e.g. `alef test-apps
  // run`) has already built and started the shared mock-server, it exports
  // MOCK_SERVER_URL into our environment. In that case, reuse it and skip
  // spawning a local binary entirely. Only self-spawn when it is unset.
  if (process.env.MOCK_SERVER_URL) {
    return;
  }

  // Mock server binary must be pre-built (e.g. by CI or `cargo build --manifest-path e2e/rust/Cargo.toml --bin mock-server --release`)
  serverProcess = spawn(
    resolve(__dirname, '../rust/target/release/mock-server'),
    [resolve(__dirname, '../../fixtures')],
    { stdio: ['pipe', 'pipe', 'inherit'] }
  );

  const url = await new Promise<string>((resolve, reject) => {
    let foundUrl = false;

    serverProcess.stdout.on('data', (data) => {
      const dataStr = data.toString();

      const urlMatch = dataStr.match(/MOCK_SERVER_URL=(.*)/);
      if (urlMatch) {
        process.env.MOCK_SERVER_URL = urlMatch[1].trim();
        foundUrl = true;
      }

      const serversMatch = dataStr.match(/MOCK_SERVERS=({.*})/);
      if (serversMatch) {
        try {
          const servers = JSON.parse(serversMatch[1]);
          for (const [fixtureId, fixtureUrl] of Object.entries(servers)) {
            process.env[`MOCK_SERVER_${fixtureId.toUpperCase()}`] = fixtureUrl as string;
          }
        } catch {
          // Ignore JSON parse errors
        }
      }

      if (foundUrl) resolve(process.env.MOCK_SERVER_URL as string);
    });
    setTimeout(() => reject(new Error('Mock server startup timeout')), 30000);
  });
}

export async function teardown() {
  if (serverProcess) {
    serverProcess.stdin.end();
    serverProcess.kill();
  }
}