1 | "use strict";
|
2 | var __importDefault = (this && this.__importDefault) || function (mod) {
|
3 | return (mod && mod.__esModule) ? mod : { "default": mod };
|
4 | };
|
5 | Object.defineProperty(exports, "__esModule", { value: true });
|
6 | exports.INIT_TEMPLATE_FILE = exports.HMR_OVERLAY_CODE = exports.HMR_CLIENT_CODE = exports.removeTrailingSlash = exports.removeLeadingSlash = exports.addTrailingSlash = exports.addLeadingSlash = exports.removeExtension = exports.addExtension = exports.replaceExtension = exports.hasExtension = exports.getExtension = exports.isJavaScript = exports.appendHtmlToHead = exports.relativeURL = exports.jsSourceMappingURL = exports.cssSourceMappingURL = exports.sanitizePackageName = exports.isRemoteUrl = exports.getExtensionMatch = exports.findMatchingAliasEntry = exports.clearCache = exports.updateLockfileHash = exports.checkLockfileHash = exports.openInBrowser = exports.MISSING_PLUGIN_SUGGESTIONS = exports.resolveDependencyManifest = exports.parsePackageImportSpecifier = exports.isFsEventsEnabled = exports.getPackageSource = exports.isTruthy = exports.writeLockfile = exports.convertSkypackImportMapToLockfile = exports.convertLockfileToSkypackImportMap = exports.readLockfile = exports.readFile = exports.deleteFromBuildSafe = exports.SVELTE_VUE_REGEX = exports.CSS_REGEX = exports.HTML_STYLE_REGEX = exports.HTML_JS_REGEX = exports.BUILD_CACHE = exports.remotePackageSDK = exports.NATIVE_REQUIRE = exports.LOCKFILE_NAME = exports.GLOBAL_CACHE_DIR = void 0;
|
7 | const cacache_1 = __importDefault(require("cacache"));
|
8 | const cachedir_1 = __importDefault(require("cachedir"));
|
9 | const etag_1 = __importDefault(require("etag"));
|
10 | const execa_1 = __importDefault(require("execa"));
|
11 | const find_up_1 = __importDefault(require("find-up"));
|
12 | const fs_1 = __importDefault(require("fs"));
|
13 | const isbinaryfile_1 = require("isbinaryfile");
|
14 | const mkdirp_1 = __importDefault(require("mkdirp"));
|
15 | const open_1 = __importDefault(require("open"));
|
16 | const path_1 = __importDefault(require("path"));
|
17 | const rimraf_1 = __importDefault(require("rimraf"));
|
18 | const skypack_1 = require("skypack");
|
19 | const url_1 = __importDefault(require("url"));
|
20 | const local_1 = __importDefault(require("./sources/local"));
|
21 | const remote_1 = __importDefault(require("./sources/remote"));
|
22 | exports.GLOBAL_CACHE_DIR = cachedir_1.default('snowpack');
|
23 | exports.LOCKFILE_NAME = 'snowpack.deps.json';
|
24 |
|
25 | exports.NATIVE_REQUIRE = eval('require');
|
26 | exports.remotePackageSDK = new skypack_1.SkypackSDK({ origin: 'https://pkg.snowpack.dev' });
|
27 |
|
28 |
|
29 |
|
30 |
|
31 |
|
32 | exports.BUILD_CACHE = path_1.default.join(exports.GLOBAL_CACHE_DIR, 'build-cache-2.7');
|
33 | const LOCKFILE_HASH_FILE = '.hash';
|
34 |
|
35 | exports.HTML_JS_REGEX = /(<script[^>]*?type="module".*?>)(.*?)<\/script>/gims;
|
36 | exports.HTML_STYLE_REGEX = /(<style.*?>)(.*?)<\/style>/gims;
|
37 | exports.CSS_REGEX = /@import\s*['"](.*?)['"];/gs;
|
38 | exports.SVELTE_VUE_REGEX = /(<script[^>]*>)(.*?)<\/script>/gims;
|
39 |
|
40 |
|
41 |
|
42 | function deleteFromBuildSafe(dir, config) {
|
43 | const { out } = config.buildOptions;
|
44 | if (!path_1.default.isAbsolute(dir)) {
|
45 | throw new Error(`rimrafSafe(): dir ${dir} must be a absolute path`);
|
46 | }
|
47 | if (!path_1.default.isAbsolute(out)) {
|
48 | throw new Error(`rimrafSafe(): buildOptions.out ${out} must be a absolute path`);
|
49 | }
|
50 | if (!dir.startsWith(out)) {
|
51 | throw new Error(`rimrafSafe(): ${dir} outside of buildOptions.out ${out}`);
|
52 | }
|
53 | return rimraf_1.default.sync(dir);
|
54 | }
|
55 | exports.deleteFromBuildSafe = deleteFromBuildSafe;
|
56 |
|
57 | async function readFile(filepath) {
|
58 | const data = await fs_1.default.promises.readFile(url_1.default.fileURLToPath(filepath));
|
59 | const isBinary = await isbinaryfile_1.isBinaryFile(data);
|
60 | return isBinary ? data : data.toString('utf8');
|
61 | }
|
62 | exports.readFile = readFile;
|
63 | async function readLockfile(cwd) {
|
64 | try {
|
65 | var lockfileContents = fs_1.default.readFileSync(path_1.default.join(cwd, exports.LOCKFILE_NAME), {
|
66 | encoding: 'utf8',
|
67 | });
|
68 | }
|
69 | catch (err) {
|
70 |
|
71 | return null;
|
72 | }
|
73 |
|
74 | return JSON.parse(lockfileContents);
|
75 | }
|
76 | exports.readLockfile = readLockfile;
|
77 | function sortObject(originalObject) {
|
78 | const newObject = {};
|
79 | for (const key of Object.keys(originalObject).sort()) {
|
80 | newObject[key] = originalObject[key];
|
81 | }
|
82 | return newObject;
|
83 | }
|
84 | function convertLockfileToSkypackImportMap(origin, lockfile) {
|
85 | const result = { imports: {} };
|
86 | for (const [key, val] of Object.entries(lockfile.lock)) {
|
87 | result.imports[key.replace(/\#.*/, '')] = origin + '/' + val;
|
88 | result.imports[key.replace(/\#.*/, '') + '/'] = origin + '/' + val + '/';
|
89 | }
|
90 | return result;
|
91 | }
|
92 | exports.convertLockfileToSkypackImportMap = convertLockfileToSkypackImportMap;
|
93 | function convertSkypackImportMapToLockfile(dependencies, importMap) {
|
94 | const result = { dependencies, lock: {} };
|
95 | for (const [key, val] of Object.entries(dependencies)) {
|
96 | const valPath = url_1.default.parse(importMap.imports[key]).pathname;
|
97 | result.lock[key + '#' + val] = valPath === null || valPath === void 0 ? void 0 : valPath.substr(1);
|
98 | }
|
99 | return result;
|
100 | }
|
101 | exports.convertSkypackImportMapToLockfile = convertSkypackImportMapToLockfile;
|
102 | async function writeLockfile(loc, importMap) {
|
103 | importMap.dependencies = sortObject(importMap.dependencies);
|
104 | importMap.lock = sortObject(importMap.lock);
|
105 | fs_1.default.writeFileSync(loc, JSON.stringify(importMap, undefined, 2), { encoding: 'utf8' });
|
106 | }
|
107 | exports.writeLockfile = writeLockfile;
|
108 | function isTruthy(item) {
|
109 | return Boolean(item);
|
110 | }
|
111 | exports.isTruthy = isTruthy;
|
112 | function getPackageSource(source) {
|
113 | return source === 'local' ? local_1.default : remote_1.default;
|
114 | }
|
115 | exports.getPackageSource = getPackageSource;
|
116 |
|
117 |
|
118 |
|
119 |
|
120 | function isFsEventsEnabled() {
|
121 | try {
|
122 | exports.NATIVE_REQUIRE('fsevents');
|
123 | return true;
|
124 | }
|
125 | catch (e) {
|
126 | return false;
|
127 | }
|
128 | }
|
129 | exports.isFsEventsEnabled = isFsEventsEnabled;
|
130 |
|
131 | function parsePackageImportSpecifier(imp) {
|
132 | const impParts = imp.split('/');
|
133 | if (imp.startsWith('@')) {
|
134 | const [scope, name, ...rest] = impParts;
|
135 | return [`${scope}/${name}`, rest.join('/') || null];
|
136 | }
|
137 | const [name, ...rest] = impParts;
|
138 | return [name, rest.join('/') || null];
|
139 | }
|
140 | exports.parsePackageImportSpecifier = parsePackageImportSpecifier;
|
141 |
|
142 |
|
143 |
|
144 |
|
145 |
|
146 |
|
147 |
|
148 |
|
149 | function resolveDependencyManifest(dep, cwd) {
|
150 |
|
151 |
|
152 |
|
153 |
|
154 | try {
|
155 | const depManifest = fs_1.default.realpathSync.native(require.resolve(`${dep}/package.json`, { paths: [cwd] }));
|
156 | return [depManifest, exports.NATIVE_REQUIRE(depManifest)];
|
157 | }
|
158 | catch (err) {
|
159 |
|
160 | if (err.code !== 'ERR_PACKAGE_PATH_NOT_EXPORTED') {
|
161 | return [null, null];
|
162 | }
|
163 | }
|
164 |
|
165 |
|
166 |
|
167 |
|
168 |
|
169 | let result = [null, null];
|
170 | try {
|
171 | const fullPath = fs_1.default.realpathSync.native(require.resolve(dep, { paths: [cwd] }));
|
172 |
|
173 |
|
174 | const searchPath = `${path_1.default.sep}node_modules${path_1.default.sep}${dep.replace('/', path_1.default.sep)}`;
|
175 | const indexOfSearch = fullPath.lastIndexOf(searchPath);
|
176 | if (indexOfSearch >= 0) {
|
177 | const manifestPath = fullPath.substring(0, indexOfSearch + searchPath.length + 1) + 'package.json';
|
178 | result[0] = manifestPath;
|
179 | const manifestStr = fs_1.default.readFileSync(manifestPath, { encoding: 'utf8' });
|
180 | result[1] = JSON.parse(manifestStr);
|
181 | }
|
182 | }
|
183 | catch (err) {
|
184 |
|
185 | }
|
186 | finally {
|
187 | return result;
|
188 | }
|
189 | }
|
190 | exports.resolveDependencyManifest = resolveDependencyManifest;
|
191 |
|
192 |
|
193 |
|
194 |
|
195 | exports.MISSING_PLUGIN_SUGGESTIONS = {
|
196 | '.svelte': 'Try installing rollup-plugin-svelte and adding it to Snowpack (https://www.snowpack.dev/tutorials/svelte)',
|
197 | '.vue': 'Try installing rollup-plugin-vue and adding it to Snowpack (https://www.snowpack.dev/guides/vue)',
|
198 | };
|
199 | const appNames = {
|
200 | win32: {
|
201 | brave: 'brave',
|
202 | chrome: 'chrome',
|
203 | },
|
204 | darwin: {
|
205 | brave: 'Brave Browser',
|
206 | chrome: 'Google Chrome',
|
207 | },
|
208 | linux: {
|
209 | brave: 'brave',
|
210 | chrome: 'google-chrome',
|
211 | },
|
212 | };
|
213 | async function openInExistingChromeBrowser(url) {
|
214 |
|
215 | await execa_1.default.command('ps cax | grep "Google Chrome"', {
|
216 | shell: true,
|
217 | });
|
218 |
|
219 | const openChrome = execa_1.default('osascript ../assets/openChrome.appleScript "' + encodeURI(url) + '"', {
|
220 | cwd: __dirname,
|
221 | stdio: 'ignore',
|
222 | shell: true,
|
223 | });
|
224 |
|
225 | let isChromeStalled = setTimeout(() => {
|
226 | openChrome.cancel();
|
227 | }, 3000);
|
228 | try {
|
229 | await openChrome;
|
230 | }
|
231 | catch (err) {
|
232 | if (err.isCanceled) {
|
233 | console.warn(`Chrome not responding to Snowpack after 3s. Opening in new tab.`);
|
234 | }
|
235 | else {
|
236 | console.error(err.toString() || err);
|
237 | }
|
238 | throw err;
|
239 | }
|
240 | finally {
|
241 | clearTimeout(isChromeStalled);
|
242 | }
|
243 | }
|
244 | async function openInBrowser(protocol, hostname, port, browser) {
|
245 | const url = `${protocol}//${hostname}:${port}`;
|
246 | browser = /chrome/i.test(browser)
|
247 | ? appNames[process.platform]['chrome']
|
248 | : /brave/i.test(browser)
|
249 | ? appNames[process.platform]['brave']
|
250 | : browser;
|
251 | const isMac = process.platform === 'darwin';
|
252 | const isBrowserChrome = /chrome|default/i.test(browser);
|
253 | if (!isMac || !isBrowserChrome) {
|
254 | await (browser === 'default' ? open_1.default(url) : open_1.default(url, { app: browser }));
|
255 | return;
|
256 | }
|
257 | try {
|
258 |
|
259 |
|
260 |
|
261 | await openInExistingChromeBrowser(url);
|
262 | }
|
263 | catch (err) {
|
264 |
|
265 | await open_1.default(url);
|
266 | }
|
267 | }
|
268 | exports.openInBrowser = openInBrowser;
|
269 | async function checkLockfileHash(dir) {
|
270 | const lockfileLoc = await find_up_1.default(['package-lock.json', 'yarn.lock']);
|
271 | if (!lockfileLoc) {
|
272 | return true;
|
273 | }
|
274 | const hashLoc = path_1.default.join(dir, LOCKFILE_HASH_FILE);
|
275 | const newLockHash = etag_1.default(await fs_1.default.promises.readFile(lockfileLoc, 'utf8'));
|
276 | const oldLockHash = await fs_1.default.promises.readFile(hashLoc, 'utf8').catch(() => '');
|
277 | return newLockHash === oldLockHash;
|
278 | }
|
279 | exports.checkLockfileHash = checkLockfileHash;
|
280 | async function updateLockfileHash(dir) {
|
281 | const lockfileLoc = await find_up_1.default(['package-lock.json', 'yarn.lock']);
|
282 | if (!lockfileLoc) {
|
283 | return;
|
284 | }
|
285 | const hashLoc = path_1.default.join(dir, LOCKFILE_HASH_FILE);
|
286 | const newLockHash = etag_1.default(await fs_1.default.promises.readFile(lockfileLoc));
|
287 | await mkdirp_1.default(path_1.default.dirname(hashLoc));
|
288 | await fs_1.default.promises.writeFile(hashLoc, newLockHash);
|
289 | }
|
290 | exports.updateLockfileHash = updateLockfileHash;
|
291 | async function clearCache() {
|
292 | return Promise.all([
|
293 | cacache_1.default.rm.all(exports.BUILD_CACHE),
|
294 | local_1.default.clearCache(),
|
295 | remote_1.default.clearCache(),
|
296 | ]);
|
297 | }
|
298 | exports.clearCache = clearCache;
|
299 | function getAliasType(val) {
|
300 | if (isRemoteUrl(val)) {
|
301 | return 'url';
|
302 | }
|
303 | return !path_1.default.isAbsolute(val) ? 'package' : 'path';
|
304 | }
|
305 |
|
306 |
|
307 |
|
308 | function findMatchingAliasEntry(config, spec) {
|
309 |
|
310 | if (spec === '.' ||
|
311 | spec === '..' ||
|
312 | spec.startsWith('./') ||
|
313 | spec.startsWith('../') ||
|
314 | spec.startsWith('/') ||
|
315 | spec.startsWith('http://') ||
|
316 | spec.startsWith('https://')) {
|
317 | return undefined;
|
318 | }
|
319 | for (const [from, to] of Object.entries(config.alias)) {
|
320 | const isExactMatch = spec === from;
|
321 | const isDeepMatch = spec.startsWith(addTrailingSlash(from));
|
322 | if (isExactMatch || isDeepMatch) {
|
323 | return {
|
324 | from,
|
325 | to,
|
326 | type: getAliasType(to),
|
327 | };
|
328 | }
|
329 | }
|
330 | }
|
331 | exports.findMatchingAliasEntry = findMatchingAliasEntry;
|
332 |
|
333 |
|
334 |
|
335 | function getExtensionMatch(fileName, extensionMap) {
|
336 | let extensionPartial;
|
337 | let extensionMatch;
|
338 |
|
339 | let extensionMatchIndex = Math.max(0, fileName.lastIndexOf('/'));
|
340 |
|
341 | while (!extensionMatch && extensionMatchIndex > -1) {
|
342 | extensionMatchIndex++;
|
343 | extensionMatchIndex = fileName.indexOf('.', extensionMatchIndex);
|
344 | extensionPartial = fileName.substr(extensionMatchIndex).toLowerCase();
|
345 | extensionMatch = extensionMap[extensionPartial];
|
346 | }
|
347 |
|
348 | return extensionMatch ? [extensionPartial, extensionMatch] : undefined;
|
349 | }
|
350 | exports.getExtensionMatch = getExtensionMatch;
|
351 | function isRemoteUrl(val) {
|
352 | var _a;
|
353 | return val.startsWith('//') || !!((_a = url_1.default.parse(val).protocol) === null || _a === void 0 ? void 0 : _a.startsWith('http'));
|
354 | }
|
355 | exports.isRemoteUrl = isRemoteUrl;
|
356 |
|
357 |
|
358 |
|
359 |
|
360 |
|
361 | function sanitizePackageName(filepath) {
|
362 | const dirs = filepath.split('/');
|
363 | const file = dirs.pop();
|
364 | return [...dirs.map((path) => path.replace(/\.js$/i, 'js')), file].join('/');
|
365 | }
|
366 | exports.sanitizePackageName = sanitizePackageName;
|
367 |
|
368 |
|
369 | function cssSourceMappingURL(code, sourceMappingURL) {
|
370 | return code + `/*# sourceMappingURL=${sourceMappingURL} */`;
|
371 | }
|
372 | exports.cssSourceMappingURL = cssSourceMappingURL;
|
373 |
|
374 | function jsSourceMappingURL(code, sourceMappingURL) {
|
375 | return code.replace(/\n*$/, '') + `\n//# sourceMappingURL=${sourceMappingURL}\n`;
|
376 | }
|
377 | exports.jsSourceMappingURL = jsSourceMappingURL;
|
378 |
|
379 | function relativeURL(path1, path2) {
|
380 | let url = path_1.default.relative(path1, path2).replace(/\\/g, '/');
|
381 | if (!url.startsWith('./') && !url.startsWith('../')) {
|
382 | url = './' + url;
|
383 | }
|
384 | return url;
|
385 | }
|
386 | exports.relativeURL = relativeURL;
|
387 | const CLOSING_HEAD_TAG = /<\s*\/\s*head\s*>/gi;
|
388 |
|
389 | function appendHtmlToHead(doc, htmlToAdd) {
|
390 | const closingHeadMatch = doc.match(CLOSING_HEAD_TAG);
|
391 |
|
392 | if (!closingHeadMatch) {
|
393 | throw new Error(`No <head> tag found in HTML (this is needed to optimize your app):\n${doc}`);
|
394 | }
|
395 |
|
396 | if (closingHeadMatch.length > 1) {
|
397 | throw new Error(`Multiple <head> tags found in HTML (perhaps commented out?):\n${doc}`);
|
398 | }
|
399 | return doc.replace(closingHeadMatch[0], htmlToAdd + closingHeadMatch[0]);
|
400 | }
|
401 | exports.appendHtmlToHead = appendHtmlToHead;
|
402 | function isJavaScript(pathname) {
|
403 | const ext = path_1.default.extname(pathname).toLowerCase();
|
404 | return ext === '.js' || ext === '.mjs' || ext === '.cjs';
|
405 | }
|
406 | exports.isJavaScript = isJavaScript;
|
407 | function getExtension(str) {
|
408 | return path_1.default.extname(str).toLowerCase();
|
409 | }
|
410 | exports.getExtension = getExtension;
|
411 | function hasExtension(str, ext) {
|
412 | return new RegExp(`\\${ext}$`, 'i').test(str);
|
413 | }
|
414 | exports.hasExtension = hasExtension;
|
415 | function replaceExtension(fileName, oldExt, newExt) {
|
416 | const extToReplace = new RegExp(`\\${oldExt}$`, 'i');
|
417 | return fileName.replace(extToReplace, newExt);
|
418 | }
|
419 | exports.replaceExtension = replaceExtension;
|
420 | function addExtension(fileName, newExt) {
|
421 | return fileName + newExt;
|
422 | }
|
423 | exports.addExtension = addExtension;
|
424 | function removeExtension(fileName, oldExt) {
|
425 | return replaceExtension(fileName, oldExt, '');
|
426 | }
|
427 | exports.removeExtension = removeExtension;
|
428 |
|
429 | function addLeadingSlash(path) {
|
430 | return path.replace(/^\/?/, '/');
|
431 | }
|
432 | exports.addLeadingSlash = addLeadingSlash;
|
433 |
|
434 | function addTrailingSlash(path) {
|
435 | return path.replace(/\/?$/, '/');
|
436 | }
|
437 | exports.addTrailingSlash = addTrailingSlash;
|
438 |
|
439 | function removeLeadingSlash(path) {
|
440 | return path.replace(/^[/\\]+/, '');
|
441 | }
|
442 | exports.removeLeadingSlash = removeLeadingSlash;
|
443 |
|
444 | function removeTrailingSlash(path) {
|
445 | return path.replace(/[/\\]+$/, '');
|
446 | }
|
447 | exports.removeTrailingSlash = removeTrailingSlash;
|
448 | exports.HMR_CLIENT_CODE = fs_1.default.readFileSync(path_1.default.resolve(__dirname, '../assets/hmr-client.js'), 'utf8');
|
449 | exports.HMR_OVERLAY_CODE = fs_1.default.readFileSync(path_1.default.resolve(__dirname, '../assets/hmr-error-overlay.js'), 'utf8');
|
450 | exports.INIT_TEMPLATE_FILE = fs_1.default.readFileSync(path_1.default.resolve(__dirname, '../assets/snowpack-init-file.js'), 'utf8');
|