mirror of
https://github.com/withastro/astro.git
synced 2025-03-10 23:01:26 -05:00
chore: Extract fs helpers into shared internal-helpers package (#11323)
This commit is contained in:
parent
9e198c41bf
commit
24fb7797d9
4 changed files with 4 additions and 97 deletions
|
@ -1,93 +0,0 @@
|
|||
import type { PathLike } from 'node:fs';
|
||||
import { existsSync } from 'node:fs';
|
||||
import * as fs from 'node:fs/promises';
|
||||
import nodePath from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
|
||||
export async function writeJson<T>(path: PathLike, data: T) {
|
||||
await fs.writeFile(path, JSON.stringify(data, null, '\t'), { encoding: 'utf-8' });
|
||||
}
|
||||
|
||||
export async function removeDir(dir: PathLike) {
|
||||
await fs.rm(dir, { recursive: true, force: true, maxRetries: 3 });
|
||||
}
|
||||
|
||||
export async function emptyDir(dir: PathLike): Promise<void> {
|
||||
await removeDir(dir);
|
||||
await fs.mkdir(dir, { recursive: true });
|
||||
}
|
||||
|
||||
export async function getFilesFromFolder(dir: URL) {
|
||||
const data = await fs.readdir(dir, { withFileTypes: true });
|
||||
let files: URL[] = [];
|
||||
for (const item of data) {
|
||||
if (item.isDirectory()) {
|
||||
const moreFiles = await getFilesFromFolder(new URL(`./${item.name}/`, dir));
|
||||
files = files.concat(moreFiles);
|
||||
} else {
|
||||
files.push(new URL(`./${item.name}`, dir));
|
||||
}
|
||||
}
|
||||
return files;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies files into a folder keeping the folder structure intact.
|
||||
* The resulting file tree will start at the common ancestor.
|
||||
*
|
||||
* @param {URL[]} files A list of files to copy (absolute path).
|
||||
* @param {URL} outDir Destination folder where to copy the files to (absolute path).
|
||||
* @param {URL[]} [exclude] A list of files to exclude (absolute path).
|
||||
* @returns {Promise<string>} The common ancestor of the copied files.
|
||||
*/
|
||||
export async function copyFilesToFunction(
|
||||
files: URL[],
|
||||
outDir: URL,
|
||||
exclude: URL[] = []
|
||||
): Promise<string> {
|
||||
const excludeList = exclude.map(fileURLToPath);
|
||||
const fileList = files.map(fileURLToPath).filter((f) => !excludeList.includes(f));
|
||||
|
||||
if (files.length === 0) throw new Error('[@astrojs/vercel] No files found to copy');
|
||||
|
||||
let commonAncestor = nodePath.dirname(fileList[0]);
|
||||
for (const file of fileList.slice(1)) {
|
||||
while (!file.startsWith(commonAncestor)) {
|
||||
commonAncestor = nodePath.dirname(commonAncestor);
|
||||
}
|
||||
}
|
||||
|
||||
for (const origin of fileList) {
|
||||
const dest = new URL(nodePath.relative(commonAncestor, origin), outDir);
|
||||
|
||||
const realpath = await fs.realpath(origin);
|
||||
const isSymlink = realpath !== origin;
|
||||
const isDir = (await fs.stat(origin)).isDirectory();
|
||||
|
||||
// Create directories recursively
|
||||
if (isDir && !isSymlink) {
|
||||
await fs.mkdir(new URL('..', dest), { recursive: true });
|
||||
} else {
|
||||
await fs.mkdir(new URL('.', dest), { recursive: true });
|
||||
}
|
||||
|
||||
if (isSymlink) {
|
||||
const realdest = fileURLToPath(new URL(nodePath.relative(commonAncestor, realpath), outDir));
|
||||
const target = nodePath.relative(fileURLToPath(new URL('.', dest)), realdest);
|
||||
// NOTE: when building function per route, dependencies are linked at the first run, then there's no need anymore to do that once more.
|
||||
// So we check if the destination already exists. If it does, move on.
|
||||
// Symbolic links here are usually dependencies and not user code. Symbolic links exist because of the pnpm strategy.
|
||||
if (!existsSync(dest)) {
|
||||
await fs.symlink(target, dest, isDir ? 'dir' : 'file');
|
||||
}
|
||||
} else if (!isDir) {
|
||||
await fs.copyFile(origin, dest);
|
||||
}
|
||||
}
|
||||
|
||||
return commonAncestor;
|
||||
}
|
||||
|
||||
export async function writeFile(path: PathLike, content: string) {
|
||||
await fs.writeFile(path, content, { encoding: 'utf-8' });
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
import { relative as relativePath } from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import type { AstroIntegrationLogger } from 'astro';
|
||||
import { copyFilesToFunction } from './fs.js';
|
||||
import { copyFilesToFolder } from '@astrojs/internal-helpers/fs';
|
||||
|
||||
export async function copyDependenciesToFunction(
|
||||
{
|
||||
|
@ -72,7 +72,7 @@ export async function copyDependenciesToFunction(
|
|||
}
|
||||
}
|
||||
|
||||
const commonAncestor = await copyFilesToFunction(
|
||||
const commonAncestor = await copyFilesToFolder(
|
||||
[...result.fileList].map((file) => new URL(file, base)).concat(includeFiles),
|
||||
outDir,
|
||||
excludeFiles
|
||||
|
|
|
@ -16,7 +16,7 @@ import {
|
|||
getAstroImageConfig,
|
||||
getDefaultImageConfig,
|
||||
} from '../image/shared.js';
|
||||
import { removeDir, writeJson } from '../lib/fs.js';
|
||||
import { removeDir, writeJson } from '@astrojs/internal-helpers/fs';
|
||||
import { copyDependenciesToFunction } from '../lib/nft.js';
|
||||
import { escapeRegex, getRedirects } from '../lib/redirects.js';
|
||||
import {
|
||||
|
|
|
@ -6,7 +6,7 @@ import {
|
|||
getAstroImageConfig,
|
||||
getDefaultImageConfig,
|
||||
} from '../image/shared.js';
|
||||
import { emptyDir, writeJson } from '../lib/fs.js';
|
||||
import { emptyDir, writeJson } from '@astrojs/internal-helpers/fs';
|
||||
import { isServerLikeOutput } from '../lib/prerender.js';
|
||||
import { getRedirects } from '../lib/redirects.js';
|
||||
import {
|
||||
|
|
Loading…
Add table
Reference in a new issue