@nutrient-sdk/node
Version:
Convert documents in your Node.js apps.
102 lines (90 loc) • 4.28 kB
JavaScript
/*!
* Nutrient for Node.js 1.3.0 (https://www.nutrient.io/nodejs)
*
* Copyright © 2024-2026 PSPDFKit GmbH. All rights reserved.
*
* THIS SOURCE CODE AND ANY ACCOMPANYING DOCUMENTATION ARE PROTECTED BY INTERNATIONAL COPYRIGHT LAW
* AND MAY NOT BE RESOLD OR REDISTRIBUTED. USAGE IS BOUND TO THE PSPDFKIT LICENSE AGREEMENT.
* UNAUTHORIZED REPRODUCTION OR DISTRIBUTION IS SUBJECT TO CIVIL AND CRIMINAL PENALTIES.
* This notice may not be removed from this file.
*
* Nutrient uses several open source third-party components: https://www.nutrient.io/legal/acknowledgements/nodejs-acknowledgements/
*/
let require;
let resources;
const ENVIRONMENT_IS_NODE = typeof globalThis.process?.versions?.node == "string";
const ENVIRONMENT_IS_DENO = (typeof window == "object" && 'Deno' in window) || (typeof self == "object" && 'Deno' in self);
export async function initialize() {
if (ENVIRONMENT_IS_NODE) {
const { createRequire } = await import('module');
// We created a `require` in globalGdPicture passed into `initDotnet` to run on Node. We need
// this function to be synchronous, dynamic imports would require an await, so that's not
// possible.
require = createRequire(import.meta.url);
} else if (ENVIRONMENT_IS_DENO) {
// External modules on Deno are usually imported with an HTTP URL, so we also need to fetch
// resources over the network as well.
// Since the `fetchResources` function must be synchronous and Deno doesn't implement XHR,
// we need to fetch the resources in advance and store them in memory.
const listURL = new URL('./resources/list.json', import.meta.url);
const filenames = await globalThis.fetch(listURL).then(resp => resp.json());
const results = await Promise.all(
filenames.map(filename => {
const fileURL = new URL(`./resources/${filename}`, import.meta.url);
return globalThis.fetch(fileURL).then(async response => {
if (!response.ok) {
// Ignore not found resources.
return undefined;
}
return response.arrayBuffer()
})
.then(buffer => ({
buffer,
filename,
})).catch(() => ({ buffer: undefined, filename }));
})
);
resources = results.reduce((acc, { filename, buffer }) => {
acc[`${globalThis.gdPicture.baseUrl}/resources/${decodeURI(filename)}`] = buffer;
return acc;
}, {});
}
}
// Used for fetching from GdPicture resources package.
export function fetchResource(fetchName, savePath) {
fetch(`${globalThis.gdPicture.baseUrl}/resources/${fetchName}`, savePath)
}
// Used to fetch from any arbitrary URL.
export function fetch(fetchUrl, savePath) {
try {
if (ENVIRONMENT_IS_NODE) {
const fs = require('node:fs');
const path = require('node:path');
const response = fs.readFileSync(path.normalize(fetchUrl));
globalThis.gdPicture.module.FS.writeFile(savePath, new Uint8Array(response));
} else if (ENVIRONMENT_IS_DENO) {
// Get prefetched resource from memory.
globalThis.gdPicture.module.FS.writeFile(savePath, new Uint8Array(resources[fetchUrl]));
} else {
const request = new XMLHttpRequest();
request.open('GET', fetchUrl, false);
request.overrideMimeType('text/plain; charset=x-user-defined');
request.send();
if (request.status === 200) {
globalThis.gdPicture.module.FS.writeFile(savePath, stringToArrayBuffer(request.response));
} else {
console.error(`Could not retrieve resource. Status: ${request.status}`);
}
}
} catch (e) {
console.error(`Could not retrieve resource. Exception: ${e.message}`);
}
}
function stringToArrayBuffer(str) {
const buf = new ArrayBuffer(str.length);
const bufView = new Uint8Array(buf);
for (let i = 0, strLen = str.length; i < strLen; i++) {
bufView[i] = str.charCodeAt(i);
}
return bufView;
}