url#pathToFileURL JavaScript Examples

The following examples show how to use url#pathToFileURL. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: index.js    From cs-wiki with GNU General Public License v3.0 6 votes vote down vote up
async function resolvePackageImports({
  importSpecifier,
  importer,
  moduleDirs,
  conditions,
  resolveId
}) {
  const result = await findPackageJson(importer, moduleDirs);
  if (!result) {
    throw new Error(createBaseErrorMsg('. Could not find a parent package.json.'));
  }

  const { pkgPath, pkgJsonPath, pkgJson } = result;
  const pkgURL = pathToFileURL(`${pkgPath}/`);
  const context = {
    importer,
    importSpecifier,
    moduleDirs,
    pkgURL,
    pkgJsonPath,
    conditions,
    resolveId
  };

  const { imports } = pkgJson;
  if (!imports) {
    throw new InvalidModuleSpecifierError(context, true);
  }

  if (importSpecifier === '#' || importSpecifier.startsWith('#/')) {
    throw new InvalidModuleSpecifierError(context, 'Invalid import specifier.');
  }

  return resolvePackageImportsExports(context, {
    matchKey: importSpecifier,
    matchObj: imports,
    internal: true
  });
}
Example #2
Source File: index.test.js    From v8-deopt-viewer with MIT License 6 votes vote down vote up
test("generateV8Log(html-external/index.html)", async (t) => {
	const srcFilePath = repoRoot("examples/html-external/index.html");
	const logContent = await runGenerateV8Log(srcFilePath);

	verifySrcFiles(t, logContent, [
		pathToFileURL(repoRoot("examples/html-external/adders.js")).toString(),
		pathToFileURL(repoRoot("examples/html-external/objects.js")).toString(),
	]);
});
Example #3
Source File: index.test.js    From v8-deopt-viewer with MIT License 6 votes vote down vote up
async function main() {
	const dirContents = await readdir(pkgRoot("test"));
	const testFiles = dirContents.filter(
		(name) => name.endsWith(".test.js") && name !== "index.test.js"
	);

	for (let testFile of testFiles) {
		try {
			await import(pathToFileURL(pkgRoot("test", testFile)).toString());
		} catch (e) {
			console.error(e);
			process.exit(1);
		}
	}
}
Example #4
Source File: main.js    From HinataMd with GNU General Public License v3.0 5 votes vote down vote up
global.__filename = function filename(pathURL = import.meta.url, rmPrefix = platform !== 'win32') { return rmPrefix ? /file:\/\/\//.test(pathURL) ? fileURLToPath(pathURL) : pathURL : pathToFileURL(pathURL).toString() };
Example #5
Source File: index.js    From v8-deopt-viewer with MIT License 5 votes vote down vote up
async function generateForLocalHTML(srcPath, options) {
	const srcUrl = pathToFileURL(makeAbsolute(srcPath)).toString();
	return runPuppeteer(srcUrl, options);
}
Example #6
Source File: index.test.js    From v8-deopt-viewer with MIT License 5 votes vote down vote up
test("generateV8Log(html-inline/adders.html)", async (t) => {
	const srcFilePath = repoRoot("examples/html-inline/adders.html");
	const logContent = await runGenerateV8Log(srcFilePath);

	verifySrcFiles(t, logContent, [pathToFileURL(srcFilePath).toString()]);
});
Example #7
Source File: helpers.js    From v8-deopt-viewer with MIT License 5 votes vote down vote up
repoFileURL = (...args) =>
	pathToFileURL(repoRoot(...args)).toString()
Example #8
Source File: helpers.js    From v8-deopt-viewer with MIT License 5 votes vote down vote up
logPathReplacements = {
	["adders.v8.log"]: [
		[
			"/tmp/v8-deopt-viewer/examples/simple/adders.js",
			repoRoot("examples/simple/adders.js"),
		],
	],
	["adders.traceMaps.v8.log"]: [
		[
			"/tmp/v8-deopt-viewer/examples/simple/adders.js",
			repoRoot("examples/simple/adders.js"),
		],
	],
	["two-modules.v8.log"]: [
		[
			"/tmp/v8-deopt-viewer/examples/two-modules/adders.js",
			repoRoot("examples/two-modules/adders.js"),
		],
		[
			"/tmp/v8-deopt-viewer/examples/two-modules/objects.js",
			repoRoot("examples/two-modules/objects.js"),
		],
	],
	["html-inline.v8.log"]: [
		[
			"file:///tmp/v8-deopt-viewer/examples/html-inline/adders.html",
			pathToFileURL(repoRoot("examples/html-inline/adders.html")).toString(),
		],
	],
	["html-inline.traceMaps.v8.log"]: [
		[
			"file:///tmp/v8-deopt-viewer/examples/html-inline/adders.html",
			pathToFileURL(repoRoot("examples/html-inline/adders.html")).toString(),
		],
	],
	["html-external.v8.log"]: [
		[
			"file:///tmp/v8-deopt-viewer/examples/html-external/adders.js",
			pathToFileURL(repoRoot("examples/html-external/adders.js")).toString(),
		],
		[
			"file:///tmp/v8-deopt-viewer/examples/html-external/objects.js",
			pathToFileURL(repoRoot("examples/html-external/objects.js")).toString(),
		],
	],
	["html-external.traceMaps.v8.log"]: [
		[
			"file:///tmp/v8-deopt-viewer/examples/html-external/adders.js",
			pathToFileURL(repoRoot("examples/html-external/adders.js")).toString(),
		],
		[
			"file:///tmp/v8-deopt-viewer/examples/html-external/objects.js",
			pathToFileURL(repoRoot("examples/html-external/objects.js")).toString(),
		],
	],
}
Example #9
Source File: index.js    From v8-deopt-viewer with MIT License 5 votes vote down vote up
/**
 * @param {string} srcFile
 * @param {import('.').Options} options
 */
export default async function run(srcFile, options) {
	let logFilePath;
	if (srcFile) {
		console.log("Running and generating log...");
		logFilePath = await generateV8Log(srcFile, {
			logFilePath: path.join(options.out, "v8.log"),
			browserTimeoutMs: options.timeout,
			traceMaps: !options["skip-maps"],
		});
	} else if (options.input) {
		logFilePath = path.isAbsolute(options.input)
			? options.input
			: path.join(process.cwd(), options.input);
	} else {
		throw new Error(
			'Either a file/url to generate a log or the "--input" flag pointing to a v8.log must be provided'
		);
	}

	// Ensure output directory exists
	await mkdir(options.out, { recursive: true });

	console.log("Parsing log...");
	const logContents = await readFile(logFilePath, "utf8");

	// New IC format has 10 values instead of 9
	const hasNewIcFormat = /\w+IC(,.*){10}/.test(logContents);
	const rawDeoptInfo = await parseV8Log(logContents, {
		keepInternals: options["keep-internals"],
		hasNewIcFormat,
	});

	console.log("Adding sources...");

	// Group DeoptInfo by files and extend the files data with sources
	const groupDeoptInfo = groupByFile(rawDeoptInfo);
	const deoptInfo = {
		...groupDeoptInfo,
		files: await addSources(groupDeoptInfo.files),
	};

	const deoptInfoString = JSON.stringify(deoptInfo, null, 2);
	const jsContents = `window.V8Data = ${deoptInfoString};`;
	await writeFile(path.join(options.out, "v8-data.js"), jsContents, "utf8");

	console.log("Generating webapp...");
	const template = await readFile(templatePath, "utf8");
	const indexPath = path.join(options.out, "index.html");
	await writeFile(indexPath, template, "utf8");

	// @ts-ignore
	const require = createRequire(import.meta.url);
	const webAppIndexPath = require.resolve("v8-deopt-webapp");
	const webAppStylesPath = webAppIndexPath.replace(/.js$/g, ".css");
	await copyFile(webAppIndexPath, path.join(options.out, "v8-deopt-webapp.js"));
	await copyFile(
		webAppStylesPath,
		path.join(options.out, "v8-deopt-webapp.css")
	);

	if (options.open) {
		await open(pathToFileURL(indexPath).toString(), { url: true });
		console.log(
			`Done! Opening ${path.join(options.out, "index.html")} in your browser...`
		);
	} else {
		console.log(
			`Done! Open ${path.join(options.out, "index.html")} in your browser.`
		);
	}
}
Example #10
Source File: index.js    From cs-wiki with GNU General Public License v3.0 4 votes vote down vote up
async function resolvePackageTarget(context, { target, subpath, pattern, internal }) {
  if (typeof target === 'string') {
    if (!pattern && subpath.length > 0 && !target.endsWith('/')) {
      throw new InvalidModuleSpecifierError(context);
    }

    if (!target.startsWith('./')) {
      if (internal && !['/', '../'].some((p) => target.startsWith(p)) && !isUrl(target)) {
        // this is a bare package import, remap it and resolve it using regular node resolve
        if (pattern) {
          const result = await context.resolveId(
            target.replace(/\*/g, subpath),
            context.pkgURL.href
          );
          return result ? pathToFileURL(result.location) : null;
        }

        const result = await context.resolveId(`${target}${subpath}`, context.pkgURL.href);
        return result ? pathToFileURL(result.location) : null;
      }
      throw new InvalidPackageTargetError(context, `Invalid mapping: "${target}".`);
    }

    if (includesInvalidSegments(target, context.moduleDirs)) {
      throw new InvalidPackageTargetError(context, `Invalid mapping: "${target}".`);
    }

    const resolvedTarget = new URL(target, context.pkgURL);
    if (!resolvedTarget.href.startsWith(context.pkgURL.href)) {
      throw new InvalidPackageTargetError(
        context,
        `Resolved to ${resolvedTarget.href} which is outside package ${context.pkgURL.href}`
      );
    }

    if (includesInvalidSegments(subpath, context.moduleDirs)) {
      throw new InvalidModuleSpecifierError(context);
    }

    if (pattern) {
      return resolvedTarget.href.replace(/\*/g, subpath);
    }
    return new URL(subpath, resolvedTarget).href;
  }

  if (Array.isArray(target)) {
    let lastError;
    for (const item of target) {
      try {
        const resolved = await resolvePackageTarget(context, {
          target: item,
          subpath,
          pattern,
          internal
        });

        // return if defined or null, but not undefined
        if (resolved !== undefined) {
          return resolved;
        }
      } catch (error) {
        if (!(error instanceof InvalidPackageTargetError)) {
          throw error;
        } else {
          lastError = error;
        }
      }
    }

    if (lastError) {
      throw lastError;
    }
    return null;
  }

  if (target && typeof target === 'object') {
    for (const [key, value] of Object.entries(target)) {
      if (key === 'default' || context.conditions.includes(key)) {
        const resolved = await resolvePackageTarget(context, {
          target: value,
          subpath,
          pattern,
          internal
        });

        // return if defined or null, but not undefined
        if (resolved !== undefined) {
          return resolved;
        }
      }
    }
    return undefined;
  }

  if (target === null) {
    return null;
  }

  throw new InvalidPackageTargetError(context, `Invalid exports field.`);
}
Example #11
Source File: index.js    From cs-wiki with GNU General Public License v3.0 4 votes vote down vote up
async function resolveId({
  importer,
  importSpecifier,
  exportConditions,
  warn,
  packageInfoCache,
  extensions,
  mainFields,
  preserveSymlinks,
  useBrowserOverrides,
  baseDir,
  moduleDirectories,
  rootDir,
  ignoreSideEffectsForRoot
}) {
  let hasModuleSideEffects = () => null;
  let hasPackageEntry = true;
  let packageBrowserField = false;
  let packageInfo;

  const filter = (pkg, pkgPath) => {
    const info = getPackageInfo({
      cache: packageInfoCache,
      extensions,
      pkg,
      pkgPath,
      mainFields,
      preserveSymlinks,
      useBrowserOverrides,
      rootDir,
      ignoreSideEffectsForRoot
    });

    ({ packageInfo, hasModuleSideEffects, hasPackageEntry, packageBrowserField } = info);

    return info.cachedPkg;
  };

  const resolveOptions = {
    basedir: baseDir,
    readFile: readCachedFile,
    isFile: isFileCached,
    isDirectory: isDirCached,
    extensions,
    includeCoreModules: false,
    moduleDirectory: moduleDirectories,
    preserveSymlinks,
    packageFilter: filter
  };

  let location;

  const pkgName = getPackageName(importSpecifier);
  if (importSpecifier.startsWith('#')) {
    // this is a package internal import, resolve using package imports field
    const resolveResult = await resolvePackageImports({
      importSpecifier,
      importer,
      moduleDirs: moduleDirectories,
      conditions: exportConditions,
      resolveId(id, parent) {
        return resolveId({
          importSpecifier: id,
          importer: parent,
          exportConditions,
          warn,
          packageInfoCache,
          extensions,
          mainFields,
          preserveSymlinks,
          useBrowserOverrides,
          baseDir,
          moduleDirectories
        });
      }
    });
    location = fileURLToPath(resolveResult);
  } else if (pkgName) {
    // it's a bare import, find the package.json and resolve using package exports if available
    const result = await getPackageJson(importer, pkgName, resolveOptions, moduleDirectories);

    if (result && result.pkgJson.exports) {
      const { pkgJson, pkgJsonPath } = result;
      try {
        const subpath =
          pkgName === importSpecifier ? '.' : `.${importSpecifier.substring(pkgName.length)}`;
        const pkgDr = pkgJsonPath.replace('package.json', '');
        const pkgURL = pathToFileURL(pkgDr);

        const context = {
          importer,
          importSpecifier,
          moduleDirs: moduleDirectories,
          pkgURL,
          pkgJsonPath,
          conditions: exportConditions
        };
        const resolvedPackageExport = await resolvePackageExports(
          context,
          subpath,
          pkgJson.exports
        );
        location = fileURLToPath(resolvedPackageExport);
      } catch (error) {
        if (error instanceof ResolveError) {
          return error;
        }
        throw error;
      }
    }
  }

  if (!location) {
    // package has no imports or exports, use classic node resolve
    try {
      location = await resolveImportPath(importSpecifier, resolveOptions);
    } catch (error) {
      if (error.code !== 'MODULE_NOT_FOUND') {
        throw error;
      }
      return null;
    }
  }

  if (!preserveSymlinks) {
    if (await exists(location)) {
      location = await realpath(location);
    }
  }

  return {
    location,
    hasModuleSideEffects,
    hasPackageEntry,
    packageBrowserField,
    packageInfo
  };
}
Example #12
Source File: prerender.js    From kit with MIT License 4 votes vote down vote up
/**
 * @param {{
 *   config: import('types').ValidatedKitConfig;
 *   entries: string[];
 *   files: Set<string>;
 *   log: Logger;
 * }} opts
 */
export async function prerender({ config, entries, files, log }) {
	/** @type {import('types').Prerendered} */
	const prerendered = {
		pages: new Map(),
		assets: new Map(),
		redirects: new Map(),
		paths: []
	};

	if (!config.prerender.enabled) {
		return prerendered;
	}

	installPolyfills();

	const server_root = join(config.outDir, 'output');

	/** @type {import('types').ServerModule} */
	const { Server, override } = await import(pathToFileURL(`${server_root}/server/index.js`).href);
	const { manifest } = await import(pathToFileURL(`${server_root}/server/manifest.js`).href);

	override({
		paths: config.paths,
		prerendering: true,
		read: (file) => readFileSync(join(config.files.assets, file))
	});

	const server = new Server(manifest);

	const error = normalise_error_handler(log, config.prerender.onError);

	const q = queue(config.prerender.concurrency);

	/**
	 * @param {string} path
	 * @param {boolean} is_html
	 */
	function output_filename(path, is_html) {
		const file = path.slice(config.paths.base.length + 1);

		if (file === '') {
			return 'index.html';
		}

		if (is_html && !file.endsWith('.html')) {
			return file + (file.endsWith('/') ? 'index.html' : '.html');
		}

		return file;
	}

	const seen = new Set();
	const written = new Set();

	/**
	 * @param {string | null} referrer
	 * @param {string} decoded
	 * @param {string} [encoded]
	 */
	function enqueue(referrer, decoded, encoded) {
		if (seen.has(decoded)) return;
		seen.add(decoded);

		const file = decoded.slice(config.paths.base.length + 1);
		if (files.has(file)) return;

		return q.add(() => visit(decoded, encoded || encodeURI(decoded), referrer));
	}

	/**
	 * @param {string} decoded
	 * @param {string} encoded
	 * @param {string?} referrer
	 */
	async function visit(decoded, encoded, referrer) {
		if (!decoded.startsWith(config.paths.base)) {
			error({ status: 404, path: decoded, referrer, referenceType: 'linked' });
			return;
		}

		/** @type {Map<string, import('types').PrerenderDependency>} */
		const dependencies = new Map();

		const response = await server.respond(new Request(`http://sveltekit-prerender${encoded}`), {
			getClientAddress,
			prerendering: {
				dependencies
			}
		});

		const text = await response.text();

		save('pages', response, text, decoded, encoded, referrer, 'linked');

		for (const [dependency_path, result] of dependencies) {
			// this seems circuitous, but using new URL allows us to not care
			// whether dependency_path is encoded or not
			const encoded_dependency_path = new URL(dependency_path, 'http://localhost').pathname;
			const decoded_dependency_path = decodeURI(encoded_dependency_path);

			const body = result.body ?? new Uint8Array(await result.response.arrayBuffer());
			save(
				'dependencies',
				result.response,
				body,
				decoded_dependency_path,
				encoded_dependency_path,
				decoded,
				'fetched'
			);
		}

		if (config.prerender.crawl && response.headers.get('content-type') === 'text/html') {
			for (const href of crawl(text)) {
				if (href.startsWith('data:') || href.startsWith('#')) continue;

				const resolved = resolve(encoded, href);
				if (!is_root_relative(resolved)) continue;

				const { pathname, search } = new URL(resolved, 'http://localhost');

				if (search) {
					// TODO warn that query strings have no effect on statically-exported pages
				}

				enqueue(decoded, decodeURI(pathname), pathname);
			}
		}
	}

	/**
	 * @param {'pages' | 'dependencies'} category
	 * @param {Response} response
	 * @param {string | Uint8Array} body
	 * @param {string} decoded
	 * @param {string} encoded
	 * @param {string | null} referrer
	 * @param {'linked' | 'fetched'} referenceType
	 */
	function save(category, response, body, decoded, encoded, referrer, referenceType) {
		const response_type = Math.floor(response.status / 100);
		const type = /** @type {string} */ (response.headers.get('content-type'));
		const is_html = response_type === REDIRECT || type === 'text/html';

		const file = output_filename(decoded, is_html);
		const dest = `${config.outDir}/output/prerendered/${category}/${file}`;

		if (written.has(file)) return;

		if (response_type === REDIRECT) {
			const location = response.headers.get('location');

			if (location) {
				const resolved = resolve(encoded, location);
				if (is_root_relative(resolved)) {
					enqueue(decoded, decodeURI(resolved), resolved);
				}

				if (!response.headers.get('x-sveltekit-normalize')) {
					mkdirp(dirname(dest));

					log.warn(`${response.status} ${decoded} -> ${location}`);

					writeFileSync(
						dest,
						`<meta http-equiv="refresh" content=${escape_html_attr(`0;url=${location}`)}>`
					);

					written.add(file);

					if (!prerendered.redirects.has(decoded)) {
						prerendered.redirects.set(decoded, {
							status: response.status,
							location: resolved
						});

						prerendered.paths.push(normalize_path(decoded, 'never'));
					}
				}
			} else {
				log.warn(`location header missing on redirect received from ${decoded}`);
			}

			return;
		}

		if (response.status === 200) {
			mkdirp(dirname(dest));

			log.info(`${response.status} ${decoded}`);
			writeFileSync(dest, body);
			written.add(file);

			if (is_html) {
				prerendered.pages.set(decoded, {
					file
				});
			} else {
				prerendered.assets.set(decoded, {
					type
				});
			}

			prerendered.paths.push(normalize_path(decoded, 'never'));
		} else if (response_type !== OK) {
			error({ status: response.status, path: decoded, referrer, referenceType });
		}
	}

	if (config.prerender.enabled) {
		for (const entry of config.prerender.entries) {
			if (entry === '*') {
				for (const entry of entries) {
					enqueue(null, config.paths.base + entry); // TODO can we pre-normalize these?
				}
			} else {
				enqueue(null, config.paths.base + entry);
			}
		}

		await q.done();
	}

	const rendered = await server.respond(new Request('http://sveltekit-prerender/[fallback]'), {
		getClientAddress,
		prerendering: {
			fallback: true,
			dependencies: new Map()
		}
	});

	const file = `${config.outDir}/output/prerendered/fallback.html`;
	mkdirp(dirname(file));
	writeFileSync(file, await rendered.text());

	return prerendered;
}
Example #13
Source File: index.js    From kit with MIT License 4 votes vote down vote up
/** @typedef {import('http').IncomingMessage} Req */
/** @typedef {import('http').ServerResponse} Res */
/** @typedef {(req: Req, res: Res, next: () => void) => void} Handler */

/**
 * @param {{
 *   middlewares: import('connect').Server;
 *   httpServer: import('http').Server;
 * }} vite
 * @param {import('types').ValidatedConfig} config
 * @param {'http' | 'https'} protocol
 */
export async function preview(vite, config, protocol) {
	installPolyfills();

	const { paths } = config.kit;
	const base = paths.base;
	const assets = paths.assets ? SVELTE_KIT_ASSETS : paths.base;

	const etag = `"${Date.now()}"`;

	const index_file = join(config.kit.outDir, 'output/server/index.js');
	const manifest_file = join(config.kit.outDir, 'output/server/manifest.js');

	/** @type {import('types').ServerModule} */
	const { Server, override } = await import(pathToFileURL(index_file).href);
	const { manifest } = await import(pathToFileURL(manifest_file).href);

	override({
		paths: { base, assets },
		prerendering: false,
		protocol,
		read: (file) => fs.readFileSync(join(config.kit.files.assets, file))
	});

	const server = new Server(manifest);

	return () => {
		// files in `static`
		vite.middlewares.use(scoped(assets, mutable(config.kit.files.assets)));

		// immutable generated client assets
		vite.middlewares.use(
			scoped(
				assets,
				sirv(join(config.kit.outDir, 'output/client'), {
					setHeaders: (res, pathname) => {
						// only apply to build directory, not e.g. version.json
						if (pathname.startsWith(`/${config.kit.appDir}/immutable`)) {
							res.setHeader('cache-control', 'public,max-age=31536000,immutable');
						}
					}
				})
			)
		);

		vite.middlewares.use((req, res, next) => {
			const original_url = /** @type {string} */ (req.url);
			const { pathname } = new URL(original_url, 'http://dummy');

			if (pathname.startsWith(base)) {
				next();
			} else {
				res.statusCode = 404;
				res.end(`Not found (did you mean ${base + pathname}?)`);
			}
		});

		// prerendered dependencies
		vite.middlewares.use(
			scoped(base, mutable(join(config.kit.outDir, 'output/prerendered/dependencies')))
		);

		// prerendered pages (we can't just use sirv because we need to
		// preserve the correct trailingSlash behaviour)
		vite.middlewares.use(
			scoped(base, (req, res, next) => {
				let if_none_match_value = req.headers['if-none-match'];

				if (if_none_match_value?.startsWith('W/"')) {
					if_none_match_value = if_none_match_value.substring(2);
				}

				if (if_none_match_value === etag) {
					res.statusCode = 304;
					res.end();
					return;
				}

				const { pathname } = new URL(/** @type {string} */ (req.url), 'http://dummy');

				// only treat this as a page if it doesn't include an extension
				if (pathname === '/' || /\/[^./]+\/?$/.test(pathname)) {
					const file = join(
						config.kit.outDir,
						'output/prerendered/pages' +
							pathname +
							(pathname.endsWith('/') ? 'index.html' : '.html')
					);

					if (fs.existsSync(file)) {
						res.writeHead(200, {
							'content-type': 'text/html',
							etag
						});

						fs.createReadStream(file).pipe(res);
						return;
					}
				}

				next();
			})
		);

		// SSR
		vite.middlewares.use(async (req, res) => {
			const host = req.headers['host'];

			let request;

			try {
				request = await getRequest(`${protocol}://${host}`, req);
			} catch (/** @type {any} */ err) {
				res.statusCode = err.status || 400;
				return res.end(err.reason || 'Invalid request body');
			}

			setResponse(
				res,
				await server.respond(request, {
					getClientAddress: () => {
						const { remoteAddress } = req.socket;
						if (remoteAddress) return remoteAddress;
						throw new Error('Could not determine clientAddress');
					}
				})
			);
		});
	};
}