forked from sveltejs/kit
-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
127 lines (105 loc) · 3.57 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
import { execSync } from 'node:child_process';
import { pathToFileURL } from 'node:url';
import { resolve } from 'import-meta-resolve';
import { adapters } from './adapters.js';
import { dirname, join } from 'node:path';
import { existsSync } from 'node:fs';
/** @type {Record<string, (name: string, version: string) => string>} */
const commands = {
npm: (name, version) => `npm install -D ${name}@${version}`,
pnpm: (name, version) => `pnpm add -D ${name}@${version}`,
yarn: (name, version) => `yarn add -D ${name}@${version}`
};
function detect_lockfile() {
let dir = process.cwd();
do {
if (existsSync(join(dir, 'pnpm-lock.yaml'))) return 'pnpm';
if (existsSync(join(dir, 'yarn.lock'))) return 'yarn';
if (existsSync(join(dir, 'package-lock.json'))) return 'npm';
} while (dir !== (dir = dirname(dir)));
return 'npm';
}
function detect_package_manager() {
const manager = detect_lockfile();
try {
execSync(`${manager} --version`);
return manager;
} catch {
return 'npm';
}
}
/** @param {string} name */
async function import_from_cwd(name) {
const cwd = pathToFileURL(process.cwd()).href;
const url = await resolve(name, cwd + '/x.js');
return import(url);
}
/** @typedef {import('@sveltejs/kit').Adapter} Adapter */
/**
* @returns {Promise<Adapter | undefined>} The corresponding adapter for the current environment if found otherwise undefined
*/
async function get_adapter() {
const match = adapters.find((candidate) => candidate.test());
if (!match) return;
/** @type {{ default: () => Adapter }} */
let module;
try {
module = await import_from_cwd(match.module);
} catch (error) {
if (
error.code === 'ERR_MODULE_NOT_FOUND' &&
error.message.startsWith(`Cannot find package '${match.module}'`)
) {
const package_manager = detect_package_manager();
const command = commands[package_manager](match.module, match.version);
try {
console.log(`Installing ${match.module}...`);
execSync(command, {
stdio: 'inherit',
env: {
...process.env,
NODE_ENV: undefined
}
});
module = await import_from_cwd(match.module);
console.log(`Successfully installed ${match.module}.`);
console.warn(
`\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`
);
} catch (e) {
throw new Error(
`Could not install ${match.module}. Please install it yourself by adding it to your package.json's devDependencies and try building your project again.`,
{ cause: e }
);
}
} else {
throw error;
}
}
const adapter = module.default();
return {
...adapter,
adapt: (builder) => {
builder.log.info(`Detected environment: ${match.name}. Using ${match.module}`);
return adapter.adapt(builder);
}
};
}
/** @type {() => Adapter} */
export default () => ({
name: '@sveltejs/adapter-auto',
adapt: async (builder) => {
const adapter = await get_adapter();
if (adapter) return adapter.adapt(builder);
builder.log.warn(
'Could not detect a supported production environment. See https://kit.svelte.dev/docs/adapters to learn how to configure your app to run on the platform of your choosing'
);
},
supports: {
read: () => {
throw new Error(
"The read function imported from $app/server only works in certain environments. Since you're using @sveltejs/adapter-auto, SvelteKit cannot determine whether it will work when your app is deployed. Please replace it with an adapter tailored to your target environment."
);
}
}
});