11import { execSync } from 'node:child_process' ;
2- import { pathToFileURL } from 'node:url' ;
3- import { resolve } from 'import-meta-resolve' ;
42import { adapters } from './adapters.js' ;
5- import { dirname , join } from 'node:path' ;
6- import { existsSync } from 'node:fs' ;
3+ import path from 'node:path' ;
4+ import fs from 'node:fs' ;
75import process from 'node:process' ;
86
97/** @type {Record<string, (name: string, version: string) => string> } */
@@ -17,12 +15,15 @@ const commands = {
1715function detect_lockfile ( ) {
1816 let dir = process . cwd ( ) ;
1917
18+ /** @param {string } file */
19+ const exists = ( file ) => fs . existsSync ( path . join ( dir , file ) ) ;
20+
2021 do {
21- if ( existsSync ( join ( dir , 'pnpm-lock.yaml' ) ) ) return 'pnpm' ;
22- if ( existsSync ( join ( dir , 'yarn.lock' ) ) ) return 'yarn' ;
23- if ( existsSync ( join ( dir , 'package-lock.json' ) ) ) return 'npm' ;
24- if ( existsSync ( join ( dir , 'bun.lockb' ) ) || existsSync ( join ( dir , 'bun.lock' ) ) ) return 'bun' ;
25- } while ( dir !== ( dir = dirname ( dir ) ) ) ;
22+ if ( exists ( 'pnpm-lock.yaml' ) ) return 'pnpm' ;
23+ if ( exists ( 'yarn.lock' ) ) return 'yarn' ;
24+ if ( exists ( 'package-lock.json' ) ) return 'npm' ;
25+ if ( exists ( 'bun.lockb' ) || exists ( 'bun.lock' ) ) return 'bun' ;
26+ } while ( dir !== ( dir = path . dirname ( dir ) ) ) ;
2627
2728 return 'npm' ;
2829}
@@ -38,12 +39,40 @@ function detect_package_manager() {
3839 }
3940}
4041
41- /** @param {string } name */
42- function import_from_cwd ( name ) {
43- const cwd = pathToFileURL ( process . cwd ( ) ) . href ;
44- const url = resolve ( name , cwd + '/x.js' ) ;
42+ /**
43+ * Resolves a peer dependency relative to the current CWD. Duplicated with `packages/kit`
44+ * @param {string } dependency
45+ */
46+ function resolve_peer ( dependency ) {
47+ let [ name , ...parts ] = dependency . split ( '/' ) ;
48+ if ( name [ 0 ] === '@' ) name += `/${ parts . shift ( ) } ` ;
49+
50+ let dir = process . cwd ( ) ;
51+
52+ while ( ! fs . existsSync ( `${ dir } /node_modules/${ name } /package.json` ) ) {
53+ if ( dir === ( dir = path . dirname ( dir ) ) ) {
54+ throw new Error (
55+ `Could not resolve peer dependency "${ name } " relative to your project — please install it and try again.`
56+ ) ;
57+ }
58+ }
59+
60+ const pkg_dir = `${ dir } /node_modules/${ name } ` ;
61+ const pkg = JSON . parse ( fs . readFileSync ( `${ pkg_dir } /package.json` , 'utf-8' ) ) ;
62+
63+ const subpackage = [ '.' , ...parts ] . join ( '/' ) ;
64+
65+ let exported = pkg . exports [ subpackage ] ;
66+
67+ while ( typeof exported !== 'string' ) {
68+ if ( ! exported ) {
69+ throw new Error ( `Could not find valid "${ subpackage } " export in ${ name } /package.json` ) ;
70+ }
71+
72+ exported = exported [ 'import' ] ?? exported [ 'default' ] ;
73+ }
4574
46- return import ( url ) ;
75+ return path . resolve ( pkg_dir , exported ) ;
4776}
4877
4978/** @typedef {import('@sveltejs/kit').Adapter } Adapter */
@@ -56,47 +85,43 @@ async function get_adapter() {
5685
5786 if ( ! match ) return ;
5887
59- /** @type {{ default: () => Adapter } } */
60- let module ;
88+ /** @type {string } */
89+ let resolved ;
6190
6291 try {
63- module = await import_from_cwd ( match . module ) ;
64- } catch ( error ) {
65- if (
66- error . code === 'ERR_MODULE_NOT_FOUND' &&
67- error . message . startsWith ( `Cannot find package '${ match . module } '` )
68- ) {
69- const package_manager = detect_package_manager ( ) ;
70- const command = commands [ package_manager ] ( match . module , match . version ) ;
71-
72- try {
73- console . log ( `Installing ${ match . module } ...` ) ;
74-
75- execSync ( command , {
76- stdio : 'inherit' ,
77- env : {
78- ...process . env ,
79- NODE_ENV : undefined
80- }
81- } ) ;
82-
83- module = await import_from_cwd ( match . module ) ;
84-
85- console . log ( `Successfully installed ${ match . module } .` ) ;
86- console . warn (
87- `\nIf you plan on staying on this deployment platform, consider replacing @sveltejs/adapter-auto with ${ match . module } . This will give you faster and more robust installs, and more control over deployment configuration.\n`
88- ) ;
89- } catch ( e ) {
90- throw new Error (
91- `Could not install ${ match . module } . Please install it yourself by adding it to your package.json's devDependencies and try building your project again.` ,
92- { cause : e }
93- ) ;
94- }
95- } else {
96- throw error ;
92+ resolved = resolve_peer ( match . module ) ;
93+ } catch {
94+ const package_manager = detect_package_manager ( ) ;
95+ const command = commands [ package_manager ] ( match . module , match . version ) ;
96+
97+ try {
98+ console . log ( `Installing ${ match . module } ...` ) ;
99+
100+ execSync ( command , {
101+ stdio : 'inherit' ,
102+ env : {
103+ ...process . env ,
104+ NODE_ENV : undefined
105+ }
106+ } ) ;
107+
108+ resolved = resolve_peer ( match . module ) ;
109+
110+ console . log ( `Successfully installed ${ match . module } .` ) ;
111+ console . warn (
112+ `\nIf you plan on staying on this deployment platform, consider replacing @sveltejs/adapter-auto with ${ match . module } . This will give you faster and more robust installs, and more control over deployment configuration.\n`
113+ ) ;
114+ } catch ( e ) {
115+ throw new Error (
116+ `Could not install ${ match . module } . Please install it yourself by adding it to your package.json's devDependencies and try building your project again.` ,
117+ { cause : e }
118+ ) ;
97119 }
98120 }
99121
122+ /** @type {{ default: () => Adapter } } */
123+ const module = await import ( resolved ) ;
124+
100125 const adapter = module . default ( ) ;
101126
102127 return {
0 commit comments