mirror of
https://github.com/marko-js/marko.git
synced 2026-02-01 16:07:13 +00:00
feat: expose ability to intercept taglib errors
This commit is contained in:
parent
7ddbeb00f6
commit
4fc38e8001
7
.changeset/real-laws-walk.md
Normal file
7
.changeset/real-laws-walk.md
Normal file
@ -0,0 +1,7 @@
|
||||
---
|
||||
"@marko/compiler": minor
|
||||
"marko": minor
|
||||
"@marko/translator-default": minor
|
||||
---
|
||||
|
||||
Expose the ability to intercept errors from the taglib builder.
|
||||
12
package-lock.json
generated
12
package-lock.json
generated
@ -8133,11 +8133,6 @@
|
||||
"node": ">=0.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/property-handlers": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/property-handlers/-/property-handlers-1.1.1.tgz",
|
||||
"integrity": "sha512-bPlermJL6CETDwI6SxODyMzr1a0aXzbXpNGCW9SnsnetEMJdjon1mdgLbidSN7o47B2oqLOwXYzGyyIQHsQrmw=="
|
||||
},
|
||||
"node_modules/proxy-addr": {
|
||||
"version": "2.0.7",
|
||||
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
|
||||
@ -10502,7 +10497,6 @@
|
||||
"htmljs-parser": "^5.1.5",
|
||||
"jsesc": "^3.0.2",
|
||||
"lasso-package-root": "^1.0.1",
|
||||
"property-handlers": "^1.1.1",
|
||||
"raptor-regexp": "^1.0.1",
|
||||
"raptor-util": "^3.2.0",
|
||||
"resolve-from": "^5.0.0",
|
||||
@ -12209,7 +12203,6 @@
|
||||
"htmljs-parser": "^5.1.5",
|
||||
"jsesc": "^3.0.2",
|
||||
"lasso-package-root": "^1.0.1",
|
||||
"property-handlers": "^1.1.1",
|
||||
"raptor-regexp": "^1.0.1",
|
||||
"raptor-util": "^3.2.0",
|
||||
"resolve-from": "^5.0.0",
|
||||
@ -16740,11 +16733,6 @@
|
||||
"integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==",
|
||||
"dev": true
|
||||
},
|
||||
"property-handlers": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/property-handlers/-/property-handlers-1.1.1.tgz",
|
||||
"integrity": "sha512-bPlermJL6CETDwI6SxODyMzr1a0aXzbXpNGCW9SnsnetEMJdjon1mdgLbidSN7o47B2oqLOwXYzGyyIQHsQrmw=="
|
||||
},
|
||||
"proxy-addr": {
|
||||
"version": "2.0.7",
|
||||
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
|
||||
|
||||
8
packages/compiler/index.d.ts
vendored
8
packages/compiler/index.d.ts
vendored
@ -1,8 +1,9 @@
|
||||
import { SourceMap } from "magic-string";
|
||||
import { TaglibLookup } from "@marko/babel-utils";
|
||||
import * as types from "./babel-types";
|
||||
import Config from "./config";
|
||||
export { type Config, types };
|
||||
export { types };
|
||||
|
||||
export type Config = typeof import("./config")
|
||||
|
||||
type Dep = {
|
||||
type: string;
|
||||
@ -65,7 +66,8 @@ export namespace taglib {
|
||||
export function register(id: string, props: { [x: string]: unknown }): void;
|
||||
export function buildLookup(
|
||||
dirname: string,
|
||||
translator?: unknown
|
||||
translator?: unknown,
|
||||
onError?: (err: Error) => void
|
||||
): TaglibLookup;
|
||||
export function clearCaches(): void;
|
||||
}
|
||||
|
||||
@ -21,7 +21,6 @@
|
||||
"htmljs-parser": "^5.1.5",
|
||||
"jsesc": "^3.0.2",
|
||||
"lasso-package-root": "^1.0.1",
|
||||
"property-handlers": "^1.1.1",
|
||||
"raptor-regexp": "^1.0.1",
|
||||
"raptor-util": "^3.2.0",
|
||||
"resolve-from": "^5.0.0",
|
||||
|
||||
@ -8,7 +8,7 @@ import { parseMarko } from "./parser";
|
||||
import { visitor as migrate } from "./plugins/migrate";
|
||||
import { visitor as transform } from "./plugins/transform";
|
||||
import { MarkoFile } from "./file";
|
||||
import { curFS, setFS } from "../taglib/fs";
|
||||
import taglibConfig from "../taglib/config";
|
||||
import tryLoadTranslator from "../util/try-load-translator";
|
||||
import shouldOptimize from "../util/should-optimize";
|
||||
|
||||
@ -49,21 +49,21 @@ export default (api, markoOpts) => {
|
||||
curOpts = opts;
|
||||
},
|
||||
parserOverride(code) {
|
||||
let prevFS = curFS;
|
||||
setFS(markoOpts.fileSystem);
|
||||
let prevFS = taglibConfig.fs;
|
||||
taglibConfig.fs = markoOpts.fileSystem;
|
||||
try {
|
||||
const file = getMarkoFile(code, curOpts, markoOpts);
|
||||
const finalAst = t.cloneNode(file.ast, true);
|
||||
SOURCE_FILES.set(finalAst, file);
|
||||
return finalAst;
|
||||
} finally {
|
||||
setFS(prevFS);
|
||||
taglibConfig.fs = prevFS;
|
||||
}
|
||||
},
|
||||
pre(file) {
|
||||
let prevFS = curFS;
|
||||
let prevFS = taglibConfig.fs;
|
||||
taglibConfig.fs = markoOpts.fileSystem;
|
||||
curOpts = undefined;
|
||||
setFS(markoOpts.fileSystem);
|
||||
try {
|
||||
if (markoOpts.output === "source" || markoOpts.output === "migrate") {
|
||||
return file;
|
||||
@ -104,7 +104,7 @@ export default (api, markoOpts) => {
|
||||
metadata.marko.watchFiles = metadata.marko.watchFiles.filter(unique);
|
||||
file.path.scope.crawl(); // Ensure all scopes are accurate for subsequent babel plugins
|
||||
} finally {
|
||||
setFS(prevFS);
|
||||
taglibConfig.fs = prevFS;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@ -156,5 +156,5 @@ if (globalThis[MARKO_CONFIG_KEY]) {
|
||||
|
||||
export default config;
|
||||
|
||||
import { setFS } from "./taglib/fs";
|
||||
setFS(config.fileSystem);
|
||||
import taglibConfig from "./taglib/config";
|
||||
taglibConfig.fs = config.fileSystem;
|
||||
|
||||
6
packages/compiler/src/taglib/config.js
Normal file
6
packages/compiler/src/taglib/config.js
Normal file
@ -0,0 +1,6 @@
|
||||
module.exports = {
|
||||
fs: undefined,
|
||||
onError: err => {
|
||||
throw err;
|
||||
}
|
||||
};
|
||||
@ -1,7 +1,7 @@
|
||||
"use strict";
|
||||
var nodePath = require("path");
|
||||
var resolveFrom = require("resolve-from").silent;
|
||||
var taglibFS = require("../fs");
|
||||
var taglibConfig = require("../config");
|
||||
var taglibLoader = require("../loader");
|
||||
var lassoPackageRoot = require("lasso-package-root");
|
||||
var findCache = {};
|
||||
@ -148,7 +148,7 @@ function excludePackage(name) {
|
||||
|
||||
function existsSync(file) {
|
||||
try {
|
||||
taglibFS.curFS.statSync(file);
|
||||
taglibConfig.fs.statSync(file);
|
||||
return true;
|
||||
} catch (_) {
|
||||
return false;
|
||||
|
||||
@ -1,4 +0,0 @@
|
||||
export let curFS;
|
||||
export function setFS(fs) {
|
||||
curFS = fs;
|
||||
}
|
||||
@ -1,6 +1,7 @@
|
||||
import loader from "./loader";
|
||||
import finder from "./finder";
|
||||
import Lookup from "./lookup";
|
||||
import taglibConfig from "./config";
|
||||
import tryLoadTranslator from "../util/try-load-translator";
|
||||
|
||||
export const excludeDir = finder.excludeDir;
|
||||
@ -18,7 +19,7 @@ register("marko/html", markoHTMLTaglib);
|
||||
register("marko/svg", markoSVGTaglib);
|
||||
register("marko/math", markoMathTaglib);
|
||||
|
||||
export function buildLookup(dirname, requestedTranslator) {
|
||||
export function buildLookup(dirname, requestedTranslator, onError) {
|
||||
const translator = tryLoadTranslator(requestedTranslator);
|
||||
if (!translator || !Array.isArray(translator.taglibs)) {
|
||||
throw new Error(
|
||||
@ -26,19 +27,35 @@ export function buildLookup(dirname, requestedTranslator) {
|
||||
);
|
||||
}
|
||||
|
||||
if (!loadedTranslatorsTaglibs.has(translator)) {
|
||||
let taglibsForDir = loadedTranslatorsTaglibs.get(translator);
|
||||
|
||||
if (!taglibsForDir) {
|
||||
loadedTranslatorsTaglibs.set(
|
||||
translator,
|
||||
translator.taglibs.map(([id, props]) => loadTaglib(id, props))
|
||||
(taglibsForDir = registeredTaglibs.concat(
|
||||
translator.taglibs.map(([id, props]) => loadTaglib(id, props))
|
||||
))
|
||||
);
|
||||
}
|
||||
|
||||
const taglibsForDir = finder.find(
|
||||
dirname,
|
||||
registeredTaglibs.concat(loadedTranslatorsTaglibs.get(translator))
|
||||
);
|
||||
if (onError) {
|
||||
const prevOnError = taglibConfig.onError;
|
||||
taglibConfig.onError = onError;
|
||||
try {
|
||||
taglibsForDir = finder.find(dirname, taglibsForDir);
|
||||
} catch (err) {
|
||||
taglibConfig.onError(err);
|
||||
} finally {
|
||||
taglibConfig.onError = prevOnError;
|
||||
}
|
||||
} else {
|
||||
taglibsForDir = finder.find(dirname, taglibsForDir);
|
||||
}
|
||||
|
||||
const cacheKey = taglibsForDir.map(it => it.id).join();
|
||||
const cacheKey = taglibsForDir
|
||||
.map(it => it.id)
|
||||
.sort()
|
||||
.join();
|
||||
let lookup = lookupCache[cacheKey];
|
||||
|
||||
if (!lookup) {
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
var taglibFS = require("../fs");
|
||||
var taglibConfig = require("../config");
|
||||
var stripJsonComments = require("strip-json-comments");
|
||||
var fsReadOptions = { encoding: "utf8" };
|
||||
|
||||
exports.readFileSync = function (path) {
|
||||
var json = String(taglibFS.curFS.readFileSync(path, fsReadOptions));
|
||||
var json = String(taglibConfig.fs.readFileSync(path, fsReadOptions));
|
||||
|
||||
try {
|
||||
var taglibProps = JSON.parse(stripJsonComments(json));
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
|
||||
var assert = require("assert");
|
||||
var raptorRegexp = require("raptor-regexp");
|
||||
var propertyHandlers = require("property-handlers");
|
||||
var propertyHandlers = require("./property-handlers");
|
||||
var types = require("./types");
|
||||
var createError = require("raptor-util/createError");
|
||||
var hasOwnProperty = Object.prototype.hasOwnProperty;
|
||||
|
||||
@ -2,11 +2,11 @@
|
||||
|
||||
var ok = require("assert").ok;
|
||||
var resolveFrom = require("resolve-from").silent;
|
||||
var propertyHandlers = require("property-handlers");
|
||||
var propertyHandlers = require("./property-handlers");
|
||||
var isObjectEmpty = require("raptor-util/isObjectEmpty");
|
||||
var nodePath = require("path");
|
||||
var createError = require("raptor-util/createError");
|
||||
var taglibFS = require("../fs");
|
||||
var taglibConfig = require("../config");
|
||||
var types = require("./types");
|
||||
var loaders = require("./loaders");
|
||||
var markoModules = require("../../../modules");
|
||||
@ -315,7 +315,7 @@ class TagLoader {
|
||||
var path = nodePath.resolve(dirname, value);
|
||||
|
||||
try {
|
||||
taglibFS.curFS.statSync(path);
|
||||
taglibConfig.fs.statSync(path);
|
||||
tag.template = path;
|
||||
} catch (_) {
|
||||
throw new Error('Template at path "' + path + '" does not exist.');
|
||||
|
||||
@ -4,9 +4,9 @@ var ok = require("assert").ok;
|
||||
var resolveFrom = require("resolve-from").silent;
|
||||
var nodePath = require("path");
|
||||
var types = require("./types");
|
||||
var taglibFS = require("../fs");
|
||||
var taglibFS = require("../config");
|
||||
var scanTagsDir = require("./scanTagsDir");
|
||||
var propertyHandlers = require("property-handlers");
|
||||
var propertyHandlers = require("./property-handlers");
|
||||
var jsonFileReader = require("./json-file-reader");
|
||||
var DependencyChain = require("./DependencyChain");
|
||||
var createError = require("raptor-util/createError");
|
||||
@ -98,7 +98,7 @@ class TaglibLoader {
|
||||
tagFilePath = nodePath.resolve(this.dirname, value);
|
||||
|
||||
try {
|
||||
taglibFS.curFS.statSync(tagFilePath);
|
||||
taglibFS.fs.statSync(tagFilePath);
|
||||
} catch (_) {
|
||||
throw new Error(
|
||||
'Tag at path "' +
|
||||
|
||||
85
packages/compiler/src/taglib/loader/property-handlers.js
Normal file
85
packages/compiler/src/taglib/loader/property-handlers.js
Normal file
@ -0,0 +1,85 @@
|
||||
"use strict";
|
||||
|
||||
const { hasOwnProperty } = Object.prototype;
|
||||
const taglibConfig = require("../config");
|
||||
|
||||
function removeDashes(str) {
|
||||
return str.replace(/-([a-z])/g, function (match, lower) {
|
||||
return lower.toUpperCase();
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = function invokeHandlers(config, handlers, path) {
|
||||
function error(message, cause) {
|
||||
if (cause) {
|
||||
if (cause.__propertyHandlers) {
|
||||
throw cause;
|
||||
}
|
||||
|
||||
message += ". Cause: " + (cause.stack || cause);
|
||||
}
|
||||
|
||||
if (path) {
|
||||
message += " (" + path + ")";
|
||||
}
|
||||
|
||||
var e = new Error(message);
|
||||
e.__propertyHandlers = true;
|
||||
taglibConfig.onError(e);
|
||||
}
|
||||
|
||||
if (!config) {
|
||||
error('"config" argument is required');
|
||||
}
|
||||
|
||||
if (typeof config !== "object") {
|
||||
error("object expected");
|
||||
}
|
||||
|
||||
for (var k in config) {
|
||||
if (hasOwnProperty.call(config, k)) {
|
||||
var value = config[k];
|
||||
var keyNoDashes = removeDashes(k);
|
||||
var handler = handlers[keyNoDashes];
|
||||
var isDefaultHandler = false;
|
||||
|
||||
if (!handler) {
|
||||
handler = handlers["*"];
|
||||
isDefaultHandler = true;
|
||||
}
|
||||
|
||||
if (!handler) {
|
||||
var badProperty = JSON.stringify(k);
|
||||
if (k !== keyNoDashes) {
|
||||
badProperty += "/" + JSON.stringify(keyNoDashes);
|
||||
}
|
||||
error(
|
||||
"Invalid option of " +
|
||||
badProperty +
|
||||
". Allowed: " +
|
||||
Object.keys(handlers).join(", ")
|
||||
);
|
||||
}
|
||||
|
||||
try {
|
||||
if (isDefaultHandler) {
|
||||
if (handler.call(handlers, k, value) === false) {
|
||||
error("Invalid option: " + k);
|
||||
}
|
||||
} else {
|
||||
handler.call(handlers, value);
|
||||
}
|
||||
} catch (e) {
|
||||
error('Error while applying option of "' + k + '"', e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (handlers._end) {
|
||||
try {
|
||||
handlers._end();
|
||||
} catch (e) {
|
||||
error("Error after applying properties", e);
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -1,7 +1,7 @@
|
||||
"use strict";
|
||||
|
||||
const nodePath = require("path");
|
||||
const taglibFS = require("../fs");
|
||||
const taglibConfig = require("../config");
|
||||
const jsonFileReader = require("./json-file-reader");
|
||||
const tagDefFromCode = require("./tag-def-from-code");
|
||||
const loaders = require("./loaders");
|
||||
@ -48,7 +48,7 @@ function createDefaultTagDef() {
|
||||
|
||||
function getFileMap(dirname) {
|
||||
let fileMap = {};
|
||||
let files = taglibFS.curFS.readdirSync(dirname);
|
||||
let files = taglibConfig.fs.readdirSync(dirname);
|
||||
|
||||
files.forEach(file => {
|
||||
let extName = nodePath.extname(file);
|
||||
@ -77,7 +77,7 @@ function getPath(filename, fileMap) {
|
||||
|
||||
function findAndSetFile(tagDef, tagDirname) {
|
||||
try {
|
||||
if (!taglibFS.curFS.statSync(tagDirname).isDirectory()) {
|
||||
if (!taglibConfig.fs.statSync(tagDirname).isDirectory()) {
|
||||
return;
|
||||
}
|
||||
} catch (_) {
|
||||
@ -133,7 +133,7 @@ module.exports = function scanTagsDir(
|
||||
}
|
||||
|
||||
dir = nodePath.resolve(tagsConfigDirname, dir);
|
||||
let children = taglibFS.curFS.readdirSync(dir);
|
||||
let children = taglibConfig.fs.readdirSync(dir);
|
||||
|
||||
for (let i = 0, len = children.length; i < len; i++) {
|
||||
let childFilename = children[i];
|
||||
@ -160,7 +160,7 @@ module.exports = function scanTagsDir(
|
||||
|
||||
let hasTagJson = false;
|
||||
try {
|
||||
taglibFS.curFS.statSync(tagJsonPath);
|
||||
taglibConfig.fs.statSync(tagJsonPath);
|
||||
hasTagJson = true;
|
||||
// eslint-disable-next-line no-empty
|
||||
} catch (_) {}
|
||||
@ -191,7 +191,7 @@ module.exports = function scanTagsDir(
|
||||
|
||||
if (!hasTagJson && (tagDef.renderer || tagDef.template)) {
|
||||
let templateCode = String(
|
||||
taglibFS.curFS.readFileSync(
|
||||
taglibConfig.fs.readFileSync(
|
||||
tagDef.renderer || tagDef.template,
|
||||
fsReadOptions
|
||||
)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user