@parcel/utils 2.0.0-beta.1 → 2.0.0-nightly.1002
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.js +6 -6
- package/lib/index.js +35850 -337
- package/lib/index.js.map +1 -0
- package/package.json +42 -20
- package/src/DefaultMap.js +1 -1
- package/src/PromiseQueue.js +16 -12
- package/src/alternatives.js +143 -0
- package/src/ansi-html.js +2 -2
- package/src/blob.js +2 -1
- package/src/bundle-url.js +1 -1
- package/src/collection.js +14 -14
- package/src/config.js +93 -53
- package/src/countLines.js +5 -2
- package/src/debounce.js +1 -1
- package/src/dependency-location.js +11 -6
- package/src/generateBuildMetrics.js +5 -5
- package/src/generateCertificate.js +1 -1
- package/src/getCertificate.js +1 -1
- package/src/getExisting.js +1 -4
- package/src/getRootDir.js +1 -2
- package/src/glob.js +36 -5
- package/src/hash.js +34 -0
- package/src/http-server.js +4 -11
- package/src/index.js +47 -20
- package/src/is-url.js +1 -1
- package/src/isDirectoryInside.js +4 -1
- package/src/openInBrowser.js +3 -1
- package/src/path.js +17 -2
- package/src/prettyDiagnostic.js +39 -27
- package/src/relativeBundlePath.js +5 -7
- package/src/replaceBundleReferences.js +50 -34
- package/src/schema.js +96 -42
- package/src/shared-buffer.js +24 -0
- package/src/sourcemap.js +84 -10
- package/src/urlJoin.js +3 -1
- package/test/DefaultMap.test.js +7 -4
- package/test/config.test.js +50 -0
- package/test/input/config/config.json +3 -0
- package/test/input/config/empty.json +0 -0
- package/test/input/config/empty.toml +0 -0
- package/test/input/sourcemap/referenced-min.js +1 -1
- package/test/replaceBundleReferences.test.js +268 -0
- package/test/sourcemap.test.js +5 -9
- package/test/throttle.test.js +1 -2
- package/test/urlJoin.test.js +37 -0
- package/lib/DefaultMap.js +0 -64
- package/lib/Deferred.js +0 -26
- package/lib/PromiseQueue.js +0 -133
- package/lib/TapStream.js +0 -38
- package/lib/ansi-html.js +0 -16
- package/lib/blob.js +0 -31
- package/lib/bundle-url.js +0 -43
- package/lib/collection.js +0 -62
- package/lib/config.js +0 -109
- package/lib/countLines.js +0 -18
- package/lib/debounce.js +0 -20
- package/lib/dependency-location.js +0 -21
- package/lib/escape-html.js +0 -24
- package/lib/escape-markdown.js +0 -15
- package/lib/generateBuildMetrics.js +0 -124
- package/lib/generateCertificate.js +0 -124
- package/lib/getCertificate.js +0 -19
- package/lib/getExisting.js +0 -23
- package/lib/getRootDir.js +0 -55
- package/lib/glob.js +0 -69
- package/lib/http-server.js +0 -81
- package/lib/is-url.js +0 -17
- package/lib/isDirectoryInside.js +0 -16
- package/lib/md5.js +0 -40
- package/lib/objectHash.js +0 -26
- package/lib/openInBrowser.js +0 -70
- package/lib/parseCSSImport.js +0 -16
- package/lib/path.js +0 -30
- package/lib/prettifyTime.js +0 -10
- package/lib/prettyDiagnostic.js +0 -75
- package/lib/promisify.js +0 -13
- package/lib/relativeBundlePath.js +0 -18
- package/lib/relativeUrl.js +0 -16
- package/lib/replaceBundleReferences.js +0 -166
- package/lib/resolve.js +0 -108
- package/lib/schema.js +0 -321
- package/lib/serializeObject.js +0 -28
- package/lib/sourcemap.js +0 -58
- package/lib/stream.js +0 -78
- package/lib/throttle.js +0 -16
- package/lib/urlJoin.js +0 -27
- package/src/.babelrc +0 -3
- package/src/escape-markdown.js +0 -10
- package/src/md5.js +0 -49
- package/src/promisify.js +0 -13
- package/src/resolve.js +0 -216
- package/src/serializeObject.js +0 -22
- package/test/escapeMarkdown.test.js +0 -29
package/src/schema.js
CHANGED
|
@@ -1,15 +1,20 @@
|
|
|
1
1
|
// @flow strict-local
|
|
2
2
|
import ThrowableDiagnostic, {
|
|
3
3
|
generateJSONCodeHighlights,
|
|
4
|
+
escapeMarkdown,
|
|
5
|
+
encodeJSONKeyComponent,
|
|
4
6
|
} from '@parcel/diagnostic';
|
|
7
|
+
import type {Mapping} from 'json-source-map';
|
|
8
|
+
import nullthrows from 'nullthrows';
|
|
5
9
|
// flowlint-next-line untyped-import:off
|
|
6
|
-
import
|
|
10
|
+
import levenshtein from 'fastest-levenshtein';
|
|
7
11
|
|
|
8
12
|
export type SchemaEntity =
|
|
9
13
|
| SchemaObject
|
|
10
14
|
| SchemaArray
|
|
11
15
|
| SchemaBoolean
|
|
12
16
|
| SchemaString
|
|
17
|
+
| SchemaNumber
|
|
13
18
|
| SchemaEnum
|
|
14
19
|
| SchemaOneOf
|
|
15
20
|
| SchemaAllOf
|
|
@@ -40,6 +45,11 @@ export type SchemaString = {|
|
|
|
40
45
|
__validate?: (val: string) => ?string,
|
|
41
46
|
__type?: string,
|
|
42
47
|
|};
|
|
48
|
+
export type SchemaNumber = {|
|
|
49
|
+
type: 'number',
|
|
50
|
+
enum?: Array<number>,
|
|
51
|
+
__type?: string,
|
|
52
|
+
|};
|
|
43
53
|
export type SchemaEnum = {|
|
|
44
54
|
enum: Array<mixed>,
|
|
45
55
|
|};
|
|
@@ -88,7 +98,7 @@ export type SchemaError =
|
|
|
88
98
|
prop: string,
|
|
89
99
|
expectedProps: Array<string>,
|
|
90
100
|
actualProps: Array<string>,
|
|
91
|
-
dataType:
|
|
101
|
+
dataType: 'key' | 'value',
|
|
92
102
|
|
|
93
103
|
dataPath: string,
|
|
94
104
|
ancestors: Array<SchemaEntity>,
|
|
@@ -99,7 +109,6 @@ export type SchemaError =
|
|
|
99
109
|
actualValue: mixed,
|
|
100
110
|
dataType: ?'key' | 'value',
|
|
101
111
|
message?: string,
|
|
102
|
-
|
|
103
112
|
dataPath: string,
|
|
104
113
|
ancestors: Array<SchemaEntity>,
|
|
105
114
|
|};
|
|
@@ -159,8 +168,7 @@ function validateSchema(schema: SchemaEntity, data: mixed): Array<SchemaError> {
|
|
|
159
168
|
}
|
|
160
169
|
} else if (schemaNode.__validate) {
|
|
161
170
|
let validationError = schemaNode.__validate(value);
|
|
162
|
-
|
|
163
|
-
if (validationError) {
|
|
171
|
+
if (typeof validationError == 'string') {
|
|
164
172
|
return {
|
|
165
173
|
type: 'other',
|
|
166
174
|
dataType: 'value',
|
|
@@ -173,6 +181,23 @@ function validateSchema(schema: SchemaEntity, data: mixed): Array<SchemaError> {
|
|
|
173
181
|
}
|
|
174
182
|
break;
|
|
175
183
|
}
|
|
184
|
+
case 'number': {
|
|
185
|
+
// $FlowFixMe type was already checked
|
|
186
|
+
let value: number = dataNode;
|
|
187
|
+
if (schemaNode.enum) {
|
|
188
|
+
if (!schemaNode.enum.includes(value)) {
|
|
189
|
+
return {
|
|
190
|
+
type: 'enum',
|
|
191
|
+
dataType: 'value',
|
|
192
|
+
dataPath,
|
|
193
|
+
expectedValues: schemaNode.enum,
|
|
194
|
+
actualValue: value,
|
|
195
|
+
ancestors: schemaAncestors,
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
break;
|
|
200
|
+
}
|
|
176
201
|
case 'object': {
|
|
177
202
|
let results: Array<Array<SchemaError> | SchemaError> = [];
|
|
178
203
|
let invalidProps;
|
|
@@ -187,7 +212,7 @@ function validateSchema(schema: SchemaEntity, data: mixed): Array<SchemaError> {
|
|
|
187
212
|
k =>
|
|
188
213
|
({
|
|
189
214
|
type: 'forbidden-prop',
|
|
190
|
-
dataPath: dataPath + '/' + k,
|
|
215
|
+
dataPath: dataPath + '/' + encodeJSONKeyComponent(k),
|
|
191
216
|
dataType: 'key',
|
|
192
217
|
prop: k,
|
|
193
218
|
expectedProps: Object.keys(schemaNode.properties),
|
|
@@ -209,7 +234,7 @@ function validateSchema(schema: SchemaEntity, data: mixed): Array<SchemaError> {
|
|
|
209
234
|
({
|
|
210
235
|
type: 'missing-prop',
|
|
211
236
|
dataPath,
|
|
212
|
-
dataType:
|
|
237
|
+
dataType: 'value',
|
|
213
238
|
prop: k,
|
|
214
239
|
expectedProps: schemaNode.required,
|
|
215
240
|
actualProps: keys,
|
|
@@ -230,7 +255,7 @@ function validateSchema(schema: SchemaEntity, data: mixed): Array<SchemaError> {
|
|
|
230
255
|
[schemaNode.properties[k]].concat(schemaAncestors),
|
|
231
256
|
// $FlowFixMe type was already checked
|
|
232
257
|
dataNode[k],
|
|
233
|
-
dataPath + '/' + k,
|
|
258
|
+
dataPath + '/' + encodeJSONKeyComponent(k),
|
|
234
259
|
);
|
|
235
260
|
if (result) results.push(result);
|
|
236
261
|
} else {
|
|
@@ -239,7 +264,7 @@ function validateSchema(schema: SchemaEntity, data: mixed): Array<SchemaError> {
|
|
|
239
264
|
results.push({
|
|
240
265
|
type: 'enum',
|
|
241
266
|
dataType: 'key',
|
|
242
|
-
dataPath: dataPath + '/' + k,
|
|
267
|
+
dataPath: dataPath + '/' + encodeJSONKeyComponent(k),
|
|
243
268
|
expectedValues: Object.keys(
|
|
244
269
|
schemaNode.properties,
|
|
245
270
|
).filter(
|
|
@@ -256,7 +281,7 @@ function validateSchema(schema: SchemaEntity, data: mixed): Array<SchemaError> {
|
|
|
256
281
|
[additionalProperties].concat(schemaAncestors),
|
|
257
282
|
// $FlowFixMe type was already checked
|
|
258
283
|
dataNode[k],
|
|
259
|
-
dataPath + '/' + k,
|
|
284
|
+
dataPath + '/' + encodeJSONKeyComponent(k),
|
|
260
285
|
);
|
|
261
286
|
if (result) results.push(result);
|
|
262
287
|
}
|
|
@@ -344,7 +369,7 @@ export function fuzzySearch(
|
|
|
344
369
|
actualValue: string,
|
|
345
370
|
): Array<string> {
|
|
346
371
|
let result = expectedValues
|
|
347
|
-
.map(exp => [exp,
|
|
372
|
+
.map(exp => [exp, levenshtein.distance(exp, actualValue)])
|
|
348
373
|
.filter(
|
|
349
374
|
// Remove if more than half of the string would need to be changed
|
|
350
375
|
([, d]) => d * 2 < actualValue.length,
|
|
@@ -353,22 +378,43 @@ export function fuzzySearch(
|
|
|
353
378
|
return result.map(([v]) => v);
|
|
354
379
|
}
|
|
355
380
|
|
|
356
|
-
validateSchema.diagnostic = function(
|
|
381
|
+
validateSchema.diagnostic = function (
|
|
357
382
|
schema: SchemaEntity,
|
|
358
|
-
data:
|
|
359
|
-
|
|
360
|
-
|
|
383
|
+
data: {|
|
|
384
|
+
...
|
|
385
|
+
| {|
|
|
386
|
+
source?: ?string,
|
|
387
|
+
data?: mixed,
|
|
388
|
+
|}
|
|
389
|
+
| {|
|
|
390
|
+
source: string,
|
|
391
|
+
map: {|
|
|
392
|
+
data: mixed,
|
|
393
|
+
pointers: {|[key: string]: Mapping|},
|
|
394
|
+
|},
|
|
395
|
+
|},
|
|
396
|
+
filePath?: ?string,
|
|
397
|
+
prependKey?: ?string,
|
|
398
|
+
|},
|
|
361
399
|
origin: string,
|
|
362
|
-
prependKey: string,
|
|
363
400
|
message: string,
|
|
364
401
|
): void {
|
|
365
|
-
|
|
402
|
+
if (
|
|
403
|
+
'source' in data &&
|
|
404
|
+
'data' in data &&
|
|
405
|
+
typeof data.source !== 'string' &&
|
|
406
|
+
!data
|
|
407
|
+
) {
|
|
408
|
+
throw new Error(
|
|
409
|
+
'At least one of data.source and data.source must be defined!',
|
|
410
|
+
);
|
|
411
|
+
}
|
|
412
|
+
let object = data.map
|
|
413
|
+
? data.map.data
|
|
414
|
+
: // $FlowFixMe we can assume it's a JSON object
|
|
415
|
+
data.data ?? JSON.parse(data.source);
|
|
416
|
+
let errors = validateSchema(schema, object);
|
|
366
417
|
if (errors.length) {
|
|
367
|
-
let dataContentsString: string =
|
|
368
|
-
typeof dataContents === 'string'
|
|
369
|
-
? dataContents
|
|
370
|
-
: // $FlowFixMe
|
|
371
|
-
JSON.stringify(dataContents, null, '\t');
|
|
372
418
|
let keys = errors.map(e => {
|
|
373
419
|
let message;
|
|
374
420
|
if (e.type === 'enum') {
|
|
@@ -406,10 +452,8 @@ validateSchema.diagnostic = function(
|
|
|
406
452
|
let {prop, actualProps} = e;
|
|
407
453
|
let likely = fuzzySearch(actualProps, prop);
|
|
408
454
|
if (likely.length > 0) {
|
|
409
|
-
message = `Did you mean ${
|
|
410
|
-
|
|
411
|
-
.join(', ')}?`;
|
|
412
|
-
e.dataPath += '/' + prop;
|
|
455
|
+
message = `Did you mean ${JSON.stringify(prop)}?`;
|
|
456
|
+
e.dataPath += '/' + likely[0];
|
|
413
457
|
e.dataType = 'key';
|
|
414
458
|
} else {
|
|
415
459
|
message = `Missing property ${prop}`;
|
|
@@ -425,26 +469,36 @@ validateSchema.diagnostic = function(
|
|
|
425
469
|
}
|
|
426
470
|
return {key: e.dataPath, type: e.dataType, message};
|
|
427
471
|
});
|
|
428
|
-
let
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
472
|
+
let map, code;
|
|
473
|
+
if (data.map) {
|
|
474
|
+
map = data.map;
|
|
475
|
+
code = data.source;
|
|
476
|
+
} else {
|
|
477
|
+
// $FlowFixMe we can assume that data is valid JSON
|
|
478
|
+
map = data.source ?? JSON.stringify(nullthrows(data.data), 0, '\t');
|
|
479
|
+
code = map;
|
|
480
|
+
}
|
|
481
|
+
let codeFrames = [
|
|
482
|
+
{
|
|
483
|
+
filePath: data.filePath ?? undefined,
|
|
484
|
+
language: 'json',
|
|
485
|
+
code,
|
|
486
|
+
codeHighlights: generateJSONCodeHighlights(
|
|
487
|
+
map,
|
|
488
|
+
keys.map(({key, type, message}) => ({
|
|
489
|
+
key: (data.prependKey ?? '') + key,
|
|
490
|
+
type: type,
|
|
491
|
+
message: message != null ? escapeMarkdown(message) : message,
|
|
492
|
+
})),
|
|
493
|
+
),
|
|
494
|
+
},
|
|
495
|
+
];
|
|
439
496
|
|
|
440
497
|
throw new ThrowableDiagnostic({
|
|
441
498
|
diagnostic: {
|
|
442
|
-
message,
|
|
499
|
+
message: message,
|
|
443
500
|
origin,
|
|
444
|
-
|
|
445
|
-
filePath: dataContentsPath || undefined,
|
|
446
|
-
language: 'json',
|
|
447
|
-
codeFrame,
|
|
501
|
+
codeFrames,
|
|
448
502
|
},
|
|
449
503
|
});
|
|
450
504
|
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
// @flow
|
|
2
|
+
/* global MessageChannel:readonly */
|
|
3
|
+
|
|
4
|
+
export let SharedBuffer: Class<ArrayBuffer> | Class<SharedArrayBuffer>;
|
|
5
|
+
|
|
6
|
+
// $FlowFixMe[prop-missing]
|
|
7
|
+
if (process.browser) {
|
|
8
|
+
SharedBuffer = ArrayBuffer;
|
|
9
|
+
// Safari has removed the constructor
|
|
10
|
+
if (typeof SharedArrayBuffer !== 'undefined') {
|
|
11
|
+
let channel = new MessageChannel();
|
|
12
|
+
try {
|
|
13
|
+
// Firefox might throw when sending the Buffer over a MessagePort
|
|
14
|
+
channel.port1.postMessage(new SharedArrayBuffer(0));
|
|
15
|
+
SharedBuffer = SharedArrayBuffer;
|
|
16
|
+
} catch (_) {
|
|
17
|
+
// NOOP
|
|
18
|
+
}
|
|
19
|
+
channel.port1.close();
|
|
20
|
+
channel.port2.close();
|
|
21
|
+
}
|
|
22
|
+
} else {
|
|
23
|
+
SharedBuffer = SharedArrayBuffer;
|
|
24
|
+
}
|
package/src/sourcemap.js
CHANGED
|
@@ -1,13 +1,27 @@
|
|
|
1
1
|
// @flow
|
|
2
|
+
import type {SourceLocation} from '@parcel/types';
|
|
2
3
|
import type {FileSystem} from '@parcel/fs';
|
|
3
4
|
import SourceMap from '@parcel/source-map';
|
|
4
5
|
import path from 'path';
|
|
5
|
-
import {normalizeSeparators} from './path';
|
|
6
|
+
import {normalizeSeparators, isAbsolute} from './path';
|
|
6
7
|
|
|
7
|
-
const SOURCEMAP_RE =
|
|
8
|
+
export const SOURCEMAP_RE: RegExp =
|
|
9
|
+
/(?:\/\*|\/\/)\s*[@#]\s*sourceMappingURL\s*=\s*([^\s*]+)(?:\s*\*\/)?\s*$/;
|
|
8
10
|
const DATA_URL_RE = /^data:[^;]+(?:;charset=[^;]+)?;base64,(.*)/;
|
|
11
|
+
export const SOURCEMAP_EXTENSIONS: Set<string> = new Set<string>([
|
|
12
|
+
'css',
|
|
13
|
+
'es',
|
|
14
|
+
'es6',
|
|
15
|
+
'js',
|
|
16
|
+
'jsx',
|
|
17
|
+
'mjs',
|
|
18
|
+
'ts',
|
|
19
|
+
'tsx',
|
|
20
|
+
]);
|
|
9
21
|
|
|
10
|
-
export function matchSourceMappingURL(
|
|
22
|
+
export function matchSourceMappingURL(
|
|
23
|
+
contents: string,
|
|
24
|
+
): null | RegExp$matchResult {
|
|
11
25
|
return contents.match(SOURCEMAP_RE);
|
|
12
26
|
}
|
|
13
27
|
|
|
@@ -15,20 +29,29 @@ export async function loadSourceMapUrl(
|
|
|
15
29
|
fs: FileSystem,
|
|
16
30
|
filename: string,
|
|
17
31
|
contents: string,
|
|
18
|
-
) {
|
|
32
|
+
): Promise<?{|filename: string, map: any, url: string|}> {
|
|
19
33
|
let match = matchSourceMappingURL(contents);
|
|
20
34
|
if (match) {
|
|
21
35
|
let url = match[1].trim();
|
|
22
36
|
let dataURLMatch = url.match(DATA_URL_RE);
|
|
23
|
-
|
|
37
|
+
|
|
38
|
+
let mapFilePath;
|
|
39
|
+
if (dataURLMatch) {
|
|
40
|
+
mapFilePath = filename;
|
|
41
|
+
} else {
|
|
42
|
+
mapFilePath = url.replace(/^file:\/\//, '');
|
|
43
|
+
mapFilePath = isAbsolute(mapFilePath)
|
|
44
|
+
? mapFilePath
|
|
45
|
+
: path.join(path.dirname(filename), mapFilePath);
|
|
46
|
+
}
|
|
24
47
|
|
|
25
48
|
return {
|
|
26
49
|
url,
|
|
27
|
-
filename,
|
|
50
|
+
filename: mapFilePath,
|
|
28
51
|
map: JSON.parse(
|
|
29
52
|
dataURLMatch
|
|
30
53
|
? Buffer.from(dataURLMatch[1], 'base64').toString()
|
|
31
|
-
: await fs.readFile(
|
|
54
|
+
: await fs.readFile(mapFilePath, 'utf8'),
|
|
32
55
|
),
|
|
33
56
|
};
|
|
34
57
|
}
|
|
@@ -49,13 +72,64 @@ export async function loadSourceMap(
|
|
|
49
72
|
mapSourceRoot = path.join(mapSourceRoot, foundMap.map.sourceRoot);
|
|
50
73
|
}
|
|
51
74
|
|
|
52
|
-
let sourcemapInstance = new SourceMap();
|
|
53
|
-
sourcemapInstance.
|
|
75
|
+
let sourcemapInstance = new SourceMap(options.projectRoot);
|
|
76
|
+
sourcemapInstance.addVLQMap({
|
|
54
77
|
...foundMap.map,
|
|
55
78
|
sources: foundMap.map.sources.map(s => {
|
|
56
|
-
return path.
|
|
79
|
+
return path.join(mapSourceRoot, s);
|
|
57
80
|
}),
|
|
58
81
|
});
|
|
59
82
|
return sourcemapInstance;
|
|
60
83
|
}
|
|
61
84
|
}
|
|
85
|
+
|
|
86
|
+
export function remapSourceLocation(
|
|
87
|
+
loc: SourceLocation,
|
|
88
|
+
originalMap: SourceMap,
|
|
89
|
+
): SourceLocation {
|
|
90
|
+
let {
|
|
91
|
+
filePath,
|
|
92
|
+
start: {line: startLine, column: startCol},
|
|
93
|
+
end: {line: endLine, column: endCol},
|
|
94
|
+
} = loc;
|
|
95
|
+
let lineDiff = endLine - startLine;
|
|
96
|
+
let colDiff = endCol - startCol;
|
|
97
|
+
let start = originalMap.findClosestMapping(startLine, startCol);
|
|
98
|
+
let end = originalMap.findClosestMapping(endLine, endCol);
|
|
99
|
+
|
|
100
|
+
if (start?.original) {
|
|
101
|
+
if (start.source) {
|
|
102
|
+
filePath = start.source;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
({line: startLine, column: startCol} = start.original);
|
|
106
|
+
startCol++; // source map columns are 0-based
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
if (end?.original) {
|
|
110
|
+
({line: endLine, column: endCol} = end.original);
|
|
111
|
+
endCol++;
|
|
112
|
+
|
|
113
|
+
if (endLine < startLine) {
|
|
114
|
+
endLine = startLine;
|
|
115
|
+
endCol = startCol;
|
|
116
|
+
} else if (endLine === startLine && endCol < startCol && lineDiff === 0) {
|
|
117
|
+
endCol = startCol + colDiff;
|
|
118
|
+
}
|
|
119
|
+
} else {
|
|
120
|
+
endLine = startLine;
|
|
121
|
+
endCol = startCol;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
return {
|
|
125
|
+
filePath,
|
|
126
|
+
start: {
|
|
127
|
+
line: startLine,
|
|
128
|
+
column: startCol,
|
|
129
|
+
},
|
|
130
|
+
end: {
|
|
131
|
+
line: endLine,
|
|
132
|
+
column: endCol,
|
|
133
|
+
},
|
|
134
|
+
};
|
|
135
|
+
}
|
package/src/urlJoin.js
CHANGED
|
@@ -9,7 +9,9 @@ import path from 'path';
|
|
|
9
9
|
*/
|
|
10
10
|
export default function urlJoin(publicURL: string, assetPath: string): string {
|
|
11
11
|
const url = URL.parse(publicURL, false, true);
|
|
12
|
-
|
|
12
|
+
// Leading / ensures that paths with colons are not parsed as a protocol.
|
|
13
|
+
let p = assetPath.startsWith('/') ? assetPath : '/' + assetPath;
|
|
14
|
+
const assetUrl = URL.parse(p);
|
|
13
15
|
url.pathname = path.posix.join(url.pathname, assetUrl.pathname);
|
|
14
16
|
url.search = assetUrl.search;
|
|
15
17
|
url.hash = assetUrl.hash;
|
package/test/DefaultMap.test.js
CHANGED
|
@@ -5,10 +5,13 @@ import {DefaultMap} from '../src/DefaultMap';
|
|
|
5
5
|
|
|
6
6
|
describe('DefaultMap', () => {
|
|
7
7
|
it('constructs with entries just like Map', () => {
|
|
8
|
-
let map = new DefaultMap(
|
|
9
|
-
|
|
10
|
-
[
|
|
11
|
-
|
|
8
|
+
let map = new DefaultMap(
|
|
9
|
+
k => k,
|
|
10
|
+
[
|
|
11
|
+
[1, 3],
|
|
12
|
+
[2, 27],
|
|
13
|
+
],
|
|
14
|
+
);
|
|
12
15
|
assert.equal(map.get(1), 3);
|
|
13
16
|
assert.deepEqual(Array.from(map.entries()), [
|
|
14
17
|
[1, 3],
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
// @flow strict-local
|
|
2
|
+
|
|
3
|
+
import assert from 'assert';
|
|
4
|
+
import {loadConfig} from '../src/config';
|
|
5
|
+
import {inputFS as fs} from '@parcel/test-utils';
|
|
6
|
+
import path from 'path';
|
|
7
|
+
|
|
8
|
+
describe('loadConfig', () => {
|
|
9
|
+
it('load config with json', async () => {
|
|
10
|
+
assert.deepEqual(
|
|
11
|
+
(
|
|
12
|
+
await loadConfig(
|
|
13
|
+
fs,
|
|
14
|
+
path.join(__dirname, './input/config/config.json'),
|
|
15
|
+
['config.json'],
|
|
16
|
+
path.join(__dirname, './input/config/'),
|
|
17
|
+
)
|
|
18
|
+
)?.config,
|
|
19
|
+
{
|
|
20
|
+
hoge: 'fuga',
|
|
21
|
+
},
|
|
22
|
+
);
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
it('should throw error with empty string json', async () => {
|
|
26
|
+
// $FlowFixMe[prop-missing]
|
|
27
|
+
await assert.rejects(async () => {
|
|
28
|
+
await loadConfig(
|
|
29
|
+
fs,
|
|
30
|
+
path.join(__dirname, './input/config/empty.json'),
|
|
31
|
+
['empty.json'],
|
|
32
|
+
path.join(__dirname, './input/config/'),
|
|
33
|
+
);
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
it('should load with empty string config toml', async () => {
|
|
38
|
+
assert.deepEqual(
|
|
39
|
+
(
|
|
40
|
+
await loadConfig(
|
|
41
|
+
fs,
|
|
42
|
+
path.join(__dirname, './input/config/empty.toml'),
|
|
43
|
+
['empty.toml'],
|
|
44
|
+
path.join(__dirname, './input/config/'),
|
|
45
|
+
)
|
|
46
|
+
)?.config,
|
|
47
|
+
{},
|
|
48
|
+
);
|
|
49
|
+
});
|
|
50
|
+
});
|
|
File without changes
|
|
File without changes
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
function hello(){var l="Hello",o="world";console.log(l+" "+o+"!")}hello();
|
|
2
|
-
//# sourceMappingURL=referenced-min.js.map
|
|
2
|
+
//# sourceMappingURL=file://referenced-min.js.map
|