Skip to content

Commit 38437bb

Browse files
committed
Fix npm publish.
1 parent 68e78bf commit 38437bb

2 files changed

Lines changed: 30 additions & 6 deletions

File tree

‎packages/purestack/src/init/init.test.ts‎

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -597,6 +597,27 @@ describe('project generation', () => {
597597
expect(git).not.toHaveBeenCalled()
598598
})
599599

600+
it.each([
601+
['npm 11 list', [{ filename: 'template.tgz' }]],
602+
['npm 12 map', { '@scope/template': { filename: 'template.tgz' } }],
603+
])('reads the archive from the %s pack output', async (_format, output) => {
604+
vi.spyOn(processes, 'runNpm').mockResolvedValue(JSON.stringify(output))
605+
expect(await fetchTemplate('starter', temporary, repository)).toBe(
606+
path.join(temporary, 'template.tgz'),
607+
)
608+
})
609+
610+
it.each([
611+
['no entries', []],
612+
['several entries', { a: { filename: 'a.tgz' }, b: { filename: 'b.tgz' } }],
613+
['a missing filename', { '@scope/template': { name: 'x' } }],
614+
])('rejects pack output with %s', async (_case, output) => {
615+
vi.spyOn(processes, 'runNpm').mockResolvedValue(JSON.stringify(output))
616+
await expect(
617+
fetchTemplate('starter', temporary, repository),
618+
).rejects.toThrow('npm did not return a template archive.')
619+
})
620+
600621
it('rejects npm pack results pointing outside the temporary directory', async () => {
601622
vi.spyOn(processes, 'runNpm').mockResolvedValue(
602623
JSON.stringify([{ filename: '../outside.tgz' }]),

‎packages/purestack/src/init/template.ts‎

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -85,14 +85,17 @@ export async function fetchTemplate(
8585
{ capture: true, signal },
8686
),
8787
)
88-
if (
89-
!Array.isArray(result) ||
90-
result.length !== 1 ||
91-
typeof result[0]?.filename !== 'string'
92-
) {
88+
// npm 11 and earlier report a list; npm 12 keys each entry by package name.
89+
const packed = Array.isArray(result)
90+
? result
91+
: isRecord(result)
92+
? Object.values(result)
93+
: []
94+
const filename = isRecord(packed[0]) ? packed[0].filename : undefined
95+
if (packed.length !== 1 || typeof filename !== 'string') {
9396
throw new Error('npm did not return a template archive.')
9497
}
95-
const archive = path.resolve(temporary, result[0].filename)
98+
const archive = path.resolve(temporary, filename)
9699
if (path.dirname(archive) !== temporary || !archive.endsWith('.tgz')) {
97100
throw new Error('npm returned an invalid template archive path.')
98101
}

0 commit comments

Comments
 (0)