mirror of
https://github.com/nexu-io/open-design.git
synced 2026-06-01 03:14:35 +07:00
fix(daemon): preserve export refs across directory moves
This commit is contained in:
parent
f2e04df500
commit
0bffe6ba40
2 changed files with 61 additions and 7 deletions
|
|
@ -716,14 +716,16 @@ function buildProjectExportManifestResponse({
|
|||
const addManifestRef = (
|
||||
ref: unknown,
|
||||
reason: string,
|
||||
options: { preferProjectRoot?: boolean } = {},
|
||||
options: { allowProjectRootFallback?: boolean; preferProjectRoot?: boolean } = {},
|
||||
) => {
|
||||
const ownerRelative = normalizeManifestProjectRef(ref, file.name);
|
||||
const projectRoot = normalizeManifestProjectRootRef(ref);
|
||||
const candidates = options.preferProjectRoot
|
||||
? [
|
||||
normalizeManifestProjectRootRef(ref),
|
||||
normalizeManifestProjectRef(ref, file.name),
|
||||
]
|
||||
: [normalizeManifestProjectRef(ref, file.name)];
|
||||
? [projectRoot, ownerRelative]
|
||||
: [
|
||||
ownerRelative,
|
||||
...(options.allowProjectRootFallback ? [projectRoot] : []),
|
||||
];
|
||||
const normalized = candidates.find((candidate) => candidate && filesByName.has(candidate));
|
||||
if (!normalized) return;
|
||||
if (normalized === file.name) return;
|
||||
|
|
@ -737,7 +739,7 @@ function buildProjectExportManifestResponse({
|
|||
}
|
||||
if (Array.isArray(manifest.supportingFiles)) {
|
||||
for (const ref of manifest.supportingFiles) {
|
||||
addManifestRef(ref, 'artifact-supporting-file');
|
||||
addManifestRef(ref, 'artifact-supporting-file', { allowProjectRootFallback: true });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -284,6 +284,58 @@ describe('project export manifest route', () => {
|
|||
});
|
||||
});
|
||||
|
||||
it('keeps artifact entry refs current when a referenced file moves out of the wrapper directory', async () => {
|
||||
const projectId = await createProject({ kind: 'prototype' });
|
||||
await writeFile(projectId, {
|
||||
name: 'index.html',
|
||||
content: '<!doctype html><main>fallback</main>',
|
||||
});
|
||||
await writeFile(projectId, {
|
||||
name: 'preview/reviewed.html',
|
||||
content: '<!doctype html><main>reviewed</main>',
|
||||
});
|
||||
await writeFile(projectId, {
|
||||
name: 'preview/wrapper.html',
|
||||
content: '<!doctype html><iframe src="reviewed.html"></iframe>',
|
||||
artifactManifest: {
|
||||
version: 1,
|
||||
kind: 'html',
|
||||
title: 'Review wrapper',
|
||||
entry: 'reviewed.html',
|
||||
renderer: 'html',
|
||||
status: 'complete',
|
||||
exports: ['html'],
|
||||
primary: 'reviewed.html',
|
||||
supportingFiles: ['reviewed.html'],
|
||||
},
|
||||
});
|
||||
|
||||
await renameFile(projectId, 'preview/reviewed.html', 'reviewed.html');
|
||||
|
||||
const response = await fetch(`${baseUrl}/api/projects/${projectId}/export/manifest`);
|
||||
expect(response.ok).toBe(true);
|
||||
const body = await response.json() as {
|
||||
entryFile: string;
|
||||
files: Array<{ name: string; role: string; reasons: string[] }>;
|
||||
artifacts: Array<{ file: string; supportingFiles: string[] }>;
|
||||
};
|
||||
|
||||
expect(body.entryFile).toBe('reviewed.html');
|
||||
expect(body.files.find((file) => file.name === 'reviewed.html')).toMatchObject({
|
||||
role: 'entry',
|
||||
reasons: expect.arrayContaining([
|
||||
'artifact-entry',
|
||||
'artifact-primary',
|
||||
'artifact-supporting-file',
|
||||
'project-entry-file',
|
||||
]),
|
||||
});
|
||||
expect(body.artifacts.find((artifact) => artifact.file === 'preview/wrapper.html'))
|
||||
.toMatchObject({
|
||||
supportingFiles: ['reviewed.html'],
|
||||
});
|
||||
});
|
||||
|
||||
it('rejects invalid project ids before listing files', async () => {
|
||||
const response = await fetch(`${baseUrl}/api/projects/bad:id/export/manifest`);
|
||||
expect(response.status).toBe(400);
|
||||
|
|
|
|||
Loading…
Reference in a new issue