@marko/compiler 5.40.1 → 5.41.0
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/babel-utils.d.ts +14 -3
- package/dist/babel-plugin/index.js +23 -0
- package/dist/babel-plugin/parser.js +21 -3
- package/dist/babel-utils/assert.js +4 -4
- package/dist/babel-utils/imports.js +33 -2
- package/dist/babel-utils/tags.js +2 -1
- package/dist/taglib/finder/index.js +3 -1
- package/dist/taglib/loader/Taglib.js +19 -1
- package/dist/taglib/loader/index.js +2 -2
- package/dist/taglib/loader/loadTaglibFromFile.js +6 -2
- package/package.json +3 -3
package/babel-utils.d.ts
CHANGED
|
@@ -54,6 +54,10 @@ export interface TagDefinition {
|
|
|
54
54
|
isRepeated?: boolean;
|
|
55
55
|
targetProperty?: string;
|
|
56
56
|
taglibId: string;
|
|
57
|
+
/** Set when the taglib was discovered by resolving an installed package. */
|
|
58
|
+
packageName?: string;
|
|
59
|
+
/** The root directory of `packageName`, which contains all files for this tag. */
|
|
60
|
+
packageRoot?: string;
|
|
57
61
|
types?: string;
|
|
58
62
|
template?: string;
|
|
59
63
|
renderer?: string;
|
|
@@ -178,11 +182,14 @@ export function assertAllowedAttributes(
|
|
|
178
182
|
path: t.NodePath<t.MarkoTag>,
|
|
179
183
|
allowed: string[],
|
|
180
184
|
): void;
|
|
181
|
-
export function assertNoArgs(path: t.NodePath<t.MarkoTag
|
|
185
|
+
export function assertNoArgs(path: t.NodePath<t.MarkoTag>, hint?: string): void;
|
|
182
186
|
export function assertNoVar(path: t.NodePath<t.MarkoTag>): void;
|
|
183
187
|
export function assertNoAttributes(path: t.NodePath<t.MarkoTag>): void;
|
|
184
188
|
export function assertNoParams(path: t.NodePath<t.MarkoTag>): void;
|
|
185
|
-
export function assertNoAttributeTags(
|
|
189
|
+
export function assertNoAttributeTags(
|
|
190
|
+
path: t.NodePath<t.MarkoTag>,
|
|
191
|
+
hint?: string,
|
|
192
|
+
): void;
|
|
186
193
|
export function assertAttributesOrArgs(path: t.NodePath<t.MarkoTag>): void;
|
|
187
194
|
export function assertAttributesOrSingleArg(path: t.NodePath<t.MarkoTag>): void;
|
|
188
195
|
|
|
@@ -300,7 +307,11 @@ export function parseTemplateLiteral(
|
|
|
300
307
|
sourceEnd?: null | number,
|
|
301
308
|
): t.TemplateLiteral;
|
|
302
309
|
|
|
303
|
-
export function resolveRelativePath(
|
|
310
|
+
export function resolveRelativePath(
|
|
311
|
+
file: t.BabelFile,
|
|
312
|
+
request: string,
|
|
313
|
+
tagDef?: TagDefinition,
|
|
314
|
+
): string;
|
|
304
315
|
export function importDefault(
|
|
305
316
|
file: t.BabelFile,
|
|
306
317
|
request: string,
|
|
@@ -323,6 +323,29 @@ function getMarkoFile(code, fileOpts, markoOpts) {
|
|
|
323
323
|
try {
|
|
324
324
|
file.___compileStage = "analyze";
|
|
325
325
|
traverseAll(file, translator.analyze);
|
|
326
|
+
|
|
327
|
+
if (!markoOpts.errorRecovery) {
|
|
328
|
+
// Analyze failures are recorded as error diagnostics so the whole
|
|
329
|
+
// template reports at once (and editors compiling with
|
|
330
|
+
// `errorRecovery` keep them as recoverable diagnostics); mirror
|
|
331
|
+
// the parse layer by throwing them together at the stage's end.
|
|
332
|
+
const seen = new Set();
|
|
333
|
+
const errors = [];
|
|
334
|
+
for (const diag of meta.diagnostics) {
|
|
335
|
+
if (diag.type !== _diagnostics.DiagnosticType.Error) continue;
|
|
336
|
+
const key = `${
|
|
337
|
+
diag.loc ? `${diag.loc.start.line}:${diag.loc.start.column}` : ""}:${
|
|
338
|
+
diag.label}`;
|
|
339
|
+
if (seen.has(key)) continue;
|
|
340
|
+
seen.add(key);
|
|
341
|
+
errors.push(
|
|
342
|
+
(0, _buildCodeFrame.buildCodeFrameError)(filename, file.code, diag.loc, diag.label)
|
|
343
|
+
);
|
|
344
|
+
if (errors.length === 8) break;
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
(0, _mergeErrors.default)(errors);
|
|
348
|
+
}
|
|
326
349
|
} catch (e) {
|
|
327
350
|
compileCache.delete(id);
|
|
328
351
|
throw e;
|
|
@@ -16,6 +16,22 @@ var _buildCodeFrame = require("../util/build-code-frame");
|
|
|
16
16
|
var _mergeErrors = _interopRequireDefault(require("../util/merge-errors"));function _interopRequireDefault(e) {return e && e.__esModule ? e : { default: e };}
|
|
17
17
|
|
|
18
18
|
const noop = () => {};
|
|
19
|
+
const jsxStyleAttrValueReg = /^\{[\s\S]*\}$/;
|
|
20
|
+
// A brace wrapped attribute value that only parses once unwrapped is almost
|
|
21
|
+
// certainly a JSX/Svelte style value (eg `onClick={handler}`); say so instead
|
|
22
|
+
// of surfacing the bare expression parse error.
|
|
23
|
+
const withWrappedAttrValueHint = (file, part, rawValue, node) => {
|
|
24
|
+
const trimmed = rawValue.trim();
|
|
25
|
+
if (
|
|
26
|
+
node.type === "MarkoParseError" &&
|
|
27
|
+
jsxStyleAttrValueReg.test(trimmed) &&
|
|
28
|
+
(0, _babelUtils.parseExpression)(file, trimmed.slice(1, -1), part.value.start).type !==
|
|
29
|
+
"MarkoParseError")
|
|
30
|
+
{
|
|
31
|
+
node.label += `${node.label.endsWith(".") ? "" : "."} Attribute values in Marko are plain JavaScript expressions, not JSX; remove the wrapping \`{ }\`.`;
|
|
32
|
+
}
|
|
33
|
+
return node;
|
|
34
|
+
};
|
|
19
35
|
const emptyRange = (part) => part.start === part.end;
|
|
20
36
|
const isAttrTag = (tag) => tag.name.value?.[0] === "@";
|
|
21
37
|
const isStatementTag = (tag) => tag.tagDef?.parseOptions?.statement;
|
|
@@ -412,10 +428,12 @@ function parseMarko(file) {
|
|
|
412
428
|
onAttrValue(part) {
|
|
413
429
|
currentAttr.end = part.end;
|
|
414
430
|
currentAttr.bound = part.bound;
|
|
415
|
-
|
|
431
|
+
const rawAttrValue = parser.read(part.value);
|
|
432
|
+
currentAttr.value = withWrappedAttrValueHint(
|
|
416
433
|
file,
|
|
417
|
-
|
|
418
|
-
|
|
434
|
+
part,
|
|
435
|
+
rawAttrValue,
|
|
436
|
+
(0, _babelUtils.parseExpression)(file, rawAttrValue, part.value.start)
|
|
419
437
|
);
|
|
420
438
|
},
|
|
421
439
|
|
|
@@ -41,23 +41,23 @@ function assertNoParams(path) {
|
|
|
41
41
|
}
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
function assertNoAttributeTags(path) {
|
|
44
|
+
function assertNoAttributeTags(path, hint) {
|
|
45
45
|
if (path.node.attributeTags.length) {
|
|
46
46
|
throw path.hub.buildError(
|
|
47
47
|
path.node.attributeTags[0],
|
|
48
|
-
|
|
48
|
+
`Tag does not support nested attribute tags.${hint ? ` ${hint}` : ""}`
|
|
49
49
|
);
|
|
50
50
|
}
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
-
function assertNoArgs(path) {
|
|
53
|
+
function assertNoArgs(path, hint) {
|
|
54
54
|
const args = path.node.arguments;
|
|
55
55
|
if (args && args.length) {
|
|
56
56
|
const start = args[0].loc.start;
|
|
57
57
|
const end = args[args.length - 1].loc.end;
|
|
58
58
|
throw path.hub.buildError(
|
|
59
59
|
{ loc: { start, end } },
|
|
60
|
-
|
|
60
|
+
`Tag does not support arguments.${hint ? ` ${hint}` : ""}`
|
|
61
61
|
);
|
|
62
62
|
}
|
|
63
63
|
}
|
|
@@ -5,10 +5,13 @@ var _relativeImportPath = require("relative-import-path");function _interopRequi
|
|
|
5
5
|
|
|
6
6
|
const IMPORTS_KEY = Symbol();
|
|
7
7
|
const FS_START = _path.default.sep === "/" ? _path.default.sep : /^(.*?:)/.exec(_modules.cwd)[1];
|
|
8
|
+
const REG_NODE_MODULES = /[\\/]node_modules[\\/]/;
|
|
8
9
|
|
|
9
|
-
function resolveRelativePath(file, request) {
|
|
10
|
+
function resolveRelativePath(file, request, tagDef) {
|
|
10
11
|
if (request.startsWith(FS_START)) {
|
|
11
|
-
request =
|
|
12
|
+
request =
|
|
13
|
+
packageImportPath(file.opts.filename, tagDef, request) ||
|
|
14
|
+
(0, _relativeImportPath.relativeImportPath)(file.opts.filename, request);
|
|
12
15
|
}
|
|
13
16
|
|
|
14
17
|
if (file.markoOpts.optimize) {
|
|
@@ -21,6 +24,34 @@ function resolveRelativePath(file, request) {
|
|
|
21
24
|
return request;
|
|
22
25
|
}
|
|
23
26
|
|
|
27
|
+
/**
|
|
28
|
+
* A tag installed into `node_modules` is imported through the name its package was
|
|
29
|
+
* resolved by, since its path is a realpath which may not be importable at all.
|
|
30
|
+
*/
|
|
31
|
+
function packageImportPath(from, tagDef, request) {
|
|
32
|
+
if (!tagDef?.packageName || !REG_NODE_MODULES.test(request)) return;
|
|
33
|
+
|
|
34
|
+
const { packageRoot } = tagDef;
|
|
35
|
+
// Within the package we stay relative, both because it always resolves and
|
|
36
|
+
// because a self reference would only work if the package exports the tag.
|
|
37
|
+
if (!isWithin(packageRoot, request) || isWithin(packageRoot, from)) return;
|
|
38
|
+
|
|
39
|
+
const subPath = _path.default.relative(packageRoot, request);
|
|
40
|
+
return `${tagDef.packageName}/${subPath.split(_path.default.sep).join("/")}`;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function isWithin(dir, filename) {
|
|
44
|
+
const rel = _path.default.relative(dir, filename);
|
|
45
|
+
// `path.relative` walks out of the dir with `..`, or returns an absolute path
|
|
46
|
+
// when it cannot relate the two at all, eg across windows drives.
|
|
47
|
+
return (
|
|
48
|
+
!!rel &&
|
|
49
|
+
rel !== ".." &&
|
|
50
|
+
!rel.startsWith(`..${_path.default.sep}`) &&
|
|
51
|
+
!_path.default.isAbsolute(rel));
|
|
52
|
+
|
|
53
|
+
}
|
|
54
|
+
|
|
24
55
|
function importDefault(file, request, nameHint) {
|
|
25
56
|
const imports = getImports(file);
|
|
26
57
|
request = resolveRelativePath(file, request);
|
package/dist/babel-utils/tags.js
CHANGED
|
@@ -347,7 +347,8 @@ function resolveTagImport(path, request) {
|
|
|
347
347
|
const tagName = request.slice(1, -1);
|
|
348
348
|
const tagDef = (0, _taglib.getTagDefForTagName)(file, tagName);
|
|
349
349
|
const tagEntry = tagDef && (tagDef.renderer || tagDef.template);
|
|
350
|
-
const relativePath =
|
|
350
|
+
const relativePath =
|
|
351
|
+
tagEntry && (0, _imports.resolveRelativePath)(file, tagEntry, tagDef);
|
|
351
352
|
|
|
352
353
|
if (!relativePath) {
|
|
353
354
|
throw path.buildCodeFrameError(
|
|
@@ -124,7 +124,9 @@ function find(dirname, registeredTaglibs, tagDiscoveryDirs) {
|
|
|
124
124
|
rootPkg.__dirname
|
|
125
125
|
);
|
|
126
126
|
if (taglibPath) {
|
|
127
|
-
|
|
127
|
+
// Resolving realpaths the taglib, which for a virtual store (eg pnpm) bears
|
|
128
|
+
// no relation to how it is imported, so hold onto the name it resolved by.
|
|
129
|
+
var taglib = taglibLoader.loadTaglibFromFile(taglibPath, true, name);
|
|
128
130
|
addTaglib(taglib);
|
|
129
131
|
}
|
|
130
132
|
}
|
|
@@ -26,11 +26,12 @@ function handleImport(taglib, importedTaglib) {
|
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
class Taglib {
|
|
29
|
-
constructor(filePath, isFromPackageJson) {
|
|
29
|
+
constructor(filePath, isFromPackageJson, packageName) {
|
|
30
30
|
ok(filePath, '"filePath" expected');
|
|
31
31
|
this.filePath = this.path /* deprecated */ = this.id = filePath;
|
|
32
32
|
this.isFromPackageJson = isFromPackageJson === true;
|
|
33
33
|
this.dirname = path.dirname(this.filePath);
|
|
34
|
+
this.packageName = packageName;
|
|
34
35
|
this.scriptLang = undefined;
|
|
35
36
|
this.tags = {};
|
|
36
37
|
this.migrators = [];
|
|
@@ -72,6 +73,23 @@ class Taglib {
|
|
|
72
73
|
}
|
|
73
74
|
this.tags[tag.name] = tag;
|
|
74
75
|
tag.taglibId = this.id || this.path;
|
|
76
|
+
this.setTagPackage(tag);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
setPackageName(packageName) {
|
|
80
|
+
this.packageName = packageName;
|
|
81
|
+
for (var name in this.tags) {
|
|
82
|
+
if (hasOwnProperty.call(this.tags, name)) {
|
|
83
|
+
this.setTagPackage(this.tags[name]);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
setTagPackage(tag) {
|
|
89
|
+
if (this.packageName) {
|
|
90
|
+
tag.packageName = this.packageName;
|
|
91
|
+
tag.packageRoot = this.dirname;
|
|
92
|
+
}
|
|
75
93
|
}
|
|
76
94
|
|
|
77
95
|
addImport(path) {
|
|
@@ -8,8 +8,8 @@ function loadTaglibFromProps(taglib, taglibProps) {
|
|
|
8
8
|
return loaders.loadTaglibFromProps(taglib, taglibProps);
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
-
function loadTaglibFromFile(filePath, isFromPackageJson) {
|
|
12
|
-
return loaders.loadTaglibFromFile(filePath, isFromPackageJson);
|
|
11
|
+
function loadTaglibFromFile(filePath, isFromPackageJson, packageName) {
|
|
12
|
+
return loaders.loadTaglibFromFile(filePath, isFromPackageJson, packageName);
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
function loadTaglibFromDir(filePath, tagDiscoveryDir) {
|
|
@@ -4,7 +4,7 @@ var jsonFileReader = require("./json-file-reader");
|
|
|
4
4
|
var loaders = require("./loaders");
|
|
5
5
|
var types = require("./types");
|
|
6
6
|
|
|
7
|
-
function loadFromFile(filePath, isFromPackageJson) {
|
|
7
|
+
function loadFromFile(filePath, isFromPackageJson, packageName) {
|
|
8
8
|
ok(filePath, '"filePath" is required');
|
|
9
9
|
|
|
10
10
|
var taglib = cache.get(filePath);
|
|
@@ -12,11 +12,15 @@ function loadFromFile(filePath, isFromPackageJson) {
|
|
|
12
12
|
// Only load a taglib once by caching the loaded taglibs using the file
|
|
13
13
|
// system file path as the key
|
|
14
14
|
if (!taglib) {
|
|
15
|
-
taglib = new types.Taglib(filePath, isFromPackageJson);
|
|
15
|
+
taglib = new types.Taglib(filePath, isFromPackageJson, packageName);
|
|
16
16
|
cache.put(filePath, taglib);
|
|
17
17
|
|
|
18
18
|
var taglibProps = jsonFileReader.readFileSync(filePath);
|
|
19
19
|
loaders.loadTaglibFromProps(taglib, taglibProps);
|
|
20
|
+
} else if (packageName && !taglib.packageName) {
|
|
21
|
+
// The taglib may have first been loaded by walking up from a file within the
|
|
22
|
+
// package itself, in which case we did not yet know the name it is installed as.
|
|
23
|
+
taglib.setPackageName(packageName);
|
|
20
24
|
}
|
|
21
25
|
|
|
22
26
|
return taglib;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@marko/compiler",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.41.0",
|
|
4
4
|
"description": "Marko template to JS compiler.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"babel",
|
|
@@ -77,13 +77,13 @@
|
|
|
77
77
|
"lasso-package-root": "^1.0.1",
|
|
78
78
|
"raptor-regexp": "^1.0.1",
|
|
79
79
|
"raptor-util": "^3.2.0",
|
|
80
|
-
"relative-import-path": "^1.0.
|
|
80
|
+
"relative-import-path": "^1.0.1",
|
|
81
81
|
"resolve-from": "^5.0.0",
|
|
82
82
|
"self-closing-tags": "^1.0.1",
|
|
83
83
|
"source-map-support": "^0.5.21"
|
|
84
84
|
},
|
|
85
85
|
"devDependencies": {
|
|
86
|
-
"marko": "^5.39.
|
|
86
|
+
"marko": "^5.39.18"
|
|
87
87
|
},
|
|
88
88
|
"engines": {
|
|
89
89
|
"node": "18 || 20 || >=22"
|