Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion index.js
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@ export class DomStack {
await this.#rebuildMaps(siteData)

// ── Copy watchers & browser-sync ─────────────────────────────────────
const copyDirs = getCopyDirs(this.opts.copy)
const copyDirs = await getCopyDirs(this.opts.copy)

this.#cpxWatchers = [
cpx.watch(getCopyGlob(this.#src), this.#dest, { ignore: this.opts.ignore }),
Expand Down
30 changes: 21 additions & 9 deletions lib/build-copy/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
// @ts-expect-error
import cpx from 'cpx2'
import { join } from 'node:path'
import { stat } from 'node:fs/promises'
const copy = cpx.copy

/**
Expand All @@ -15,11 +16,22 @@ const copy = cpx.copy

/**
* @param {string[]} copy
* @return {string[]}
* @return {Promise<string[]>}
*/
export function getCopyDirs (copy = []) {
const copyGlobs = copy?.map((dir) => join(dir, '**'))
return copyGlobs
export async function getCopyDirs (copy = []) {
const globs = await Promise.all(copy.map(async (entry) => {
try {
const stats = await stat(entry)
if (stats.isDirectory()) {
return join(entry, '**')
}
} catch {
// Path not accessible yet — treat as directory glob
return join(entry, '**')
}
return entry
}))
return globs
Comment thread
bcomnes marked this conversation as resolved.
}

/**
Expand All @@ -36,22 +48,22 @@ export async function buildCopy (_src, dest, _siteData, opts) {
warnings: [],
}

const copyDirs = getCopyDirs(opts?.copy)
const copyGlobs = await getCopyDirs(opts?.copy)

const copyTasks = copyDirs.map((copyDir) => {
return copy(copyDir, dest)
const copyTasks = copyGlobs.map((copyGlob) => {
return copy(copyGlob, dest)
})

const settled = await Promise.allSettled(copyTasks)

for (const [index, result] of Object.entries(settled)) {
// @ts-expect-error
const copyDir = copyDirs[index]
const copyGlob = copyGlobs[index]
if (result.status === 'rejected') {
const buildError = new Error('Error copying copy folders', { cause: result.reason })
Comment thread
bcomnes marked this conversation as resolved.
Outdated
results.errors.push(buildError)
} else {
results.report[copyDir] = result.value
results.report[copyGlob] = result.value
}
}
return results
Expand Down
29 changes: 27 additions & 2 deletions lib/build-copy/index.test.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,36 @@
import { test } from 'node:test'
import assert from 'node:assert'
import { mkdtemp, writeFile, rm } from 'node:fs/promises'
import { join } from 'node:path'
import os from 'node:os'
import { getCopyDirs } from './index.js'

test.describe('build-copy', () => {
test('getCopyDirs returns correct src/dest pairs', async () => {
const copyDirs = getCopyDirs(['fixtures'])
test('getCopyDirs appends ** for non-existent paths', async () => {
const copyDirs = await getCopyDirs(['fixtures'])

assert.deepStrictEqual(copyDirs, ['fixtures/**'])
Comment thread
bcomnes marked this conversation as resolved.
Outdated
})
Comment thread
bcomnes marked this conversation as resolved.

test('getCopyDirs returns file path as-is for existing files', async () => {
const dir = await mkdtemp(join(os.tmpdir(), 'domstack-copy-test-'))
const file = join(dir, 'sw.js')
try {
await writeFile(file, 'self.addEventListener("fetch", () => {})')
const result = await getCopyDirs([file])
assert.deepStrictEqual(result, [file])
} finally {
await rm(dir, { recursive: true, force: true })
}
})

test('getCopyDirs appends ** for existing directories', async () => {
const dir = await mkdtemp(join(os.tmpdir(), 'domstack-copy-test-'))
try {
const result = await getCopyDirs([dir])
assert.deepStrictEqual(result, [join(dir, '**')])
} finally {
await rm(dir, { recursive: true, force: true })
}
})
})