async function tryDownloadResource()

in packages/jsii-pacmak/lib/targets/dotnet/dotnetgenerator.ts [1329:1438]


async function tryDownloadResource(
  urlText: string,
  into: string,
): Promise<string | undefined> {
  const url = new URL(urlText);

  let request: typeof http.get | typeof https.get;
  switch (url.protocol) {
    case 'http:':
      request = http.get;
      break;
    case 'https:':
      request = https.get;
      break;
    default:
      // Unhandled protocol... ignoring
      debug(
        `Unsupported URL protocol for resource download: ${url.protocol} (full URL: ${urlText})`,
      );
      return undefined;
  }

  return new Promise((ok, ko) =>
    request(url, (res) => {
      // eslint-disable-next-line @typescript-eslint/switch-exhaustiveness-check
      switch (res.statusCode) {
        case 200:
          let fileName = path.basename(url.pathname);
          // Ensure there is a content-appropriate extension on the result...
          // eslint-disable-next-line @typescript-eslint/switch-exhaustiveness-check
          switch (res.headers['content-type']) {
            case 'image/gif':
              if (!fileName.endsWith('.gif')) {
                fileName = `${fileName}.gif`;
              }
              break;
            case 'image/jpeg':
              if (!fileName.endsWith('.jpg')) {
                fileName = `${fileName}.jpg`;
              }
              break;
            case 'image/png':
              if (!fileName.endsWith('.png')) {
                fileName = `${fileName}.png`;
              }
              break;
            default:
            // Nothing to do...
          }
          const filePath = path.join('resources', fileName);
          try {
            fs.mkdirpSync(path.join(into, 'resources'));
          } catch (err) {
            // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors
            return ko(err);
          }
          try {
            const fd = fs.openSync(
              path.join(into, filePath),
              fs.constants.O_CREAT |
                fs.constants.O_TRUNC |
                fs.constants.O_WRONLY,
            );
            res
              .once('error', (cause) => {
                try {
                  fs.closeSync(fd);
                } catch {
                  // IGNORE
                }
                ko(cause);
              })
              .on('data', (chunk) => {
                const buff = Buffer.from(chunk);
                let offset = 0;
                while (offset < buff.length) {
                  try {
                    offset += fs.writeSync(fd, buff, offset);
                  } catch (err) {
                    // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors
                    return ko(err);
                  }
                }
              })
              .once('close', () => {
                try {
                  fs.closeSync(fd);
                  ok(filePath);
                } catch (err) {
                  // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors
                  ko(err);
                }
              });
          } catch (err) {
            // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors
            return ko(err);
          }
          break;
        default:
          ko(
            new Error(
              `GET ${urlText} -- HTTP ${res.statusCode ?? 0} (${
                res.statusMessage ?? 'Unknown Error'
              })`,
            ),
          );
      }
    }).once('error', ko),
  );
}