#!/usr/bin/env node /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ const fs = require('node:fs'); const safeCodePattern = /^[A-Z0-9_]{1,64}$/; function findErrorCode(error) { const seen = new Set(); let current = error; while (current && typeof current === 'object' && !seen.has(current)) { seen.add(current); for (const value of [current.code, current.errno]) { if (typeof value === 'string' && safeCodePattern.test(value)) { return value; } } current = current.cause; } return undefined; } function contextAwareFetch(fetchImplementation, emit) { return async (...args) => { try { const response = await Reflect.apply(fetchImplementation, globalThis, args); if (!response.ok) { emit({ kind: 'http', status: response.status }); } return response; } catch (error) { const code = findErrorCode(error); emit(code ? { kind: 'fetch', code } : { kind: 'fetch' }); throw error; } }; } function writeContext(context) { try { fs.writeSync(3, `${JSON.stringify(context)}\n`); } catch { // Context is best-effort. The installer must retain its original failure when fd 3 is unavailable. } } if (require.main === module) { const installer = process.argv[2]; if (!installer) { throw new Error('Electron installer path is required'); } if (typeof globalThis.fetch !== 'function') { throw new Error('This Electron installer requires the built-in Fetch API'); } globalThis.fetch = contextAwareFetch(globalThis.fetch, writeContext); require(installer); } module.exports = { contextAwareFetch, findErrorCode };