All files / src/action pi-ncc-compat.ts

83.33% Statements 15/18
90.9% Branches 10/11
60% Functions 3/5
83.33% Lines 15/18

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70                      1x             3x                                                       3x 3x 2x   1x     3x 3x 3x 3x     3x 3x   3x     3x 1x      
import { setImmediate as waitForImmediate } from 'node:timers/promises';
 
type UnhandledRejectionListener = (reason: unknown) => void;
type PiRuntimeImporter = () => Promise<unknown>;
type PiProviderPreloader = () => Promise<void>;
 
interface UnhandledRejectionTarget {
  prependListener(eventName: 'unhandledRejection', listener: UnhandledRejectionListener): unknown;
  removeListener(eventName: 'unhandledRejection', listener: UnhandledRejectionListener): unknown;
}
 
const NCC_PI_BUILTIN_IMPORT_ERRORS = new Set([
  "Cannot find module 'node:fs'",
  "Cannot find module 'node:os'",
  "Cannot find module 'node:path'",
]);
 
function isNccPiBuiltinImportFailure(reason: unknown): boolean {
  return (
    reason instanceof Error &&
    'code' in reason &&
    reason.code === 'MODULE_NOT_FOUND' &&
    NCC_PI_BUILTIN_IMPORT_ERRORS.has(reason.message)
  );
}
 
async function preloadPiProviderModulesForActionBundle(): Promise<void> {
  const [{ setBedrockProviderModule }, { bedrockProviderModule }] = await Promise.all([
    import('@earendil-works/pi-ai'),
    import('@earendil-works/pi-ai/bedrock-provider'),
    import('@earendil-works/pi-ai/openai-codex-responses'),
  ]);
 
  setBedrockProviderModule(bedrockProviderModule);
}
 
/**
 * Preload Pi before action initialization so ncc's dynamic-import rewrite for
 * Pi's env-key helper and node-only providers cannot terminate the bundled GitHub Action.
 */
export async function preloadPiRuntimeForActionBundle(
  importPiRuntime: PiRuntimeImporter = () => import('../sdk/runtimes/pi.js'),
  unhandledRejections: UnhandledRejectionTarget = process,
  preloadProviders: PiProviderPreloader = preloadPiProviderModulesForActionBundle,
): Promise<void> {
  let unexpectedRejection: unknown;
  const onUnhandledRejection = (reason: unknown) => {
    if (isNccPiBuiltinImportFailure(reason)) {
      return;
    }
    unexpectedRejection = reason;
  };
 
  unhandledRejections.prependListener('unhandledRejection', onUnhandledRejection);
  try {
    await importPiRuntime();
    await preloadProviders();
    // ncc emits the synthetic missing-builtin rejections after Pi module
    // evaluation, so drain two turns before removing the temporary listener.
    await waitForImmediate();
    await waitForImmediate();
  } finally {
    unhandledRejections.removeListener('unhandledRejection', onUnhandledRejection);
  }
 
  if (unexpectedRejection) {
    throw unexpectedRejection;
  }
}