diff --git a/.licenserc.yaml b/.licenserc.yaml index 0f914f9..9c6170b 100644 --- a/.licenserc.yaml +++ b/.licenserc.yaml @@ -20,5 +20,6 @@ header: - node_modules/** - node_modules/.** - 'yarn.lock' + - 'jupyter_builder/yarn.js' comment: on-failure diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 1f2a14c..6da14b2 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -38,7 +38,7 @@ repos: hooks: - id: codespell args: ["-L", "sur,nd"] - exclude: jupyter_builder/yarn.js + exclude: "jupyter_builder/yarn.js|jupyter_builder/jupyterlab_semver.py" - repo: https://github.com/pre-commit/pygrep-hooks rev: "v1.10.0" diff --git a/jupyter_builder/federated_extensions.py b/jupyter_builder/federated_extensions.py index 27ace2e..b69f575 100644 --- a/jupyter_builder/federated_extensions.py +++ b/jupyter_builder/federated_extensions.py @@ -32,10 +32,9 @@ except ImportError: from tomli import load +from .commands import _test_overlap from .core_path import default_core_path -# from .commands import _test_overlap TO BE DONE ----------------------------- - DEPRECATED_ARGUMENT = object() HERE = osp.abspath(osp.dirname(__file__)) @@ -201,9 +200,7 @@ def build_labextension( # noqa: PLR0913 path, logger=None, development=False, static_url=None, source_map=False, core_path=None ): """Build a labextension in the given path""" - core_path = default_core_path() if core_path is None else str(Path(core_path).resolve()) - ext_path = str(Path(path).resolve()) if logger: @@ -293,23 +290,22 @@ def _ensure_builder(ext_path, core_path): raise ValueError(msg) target = osp.dirname(target) - # IGNORING Test Overlap --------------------------------- - - # overlap = _test_overlap( - # dep_version1, dep_version2, drop_prerelease1=True, drop_prerelease2=True - # ) - # if not overlap: - # with open( - # osp.join(target, "node_modules", "@jupyterlab", "builder", "package.json") - # ) as fid: - # dep_version2 = json.load(fid).get("version") - # overlap = _test_overlap( - # dep_version1, dep_version2, drop_prerelease1=True, drop_prerelease2=True - # ) - - # if not overlap: - # msg = f"Extensions require a devDependency on @jupyterlab/builder@{dep_version1}, you have a dependency on {dep_version2}" # noqa: E501 - # raise ValueError(msg) + # Check for compatible versions + overlap = _test_overlap( + dep_version1, dep_version2, drop_prerelease1=True, drop_prerelease2=True + ) + if not overlap: + with open( + osp.join(target, "node_modules", "@jupyterlab", "builder", "package.json") + ) as fid: + dep_version2 = json.load(fid).get("version") + overlap = _test_overlap( + dep_version1, dep_version2, drop_prerelease1=True, drop_prerelease2=True + ) + + if not overlap: + msg = f"Extensions require a devDependency on @jupyterlab/builder@{dep_version1}, you have a dependency on {dep_version2}" # noqa: E501 + raise ValueError(msg) return osp.join( target, "node_modules", "@jupyterlab", "builder", "lib", "build-labextension.js" diff --git a/jupyter_builder/jupyterlab_semver.py b/jupyter_builder/jupyterlab_semver.py index fd6d7c9..bb01354 100644 --- a/jupyter_builder/jupyterlab_semver.py +++ b/jupyter_builder/jupyterlab_semver.py @@ -32,6 +32,7 @@ logger = logging.getLogger(__name__) + SEMVER_SPEC_VERSION = "2.0.0" string_type = str @@ -549,8 +550,7 @@ def inc(self, release, identifier=None): else: self.prerelease = [identifier, 0] else: - msg = f"invalid increment argument: {release}" - raise ValueError(msg) + raise ValueError(f"invalid increment argument: {release}") self.format() self.raw = self.version return self @@ -639,9 +639,581 @@ def lt(a, b, loose): return compare(a, b, loose) < 0 +def eq(a, b, loose): + return compare(a, b, loose) == 0 + + +def neq(a, b, loose): + return compare(a, b, loose) != 0 + + def gte(a, b, loose): return compare(a, b, loose) >= 0 def lte(a, b, loose): return compare(a, b, loose) <= 0 + + +def cmp(a, op, b, loose): # noqa PLR0911 + logger.debug("cmp: %s", op) + if op == "===": + return a == b + elif op == "!==": + return a != b + elif op == "" or op == "=" or op == "==": + return eq(a, b, loose) + elif op == "!=": + return neq(a, b, loose) + elif op == ">": + return gt(a, b, loose) + elif op == ">=": + return gte(a, b, loose) + elif op == "<": + return lt(a, b, loose) + elif op == "<=": + return lte(a, b, loose) + else: + raise ValueError(f"Invalid operator: {op}") + + +def comparator(comp, loose): + if isinstance(comp, Comparator): + if comp.loose == loose: + return comp + else: + comp = comp.value + + # if (!(this instanceof Comparator)) + # return new Comparator(comp, loose) + return Comparator(comp, loose) + + +make_comparator = comparator + +ANY = object() + + +class Comparator: + semver = None + + def __init__(self, comp, loose): + logger.debug("comparator: %s %s", comp, loose) + self.loose = loose + self.parse(comp) + + if self.semver == ANY: + self.value = "" + else: + self.value = self.operator + self.semver.version + + def parse(self, comp): + r = regexp[COMPARATORLOOSE] if self.loose else regexp[COMPARATOR] + logger.debug("parse comp=%s", comp) + m = r.search(comp) + + if m is None: + raise ValueError(f"Invalid comparator: {comp}") + + self.operator = m.group(1) + # if it literally is just '>' or '' then allow anything. + if m.group(2) is None: + self.semver = ANY + else: + self.semver = semver(m.group(2), self.loose) + + def __repr__(self): + return f'' + + def __str__(self): + return self.value + + def test(self, version): + logger.debug("Comparator, test %s, %s", version, self.loose) + if self.semver == ANY: + return True + else: + return cmp(version, self.operator, self.semver, self.loose) + + +def make_range(range_, loose): + if isinstance(range_, Range) and range_.loose == loose: + return range_ + + # if (!(this instanceof Range)) + # return new Range(range, loose); + return Range(range_, loose) + + +class Range: + def __init__(self, range_, loose): + self.loose = loose + # First, split based on boolean or || + self.raw = range_ + xs = [self.parse_range(r.strip()) for r in re.split(r"\s*\|\|\s*", range_)] + self.set = [r for r in xs if r] + + if not len(self.set): + raise ValueError(f"Invalid SemVer Range: {range_}") + + self.format() + + def __repr__(self): + return f'' + + def format(self): + self.range = "||".join( + [" ".join(c.value for c in comps).strip() for comps in self.set] + ).strip() + logger.debug("Range format %s", self.range) + return self.range + + def __str__(self): + return self.range + + def parse_range(self, range_): + loose = self.loose + logger.debug("range %s %s", range_, loose) + # `1.2.3 - 1.2.4` => `>=1.2.3 <=1.2.4` + hr = regexp[HYPHENRANGELOOSE] if loose else regexp[HYPHENRANGE] + + range_ = hr.sub( + hyphen_replace, + range_, + ) + logger.debug("hyphen replace %s", range_) + + # `> 1.2.3 < 1.2.5` => `>1.2.3 <1.2.5` + range_ = regexp[COMPARATORTRIM].sub(comparatorTrimReplace, range_) + logger.debug("comparator trim %s, %s", range_, regexp[COMPARATORTRIM]) + + # `~ 1.2.3` => `~1.2.3` + range_ = regexp[TILDETRIM].sub(tildeTrimReplace, range_) + + # `^ 1.2.3` => `^1.2.3` + range_ = regexp[CARETTRIM].sub(caretTrimReplace, range_) + + # normalize spaces + range_ = " ".join(re.split(r"\s+", range_)) + + # At this point, the range is completely trimmed and + # ready to be split into comparators. + comp_re = regexp[COMPARATORLOOSE] if loose else regexp[COMPARATOR] + set_ = re.split( + r"\s+", " ".join([parse_comparator(comp, loose) for comp in range_.split(" ")]) + ) + if self.loose: + # in loose mode, throw out any that are not valid comparators + set_ = [comp for comp in set_ if comp_re.search(comp)] + set_ = [make_comparator(comp, loose) for comp in set_] + return set_ + + def test(self, version): + if not version: # xxx + return False + + if isinstance(version, string_type): + version = make_semver(version, loose=self.loose) + + return any(test_set(e, version) for e in self.set) + + +# Mostly just for testing and legacy API reasons +def to_comparators(range_, loose): + return [ + " ".join([c.value for c in comp]).strip().split(" ") + for comp in make_range(range_, loose).set + ] + + +# comprised of xranges, tildes, stars, and gtlt's at this point. +# already replaced the hyphen ranges +# turn into a set of JUST comparators. + + +def parse_comparator(comp, loose): + logger.debug("comp %s", comp) + comp = replace_carets(comp, loose) + logger.debug("caret %s", comp) + comp = replace_tildes(comp, loose) + logger.debug("tildes %s", comp) + comp = replace_xranges(comp, loose) + logger.debug("xrange %s", comp) + comp = replace_stars(comp, loose) + logger.debug("stars %s", comp) + return comp + + +def is_x(id_): + return id_ is None or id_ == "" or id_.lower() == "x" or id_ == "*" + + +# ~, ~> --> * (any, kinda silly) +# ~2, ~2.x, ~2.x.x, ~>2, ~>2.x ~>2.x.x --> >=2.0.0 <3.0.0 +# ~2.0, ~2.0.x, ~>2.0, ~>2.0.x --> >=2.0.0 <2.1.0 +# ~1.2, ~1.2.x, ~>1.2, ~>1.2.x --> >=1.2.0 <1.3.0 +# ~1.2.3, ~>1.2.3 --> >=1.2.3 <1.3.0 +# ~1.2.0, ~>1.2.0 --> >=1.2.0 <1.3.0 + + +def replace_tildes(comp, loose): + return " ".join([replace_tilde(c, loose) for c in re.split(r"\s+", comp.strip())]) + + +def replace_tilde(comp, loose): + r = regexp[TILDELOOSE] if loose else regexp[TILDE] + + def repl(mob): + _ = mob.group(0) + M, m, p, pr, _ = mob.groups() + logger.debug("tilde %s %s %s %s %s %s", comp, _, M, m, p, pr) + if is_x(M): + ret = "" + elif is_x(m): + ret = ">=" + M + ".0.0 <" + str(int(M) + 1) + ".0.0" + elif is_x(p): + # ~1.2 == >=1.2.0 <1.3.0 + ret = ">=" + M + "." + m + ".0 <" + M + "." + str(int(m) + 1) + ".0" + elif pr: + logger.debug("replaceTilde pr %s", pr) + if pr[0] != "-": + pr = "-" + pr + ret = ">=" + M + "." + m + "." + p + pr + " <" + M + "." + str(int(m) + 1) + ".0" + else: + # ~1.2.3 == >=1.2.3 <1.3.0 + ret = ">=" + M + "." + m + "." + p + " <" + M + "." + str(int(m) + 1) + ".0" + logger.debug("tilde return, %s", ret) + return ret + + return r.sub(repl, comp) + + +# ^ --> * (any, kinda silly) +# ^2, ^2.x, ^2.x.x --> >=2.0.0 <3.0.0 +# ^2.0, ^2.0.x --> >=2.0.0 <3.0.0 +# ^1.2, ^1.2.x --> >=1.2.0 <2.0.0 +# ^1.2.3 --> >=1.2.3 <2.0.0 +# ^1.2.0 --> >=1.2.0 <2.0.0 +def replace_carets(comp, loose): + return " ".join([replace_caret(c, loose) for c in re.split(r"\s+", comp.strip())]) + + +def replace_caret(comp, loose): + r = regexp[CARETLOOSE] if loose else regexp[CARET] + + def repl(mob): + m0 = mob.group(0) + M, m, p, pr, _ = mob.groups() + logger.debug("caret %s %s %s %s %s %s", comp, m0, M, m, p, pr) + + if is_x(M): + ret = "" + elif is_x(m): + ret = ">=" + M + ".0.0 <" + str(int(M) + 1) + ".0.0" + elif is_x(p): + if M == "0": + ret = ">=" + M + "." + m + ".0 <" + M + "." + str(int(m) + 1) + ".0" + else: + ret = ">=" + M + "." + m + ".0 <" + str(int(M) + 1) + ".0.0" + elif pr: + logger.debug("replaceCaret pr %s", pr) + if pr[0] != "-": + pr = "-" + pr + if M == "0": + if m == "0": + ret = ( + ">=" + + M + + "." + + m + + "." + + (p or "") + + pr + + " <" + + M + + "." + + m + + "." + + str(int(p or 0) + 1) + ) + else: + ret = ( + ">=" + + M + + "." + + m + + "." + + (p or "") + + pr + + " <" + + M + + "." + + str(int(m) + 1) + + ".0" + ) + else: + ret = ">=" + M + "." + m + "." + (p or "") + pr + " <" + str(int(M) + 1) + ".0.0" + else: + if M == "0": + if m == "0": + ret = ( + ">=" + + M + + "." + + m + + "." + + (p or "") + + " <" + + M + + "." + + m + + "." + + str(int(p or 0) + 1) + ) + else: + ret = ( + ">=" + + M + + "." + + m + + "." + + (p or "") + + " <" + + M + + "." + + str(int(m) + 1) + + ".0" + ) + else: + ret = ">=" + M + "." + m + "." + (p or "") + " <" + str(int(M) + 1) + ".0.0" + logger.debug("caret return %s", ret) + return ret + + return r.sub(repl, comp) + + +def replace_xranges(comp, loose): + logger.debug("replaceXRanges %s %s", comp, loose) + return " ".join([replace_xrange(c, loose) for c in re.split(r"\s+", comp.strip())]) + + +def replace_xrange(comp, loose): + comp = comp.strip() + r = regexp[XRANGELOOSE] if loose else regexp[XRANGE] + + def repl(mob): + ret = mob.group(0) + gtlt, M, m, p, pr, _ = mob.groups() + + logger.debug("xrange %s %s %s %s %s %s %s", comp, ret, gtlt, M, m, p, pr) + + xM = is_x(M) + xm = xM or is_x(m) + xp = xm or is_x(p) + any_x = xp + + if gtlt == "=" and any_x: + gtlt = "" + + logger.debug("xrange gtlt=%s any_x=%s", gtlt, any_x) + if xM: + if gtlt == ">" or gtlt == "<": # noqa SIM108 + # nothing is allowed + ret = "<0.0.0" + else: + ret = "*" + elif gtlt and any_x: + # replace X with 0, and then append the -0 min-prerelease + if xm: + m = 0 + if xp: + p = 0 + + if gtlt == ">": + # >1 => >=2.0.0 + # >1.2 => >=1.3.0 + # >1.2.3 => >= 1.2.4 + gtlt = ">=" + if xm: + M = int(M) + 1 + m = 0 + p = 0 + elif xp: + m = int(m) + 1 + p = 0 + elif gtlt == "<=": + # <=0.7.x is actually <0.8.0, since any 0.7.x should + # pass. Similarly, <=7.x is actually <8.0.0, etc. + gtlt = "<" + if xm: + M = int(M) + 1 + else: + m = int(m) + 1 + + ret = gtlt + str(M) + "." + str(m) + "." + str(p) + elif xm: + ret = ">=" + M + ".0.0 <" + str(int(M) + 1) + ".0.0" + elif xp: + ret = ">=" + M + "." + m + ".0 <" + M + "." + str(int(m) + 1) + ".0" + logger.debug("xRange return %s", ret) + + return ret + + return r.sub(repl, comp) + + +# Because * is AND-ed with everything else in the comparator, +# and '' means "any version", just remove the *s entirely. +def replace_stars(comp, loose): + logger.debug("replaceStars %s %s", comp, loose) + # Looseness is ignored here. star is always as loose as it gets! + return regexp[STAR].sub("", comp.strip()) + + +# This function is passed to string.replace(re[HYPHENRANGE]) +# M, m, patch, prerelease, build +# 1.2 - 3.4.5 => >=1.2.0 <=3.4.5 +# 1.2.3 - 3.4 => >=1.2.0 <3.5.0 Any 3.4.x will do +# 1.2 - 3.4 => >=1.2.0 <3.5.0 +def hyphen_replace(mob): + from_, fM, fm, fp, fpr, fb, to, tM, tm, tp, tpr, tb = mob.groups() + if is_x(fM): + from_ = "" + elif is_x(fm): + from_ = ">=" + fM + ".0.0" + elif is_x(fp): + from_ = ">=" + fM + "." + fm + ".0" + else: + from_ = ">=" + from_ + + if is_x(tM): + to = "" + elif is_x(tm): + to = "<" + str(int(tM) + 1) + ".0.0" + elif is_x(tp): + to = "<" + tM + "." + str(int(tm) + 1) + ".0" + elif tpr: + to = "<=" + tM + "." + tm + "." + tp + "-" + tpr + else: + to = "<=" + to + return (from_ + " " + to).strip() + + +def test_set(set_, version): + for e in set_: + if not e.test(version): + return False + if len(version.prerelease) > 0: + # Find the set of versions that are allowed to have prereleases + # For example, ^1.2.3-pr.1 desugars to >=1.2.3-pr.1 <2.0.0 + # That should allow `1.2.3-pr.2` to pass. + # However, `1.2.4-alpha.notready` should NOT be allowed, + # even though it's within the range set by the comparators. + for e in set_: + if e.semver == ANY: + continue + if len(e.semver.prerelease) > 0: + allowed = e.semver + if ( + allowed.major == version.major + and allowed.minor == version.minor + and allowed.patch == version.patch + ): + return True + # Version has a -pre, but it's not one of the ones we like. + return False + return True + + +def satisfies(version, range_, loose=False): + try: + range_ = make_range(range_, loose) + except Exception: + return False + return range_.test(version) + + +def max_satisfying(versions, range_, loose=False): + try: + range_ob = make_range(range_, loose=loose) + except Exception: + return None + max_ = None + max_sv = None + for v in versions: + if range_ob.test(v): # noqa # satisfies(v, range_, loose=loose) + if max_ is None or max_sv.compare(v) == -1: # compare(max, v, true) + max_ = v + max_sv = make_semver(max_, loose=loose) + return max_ + + +def valid_range(range_, loose): + try: + # Return '*' instead of '' so that truthiness works. + # This will throw if it's invalid anyway + return make_range(range_, loose).range or "*" + except Exception: + return None + + +# Determine if version is less than all the versions possible in the range +def ltr(version, range_, loose): + return outside(version, range_, "<", loose) + + +# Determine if version is greater than all the versions possible in the range. +def rtr(version, range_, loose): + return outside(version, range_, ">", loose) + + +def outside(version, range_, hilo, loose): + version = make_semver(version, loose) + range_ = make_range(range_, loose) + + if hilo == ">": + gtfn = gt + ltefn = lte + ltfn = lt + comp = ">" + ecomp = ">=" + elif hilo == "<": + gtfn = lt + ltefn = gte + ltfn = gt + comp = "<" + ecomp = "<=" + else: + raise ValueError("Must provide a hilo val of '<' or '>'") + + # If it satisfies the range it is not outside + if satisfies(version, range_, loose): + return False + + # From now on, variable terms are as if we're in "gtr" mode. + # but note that everything is flipped for the "ltr" function. + for comparators in range_.set: + high = None + low = None + + for comparator in comparators: + high = high or comparator + low = low or comparator + + if gtfn(comparator.semver, high.semver, loose): + high = comparator + elif ltfn(comparator.semver, low.semver, loose): + low = comparator + + # If the edge version comparator has a operator then our version + # isn't outside it + if high.operator == comp or high.operator == ecomp: + return False + + # If the lowest version comparator has an operator and our version + # is less than it then it isn't higher than the range + if (not low.operator or low.operator == comp) and ltefn(version, low.semver): # noqa SIM114 + return False + elif low.operator == ecomp and ltfn(version, low.semver): + return False + return True diff --git a/jupyter_builder/yarn.js b/jupyter_builder/yarn.js index 5f92912..883fe92 100644 --- a/jupyter_builder/yarn.js +++ b/jupyter_builder/yarn.js @@ -1,8 +1,3 @@ -/* - * Copyright (c) Jupyter Development Team. - * Distributed under the terms of the Modified BSD License. - */ - #!/usr/bin/env node /* eslint-disable */ //prettier-ignore diff --git a/package.json b/package.json index 5fd00ad..d03e416 100644 --- a/package.json +++ b/package.json @@ -44,7 +44,32 @@ "prettier:check": "jlpm prettier:base --check", "watch": "tsc -w --sourceMap" }, + "dependencies": { + "ajv": "^8.12.0", + "commander": "^9.4.1", + "css-loader": "^6.7.1", + "duplicate-package-checker-webpack-plugin": "^3.0.0", + "fs-extra": "^10.1.0", + "glob": "~7.1.6", + "license-webpack-plugin": "^2.3.14", + "mini-css-extract-plugin": "^2.7.0", + "mini-svg-data-uri": "^1.4.4", + "path-browserify": "^1.0.0", + "process": "^0.11.10", + "source-map-loader": "~1.0.2", + "style-loader": "~3.3.1", + "supports-color": "^7.2.0", + "terser-webpack-plugin": "^5.3.7", + "webpack": "^5.76.1", + "webpack-cli": "^5.0.1", + "webpack-merge": "^5.8.0", + "worker-loader": "^3.0.2" + }, "devDependencies": { + "@types/fs-extra": "^9.0.1", + "@types/glob": "^7.1.1", + "@types/node": "^20.11.27", + "@types/supports-color": "^5.3.0", "@typescript-eslint/eslint-plugin": "^6.1.0", "@typescript-eslint/parser": "^6.1.0", "eslint": "^8.36.0", @@ -52,9 +77,9 @@ "eslint-plugin-prettier": "^5.0.0", "npm-run-all": "^4.1.5", "prettier": "^3.0.0", - "rimraf": "^5.0.1", + "rimraf": "^5.0.5", "source-map-loader": "^1.0.2", - "typescript": "~5.0.2" + "typescript": "~5.1.6" }, "publishConfig": { "access": "public" diff --git a/src/build-labextension.ts b/src/build-labextension.ts new file mode 100644 index 0000000..b346760 --- /dev/null +++ b/src/build-labextension.ts @@ -0,0 +1,149 @@ +#!/usr/bin/env node +/* ----------------------------------------------------------------------------- +| Copyright (c) Jupyter Development Team. +| Distributed under the terms of the Modified BSD License. +|----------------------------------------------------------------------------*/ + +// Build an extension + +// Inputs: +// Path to extension (required) +// Dev vs prod (dev is default) +// Output path (defaults to /build) + +// Outputs +// Webpack build assets + +/////////////////////////////////////////////////////// +// Portions of the below code handling watch mode and displaying output were +// adapted from the https://github.com/webpack/webpack-cli project, which has +// an MIT license (https://github.com/webpack/webpack-cli/blob/4dc6dfbf29da16e61745770f7b48638963fb05c5/LICENSE): +// +// Copyright JS Foundation and other contributors +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// 'Software'), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +/////////////////////////////////////////////////////// + +import * as path from 'path'; +import { program as commander } from 'commander'; +import webpack from 'webpack'; +import generateConfig from './extensionConfig'; +import { stdout as colors } from 'supports-color'; + +commander + .description('Build an extension') + .option('--development', 'build in development mode (implies --source-map)') + .option('--source-map', 'generate source maps') + .requiredOption('--core-path ', 'the core package directory') + .option( + '--static-url ', + 'url for build assets, if hosted outside the built extension' + ) + .option('--watch') + .action(async (options, command) => { + const mode = options.development ? 'development' : 'production'; + const corePath = path.resolve(options.corePath || process.cwd()); + const packagePath = path.resolve(command.args[0]); + const devtool = options.sourceMap ? 'source-map' : undefined; + + const config = generateConfig({ + packagePath, + mode, + corePath, + staticUrl: options.staticUrl, + devtool, + watchMode: options.watch + }); + const compiler = webpack(config); + + let lastHash: string | null = null; + + function compilerCallback(err: any, stats: any) { + if (!options.watch || err) { + // Do not keep cache anymore + compiler.purgeInputFileSystem(); + } + + if (err) { + console.error(err.stack || err); + if (err.details) { + console.error(err.details); + } + throw new Error(err.details); + } + + const info = stats.toJson(); + + if (stats.hasErrors()) { + console.error(info.errors); + if (!options.watch) { + process.exit(2); + } + } + + if (stats.hash !== lastHash) { + lastHash = stats.hash; + const statsString = stats.toString({ colors }); + const delimiter = ''; + if (statsString) { + process.stdout.write(`${statsString}\n${delimiter}`); + } + } + } + + if (options.watch) { + compiler.hooks.watchRun.tap('WebpackInfo', () => { + console.error('\nWatch Compilation starting…\n'); + }); + compiler.hooks.done.tap('WebpackInfo', () => { + console.error('\nWatch Compilation finished\n'); + }); + } else { + compiler.hooks.run.tap('WebpackInfo', () => { + console.error('\nCompilation starting…\n'); + }); + compiler.hooks.done.tap('WebpackInfo', () => { + console.error('\nCompilation finished\n'); + }); + } + + if (options.watch) { + compiler.watch(config[0].watchOptions || {}, compilerCallback); + console.error('\nwebpack is watching the files…\n'); + } else { + compiler.run((err: any, stats: any) => { + if (compiler.close) { + compiler.close((err2: any) => { + compilerCallback(err || err2, stats); + }); + } else { + compilerCallback(err, stats); + } + }); + } + }); + +commander.parse(process.argv); + +// If no arguments supplied +if (!process.argv.slice(2).length) { + commander.outputHelp(); + process.exit(1); +} diff --git a/src/build.ts b/src/build.ts new file mode 100644 index 0000000..1c0c151 --- /dev/null +++ b/src/build.ts @@ -0,0 +1,281 @@ +/* ----------------------------------------------------------------------------- +| Copyright (c) Jupyter Development Team. +| Distributed under the terms of the Modified BSD License. +|----------------------------------------------------------------------------*/ + +import MiniCssExtractPlugin from 'mini-css-extract-plugin'; +import miniSVGDataURI from 'mini-svg-data-uri'; + +import * as webpack from 'webpack'; +import * as fs from 'fs-extra'; +import * as glob from 'glob'; +import * as path from 'path'; + +/** + * A namespace for JupyterLab build utilities. + */ +export namespace Build { + /** + * The options used to ensure a root package has the appropriate + * assets for its JupyterLab extension packages. + */ + export interface IEnsureOptions { + /** + * The output directory where the build assets should reside. + */ + output: string; + + /** + * The directory for the schema directory, defaults to the output directory. + */ + schemaOutput?: string; + + /** + * The directory for the theme directory, defaults to the output directory + */ + themeOutput?: string; + + /** + * The names of the packages to ensure. + */ + packageNames: ReadonlyArray; + + /** + * The package paths to ensure. + */ + packagePaths?: ReadonlyArray; + } + + /** + * The JupyterLab extension attributes in a module. + */ + export interface ILabExtension { + /** + * Indicates whether the extension is a standalone extension. + * + * #### Notes + * If `true`, the `main` export of the package is used. If set to a string + * path, the export from that path is loaded as a JupyterLab extension. It + * is possible for one package to have both an `extension` and a + * `mimeExtension` but they cannot be identical (i.e., the same export + * cannot be declared both an `extension` and a `mimeExtension`). + */ + readonly extension?: boolean | string; + + /** + * Indicates whether the extension is a MIME renderer extension. + * + * #### Notes + * If `true`, the `main` export of the package is used. If set to a string + * path, the export from that path is loaded as a JupyterLab extension. It + * is possible for one package to have both an `extension` and a + * `mimeExtension` but they cannot be identical (i.e., the same export + * cannot be declared both an `extension` and a `mimeExtension`). + */ + readonly mimeExtension?: boolean | string; + + /** + * The local schema file path in the extension package. + */ + readonly schemaDir?: string; + + /** + * The local theme file path in the extension package. + */ + readonly themePath?: string; + } + + /** + * A minimal definition of a module's package definition (i.e., package.json). + */ + export interface IModule { + /** + * The JupyterLab metadata/ + */ + jupyterlab?: ILabExtension; + + /** + * The main entry point in a module. + */ + main?: string; + + /** + * The name of a module. + */ + name: string; + } + + /** + * Ensures that the assets of plugin packages are populated for a build. + * + * @ Returns An array of lab extension config data. + */ + export function ensureAssets( + options: IEnsureOptions + ): webpack.Configuration[] { + const { + output, + schemaOutput = output, + themeOutput = output, + packageNames + } = options; + + const themeConfig: webpack.Configuration[] = []; + + const packagePaths: string[] = options.packagePaths?.slice() || []; + + const cssImports: string[] = []; + + packageNames.forEach(name => { + packagePaths.push( + path.dirname(require.resolve(path.join(name, 'package.json'))) + ); + }); + + packagePaths.forEach(packagePath => { + const packageDataPath = require.resolve( + path.join(packagePath, 'package.json') + ); + const packageDir = path.dirname(packageDataPath); + const data = fs.readJSONSync(packageDataPath); + const name = data.name; + const extension = normalizeExtension(data); + + const { schemaDir, themePath } = extension; + + // We prefer the styleModule key if it exists, falling back to + // the normal style key. + if (typeof data.styleModule === 'string') { + cssImports.push(`${name}/${data.styleModule}`); + } else if (typeof data.style === 'string') { + cssImports.push(`${name}/${data.style}`); + } + + // Handle schemas. + if (schemaDir) { + const schemas = glob.sync( + path.join(path.join(packageDir, schemaDir), '*') + ); + const destination = path.join(schemaOutput, 'schemas', name); + + // Remove the existing directory if necessary. + if (fs.existsSync(destination)) { + try { + const oldPackagePath = path.join(destination, 'package.json.orig'); + const oldPackageData = fs.readJSONSync(oldPackagePath); + if (oldPackageData.version === data.version) { + fs.removeSync(destination); + } + } catch (e) { + fs.removeSync(destination); + } + } + + // Make sure the schema directory exists. + fs.mkdirpSync(destination); + + // Copy schemas. + schemas.forEach(schema => { + const file = path.basename(schema); + fs.copySync(schema, path.join(destination, file)); + }); + + // Write the package.json file for future comparison. + fs.copySync( + path.join(packageDir, 'package.json'), + path.join(destination, 'package.json.orig') + ); + } + + if (!themePath) { + return; + } + themeConfig.push({ + mode: 'production', + entry: { + index: path.join(packageDir, themePath) + }, + output: { + path: path.resolve(path.join(themeOutput, 'themes', name)), + // we won't use these JS files, only the extracted CSS + filename: '[name].js', + hashFunction: 'sha256' + }, + module: { + rules: [ + { + test: /\.css$/, + use: [MiniCssExtractPlugin.loader, require.resolve('css-loader')] + }, + { + test: /\.svg/, + type: 'asset/inline', + generator: { + dataUrl: (content: any) => miniSVGDataURI(content.toString()) + } + }, + { + test: /\.(cur|png|jpg|gif|ttf|woff|woff2|eot)(\?v=[0-9]\.[0-9]\.[0-9])?$/, + type: 'asset' + } + ] + }, + plugins: [ + new MiniCssExtractPlugin({ + // Options similar to the same options in webpackOptions.output + // both options are optional + filename: '[name].css', + chunkFilename: '[id].css' + }) + ] + }); + }); + + cssImports.sort((a, b) => a.localeCompare(b)); + const styleContents = `/* This is a generated file of CSS imports */ +/* It was generated by @jupyterlab/builder in Build.ensureAssets() */ + +${cssImports.map(x => `import '${x}';`).join('\n')} +`; + + const stylePath = path.join(output, 'style.js'); + + // Make sure the output dir exists before writing to it. + if (!fs.existsSync(output)) { + fs.mkdirSync(output); + } + fs.writeFileSync(stylePath, styleContents, { + encoding: 'utf8' + }); + + return themeConfig; + } + + /** + * Returns JupyterLab extension metadata from a module. + */ + export function normalizeExtension(module: IModule): ILabExtension { + const { jupyterlab, name } = module; + let { main } = module; + + main = main || 'index.js'; + + if (!jupyterlab) { + throw new Error(`Module ${name} does not contain JupyterLab metadata.`); + } + + const { schemaDir, themePath } = jupyterlab; + let { extension, mimeExtension } = jupyterlab; + + extension = extension === true ? main : extension; + mimeExtension = mimeExtension === true ? main : mimeExtension; + + if (extension && mimeExtension && extension === mimeExtension) { + const message = 'extension and mimeExtension cannot be the same export.'; + + throw new Error(message); + } + + return { extension, mimeExtension, schemaDir, themePath }; + } +} diff --git a/src/duplicate-package-checker-webpack-plugin.d.ts b/src/duplicate-package-checker-webpack-plugin.d.ts new file mode 100644 index 0000000..897d28d --- /dev/null +++ b/src/duplicate-package-checker-webpack-plugin.d.ts @@ -0,0 +1,64 @@ +/* + * Copyright (c) Jupyter Development Team. + * Distributed under the terms of the Modified BSD License. + */ + +// Type definitions for duplicate-package-checker-webpack-plugin 2.1 +// Project: https://github.com/darrenscerri/duplicate-package-checker-webpack-plugin#readme +// Definitions by: Matt Traynham +// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped +// TypeScript Version: 2.3 + +// Modified to work with Webpack 5 typings by Jason Grout + +/* eslint-disable @typescript-eslint/naming-convention */ + +// Once to get a typed module first. +declare module 'duplicate-package-checker-webpack-plugin'; + +// Then we expand the definition with the things we use. +declare module 'duplicate-package-checker-webpack-plugin' { + import * as webpack from 'webpack'; + + export = DuplicatePackageCheckerWebpackPlugin; + + class DuplicatePackageCheckerWebpackPlugin { + constructor(options?: DuplicatePackageCheckerWebpackPlugin.Options); + apply(compiler: webpack.Compiler): void; + } + + namespace DuplicatePackageCheckerWebpackPlugin { + /** The properties of the instance of a package */ + interface PackageInstanceProperties { + /** The name of the package */ + name: string; + /** The version of the package */ + version: string; + /** Absolute path to the package */ + path: string; + /** Absolute path to the module that requested the package */ + issuer?: string; + } + + /** The configurable options for the plugin */ + interface Options { + /** Also show module that is requiring each duplicate package (default: false) */ + verbose?: boolean; + /** Emit errors instead of warnings (default: false) */ + emitError?: boolean; + /** Show help message if duplicate packages are found (default: true) */ + showHelp?: boolean; + /** Warn also if major versions differ (default: true) */ + strict?: boolean; + + /** + * Exclude instances of packages from the results. + * If all instances of a package are excluded, or all instances except one, + * then the package is no longer considered duplicated and won't be emitted as a warning/error. + * @param instance The instance of a package being evaluated for exclusion. + * @returns true to exclude the instance, false otherwise + */ + exclude?: (instance: PackageInstanceProperties) => boolean; + } + } +} diff --git a/src/extensionConfig.ts b/src/extensionConfig.ts new file mode 100644 index 0000000..da196a2 --- /dev/null +++ b/src/extensionConfig.ts @@ -0,0 +1,307 @@ +// Copyright (c) Jupyter Development Team. +// Distributed under the terms of the Modified BSD License. + +import * as path from 'path'; +import * as webpack from 'webpack'; +import { Build } from './build'; +import { WPPlugin } from './webpack-plugins'; +import { merge } from 'webpack-merge'; +import * as fs from 'fs-extra'; +import * as glob from 'glob'; +import Ajv from 'ajv'; +import * as baseConfig from './webpack.config.base'; +import metadataSchema from './metadata_schema.json'; + +const { ModuleFederationPlugin } = webpack.container; + +export interface IOptions { + packagePath?: string; + corePath?: string; + staticUrl?: string; + mode?: 'development' | 'production'; + devtool?: string; + watchMode?: boolean; +} + +function generateConfig({ + packagePath = '', + corePath = '', + staticUrl = '', + mode = 'production', + devtool = mode === 'development' ? 'source-map' : undefined, + watchMode = false +}: IOptions = {}): webpack.Configuration[] { + const data = JSON.parse( + fs.readFileSync(path.join(packagePath, 'package.json'), { + encoding: 'utf8' + }) + ); + const ajv = new Ajv({ useDefaults: true, strict: false }); + const validate = ajv.compile(metadataSchema); + const valid = validate(data.jupyterlab ?? {}); + if (!valid) { + console.error(validate.errors); + process.exit(1); + } + + const outputPath = path.join(packagePath, data.jupyterlab['outputDir']); + const staticPath = path.join(outputPath, 'static'); + + // Handle the extension entry point and the lib entry point, if different + const index = require.resolve(packagePath); + const exposes: { [id: string]: string } = { + './index': index + }; + + const extension = data.jupyterlab.extension; + if (extension === true) { + exposes['./extension'] = index; + } else if (typeof extension === 'string') { + exposes['./extension'] = path.join(packagePath, extension); + } + + const mimeExtension = data.jupyterlab.mimeExtension; + if (mimeExtension === true) { + exposes['./mimeExtension'] = index; + } else if (typeof mimeExtension === 'string') { + exposes['./mimeExtension'] = path.join(packagePath, mimeExtension); + } + + if (typeof data.styleModule === 'string') { + exposes['./style'] = path.join(packagePath, data.styleModule); + } else if (typeof data.style === 'string') { + exposes['./style'] = path.join(packagePath, data.style); + } + const coreData = JSON.parse( + fs.readFileSync(path.join(corePath, 'package.json'), { encoding: 'utf8' }) + ); + + let shared: any = {}; + + // Start with core package versions. + const coreDeps: any = { + ...coreData.dependencies, + ...(coreData.resolutions ?? {}) + }; + + // Allow extensions to match a wider range than the core dependency + // To ensure forward compatibility. + Object.keys(coreDeps).forEach(element => { + shared[element] = { + requiredVersion: coreDeps[element].replace('~', '^'), + import: false + }; + }); + + // Add package dependencies. + Object.keys(data.dependencies).forEach(element => { + // TODO: make sure that the core dependency semver range is a subset of our + // data.dependencies version range for any packages in the core deps. + if (!shared[element]) { + shared[element] = {}; + } + }); + + // Set core packages as singletons that are not bundled. + coreData.jupyterlab.singletonPackages.forEach((element: string) => { + if (!shared[element]) { + shared[element] = {}; + } + shared[element].import = false; + shared[element].singleton = true; + }); + + // Now we merge in the sharedPackages configuration provided by the extension. + + const sharedPackages = data.jupyterlab.sharedPackages ?? {}; + + // Delete any modules that are explicitly not shared + Object.keys(sharedPackages).forEach(pkg => { + if (sharedPackages[pkg] === false) { + delete shared[pkg]; + delete sharedPackages[pkg]; + } + }); + + // Transform the sharedPackages information into valid webpack config + Object.keys(sharedPackages).forEach(pkg => { + // Convert `bundled` to `import` + if (sharedPackages[pkg].bundled === false) { + sharedPackages[pkg].import = false; + } else if ( + sharedPackages[pkg].bundled === true && + shared[pkg]?.import === false + ) { + // We can't delete a key in the merge, so we have to delete it in the source + delete shared[pkg].import; + } + delete sharedPackages[pkg].bundled; + }); + + shared = merge(shared, sharedPackages); + + // add the root module itself to shared + if (shared[data.name]) { + console.error( + `The root package itself '${data.name}' may not specified as a shared dependency.` + ); + } + shared[data.name] = { + version: data.version, + singleton: true, + import: index + }; + + // Ensure a clean output directory - remove files but not the directory + // in case it is a symlink + fs.emptyDirSync(outputPath); + + const extras = Build.ensureAssets({ + packageNames: [], + packagePaths: [packagePath], + output: staticPath, + schemaOutput: outputPath, + themeOutput: outputPath + }); + + fs.copyFileSync( + path.join(packagePath, 'package.json'), + path.join(outputPath, 'package.json') + ); + + class CleanupPlugin { + apply(compiler: any) { + compiler.hooks.done.tap('Cleanup', (stats: any) => { + const newlyCreatedAssets = stats.compilation.assets; + + // Clear out any remoteEntry files that are stale + // https://stackoverflow.com/a/40370750 + const files = glob.sync(path.join(staticPath, 'remoteEntry.*.js')); + let newEntry = ''; + const unlinked: string[] = []; + files.forEach(file => { + const fileName = path.basename(file); + if (!newlyCreatedAssets[fileName]) { + fs.unlinkSync(path.resolve(file)); + unlinked.push(fileName); + } else { + newEntry = fileName; + } + }); + if (unlinked.length > 0) { + console.log('Removed old assets: ', unlinked); + } + + // Find the remoteEntry file and add it to the package.json metadata + const data = fs.readJSONSync(path.join(outputPath, 'package.json')); + const _build: any = { + load: path.join('static', newEntry) + }; + if (exposes['./extension'] !== undefined) { + _build.extension = './extension'; + } + if (exposes['./mimeExtension'] !== undefined) { + _build.mimeExtension = './mimeExtension'; + } + if (exposes['./style'] !== undefined) { + _build.style = './style'; + } + data.jupyterlab._build = _build; + fs.writeJSONSync(path.join(outputPath, 'package.json'), data, { + spaces: 2 + }); + }); + } + } + + // Allow custom webpack config + let webpackConfigPath = data.jupyterlab['webpackConfig']; + let webpackConfig = {}; + + // Use the custom webpack config only if the path to the config + // is specified in package.json (opt-in) + if (webpackConfigPath) { + webpackConfigPath = path.join(packagePath, webpackConfigPath); + if (fs.existsSync(webpackConfigPath)) { + webpackConfig = require(webpackConfigPath); + } + } + + const plugins = [ + new ModuleFederationPlugin({ + name: data.name, + library: { + type: 'var', + name: ['_JUPYTERLAB', data.name] + }, + filename: 'remoteEntry.[contenthash].js', + exposes, + shared + }), + new CleanupPlugin() + ]; + + if (mode === 'production') { + plugins.push( + new WPPlugin.JSONLicenseWebpackPlugin({ + excludedPackageTest: packageName => packageName === data.name + }) + ); + } + + // Add version argument when in production so the Jupyter server + // allows caching of files (i.e., does not set the CacheControl header to no-cache to prevent caching static files) + let filename = '[name].[contenthash].js'; + if (mode === 'production') { + filename += '?v=[contenthash]'; + } + + const rules: any = [{ test: /\.html$/, type: 'asset/resource' }]; + + if (mode === 'development') { + rules.push({ + test: /\.js$/, + enforce: 'pre', + use: [require.resolve('source-map-loader')] + }); + } + + const config = [ + merge( + baseConfig, + { + mode, + devtool, + entry: {}, + output: { + filename, + path: staticPath, + publicPath: staticUrl || 'auto' + }, + plugins + }, + webpackConfig, + { + module: { + rules + } + } + ) + ].concat(extras); + + function regExpReplacer(key: any, value: any) { + if (value instanceof RegExp) { + return value.toString(); + } else { + return value; + } + } + + if (mode === 'development') { + const logPath = path.join(outputPath, 'build_log.json'); + fs.writeFileSync(logPath, JSON.stringify(config, regExpReplacer, ' ')); + } + return config; +} + +export default generateConfig; diff --git a/src/index.ts b/src/index.ts index 8f2b875..5bf662c 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,6 +1,7 @@ -/* - * Copyright (c) Jupyter Development Team. - * Distributed under the terms of the Modified BSD License. - */ +/* ----------------------------------------------------------------------------- +| Copyright (c) Jupyter Development Team. +| Distributed under the terms of the Modified BSD License. +|----------------------------------------------------------------------------*/ -console.log('hello'); +export * from './build'; +export * from './webpack-plugins'; diff --git a/src/metadata_schema.json b/src/metadata_schema.json new file mode 100644 index 0000000..a6666e4 --- /dev/null +++ b/src/metadata_schema.json @@ -0,0 +1,119 @@ +{ + "title": "JupyterLab Package Metadata", + "version": "0.1.0", + "description": "JupyterLab package.json settings.", + "definitions": { + "extension": { + "type": ["boolean", "string"] + }, + "relativePath": { + "type": ["string", "null"] + }, + "sharedObject": { + "description": "Modules that should be shared in the share scope. Property names are used to match requested modules in this compilation. Relative requests are resolved, module requests are matched unresolved, absolute paths will match resolved requests.", + "type": "object", + "additionalProperties": { + "description": "Module sharing information.", + "anyOf": [ + { + "description": "Module is not shared. A local copy will be bundled and used.", + "enum": [false] + }, + { + "$ref": "#/definitions/sharedConfig" + } + ] + } + }, + "sharedConfig": { + "description": "Configuration data for package sharing.", + "type": "object", + "additionalProperties": false, + "properties": { + "bundled": { + "description": "The module will be bundled and provided to the system as a shared module (the system will use the latest bundled version from any extension). This bundled local copy will be used if the system version does not match the requiredVersion. Defaults to true", + "type": "boolean", + "default": "true" + }, + "requiredVersion": { + "description": "Version requirement from module in share scope. Defaults to the version required in the package.json, or false if the version cannot be determined. You can specify it here in case the version cannot be determined automatically.", + "anyOf": [ + { + "description": "No version requirement check.", + "enum": [false] + }, + { + "description": "The semver range required for the shared module.", + "type": "string" + } + ] + }, + "singleton": { + "description": "Allow only a single version of the shared module in share scope. Will only use the system provided version, and not fall back to a local bundled copy. Default is false.", + "type": "boolean", + "default": "false" + }, + "strictVersion": { + "description": "Throw an error (instead of a warning) if the shared module version does not satisfy the requiredVersion. Defaults to false when forced to use the system-provided version of the module (i.e., singleton is true or bundled is false), in which case we will just print a console warning if the system-provided version does not satisfy the requiredVersion. This has no effect if requiredVersion is false.", + "type": "boolean" + } + } + } + }, + "properties": { + "extension": { + "title": "Extension", + "description": "Presence of or relative path to a standard JupyterLab extension", + "$ref": "#/definitions/extension", + "default": false + }, + "mimeExtension": { + "title": "Mime extension", + "description": "Presence of or relative path to a JupyterLab MIME renderer extension", + "$ref": "#/definitions/extension", + "default": false + }, + "themePath": { + "title": "Theme path", + "description": "The relative path to theme files", + "$ref": "#/definitions/relativePath", + "default": null + }, + "schemaDir": { + "title": "Schema directory", + "description": "The relative path to schema files", + "$ref": "#/definitions/relativePath", + "default": null + }, + "outputDir": { + "title": "Output directory", + "description": "The relative path to the static assets", + "$ref": "#/definitions/relativePath", + "default": "static" + }, + "webpackConfig": { + "title": "Custom Webpack config", + "description": "The relative path to a custom webpack config", + "$ref": "#/definitions/relativePath", + "default": null + }, + "sharedPackages": { + "description": "Modules that should be shared in the share scope. When provided, property names are used to match requested modules in this compilation.", + "ref": "#/definitions/sharedObject" + }, + "discovery": { + "title": "Discovery metadata", + "description": "Discovery metadata used to for companion packages", + "type": "object" + }, + "disabledExtensions": { + "title": "List of disabled extension modules and/or regex patterns for extension ids", + "type": "array", + "items": { + "type": "string" + } + } + }, + "additionalProperties": false, + "type": "object" +} diff --git a/src/mini-css-extract-plugin.d.ts b/src/mini-css-extract-plugin.d.ts new file mode 100644 index 0000000..321acb2 --- /dev/null +++ b/src/mini-css-extract-plugin.d.ts @@ -0,0 +1,8 @@ +/* + * Copyright (c) Jupyter Development Team. + * Distributed under the terms of the Modified BSD License. + */ + +// We use our own declaration because the existing typings do not work with webpack 5 + +declare module 'mini-css-extract-plugin'; diff --git a/src/webpack-plugins.ts b/src/webpack-plugins.ts new file mode 100644 index 0000000..d22f13f --- /dev/null +++ b/src/webpack-plugins.ts @@ -0,0 +1,256 @@ +/* ----------------------------------------------------------------------------- +| Copyright (c) Jupyter Development Team. +| Distributed under the terms of the Modified BSD License. +|----------------------------------------------------------------------------*/ + +import DuplicatePackageCheckerPlugin from 'duplicate-package-checker-webpack-plugin'; +import * as fs from 'fs-extra'; +import * as webpack from 'webpack'; +import { LicenseWebpackPlugin } from 'license-webpack-plugin'; +import { LicenseIdentifiedModule } from 'license-webpack-plugin/dist/LicenseIdentifiedModule'; +import { PluginOptions } from 'license-webpack-plugin/dist/PluginOptions'; + +// From +// https://github.com/webpack/webpack/blob/95120bdf98a01649740b104bebc426b0123651ce/lib/WatchIgnorePlugin.js +const IGNORE_TIME_ENTRY = 'ignore'; + +export namespace WPPlugin { + /** + * A WebPack Plugin that copies the assets to the static directory + */ + export class FrontEndPlugin { + constructor(buildDir: string, staticDir: string) { + this.buildDir = buildDir; + this.staticDir = staticDir; + + this._first = true; + } + + apply(compiler: webpack.Compiler): void { + compiler.hooks.afterEmit.tap('FrontEndPlugin', () => { + // bail if no staticDir + if (!this.staticDir) { + return; + } + + // ensure a clean static directory on the first emit + if (this._first && fs.existsSync(this.staticDir)) { + fs.removeSync(this.staticDir); + } + this._first = false; + + fs.copySync(this.buildDir, this.staticDir); + }); + } + + buildDir: string; + staticDir: string; + + private _first: boolean; + } + + /** + * A helper class for the WatchIgnoreFilterPlugin. This is a close copy of + * (the non-exported) webpack.IgnoringWatchFileSystem + */ + class FilterIgnoringWatchFileSystem { + constructor(wfs: any, ignored: (path: string) => boolean) { + this.wfs = wfs; + + // ignored should be a callback function that filters the build files + this.ignored = ignored; + } + + watch( + files: any, + dirs: any, + missing: any, + startTime: any, + options: any, + callback: any, + callbackUndelayed: any + ) { + files = Array.from(files); + dirs = Array.from(dirs); + const notIgnored = (path: string) => !this.ignored(path); + const ignoredFiles = files.filter(this.ignored); + const ignoredDirs = dirs.filter(this.ignored); + + const watcher = this.wfs.watch( + files.filter(notIgnored), + dirs.filter(notIgnored), + missing, + startTime, + options, + ( + err: any, + fileTimestamps: any, + dirTimestamps: any, + changedFiles: any, + removedFiles: any + ) => { + if (err) { + return callback(err); + } + for (const path of ignoredFiles) { + fileTimestamps.set(path, IGNORE_TIME_ENTRY); + } + + for (const path of ignoredDirs) { + dirTimestamps.set(path, IGNORE_TIME_ENTRY); + } + + callback( + err, + fileTimestamps, + dirTimestamps, + changedFiles, + removedFiles + ); + }, + callbackUndelayed + ); + + return { + close: () => watcher.close(), + pause: () => watcher.pause(), + getContextTimeInfoEntries: () => { + const dirTimestamps = watcher.getContextTimeInfoEntries(); + for (const path of ignoredDirs) { + dirTimestamps.set(path, IGNORE_TIME_ENTRY); + } + return dirTimestamps; + }, + getFileTimeInfoEntries: () => { + const fileTimestamps = watcher.getFileTimeInfoEntries(); + for (const path of ignoredFiles) { + fileTimestamps.set(path, IGNORE_TIME_ENTRY); + } + return fileTimestamps; + } + }; + } + + ignored: (path: string) => boolean; + wfs: any; + } + + /** + * A WebPack Plugin that ignores files files that are filtered + * by a callback during a `--watch` build + */ + export class FilterWatchIgnorePlugin { + constructor(ignored: (path: string) => boolean) { + this.ignored = ignored; + } + + apply(compiler: webpack.Compiler): void { + compiler.hooks.afterEnvironment.tap('FilterWatchIgnorePlugin', () => { + compiler.watchFileSystem = new FilterIgnoringWatchFileSystem( + compiler.watchFileSystem, + this.ignored + ); + }); + } + + ignored: (path: string) => boolean; + } + + export class NowatchDuplicatePackageCheckerPlugin extends DuplicatePackageCheckerPlugin { + apply(compiler: webpack.Compiler): void { + const options = this.options; + + compiler.hooks.run.tap( + 'NowatchDuplicatePackageCheckerPlugin', + compiler => { + const p = new DuplicatePackageCheckerPlugin(options); + p.apply(compiler); + } + ); + } + + options: DuplicatePackageCheckerPlugin.Options; + } + + /** + * A top-level report of the licenses for all code included in a bundle + * + * ### Note + * + * This is roughly informed by the terms defined in the SPDX spec, though is not + * an SPDX Document, since there seem to be several (incompatible) specs + * in that repo. + * + * @see https://github.com/spdx/spdx-spec/blob/development/v2.2.1/schemas/spdx-schema.json + **/ + export interface ILicenseReport { + packages: IPackageLicenseInfo[]; + } + + /** + * A best-effort single bundled package's information. + * + * ### Note + * + * This is roughly informed by SPDX `packages` and `hasExtractedLicenseInfos`, + * as making it conformant would vastly complicate the structure. + * + * @see https://github.com/spdx/spdx-spec/blob/development/v2.2.1/schemas/spdx-schema.json + **/ + export interface IPackageLicenseInfo { + /** the name of the package as it appears in node_modules */ + name: string; + /** the version of the package, or an empty string if unknown */ + versionInfo: string; + /** an SPDX license or LicenseRef, or an empty string if unknown */ + licenseId: string; + /** the verbatim extracted text of the license, or an empty string if unknown */ + extractedText: string; + } + + /** + * A well-known filename for third-party license information. + * + * ### Note + * If an alternate JupyterLab-based ecosystem wanted to implement a different + * name, they may _still_ need to handle the presence of this file if reusing + * any core files or extensions. + * + * If multiple files are found by `jupyterlab_server, their `packages` will + * be concatenated. + */ + export const DEFAULT_LICENSE_REPORT_FILENAME = 'third-party-licenses.json'; + + /** + * a plugin that creates a predictable, machine-readable report of licenses for + * all modules included in this build + */ + export class JSONLicenseWebpackPlugin extends LicenseWebpackPlugin { + constructor(pluginOptions: PluginOptions = {}) { + super({ + outputFilename: DEFAULT_LICENSE_REPORT_FILENAME, + ...pluginOptions, + renderLicenses: modules => this.renderLicensesJSON(modules), + perChunkOutput: false + }); + } + + /** render an SPDX-like record */ + renderLicensesJSON(modules: LicenseIdentifiedModule[]): string { + const report: ILicenseReport = { packages: [] }; + + modules.sort((left, right) => (left.name < right.name ? -1 : 1)); + + for (const mod of modules) { + report.packages.push({ + name: mod.name || '', + versionInfo: mod.packageJson.version || '', + licenseId: mod.licenseId || '', + extractedText: mod.licenseText || '' + }); + } + + return JSON.stringify(report, null, 2); + } + } +} diff --git a/src/webpack.config.base.ts b/src/webpack.config.base.ts new file mode 100644 index 0000000..7d598a6 --- /dev/null +++ b/src/webpack.config.base.ts @@ -0,0 +1,90 @@ +// Copyright (c) Jupyter Development Team. +// Distributed under the terms of the Modified BSD License. +import * as webpack from 'webpack'; +import miniSVGDataURI from 'mini-svg-data-uri'; + +const rules = [ + { test: /\.raw\.css$/, type: 'asset/source' }, + { + test: /(? miniSVGDataURI(content.toString()) + } + }, + { + // In .ts and .tsx files (both of which compile to .js), svg files + // must be loaded as a raw string instead of data URIs. + test: /\.svg(\?v=\d+\.\d+\.\d+)?$/, + issuer: /\.js$/, + type: 'asset/source' + }, + { + test: /\.m?js$/, + type: 'javascript/auto' + }, + { + test: /\.m?js/, + resolve: { + fullySpecified: false + } + }, + { + test: /\.c?js/, + resolve: { + fullySpecified: false + } + } +]; + +const watch = process.argv.includes('--watch'); + +module.exports = { + bail: !watch, + module: { rules }, + resolve: { + fallback: { + url: false, + buffer: false, + crypto: false, + // See https://github.com/webpack/webpack/blob/3471c776059ac2d26593ea39f9c47c1874253dbb/lib/ModuleNotFoundError.js#L13-L42 + path: require.resolve('path-browserify'), + process: require.resolve('process/browser') + } + }, + watchOptions: { + poll: 500, + aggregateTimeout: 1000 + }, + output: { + hashFunction: 'sha256' + }, + plugins: [ + new webpack.ProvidePlugin({ + process: 'process/browser' + }) + ] +}; diff --git a/tests/test_tpl.py b/tests/test_tpl.py index 3d8f66b..7bd5419 100644 --- a/tests/test_tpl.py +++ b/tests/test_tpl.py @@ -1,13 +1,17 @@ # Copyright (c) Jupyter Development Team. # Distributed under the terms of the Modified BSD License. +import json import os import platform +import re import subprocess import time from pathlib import Path from subprocess import Popen, run +import pytest + def helper(dest): run( @@ -162,3 +166,42 @@ def test_watch_functionality(tmp_path): # else: # watch_process.send_signal(signal.SIGINT) # watch_process.wait() + + +def test_builder_version_mismatch(tmp_path): + extension_folder = tmp_path / "ext" + extension_folder.mkdir() + helper(str(extension_folder)) + + package_json_path = extension_folder / "package.json" + + # Modify the @jupyterlab/builder version to an incompatible range + package_data = json.loads(package_json_path.read_text()) + package_data["devDependencies"]["@jupyterlab/builder"] = "4.0.0" + package_json_path.write_text(json.dumps(package_data, indent=2)) + + env = os.environ.copy() + env.update({"YARN_ENABLE_IMMUTABLE_INSTALLS": "false"}) + run( + ["jlpm", "install"], + cwd=extension_folder, + check=True, + env=env, + ) + + with pytest.raises(subprocess.CalledProcessError) as excinfo: + run( + ["jupyter-builder", "build", str(extension_folder)], + cwd=extension_folder, + check=True, + capture_output=True, + text=True, + ) + # Check if the expected error message is in the output + assert re.search( + ( + r"ValueError: Extensions require a devDependency on @jupyterlab/builder@\^.+?, " + r"you have a dependency on 4\.0\.0" + ), + excinfo.value.stderr, + ), "Expected version mismatch error message not found in output!" diff --git a/tsconfig.json b/tsconfig.json index 9897917..ae247c2 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,4 +1,5 @@ { + "$schema": "http://json.schemastore.org/tsconfig", "compilerOptions": { "allowSyntheticDefaultImports": true, "composite": true, @@ -6,7 +7,7 @@ "esModuleInterop": true, "incremental": true, "jsx": "react", - "module": "esnext", + "module": "commonjs", "moduleResolution": "node", "noEmitOnError": true, "noImplicitAny": true, @@ -15,9 +16,12 @@ "resolveJsonModule": true, "outDir": "lib", "rootDir": "src", - "strict": true, "strictNullChecks": true, - "target": "ES2018" + "target": "ES2018", + "lib": ["DOM", "DOM.Iterable", "ES2018", "ES2020.Intl"], + "sourceMap": true, + "types": [] }, - "include": ["src/*"] + "include": ["src/*", "src/metadata_schema.json"], + "references": [] } diff --git a/yarn.lock b/yarn.lock index 8477ea6..fd51f29 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5,6 +5,13 @@ __metadata: version: 6 cacheKey: 8 +"@discoveryjs/json-ext@npm:^0.5.0": + version: 0.5.7 + resolution: "@discoveryjs/json-ext@npm:0.5.7" + checksum: 2176d301cc258ea5c2324402997cf8134ebb212469c0d397591636cea8d3c02f2b3cf9fd58dcb748c7a0dade77ebdc1b10284fa63e608c033a1db52fddc69918 + languageName: node + linkType: hard + "@eslint-community/eslint-utils@npm:^4.2.0, @eslint-community/eslint-utils@npm:^4.4.0": version: 4.4.0 resolution: "@eslint-community/eslint-utils@npm:4.4.0" @@ -86,20 +93,94 @@ __metadata: languageName: node linkType: hard +"@jridgewell/gen-mapping@npm:^0.3.5": + version: 0.3.5 + resolution: "@jridgewell/gen-mapping@npm:0.3.5" + dependencies: + "@jridgewell/set-array": ^1.2.1 + "@jridgewell/sourcemap-codec": ^1.4.10 + "@jridgewell/trace-mapping": ^0.3.24 + checksum: ff7a1764ebd76a5e129c8890aa3e2f46045109dabde62b0b6c6a250152227647178ff2069ea234753a690d8f3c4ac8b5e7b267bbee272bffb7f3b0a370ab6e52 + languageName: node + linkType: hard + +"@jridgewell/resolve-uri@npm:^3.1.0": + version: 3.1.2 + resolution: "@jridgewell/resolve-uri@npm:3.1.2" + checksum: 83b85f72c59d1c080b4cbec0fef84528963a1b5db34e4370fa4bd1e3ff64a0d80e0cee7369d11d73c704e0286fb2865b530acac7a871088fbe92b5edf1000870 + languageName: node + linkType: hard + +"@jridgewell/set-array@npm:^1.2.1": + version: 1.2.1 + resolution: "@jridgewell/set-array@npm:1.2.1" + checksum: 832e513a85a588f8ed4f27d1279420d8547743cc37fcad5a5a76fc74bb895b013dfe614d0eed9cb860048e6546b798f8f2652020b4b2ba0561b05caa8c654b10 + languageName: node + linkType: hard + +"@jridgewell/source-map@npm:^0.3.3": + version: 0.3.6 + resolution: "@jridgewell/source-map@npm:0.3.6" + dependencies: + "@jridgewell/gen-mapping": ^0.3.5 + "@jridgewell/trace-mapping": ^0.3.25 + checksum: c9dc7d899397df95e3c9ec287b93c0b56f8e4453cd20743e2b9c8e779b1949bc3cccf6c01bb302779e46560eb45f62ea38d19fedd25370d814734268450a9f30 + languageName: node + linkType: hard + +"@jridgewell/sourcemap-codec@npm:^1.4.10, @jridgewell/sourcemap-codec@npm:^1.4.14": + version: 1.5.0 + resolution: "@jridgewell/sourcemap-codec@npm:1.5.0" + checksum: 05df4f2538b3b0f998ea4c1cd34574d0feba216fa5d4ccaef0187d12abf82eafe6021cec8b49f9bb4d90f2ba4582ccc581e72986a5fcf4176ae0cfeb04cf52ec + languageName: node + linkType: hard + +"@jridgewell/trace-mapping@npm:^0.3.20, @jridgewell/trace-mapping@npm:^0.3.24, @jridgewell/trace-mapping@npm:^0.3.25": + version: 0.3.25 + resolution: "@jridgewell/trace-mapping@npm:0.3.25" + dependencies: + "@jridgewell/resolve-uri": ^3.1.0 + "@jridgewell/sourcemap-codec": ^1.4.14 + checksum: 9d3c40d225e139987b50c48988f8717a54a8c994d8a948ee42e1412e08988761d0754d7d10b803061cc3aebf35f92a5dbbab493bd0e1a9ef9e89a2130e83ba34 + languageName: node + linkType: hard + "@jupyterlab/builder@workspace:.": version: 0.0.0-use.local resolution: "@jupyterlab/builder@workspace:." dependencies: + "@types/fs-extra": ^9.0.1 + "@types/glob": ^7.1.1 + "@types/node": ^20.11.27 + "@types/supports-color": ^5.3.0 "@typescript-eslint/eslint-plugin": ^6.1.0 "@typescript-eslint/parser": ^6.1.0 + ajv: ^8.12.0 + commander: ^9.4.1 + css-loader: ^6.7.1 + duplicate-package-checker-webpack-plugin: ^3.0.0 eslint: ^8.36.0 eslint-config-prettier: ^8.8.0 eslint-plugin-prettier: ^5.0.0 + fs-extra: ^10.1.0 + glob: ~7.1.6 + license-webpack-plugin: ^2.3.14 + mini-css-extract-plugin: ^2.7.0 + mini-svg-data-uri: ^1.4.4 npm-run-all: ^4.1.5 + path-browserify: ^1.0.0 prettier: ^3.0.0 - rimraf: ^5.0.1 + process: ^0.11.10 + rimraf: ^5.0.5 source-map-loader: ^1.0.2 - typescript: ~5.0.2 + style-loader: ~3.3.1 + supports-color: ^7.2.0 + terser-webpack-plugin: ^5.3.7 + typescript: ~5.1.6 + webpack: ^5.76.1 + webpack-cli: ^5.0.1 + webpack-merge: ^5.8.0 + worker-loader: ^3.0.2 languageName: unknown linkType: soft @@ -144,13 +225,64 @@ __metadata: languageName: node linkType: hard -"@types/json-schema@npm:^7.0.12, @types/json-schema@npm:^7.0.8": +"@types/estree@npm:^1.0.5": + version: 1.0.6 + resolution: "@types/estree@npm:1.0.6" + checksum: 8825d6e729e16445d9a1dd2fb1db2edc5ed400799064cd4d028150701031af012ba30d6d03fe9df40f4d7a437d0de6d2b256020152b7b09bde9f2e420afdffd9 + languageName: node + linkType: hard + +"@types/fs-extra@npm:^9.0.1": + version: 9.0.13 + resolution: "@types/fs-extra@npm:9.0.13" + dependencies: + "@types/node": "*" + checksum: add79e212acd5ac76b97b9045834e03a7996aef60a814185e0459088fd290519a3c1620865d588fa36c4498bf614210d2a703af5cf80aa1dbc125db78f6edac3 + languageName: node + linkType: hard + +"@types/glob@npm:^7.1.1": + version: 7.2.0 + resolution: "@types/glob@npm:7.2.0" + dependencies: + "@types/minimatch": "*" + "@types/node": "*" + checksum: 6ae717fedfdfdad25f3d5a568323926c64f52ef35897bcac8aca8e19bc50c0bd84630bbd063e5d52078b2137d8e7d3c26eabebd1a2f03ff350fff8a91e79fc19 + languageName: node + linkType: hard + +"@types/json-schema@npm:^7.0.12, @types/json-schema@npm:^7.0.8, @types/json-schema@npm:^7.0.9": version: 7.0.15 resolution: "@types/json-schema@npm:7.0.15" checksum: 97ed0cb44d4070aecea772b7b2e2ed971e10c81ec87dd4ecc160322ffa55ff330dace1793489540e3e318d90942064bb697cc0f8989391797792d919737b3b98 languageName: node linkType: hard +"@types/minimatch@npm:*": + version: 5.1.2 + resolution: "@types/minimatch@npm:5.1.2" + checksum: 0391a282860c7cb6fe262c12b99564732401bdaa5e395bee9ca323c312c1a0f45efbf34dce974682036e857db59a5c9b1da522f3d6055aeead7097264c8705a8 + languageName: node + linkType: hard + +"@types/node@npm:*": + version: 22.7.8 + resolution: "@types/node@npm:22.7.8" + dependencies: + undici-types: ~6.19.2 + checksum: c1dd36bd0bf82588e61f82edb29a792f21ce902f90cc5485591f9fd60cec3ea9172e044bf7b1c0849e7cf3a5a01da39516db260cb65cb0b94904010e00634a1c + languageName: node + linkType: hard + +"@types/node@npm:^20.11.27": + version: 20.16.14 + resolution: "@types/node@npm:20.16.14" + dependencies: + undici-types: ~6.19.2 + checksum: d80071cb9a808a64fc33721a705d1d8931e089efa5264f8b85d3c9203f14704af3069c8b3db9c022665bd571aad3a380b50ea620991e1739ec5e152ab1f6a374 + languageName: node + linkType: hard + "@types/semver@npm:^7.5.0": version: 7.5.8 resolution: "@types/semver@npm:7.5.8" @@ -158,6 +290,31 @@ __metadata: languageName: node linkType: hard +"@types/source-list-map@npm:*": + version: 0.1.6 + resolution: "@types/source-list-map@npm:0.1.6" + checksum: 9cd294c121f1562062de5d241fe4d10780b1131b01c57434845fe50968e9dcf67ede444591c2b1ad6d3f9b6bc646ac02cc8f51a3577c795f9c64cf4573dcc6b1 + languageName: node + linkType: hard + +"@types/supports-color@npm:^5.3.0": + version: 5.3.0 + resolution: "@types/supports-color@npm:5.3.0" + checksum: abb7d12804402c4f59bf2d9d32800d1fc2b6a1003cb2459fc843e9fa128d24b5a62e6e7cd3d5cdaadcdf9c0af36208a12c9dff4fa9f90de0565f545457a93736 + languageName: node + linkType: hard + +"@types/webpack-sources@npm:^0.1.5": + version: 0.1.12 + resolution: "@types/webpack-sources@npm:0.1.12" + dependencies: + "@types/node": "*" + "@types/source-list-map": "*" + source-map: ^0.6.1 + checksum: 75342659a9889478969f7bb7360b998aa084ba11ab523c172ded6a807dac43ab2a9e1212078ef8bbf0f33e4fadd2c8a91b75d38184d8030d96a32fe819c9bb57 + languageName: node + linkType: hard + "@typescript-eslint/eslint-plugin@npm:^6.1.0": version: 6.21.0 resolution: "@typescript-eslint/eslint-plugin@npm:6.21.0" @@ -288,6 +445,204 @@ __metadata: languageName: node linkType: hard +"@webassemblyjs/ast@npm:1.12.1, @webassemblyjs/ast@npm:^1.12.1": + version: 1.12.1 + resolution: "@webassemblyjs/ast@npm:1.12.1" + dependencies: + "@webassemblyjs/helper-numbers": 1.11.6 + "@webassemblyjs/helper-wasm-bytecode": 1.11.6 + checksum: 31bcc64147236bd7b1b6d29d1f419c1f5845c785e1e42dc9e3f8ca2e05a029e9393a271b84f3a5bff2a32d35f51ff59e2181a6e5f953fe88576acd6750506202 + languageName: node + linkType: hard + +"@webassemblyjs/floating-point-hex-parser@npm:1.11.6": + version: 1.11.6 + resolution: "@webassemblyjs/floating-point-hex-parser@npm:1.11.6" + checksum: 29b08758841fd8b299c7152eda36b9eb4921e9c584eb4594437b5cd90ed6b920523606eae7316175f89c20628da14326801090167cc7fbffc77af448ac84b7e2 + languageName: node + linkType: hard + +"@webassemblyjs/helper-api-error@npm:1.11.6": + version: 1.11.6 + resolution: "@webassemblyjs/helper-api-error@npm:1.11.6" + checksum: e8563df85161096343008f9161adb138a6e8f3c2cc338d6a36011aa55eabb32f2fd138ffe63bc278d009ada001cc41d263dadd1c0be01be6c2ed99076103689f + languageName: node + linkType: hard + +"@webassemblyjs/helper-buffer@npm:1.12.1": + version: 1.12.1 + resolution: "@webassemblyjs/helper-buffer@npm:1.12.1" + checksum: c3ffb723024130308db608e86e2bdccd4868bbb62dffb0a9a1530606496f79c87f8565bd8e02805ce64912b71f1a70ee5fb00307258b0c082c3abf961d097eca + languageName: node + linkType: hard + +"@webassemblyjs/helper-numbers@npm:1.11.6": + version: 1.11.6 + resolution: "@webassemblyjs/helper-numbers@npm:1.11.6" + dependencies: + "@webassemblyjs/floating-point-hex-parser": 1.11.6 + "@webassemblyjs/helper-api-error": 1.11.6 + "@xtuc/long": 4.2.2 + checksum: f4b562fa219f84368528339e0f8d273ad44e047a07641ffcaaec6f93e5b76fd86490a009aa91a294584e1436d74b0a01fa9fde45e333a4c657b58168b04da424 + languageName: node + linkType: hard + +"@webassemblyjs/helper-wasm-bytecode@npm:1.11.6": + version: 1.11.6 + resolution: "@webassemblyjs/helper-wasm-bytecode@npm:1.11.6" + checksum: 3535ef4f1fba38de3475e383b3980f4bbf3de72bbb631c2b6584c7df45be4eccd62c6ff48b5edd3f1bcff275cfd605a37679ec199fc91fd0a7705d7f1e3972dc + languageName: node + linkType: hard + +"@webassemblyjs/helper-wasm-section@npm:1.12.1": + version: 1.12.1 + resolution: "@webassemblyjs/helper-wasm-section@npm:1.12.1" + dependencies: + "@webassemblyjs/ast": 1.12.1 + "@webassemblyjs/helper-buffer": 1.12.1 + "@webassemblyjs/helper-wasm-bytecode": 1.11.6 + "@webassemblyjs/wasm-gen": 1.12.1 + checksum: c19810cdd2c90ff574139b6d8c0dda254d42d168a9e5b3d353d1bc085f1d7164ccd1b3c05592a45a939c47f7e403dc8d03572bb686642f06a3d02932f6f0bc8f + languageName: node + linkType: hard + +"@webassemblyjs/ieee754@npm:1.11.6": + version: 1.11.6 + resolution: "@webassemblyjs/ieee754@npm:1.11.6" + dependencies: + "@xtuc/ieee754": ^1.2.0 + checksum: 13574b8e41f6ca39b700e292d7edf102577db5650fe8add7066a320aa4b7a7c09a5056feccac7a74eb68c10dea9546d4461412af351f13f6b24b5f32379b49de + languageName: node + linkType: hard + +"@webassemblyjs/leb128@npm:1.11.6": + version: 1.11.6 + resolution: "@webassemblyjs/leb128@npm:1.11.6" + dependencies: + "@xtuc/long": 4.2.2 + checksum: 7ea942dc9777d4b18a5ebfa3a937b30ae9e1d2ce1fee637583ed7f376334dd1d4274f813d2e250056cca803e0952def4b954913f1a3c9068bcd4ab4ee5143bf0 + languageName: node + linkType: hard + +"@webassemblyjs/utf8@npm:1.11.6": + version: 1.11.6 + resolution: "@webassemblyjs/utf8@npm:1.11.6" + checksum: 807fe5b5ce10c390cfdd93e0fb92abda8aebabb5199980681e7c3743ee3306a75729bcd1e56a3903980e96c885ee53ef901fcbaac8efdfa480f9c0dae1d08713 + languageName: node + linkType: hard + +"@webassemblyjs/wasm-edit@npm:^1.12.1": + version: 1.12.1 + resolution: "@webassemblyjs/wasm-edit@npm:1.12.1" + dependencies: + "@webassemblyjs/ast": 1.12.1 + "@webassemblyjs/helper-buffer": 1.12.1 + "@webassemblyjs/helper-wasm-bytecode": 1.11.6 + "@webassemblyjs/helper-wasm-section": 1.12.1 + "@webassemblyjs/wasm-gen": 1.12.1 + "@webassemblyjs/wasm-opt": 1.12.1 + "@webassemblyjs/wasm-parser": 1.12.1 + "@webassemblyjs/wast-printer": 1.12.1 + checksum: ae23642303f030af888d30c4ef37b08dfec7eab6851a9575a616e65d1219f880d9223913a39056dd654e49049d76e97555b285d1f7e56935047abf578cce0692 + languageName: node + linkType: hard + +"@webassemblyjs/wasm-gen@npm:1.12.1": + version: 1.12.1 + resolution: "@webassemblyjs/wasm-gen@npm:1.12.1" + dependencies: + "@webassemblyjs/ast": 1.12.1 + "@webassemblyjs/helper-wasm-bytecode": 1.11.6 + "@webassemblyjs/ieee754": 1.11.6 + "@webassemblyjs/leb128": 1.11.6 + "@webassemblyjs/utf8": 1.11.6 + checksum: 5787626bb7f0b033044471ddd00ce0c9fe1ee4584e8b73e232051e3a4c99ba1a102700d75337151c8b6055bae77eefa4548960c610a5e4a504e356bd872138ff + languageName: node + linkType: hard + +"@webassemblyjs/wasm-opt@npm:1.12.1": + version: 1.12.1 + resolution: "@webassemblyjs/wasm-opt@npm:1.12.1" + dependencies: + "@webassemblyjs/ast": 1.12.1 + "@webassemblyjs/helper-buffer": 1.12.1 + "@webassemblyjs/wasm-gen": 1.12.1 + "@webassemblyjs/wasm-parser": 1.12.1 + checksum: 0e8fa8a0645304a1e18ff40d3db5a2e9233ebaa169b19fcc651d6fc9fe2cac0ce092ddee927318015ae735d9cd9c5d97c0cafb6a51dcd2932ac73587b62df991 + languageName: node + linkType: hard + +"@webassemblyjs/wasm-parser@npm:1.12.1, @webassemblyjs/wasm-parser@npm:^1.12.1": + version: 1.12.1 + resolution: "@webassemblyjs/wasm-parser@npm:1.12.1" + dependencies: + "@webassemblyjs/ast": 1.12.1 + "@webassemblyjs/helper-api-error": 1.11.6 + "@webassemblyjs/helper-wasm-bytecode": 1.11.6 + "@webassemblyjs/ieee754": 1.11.6 + "@webassemblyjs/leb128": 1.11.6 + "@webassemblyjs/utf8": 1.11.6 + checksum: 176015de3551ac068cd4505d837414f258d9ade7442bd71efb1232fa26c9f6d7d4e11a5c816caeed389943f409af7ebff6899289a992d7a70343cb47009d21a8 + languageName: node + linkType: hard + +"@webassemblyjs/wast-printer@npm:1.12.1": + version: 1.12.1 + resolution: "@webassemblyjs/wast-printer@npm:1.12.1" + dependencies: + "@webassemblyjs/ast": 1.12.1 + "@xtuc/long": 4.2.2 + checksum: 2974b5dda8d769145ba0efd886ea94a601e61fb37114c14f9a9a7606afc23456799af652ac3052f284909bd42edc3665a76bc9b50f95f0794c053a8a1757b713 + languageName: node + linkType: hard + +"@webpack-cli/configtest@npm:^2.1.1": + version: 2.1.1 + resolution: "@webpack-cli/configtest@npm:2.1.1" + peerDependencies: + webpack: 5.x.x + webpack-cli: 5.x.x + checksum: 9f9f9145c2d05471fc83d426db1df85cf49f329836b0c4b9f46b6948bed4b013464c00622b136d2a0a26993ce2306976682592245b08ee717500b1db45009a72 + languageName: node + linkType: hard + +"@webpack-cli/info@npm:^2.0.2": + version: 2.0.2 + resolution: "@webpack-cli/info@npm:2.0.2" + peerDependencies: + webpack: 5.x.x + webpack-cli: 5.x.x + checksum: 8f9a178afca5c82e113aed1efa552d64ee5ae4fdff63fe747c096a981ec74f18a5d07bd6e89bbe6715c3e57d96eea024a410e58977169489fe1df044c10dd94e + languageName: node + linkType: hard + +"@webpack-cli/serve@npm:^2.0.5": + version: 2.0.5 + resolution: "@webpack-cli/serve@npm:2.0.5" + peerDependencies: + webpack: 5.x.x + webpack-cli: 5.x.x + peerDependenciesMeta: + webpack-dev-server: + optional: true + checksum: 75f0e54681796d567a71ac3e2781d2901a8d8cf1cdfc82f261034dddac59a8343e8c3bc5e32b4bb9d6766759ba49fb29a5cd86ef1701d79c506fe886bb63ac75 + languageName: node + linkType: hard + +"@xtuc/ieee754@npm:^1.2.0": + version: 1.2.0 + resolution: "@xtuc/ieee754@npm:1.2.0" + checksum: ac56d4ca6e17790f1b1677f978c0c6808b1900a5b138885d3da21732f62e30e8f0d9120fcf8f6edfff5100ca902b46f8dd7c1e3f903728634523981e80e2885a + languageName: node + linkType: hard + +"@xtuc/long@npm:4.2.2": + version: 4.2.2 + resolution: "@xtuc/long@npm:4.2.2" + checksum: 8ed0d477ce3bc9c6fe2bf6a6a2cc316bb9c4127c5a7827bae947fa8ec34c7092395c5a283cc300c05b5fa01cbbfa1f938f410a7bf75db7c7846fea41949989ec + languageName: node + linkType: hard + "abab@npm:^2.0.5": version: 2.0.6 resolution: "abab@npm:2.0.6" @@ -295,6 +650,15 @@ __metadata: languageName: node linkType: hard +"acorn-import-attributes@npm:^1.9.5": + version: 1.9.5 + resolution: "acorn-import-attributes@npm:1.9.5" + peerDependencies: + acorn: ^8 + checksum: 1c0c49b6a244503964ae46ae850baccf306e84caf99bc2010ed6103c69a423987b07b520a6c619f075d215388bd4923eccac995886a54309eda049ab78a4be95 + languageName: node + linkType: hard + "acorn-jsx@npm:^5.3.2": version: 5.3.2 resolution: "acorn-jsx@npm:5.3.2" @@ -304,6 +668,15 @@ __metadata: languageName: node linkType: hard +"acorn@npm:^8.7.1, acorn@npm:^8.8.2": + version: 8.13.0 + resolution: "acorn@npm:8.13.0" + bin: + acorn: bin/acorn + checksum: f1541f05eb5d6ff67990d1927290809b1ebb663ac96d9c7057c935cf29c5bcaba6d39f37bd007f4bb814f162f142b0f2b2dd4b14128b8fcfaf9f0508a6f05f1c + languageName: node + linkType: hard + "acorn@npm:^8.9.0": version: 8.12.1 resolution: "acorn@npm:8.12.1" @@ -313,6 +686,20 @@ __metadata: languageName: node linkType: hard +"ajv-formats@npm:^2.1.1": + version: 2.1.1 + resolution: "ajv-formats@npm:2.1.1" + dependencies: + ajv: ^8.0.0 + peerDependencies: + ajv: ^8.0.0 + peerDependenciesMeta: + ajv: + optional: true + checksum: 4a287d937f1ebaad4683249a4c40c0fa3beed30d9ddc0adba04859026a622da0d317851316ea64b3680dc60f5c3c708105ddd5d5db8fe595d9d0207fd19f90b7 + languageName: node + linkType: hard + "ajv-keywords@npm:^3.5.2": version: 3.5.2 resolution: "ajv-keywords@npm:3.5.2" @@ -322,6 +709,17 @@ __metadata: languageName: node linkType: hard +"ajv-keywords@npm:^5.1.0": + version: 5.1.0 + resolution: "ajv-keywords@npm:5.1.0" + dependencies: + fast-deep-equal: ^3.1.3 + peerDependencies: + ajv: ^8.8.2 + checksum: c35193940b853119242c6757787f09ecf89a2c19bcd36d03ed1a615e710d19d450cb448bfda407b939aba54b002368c8bff30529cc50a0536a8e10bcce300421 + languageName: node + linkType: hard + "ajv@npm:^6.12.4, ajv@npm:^6.12.5": version: 6.12.6 resolution: "ajv@npm:6.12.6" @@ -334,6 +732,18 @@ __metadata: languageName: node linkType: hard +"ajv@npm:^8.0.0, ajv@npm:^8.12.0, ajv@npm:^8.9.0": + version: 8.17.1 + resolution: "ajv@npm:8.17.1" + dependencies: + fast-deep-equal: ^3.1.3 + fast-uri: ^3.0.1 + json-schema-traverse: ^1.0.0 + require-from-string: ^2.0.2 + checksum: 1797bf242cfffbaf3b870d13565bd1716b73f214bb7ada9a497063aada210200da36e3ed40237285f3255acc4feeae91b1fb183625331bad27da95973f7253d9 + languageName: node + linkType: hard + "ansi-regex@npm:^5.0.1": version: 5.0.1 resolution: "ansi-regex@npm:5.0.1" @@ -464,6 +874,27 @@ __metadata: languageName: node linkType: hard +"browserslist@npm:^4.21.10": + version: 4.24.2 + resolution: "browserslist@npm:4.24.2" + dependencies: + caniuse-lite: ^1.0.30001669 + electron-to-chromium: ^1.5.41 + node-releases: ^2.0.18 + update-browserslist-db: ^1.1.1 + bin: + browserslist: cli.js + checksum: cf64085f12132d38638f38937a255edb82c7551b164a98577b055dd79719187a816112f7b97b9739e400c4954cd66479c0d7a843cb816e346f4795dc24fd5d97 + languageName: node + linkType: hard + +"buffer-from@npm:^1.0.0": + version: 1.1.2 + resolution: "buffer-from@npm:1.1.2" + checksum: 0448524a562b37d4d7ed9efd91685a5b77a50672c556ea254ac9a6d30e3403a517d8981f10e565db24e8339413b43c97ca2951f10e399c6125a0d8911f5679bb + languageName: node + linkType: hard + "call-bind@npm:^1.0.2, call-bind@npm:^1.0.5, call-bind@npm:^1.0.6, call-bind@npm:^1.0.7": version: 1.0.7 resolution: "call-bind@npm:1.0.7" @@ -484,7 +915,14 @@ __metadata: languageName: node linkType: hard -"chalk@npm:^2.4.1": +"caniuse-lite@npm:^1.0.30001669": + version: 1.0.30001669 + resolution: "caniuse-lite@npm:1.0.30001669" + checksum: 8ed0c69d0c6aa3b1cbc5ba4e5f5330943e7b7165e257f6955b8b73f043d07ad922265261f2b54d9bbaf02886bbdba5e6f5b16662310a13f91f17035af3212de1 + languageName: node + linkType: hard + +"chalk@npm:^2.3.0, chalk@npm:^2.4.1": version: 2.4.2 resolution: "chalk@npm:2.4.2" dependencies: @@ -505,6 +943,24 @@ __metadata: languageName: node linkType: hard +"chrome-trace-event@npm:^1.0.2": + version: 1.0.4 + resolution: "chrome-trace-event@npm:1.0.4" + checksum: fcbbd9dd0cd5b48444319007cc0c15870fd8612cc0df320908aa9d5e8a244084d48571eb28bf3c58c19327d2c5838f354c2d89fac3956d8e992273437401ac19 + languageName: node + linkType: hard + +"clone-deep@npm:^4.0.1": + version: 4.0.1 + resolution: "clone-deep@npm:4.0.1" + dependencies: + is-plain-object: ^2.0.4 + kind-of: ^6.0.2 + shallow-clone: ^3.0.0 + checksum: 770f912fe4e6f21873c8e8fbb1e99134db3b93da32df271d00589ea4a29dbe83a9808a322c93f3bcaf8584b8b4fa6fc269fc8032efbaa6728e0c9886c74467d2 + languageName: node + linkType: hard + "color-convert@npm:^1.9.0": version: 1.9.3 resolution: "color-convert@npm:1.9.3" @@ -537,6 +993,34 @@ __metadata: languageName: node linkType: hard +"colorette@npm:^2.0.14": + version: 2.0.20 + resolution: "colorette@npm:2.0.20" + checksum: 0c016fea2b91b733eb9f4bcdb580018f52c0bc0979443dad930e5037a968237ac53d9beb98e218d2e9235834f8eebce7f8e080422d6194e957454255bde71d3d + languageName: node + linkType: hard + +"commander@npm:^10.0.1": + version: 10.0.1 + resolution: "commander@npm:10.0.1" + checksum: 436901d64a818295803c1996cd856621a74f30b9f9e28a588e726b2b1670665bccd7c1a77007ebf328729f0139838a88a19265858a0fa7a8728c4656796db948 + languageName: node + linkType: hard + +"commander@npm:^2.20.0": + version: 2.20.3 + resolution: "commander@npm:2.20.3" + checksum: ab8c07884e42c3a8dbc5dd9592c606176c7eb5c1ca5ff274bcf907039b2c41de3626f684ea75ccf4d361ba004bbaff1f577d5384c155f3871e456bdf27becf9e + languageName: node + linkType: hard + +"commander@npm:^9.4.1": + version: 9.5.0 + resolution: "commander@npm:9.5.0" + checksum: c7a3e27aa59e913b54a1bafd366b88650bc41d6651f0cbe258d4ff09d43d6a7394232a4dadd0bf518b3e696fdf595db1028a0d82c785b88bd61f8a440cecfade + languageName: node + linkType: hard + "concat-map@npm:0.0.1": version: 0.0.1 resolution: "concat-map@npm:0.0.1" @@ -557,7 +1041,7 @@ __metadata: languageName: node linkType: hard -"cross-spawn@npm:^7.0.0, cross-spawn@npm:^7.0.2": +"cross-spawn@npm:^7.0.0, cross-spawn@npm:^7.0.2, cross-spawn@npm:^7.0.3": version: 7.0.3 resolution: "cross-spawn@npm:7.0.3" dependencies: @@ -568,6 +1052,39 @@ __metadata: languageName: node linkType: hard +"css-loader@npm:^6.7.1": + version: 6.11.0 + resolution: "css-loader@npm:6.11.0" + dependencies: + icss-utils: ^5.1.0 + postcss: ^8.4.33 + postcss-modules-extract-imports: ^3.1.0 + postcss-modules-local-by-default: ^4.0.5 + postcss-modules-scope: ^3.2.0 + postcss-modules-values: ^4.0.0 + postcss-value-parser: ^4.2.0 + semver: ^7.5.4 + peerDependencies: + "@rspack/core": 0.x || 1.x + webpack: ^5.0.0 + peerDependenciesMeta: + "@rspack/core": + optional: true + webpack: + optional: true + checksum: 5c8d35975a7121334905394e88e28f05df72f037dbed2fb8fec4be5f0b313ae73a13894ba791867d4a4190c35896da84a7fd0c54fb426db55d85ba5e714edbe3 + languageName: node + linkType: hard + +"cssesc@npm:^3.0.0": + version: 3.0.0 + resolution: "cssesc@npm:3.0.0" + bin: + cssesc: bin/cssesc + checksum: f8c4ababffbc5e2ddf2fa9957dda1ee4af6048e22aeda1869d0d00843223c1b13ad3f5d88b51caa46c994225eacb636b764eb807a8883e2fb6f99b4f4e8c48b2 + languageName: node + linkType: hard + "data-view-buffer@npm:^1.0.1": version: 1.0.1 resolution: "data-view-buffer@npm:1.0.1" @@ -660,6 +1177,18 @@ __metadata: languageName: node linkType: hard +"duplicate-package-checker-webpack-plugin@npm:^3.0.0": + version: 3.0.0 + resolution: "duplicate-package-checker-webpack-plugin@npm:3.0.0" + dependencies: + chalk: ^2.3.0 + find-root: ^1.0.0 + lodash: ^4.17.4 + semver: ^5.4.1 + checksum: d77be45cb72d79a429c64d8f8f7603fea681d182fb795459a3d4afa608faad9a923378a7e80c6855f465263e1983140b6fc3682bd0213228b8cd7906ab4b934d + languageName: node + linkType: hard + "eastasianwidth@npm:^0.2.0": version: 0.2.0 resolution: "eastasianwidth@npm:0.2.0" @@ -667,6 +1196,13 @@ __metadata: languageName: node linkType: hard +"electron-to-chromium@npm:^1.5.41": + version: 1.5.42 + resolution: "electron-to-chromium@npm:1.5.42" + checksum: 8527f6e050b7f869d0135869587b3273fefa1cc2cbb9799bff552e10586b61860139758ee9824c803cdce632e24d4897bb7f67dcecf1c2bef279977fdfa9afa1 + languageName: node + linkType: hard + "emoji-regex@npm:^8.0.0": version: 8.0.0 resolution: "emoji-regex@npm:8.0.0" @@ -688,6 +1224,25 @@ __metadata: languageName: node linkType: hard +"enhanced-resolve@npm:^5.17.1": + version: 5.17.1 + resolution: "enhanced-resolve@npm:5.17.1" + dependencies: + graceful-fs: ^4.2.4 + tapable: ^2.2.0 + checksum: 4bc38cf1cea96456f97503db7280394177d1bc46f8f87c267297d04f795ac5efa81e48115a2f5b6273c781027b5b6bfc5f62b54df629e4d25fa7001a86624f59 + languageName: node + linkType: hard + +"envinfo@npm:^7.7.3": + version: 7.14.0 + resolution: "envinfo@npm:7.14.0" + bin: + envinfo: dist/cli.js + checksum: 137c1dd9a4d5781c4a6cdc6b695454ba3c4ba1829f73927198aa4122f11b35b59d7b2cb7e1ceea1364925a30278897548511d22f860c14253a33797d0bebd551 + languageName: node + linkType: hard + "error-ex@npm:^1.3.1": version: 1.3.2 resolution: "error-ex@npm:1.3.2" @@ -767,6 +1322,13 @@ __metadata: languageName: node linkType: hard +"es-module-lexer@npm:^1.2.1": + version: 1.5.4 + resolution: "es-module-lexer@npm:1.5.4" + checksum: a0cf04fb92d052647ac7d818d1913b98d3d3d0f5b9d88f0eafb993436e4c3e2c958599db68839d57f2dfa281fdf0f60e18d448eb78fc292c33c0f25635b6854f + languageName: node + linkType: hard + "es-object-atoms@npm:^1.0.0": version: 1.0.0 resolution: "es-object-atoms@npm:1.0.0" @@ -798,6 +1360,13 @@ __metadata: languageName: node linkType: hard +"escalade@npm:^3.2.0": + version: 3.2.0 + resolution: "escalade@npm:3.2.0" + checksum: 47b029c83de01b0d17ad99ed766347b974b0d628e848de404018f3abee728e987da0d2d370ad4574aa3d5b5bfc368754fd085d69a30f8e75903486ec4b5b709e + languageName: node + linkType: hard + "escape-string-regexp@npm:^1.0.5": version: 1.0.5 resolution: "escape-string-regexp@npm:1.0.5" @@ -843,6 +1412,16 @@ __metadata: languageName: node linkType: hard +"eslint-scope@npm:5.1.1": + version: 5.1.1 + resolution: "eslint-scope@npm:5.1.1" + dependencies: + esrecurse: ^4.3.0 + estraverse: ^4.1.1 + checksum: 47e4b6a3f0cc29c7feedee6c67b225a2da7e155802c6ea13bbef4ac6b9e10c66cd2dcb987867ef176292bf4e64eccc680a49e35e9e9c669f4a02bac17e86abdb + languageName: node + linkType: hard + "eslint-scope@npm:^7.2.2": version: 7.2.2 resolution: "eslint-scope@npm:7.2.2" @@ -937,6 +1516,13 @@ __metadata: languageName: node linkType: hard +"estraverse@npm:^4.1.1": + version: 4.3.0 + resolution: "estraverse@npm:4.3.0" + checksum: a6299491f9940bb246124a8d44b7b7a413a8336f5436f9837aaa9330209bd9ee8af7e91a654a3545aee9c54b3308e78ee360cef1d777d37cfef77d2fa33b5827 + languageName: node + linkType: hard + "estraverse@npm:^5.1.0, estraverse@npm:^5.2.0": version: 5.3.0 resolution: "estraverse@npm:5.3.0" @@ -951,6 +1537,13 @@ __metadata: languageName: node linkType: hard +"events@npm:^3.2.0": + version: 3.3.0 + resolution: "events@npm:3.3.0" + checksum: f6f487ad2198aa41d878fa31452f1a3c00958f46e9019286ff4787c84aac329332ab45c9cdc8c445928fc6d7ded294b9e005a7fce9426488518017831b272780 + languageName: node + linkType: hard + "fast-deep-equal@npm:^3.1.1, fast-deep-equal@npm:^3.1.3": version: 3.1.3 resolution: "fast-deep-equal@npm:3.1.3" @@ -992,6 +1585,20 @@ __metadata: languageName: node linkType: hard +"fast-uri@npm:^3.0.1": + version: 3.0.3 + resolution: "fast-uri@npm:3.0.3" + checksum: c52e6c86465f5c240e84a4485fb001088cc743d261a4b54b0050ce4758b1648bdbe53da1328ef9620149dca1435e3de64184f226d7c0a3656cb5837b3491e149 + languageName: node + linkType: hard + +"fastest-levenshtein@npm:^1.0.12": + version: 1.0.16 + resolution: "fastest-levenshtein@npm:1.0.16" + checksum: a78d44285c9e2ae2c25f3ef0f8a73f332c1247b7ea7fb4a191e6bb51aa6ee1ef0dfb3ed113616dcdc7023e18e35a8db41f61c8d88988e877cf510df8edafbc71 + languageName: node + linkType: hard + "fastq@npm:^1.6.0": version: 1.17.1 resolution: "fastq@npm:1.17.1" @@ -1019,6 +1626,23 @@ __metadata: languageName: node linkType: hard +"find-root@npm:^1.0.0": + version: 1.1.0 + resolution: "find-root@npm:1.1.0" + checksum: b2a59fe4b6c932eef36c45a048ae8f93c85640212ebe8363164814990ee20f154197505965f3f4f102efc33bfb1cbc26fd17c4a2fc739ebc51b886b137cbefaf + languageName: node + linkType: hard + +"find-up@npm:^4.0.0": + version: 4.1.0 + resolution: "find-up@npm:4.1.0" + dependencies: + locate-path: ^5.0.0 + path-exists: ^4.0.0 + checksum: 4c172680e8f8c1f78839486e14a43ef82e9decd0e74145f40707cc42e7420506d5ec92d9a11c22bd2c48fb0c384ea05dd30e10dd152fefeec6f2f75282a8b844 + languageName: node + linkType: hard + "find-up@npm:^5.0.0": version: 5.0.0 resolution: "find-up@npm:5.0.0" @@ -1040,6 +1664,15 @@ __metadata: languageName: node linkType: hard +"flat@npm:^5.0.2": + version: 5.0.2 + resolution: "flat@npm:5.0.2" + bin: + flat: cli.js + checksum: 12a1536ac746db74881316a181499a78ef953632ddd28050b7a3a43c62ef5462e3357c8c29d76072bb635f147f7a9a1f0c02efef6b4be28f8db62ceb3d5c7f5d + languageName: node + linkType: hard + "flatted@npm:^3.2.9": version: 3.3.1 resolution: "flatted@npm:3.3.1" @@ -1066,6 +1699,17 @@ __metadata: languageName: node linkType: hard +"fs-extra@npm:^10.1.0": + version: 10.1.0 + resolution: "fs-extra@npm:10.1.0" + dependencies: + graceful-fs: ^4.2.0 + jsonfile: ^6.0.1 + universalify: ^2.0.0 + checksum: dc94ab37096f813cc3ca12f0f1b5ad6744dfed9ed21e953d72530d103cea193c2f81584a39e9dee1bea36de5ee66805678c0dddc048e8af1427ac19c00fffc50 + languageName: node + linkType: hard + "fs.realpath@npm:^1.0.0": version: 1.0.0 resolution: "fs.realpath@npm:1.0.0" @@ -1141,6 +1785,13 @@ __metadata: languageName: node linkType: hard +"glob-to-regexp@npm:^0.4.1": + version: 0.4.1 + resolution: "glob-to-regexp@npm:0.4.1" + checksum: e795f4e8f06d2a15e86f76e4d92751cf8bbfcf0157cea5c2f0f35678a8195a750b34096b1256e436f0cebc1883b5ff0888c47348443e69546a5a87f9e1eb1167 + languageName: node + linkType: hard + "glob@npm:^10.3.7": version: 10.4.5 resolution: "glob@npm:10.4.5" @@ -1171,6 +1822,20 @@ __metadata: languageName: node linkType: hard +"glob@npm:~7.1.6": + version: 7.1.7 + resolution: "glob@npm:7.1.7" + dependencies: + fs.realpath: ^1.0.0 + inflight: ^1.0.4 + inherits: 2 + minimatch: ^3.0.4 + once: ^1.3.0 + path-is-absolute: ^1.0.0 + checksum: b61f48973bbdcf5159997b0874a2165db572b368b931135832599875919c237fc05c12984e38fe828e69aa8a921eb0e8a4997266211c517c9cfaae8a93988bb8 + languageName: node + linkType: hard + "globals@npm:^13.19.0": version: 13.24.0 resolution: "globals@npm:13.24.0" @@ -1213,7 +1878,7 @@ __metadata: languageName: node linkType: hard -"graceful-fs@npm:^4.1.2": +"graceful-fs@npm:^4.1.2, graceful-fs@npm:^4.1.6, graceful-fs@npm:^4.2.0, graceful-fs@npm:^4.2.11, graceful-fs@npm:^4.2.4": version: 4.2.11 resolution: "graceful-fs@npm:4.2.11" checksum: ac85f94da92d8eb6b7f5a8b20ce65e43d66761c55ce85ac96df6865308390da45a8d3f0296dd3a663de65d30ba497bd46c696cc1e248c72b13d6d567138a4fc7 @@ -1305,6 +1970,15 @@ __metadata: languageName: node linkType: hard +"icss-utils@npm:^5.0.0, icss-utils@npm:^5.1.0": + version: 5.1.0 + resolution: "icss-utils@npm:5.1.0" + peerDependencies: + postcss: ^8.1.0 + checksum: 5c324d283552b1269cfc13a503aaaa172a280f914e5b81544f3803bc6f06a3b585fb79f66f7c771a2c052db7982c18bf92d001e3b47282e3abbbb4c4cc488d68 + languageName: node + linkType: hard + "ignore@npm:^5.2.0, ignore@npm:^5.2.4": version: 5.3.1 resolution: "ignore@npm:5.3.1" @@ -1322,6 +1996,18 @@ __metadata: languageName: node linkType: hard +"import-local@npm:^3.0.2": + version: 3.2.0 + resolution: "import-local@npm:3.2.0" + dependencies: + pkg-dir: ^4.2.0 + resolve-cwd: ^3.0.0 + bin: + import-local-fixture: fixtures/cli.js + checksum: 0b0b0b412b2521739fbb85eeed834a3c34de9bc67e670b3d0b86248fc460d990a7b116ad056c084b87a693ef73d1f17268d6a5be626bb43c998a8b1c8a230004 + languageName: node + linkType: hard + "imurmurhash@npm:^0.1.4": version: 0.1.4 resolution: "imurmurhash@npm:0.1.4" @@ -1357,6 +2043,13 @@ __metadata: languageName: node linkType: hard +"interpret@npm:^3.1.1": + version: 3.1.1 + resolution: "interpret@npm:3.1.1" + checksum: 35cebcf48c7351130437596d9ab8c8fe131ce4038da4561e6d665f25640e0034702a031cf7e3a5cea60ac7ac548bf17465e0571ede126f3d3a6933152171ac82 + languageName: node + linkType: hard + "is-array-buffer@npm:^3.0.4": version: 3.0.4 resolution: "is-array-buffer@npm:3.0.4" @@ -1480,6 +2173,15 @@ __metadata: languageName: node linkType: hard +"is-plain-object@npm:^2.0.4": + version: 2.0.4 + resolution: "is-plain-object@npm:2.0.4" + dependencies: + isobject: ^3.0.1 + checksum: 2a401140cfd86cabe25214956ae2cfee6fbd8186809555cd0e84574f88de7b17abacb2e477a6a658fa54c6083ecbda1e6ae404c7720244cd198903848fca70ca + languageName: node + linkType: hard + "is-regex@npm:^1.1.4": version: 1.1.4 resolution: "is-regex@npm:1.1.4" @@ -1549,6 +2251,13 @@ __metadata: languageName: node linkType: hard +"isobject@npm:^3.0.1": + version: 3.0.1 + resolution: "isobject@npm:3.0.1" + checksum: db85c4c970ce30693676487cca0e61da2ca34e8d4967c2e1309143ff910c207133a969f9e4ddb2dc6aba670aabce4e0e307146c310350b298e74a31f7d464703 + languageName: node + linkType: hard + "jackspeak@npm:^3.1.2": version: 3.4.3 resolution: "jackspeak@npm:3.4.3" @@ -1562,6 +2271,17 @@ __metadata: languageName: node linkType: hard +"jest-worker@npm:^27.4.5": + version: 27.5.1 + resolution: "jest-worker@npm:27.5.1" + dependencies: + "@types/node": "*" + merge-stream: ^2.0.0 + supports-color: ^8.0.0 + checksum: 98cd68b696781caed61c983a3ee30bf880b5bd021c01d98f47b143d4362b85d0737f8523761e2713d45e18b4f9a2b98af1eaee77afade4111bb65c77d6f7c980 + languageName: node + linkType: hard + "js-yaml@npm:^4.1.0": version: 4.1.0 resolution: "js-yaml@npm:4.1.0" @@ -1587,6 +2307,13 @@ __metadata: languageName: node linkType: hard +"json-parse-even-better-errors@npm:^2.3.1": + version: 2.3.1 + resolution: "json-parse-even-better-errors@npm:2.3.1" + checksum: 798ed4cf3354a2d9ccd78e86d2169515a0097a5c133337807cdf7f1fc32e1391d207ccfc276518cc1d7d8d4db93288b8a50ba4293d212ad1336e52a8ec0a941f + languageName: node + linkType: hard + "json-schema-traverse@npm:^0.4.1": version: 0.4.1 resolution: "json-schema-traverse@npm:0.4.1" @@ -1594,6 +2321,13 @@ __metadata: languageName: node linkType: hard +"json-schema-traverse@npm:^1.0.0": + version: 1.0.0 + resolution: "json-schema-traverse@npm:1.0.0" + checksum: 02f2f466cdb0362558b2f1fd5e15cce82ef55d60cd7f8fa828cf35ba74330f8d767fcae5c5c2adb7851fa811766c694b9405810879bc4e1ddd78a7c0e03658ad + languageName: node + linkType: hard + "json-stable-stringify-without-jsonify@npm:^1.0.1": version: 1.0.1 resolution: "json-stable-stringify-without-jsonify@npm:1.0.1" @@ -1610,6 +2344,19 @@ __metadata: languageName: node linkType: hard +"jsonfile@npm:^6.0.1": + version: 6.1.0 + resolution: "jsonfile@npm:6.1.0" + dependencies: + graceful-fs: ^4.1.6 + universalify: ^2.0.0 + dependenciesMeta: + graceful-fs: + optional: true + checksum: 7af3b8e1ac8fe7f1eccc6263c6ca14e1966fcbc74b618d3c78a0a2075579487547b94f72b7a1114e844a1e15bb00d440e5d1720bfc4612d790a6f285d5ea8354 + languageName: node + linkType: hard + "keyv@npm:^4.5.3": version: 4.5.4 resolution: "keyv@npm:4.5.4" @@ -1619,6 +2366,13 @@ __metadata: languageName: node linkType: hard +"kind-of@npm:^6.0.2": + version: 6.0.3 + resolution: "kind-of@npm:6.0.3" + checksum: 3ab01e7b1d440b22fe4c31f23d8d38b4d9b91d9f291df683476576493d5dfd2e03848a8b05813dd0c3f0e835bc63f433007ddeceb71f05cb25c45ae1b19c6d3b + languageName: node + linkType: hard + "levn@npm:^0.4.1": version: 0.4.1 resolution: "levn@npm:0.4.1" @@ -1629,6 +2383,19 @@ __metadata: languageName: node linkType: hard +"license-webpack-plugin@npm:^2.3.14": + version: 2.3.21 + resolution: "license-webpack-plugin@npm:2.3.21" + dependencies: + "@types/webpack-sources": ^0.1.5 + webpack-sources: ^1.2.0 + peerDependenciesMeta: + webpack: + optional: true + checksum: 6208bd2060d200fbffbcc89702c929d50c5a4a3f2158b046cf813b3f7f728bbbe4611b9fea2d67843bb5e7d64ad9122cc368a19ac73f5c4ad41765e6283bdc0c + languageName: node + linkType: hard + "load-json-file@npm:^4.0.0": version: 4.0.0 resolution: "load-json-file@npm:4.0.0" @@ -1641,6 +2408,13 @@ __metadata: languageName: node linkType: hard +"loader-runner@npm:^4.2.0": + version: 4.3.0 + resolution: "loader-runner@npm:4.3.0" + checksum: a90e00dee9a16be118ea43fec3192d0b491fe03a32ed48a4132eb61d498f5536a03a1315531c19d284392a8726a4ecad71d82044c28d7f22ef62e029bf761569 + languageName: node + linkType: hard + "loader-utils@npm:^2.0.0": version: 2.0.4 resolution: "loader-utils@npm:2.0.4" @@ -1652,6 +2426,15 @@ __metadata: languageName: node linkType: hard +"locate-path@npm:^5.0.0": + version: 5.0.0 + resolution: "locate-path@npm:5.0.0" + dependencies: + p-locate: ^4.1.0 + checksum: 83e51725e67517287d73e1ded92b28602e3ae5580b301fe54bfb76c0c723e3f285b19252e375712316774cf52006cb236aed5704692c32db0d5d089b69696e30 + languageName: node + linkType: hard + "locate-path@npm:^6.0.0": version: 6.0.0 resolution: "locate-path@npm:6.0.0" @@ -1668,6 +2451,13 @@ __metadata: languageName: node linkType: hard +"lodash@npm:^4.17.4": + version: 4.17.21 + resolution: "lodash@npm:4.17.21" + checksum: eb835a2e51d381e561e508ce932ea50a8e5a68f4ebdd771ea240d3048244a8d13658acbd502cd4829768c56f2e16bdd4340b9ea141297d472517b83868e677f7 + languageName: node + linkType: hard + "lru-cache@npm:^10.2.0": version: 10.4.3 resolution: "lru-cache@npm:10.4.3" @@ -1682,6 +2472,13 @@ __metadata: languageName: node linkType: hard +"merge-stream@npm:^2.0.0": + version: 2.0.0 + resolution: "merge-stream@npm:2.0.0" + checksum: 6fa4dcc8d86629705cea944a4b88ef4cb0e07656ebf223fa287443256414283dd25d91c1cd84c77987f2aec5927af1a9db6085757cb43d90eb170ebf4b47f4f4 + languageName: node + linkType: hard + "merge2@npm:^1.3.0, merge2@npm:^1.4.1": version: 1.4.1 resolution: "merge2@npm:1.4.1" @@ -1699,6 +2496,43 @@ __metadata: languageName: node linkType: hard +"mime-db@npm:1.52.0": + version: 1.52.0 + resolution: "mime-db@npm:1.52.0" + checksum: 0d99a03585f8b39d68182803b12ac601d9c01abfa28ec56204fa330bc9f3d1c5e14beb049bafadb3dbdf646dfb94b87e24d4ec7b31b7279ef906a8ea9b6a513f + languageName: node + linkType: hard + +"mime-types@npm:^2.1.27": + version: 2.1.35 + resolution: "mime-types@npm:2.1.35" + dependencies: + mime-db: 1.52.0 + checksum: 89a5b7f1def9f3af5dad6496c5ed50191ae4331cc5389d7c521c8ad28d5fdad2d06fd81baf38fed813dc4e46bb55c8145bb0ff406330818c9cf712fb2e9b3836 + languageName: node + linkType: hard + +"mini-css-extract-plugin@npm:^2.7.0": + version: 2.9.1 + resolution: "mini-css-extract-plugin@npm:2.9.1" + dependencies: + schema-utils: ^4.0.0 + tapable: ^2.2.1 + peerDependencies: + webpack: ^5.0.0 + checksum: 036b0fbb207cf9a56e2f5f5dce5e35100cbd255e5b5a920a5357ec99215af16a77136020729b2d004a041d04ebb0a544b2f442535cbb982704dcd50297014c9e + languageName: node + linkType: hard + +"mini-svg-data-uri@npm:^1.4.4": + version: 1.4.4 + resolution: "mini-svg-data-uri@npm:1.4.4" + bin: + mini-svg-data-uri: cli.js + checksum: 997f1fbd8d59a70f03761e18626d335197a3479cb9d1ff75678e4b64b864d32a0b8fc18115eabde035e5299b8b4a354a78e57dd6ac10f9d604162a6170898d09 + languageName: node + linkType: hard + "minimatch@npm:9.0.3": version: 9.0.3 resolution: "minimatch@npm:9.0.3" @@ -1740,6 +2574,15 @@ __metadata: languageName: node linkType: hard +"nanoid@npm:^3.3.7": + version: 3.3.7 + resolution: "nanoid@npm:3.3.7" + bin: + nanoid: bin/nanoid.cjs + checksum: d36c427e530713e4ac6567d488b489a36582ef89da1d6d4e3b87eded11eb10d7042a877958c6f104929809b2ab0bafa17652b076cdf84324aa75b30b722204f2 + languageName: node + linkType: hard + "natural-compare@npm:^1.4.0": version: 1.4.0 resolution: "natural-compare@npm:1.4.0" @@ -1747,6 +2590,13 @@ __metadata: languageName: node linkType: hard +"neo-async@npm:^2.6.2": + version: 2.6.2 + resolution: "neo-async@npm:2.6.2" + checksum: deac9f8d00eda7b2e5cd1b2549e26e10a0faa70adaa6fdadca701cc55f49ee9018e427f424bac0c790b7c7e2d3068db97f3093f1093975f2acb8f8818b936ed9 + languageName: node + linkType: hard + "nice-try@npm:^1.0.4": version: 1.0.5 resolution: "nice-try@npm:1.0.5" @@ -1754,6 +2604,13 @@ __metadata: languageName: node linkType: hard +"node-releases@npm:^2.0.18": + version: 2.0.18 + resolution: "node-releases@npm:2.0.18" + checksum: ef55a3d853e1269a6d6279b7692cd6ff3e40bc74947945101138745bfdc9a5edabfe72cb19a31a8e45752e1910c4c65c77d931866af6357f242b172b7283f5b3 + languageName: node + linkType: hard + "normalize-package-data@npm:^2.3.2": version: 2.5.0 resolution: "normalize-package-data@npm:2.5.0" @@ -1836,6 +2693,15 @@ __metadata: languageName: node linkType: hard +"p-limit@npm:^2.2.0": + version: 2.3.0 + resolution: "p-limit@npm:2.3.0" + dependencies: + p-try: ^2.0.0 + checksum: 84ff17f1a38126c3314e91ecfe56aecbf36430940e2873dadaa773ffe072dc23b7af8e46d4b6485d302a11673fe94c6b67ca2cfbb60c989848b02100d0594ac1 + languageName: node + linkType: hard + "p-limit@npm:^3.0.2": version: 3.1.0 resolution: "p-limit@npm:3.1.0" @@ -1845,6 +2711,15 @@ __metadata: languageName: node linkType: hard +"p-locate@npm:^4.1.0": + version: 4.1.0 + resolution: "p-locate@npm:4.1.0" + dependencies: + p-limit: ^2.2.0 + checksum: 513bd14a455f5da4ebfcb819ef706c54adb09097703de6aeaa5d26fe5ea16df92b48d1ac45e01e3944ce1e6aa2a66f7f8894742b8c9d6e276e16cd2049a2b870 + languageName: node + linkType: hard + "p-locate@npm:^5.0.0": version: 5.0.0 resolution: "p-locate@npm:5.0.0" @@ -1854,6 +2729,13 @@ __metadata: languageName: node linkType: hard +"p-try@npm:^2.0.0": + version: 2.2.0 + resolution: "p-try@npm:2.2.0" + checksum: f8a8e9a7693659383f06aec604ad5ead237c7a261c18048a6e1b5b85a5f8a067e469aa24f5bc009b991ea3b058a87f5065ef4176793a200d4917349881216cae + languageName: node + linkType: hard + "package-json-from-dist@npm:^1.0.0": version: 1.0.0 resolution: "package-json-from-dist@npm:1.0.0" @@ -1880,6 +2762,13 @@ __metadata: languageName: node linkType: hard +"path-browserify@npm:^1.0.0": + version: 1.0.1 + resolution: "path-browserify@npm:1.0.1" + checksum: c6d7fa376423fe35b95b2d67990060c3ee304fc815ff0a2dc1c6c3cfaff2bd0d572ee67e18f19d0ea3bbe32e8add2a05021132ac40509416459fffee35200699 + languageName: node + linkType: hard + "path-exists@npm:^4.0.0": version: 4.0.0 resolution: "path-exists@npm:4.0.0" @@ -1941,6 +2830,13 @@ __metadata: languageName: node linkType: hard +"picocolors@npm:^1.1.0": + version: 1.1.1 + resolution: "picocolors@npm:1.1.1" + checksum: e1cf46bf84886c79055fdfa9dcb3e4711ad259949e3565154b004b260cd356c5d54b31a1437ce9782624bf766272fe6b0154f5f0c744fb7af5d454d2b60db045 + languageName: node + linkType: hard + "picomatch@npm:^2.3.1": version: 2.3.1 resolution: "picomatch@npm:2.3.1" @@ -1964,6 +2860,15 @@ __metadata: languageName: node linkType: hard +"pkg-dir@npm:^4.2.0": + version: 4.2.0 + resolution: "pkg-dir@npm:4.2.0" + dependencies: + find-up: ^4.0.0 + checksum: 9863e3f35132bf99ae1636d31ff1e1e3501251d480336edb1c211133c8d58906bed80f154a1d723652df1fda91e01c7442c2eeaf9dc83157c7ae89087e43c8d6 + languageName: node + linkType: hard + "possible-typed-array-names@npm:^1.0.0": version: 1.0.0 resolution: "possible-typed-array-names@npm:1.0.0" @@ -1971,6 +2876,78 @@ __metadata: languageName: node linkType: hard +"postcss-modules-extract-imports@npm:^3.1.0": + version: 3.1.0 + resolution: "postcss-modules-extract-imports@npm:3.1.0" + peerDependencies: + postcss: ^8.1.0 + checksum: b9192e0f4fb3d19431558be6f8af7ca45fc92baaad9b2778d1732a5880cd25c3df2074ce5484ae491e224f0d21345ffc2d419bd51c25b019af76d7a7af88c17f + languageName: node + linkType: hard + +"postcss-modules-local-by-default@npm:^4.0.5": + version: 4.0.5 + resolution: "postcss-modules-local-by-default@npm:4.0.5" + dependencies: + icss-utils: ^5.0.0 + postcss-selector-parser: ^6.0.2 + postcss-value-parser: ^4.1.0 + peerDependencies: + postcss: ^8.1.0 + checksum: ca9b01f4a0a3dfb33e016299e2dfb7e85c3123292f7aec2efc0c6771b9955648598bfb4c1561f7ee9732fb27fb073681233661b32eef98baab43743f96735452 + languageName: node + linkType: hard + +"postcss-modules-scope@npm:^3.2.0": + version: 3.2.0 + resolution: "postcss-modules-scope@npm:3.2.0" + dependencies: + postcss-selector-parser: ^6.0.4 + peerDependencies: + postcss: ^8.1.0 + checksum: 2ffe7e98c1fa993192a39c8dd8ade93fc4f59fbd1336ce34fcedaee0ee3bafb29e2e23fb49189256895b30e4f21af661c6a6a16ef7b17ae2c859301e4a4459ae + languageName: node + linkType: hard + +"postcss-modules-values@npm:^4.0.0": + version: 4.0.0 + resolution: "postcss-modules-values@npm:4.0.0" + dependencies: + icss-utils: ^5.0.0 + peerDependencies: + postcss: ^8.1.0 + checksum: f7f2cdf14a575b60e919ad5ea52fed48da46fe80db2733318d71d523fc87db66c835814940d7d05b5746b0426e44661c707f09bdb83592c16aea06e859409db6 + languageName: node + linkType: hard + +"postcss-selector-parser@npm:^6.0.2, postcss-selector-parser@npm:^6.0.4": + version: 6.1.2 + resolution: "postcss-selector-parser@npm:6.1.2" + dependencies: + cssesc: ^3.0.0 + util-deprecate: ^1.0.2 + checksum: ce9440fc42a5419d103f4c7c1847cb75488f3ac9cbe81093b408ee9701193a509f664b4d10a2b4d82c694ee7495e022f8f482d254f92b7ffd9ed9dea696c6f84 + languageName: node + linkType: hard + +"postcss-value-parser@npm:^4.1.0, postcss-value-parser@npm:^4.2.0": + version: 4.2.0 + resolution: "postcss-value-parser@npm:4.2.0" + checksum: 819ffab0c9d51cf0acbabf8996dffbfafbafa57afc0e4c98db88b67f2094cb44488758f06e5da95d7036f19556a4a732525e84289a425f4f6fd8e412a9d7442f + languageName: node + linkType: hard + +"postcss@npm:^8.4.33": + version: 8.4.47 + resolution: "postcss@npm:8.4.47" + dependencies: + nanoid: ^3.3.7 + picocolors: ^1.1.0 + source-map-js: ^1.2.1 + checksum: f78440a9d8f97431dd2ab1ab8e1de64f12f3eff38a3d8d4a33919b96c381046a314658d2de213a5fa5eb296b656de76a3ec269fdea27f16d5ab465b916a0f52c + languageName: node + linkType: hard + "prelude-ls@npm:^1.2.1": version: 1.2.1 resolution: "prelude-ls@npm:1.2.1" @@ -1996,6 +2973,13 @@ __metadata: languageName: node linkType: hard +"process@npm:^0.11.10": + version: 0.11.10 + resolution: "process@npm:0.11.10" + checksum: bfcce49814f7d172a6e6a14d5fa3ac92cc3d0c3b9feb1279774708a719e19acd673995226351a082a9ae99978254e320ccda4240ddc474ba31a76c79491ca7c3 + languageName: node + linkType: hard + "punycode@npm:^2.1.0": version: 2.3.1 resolution: "punycode@npm:2.3.1" @@ -2010,6 +2994,15 @@ __metadata: languageName: node linkType: hard +"randombytes@npm:^2.1.0": + version: 2.1.0 + resolution: "randombytes@npm:2.1.0" + dependencies: + safe-buffer: ^5.1.0 + checksum: d779499376bd4cbb435ef3ab9a957006c8682f343f14089ed5f27764e4645114196e75b7f6abf1cbd84fd247c0cb0651698444df8c9bf30e62120fbbc52269d6 + languageName: node + linkType: hard + "read-pkg@npm:^3.0.0": version: 3.0.0 resolution: "read-pkg@npm:3.0.0" @@ -2021,6 +3014,15 @@ __metadata: languageName: node linkType: hard +"rechoir@npm:^0.8.0": + version: 0.8.0 + resolution: "rechoir@npm:0.8.0" + dependencies: + resolve: ^1.20.0 + checksum: ad3caed8afdefbc33fbc30e6d22b86c35b3d51c2005546f4e79bcc03c074df804b3640ad18945e6bef9ed12caedc035655ec1082f64a5e94c849ff939dc0a788 + languageName: node + linkType: hard + "regexp.prototype.flags@npm:^1.5.2": version: 1.5.2 resolution: "regexp.prototype.flags@npm:1.5.2" @@ -2033,6 +3035,22 @@ __metadata: languageName: node linkType: hard +"require-from-string@npm:^2.0.2": + version: 2.0.2 + resolution: "require-from-string@npm:2.0.2" + checksum: a03ef6895445f33a4015300c426699bc66b2b044ba7b670aa238610381b56d3f07c686251740d575e22f4c87531ba662d06937508f0f3c0f1ddc04db3130560b + languageName: node + linkType: hard + +"resolve-cwd@npm:^3.0.0": + version: 3.0.0 + resolution: "resolve-cwd@npm:3.0.0" + dependencies: + resolve-from: ^5.0.0 + checksum: 546e0816012d65778e580ad62b29e975a642989108d9a3c5beabfb2304192fa3c9f9146fbdfe213563c6ff51975ae41bac1d3c6e047dd9572c94863a057b4d81 + languageName: node + linkType: hard + "resolve-from@npm:^4.0.0": version: 4.0.0 resolution: "resolve-from@npm:4.0.0" @@ -2040,7 +3058,14 @@ __metadata: languageName: node linkType: hard -"resolve@npm:^1.10.0": +"resolve-from@npm:^5.0.0": + version: 5.0.0 + resolution: "resolve-from@npm:5.0.0" + checksum: 4ceeb9113e1b1372d0cd969f3468fa042daa1dd9527b1b6bb88acb6ab55d8b9cd65dbf18819f9f9ddf0db804990901dcdaade80a215e7b2c23daae38e64f5bdf + languageName: node + linkType: hard + +"resolve@npm:^1.10.0, resolve@npm:^1.20.0": version: 1.22.8 resolution: "resolve@npm:1.22.8" dependencies: @@ -2053,7 +3078,7 @@ __metadata: languageName: node linkType: hard -"resolve@patch:resolve@^1.10.0#~builtin": +"resolve@patch:resolve@^1.10.0#~builtin, resolve@patch:resolve@^1.20.0#~builtin": version: 1.22.8 resolution: "resolve@patch:resolve@npm%3A1.22.8#~builtin::version=1.22.8&hash=c3c19d" dependencies: @@ -2084,14 +3109,14 @@ __metadata: languageName: node linkType: hard -"rimraf@npm:^5.0.1": - version: 5.0.9 - resolution: "rimraf@npm:5.0.9" +"rimraf@npm:^5.0.5": + version: 5.0.10 + resolution: "rimraf@npm:5.0.10" dependencies: glob: ^10.3.7 bin: rimraf: dist/esm/bin.mjs - checksum: e6dd5007e34181e1fa732437499d798035b2f3313887435cb855c5c9055bf9646795fc1c63ef843de830df8577cd9862df2dabf913fe08dcc1758c96de4a4fdb + checksum: 50e27388dd2b3fa6677385fc1e2966e9157c89c86853b96d02e6915663a96b7ff4d590e14f6f70e90f9b554093aa5dbc05ac3012876be558c06a65437337bc05 languageName: node linkType: hard @@ -2116,6 +3141,13 @@ __metadata: languageName: node linkType: hard +"safe-buffer@npm:^5.1.0": + version: 5.2.1 + resolution: "safe-buffer@npm:5.2.1" + checksum: b99c4b41fdd67a6aaf280fcd05e9ffb0813654894223afb78a31f14a19ad220bba8aba1cb14eddce1fcfb037155fe6de4e861784eb434f7d11ed58d1e70dd491 + languageName: node + linkType: hard + "safe-regex-test@npm:^1.0.3": version: 1.0.3 resolution: "safe-regex-test@npm:1.0.3" @@ -2134,7 +3166,7 @@ __metadata: languageName: node linkType: hard -"schema-utils@npm:^3.0.0": +"schema-utils@npm:^3.0.0, schema-utils@npm:^3.1.1, schema-utils@npm:^3.2.0": version: 3.3.0 resolution: "schema-utils@npm:3.3.0" dependencies: @@ -2145,7 +3177,19 @@ __metadata: languageName: node linkType: hard -"semver@npm:2 || 3 || 4 || 5, semver@npm:^5.5.0": +"schema-utils@npm:^4.0.0": + version: 4.2.0 + resolution: "schema-utils@npm:4.2.0" + dependencies: + "@types/json-schema": ^7.0.9 + ajv: ^8.9.0 + ajv-formats: ^2.1.1 + ajv-keywords: ^5.1.0 + checksum: 26a0463d47683258106e6652e9aeb0823bf0b85843039e068b57da1892f7ae6b6b1094d48e9ed5ba5cbe9f7166469d880858b9d91abe8bd249421eb813850cde + languageName: node + linkType: hard + +"semver@npm:2 || 3 || 4 || 5, semver@npm:^5.4.1, semver@npm:^5.5.0": version: 5.7.2 resolution: "semver@npm:5.7.2" bin: @@ -2163,6 +3207,15 @@ __metadata: languageName: node linkType: hard +"serialize-javascript@npm:^6.0.1": + version: 6.0.2 + resolution: "serialize-javascript@npm:6.0.2" + dependencies: + randombytes: ^2.1.0 + checksum: c4839c6206c1d143c0f80763997a361310305751171dd95e4b57efee69b8f6edd8960a0b7fbfc45042aadff98b206d55428aee0dc276efe54f100899c7fa8ab7 + languageName: node + linkType: hard + "set-function-length@npm:^1.2.1": version: 1.2.2 resolution: "set-function-length@npm:1.2.2" @@ -2189,6 +3242,15 @@ __metadata: languageName: node linkType: hard +"shallow-clone@npm:^3.0.0": + version: 3.0.1 + resolution: "shallow-clone@npm:3.0.1" + dependencies: + kind-of: ^6.0.2 + checksum: 39b3dd9630a774aba288a680e7d2901f5c0eae7b8387fc5c8ea559918b29b3da144b7bdb990d7ccd9e11be05508ac9e459ce51d01fd65e583282f6ffafcba2e7 + languageName: node + linkType: hard + "shebang-command@npm:^1.2.0": version: 1.2.0 resolution: "shebang-command@npm:1.2.0" @@ -2254,6 +3316,20 @@ __metadata: languageName: node linkType: hard +"source-list-map@npm:^2.0.0": + version: 2.0.1 + resolution: "source-list-map@npm:2.0.1" + checksum: 806efc6f75e7cd31e4815e7a3aaf75a45c704871ea4075cb2eb49882c6fca28998f44fc5ac91adb6de03b2882ee6fb02f951fdc85e6a22b338c32bfe19557938 + languageName: node + linkType: hard + +"source-map-js@npm:^1.2.1": + version: 1.2.1 + resolution: "source-map-js@npm:1.2.1" + checksum: 4eb0cd997cdf228bc253bcaff9340afeb706176e64868ecd20efbe6efea931465f43955612346d6b7318789e5265bdc419bc7669c1cebe3db0eb255f57efa76b + languageName: node + linkType: hard + "source-map-loader@npm:^1.0.2": version: 1.1.3 resolution: "source-map-loader@npm:1.1.3" @@ -2270,7 +3346,17 @@ __metadata: languageName: node linkType: hard -"source-map@npm:^0.6.1": +"source-map-support@npm:~0.5.20": + version: 0.5.21 + resolution: "source-map-support@npm:0.5.21" + dependencies: + buffer-from: ^1.0.0 + source-map: ^0.6.0 + checksum: 43e98d700d79af1d36f859bdb7318e601dfc918c7ba2e98456118ebc4c4872b327773e5a1df09b0524e9e5063bb18f0934538eace60cca2710d1fa687645d137 + languageName: node + linkType: hard + +"source-map@npm:^0.6.0, source-map@npm:^0.6.1, source-map@npm:~0.6.1": version: 0.6.1 resolution: "source-map@npm:0.6.1" checksum: 59ce8640cf3f3124f64ac289012c2b8bd377c238e316fb323ea22fbfe83da07d81e000071d7242cad7a23cd91c7de98e4df8830ec3f133cb6133a5f6e9f67bc2 @@ -2411,6 +3497,15 @@ __metadata: languageName: node linkType: hard +"style-loader@npm:~3.3.1": + version: 3.3.4 + resolution: "style-loader@npm:3.3.4" + peerDependencies: + webpack: ^5.0.0 + checksum: caac3f2fe2c3c89e49b7a2a9329e1cfa515ecf5f36b9c4885f9b218019fda207a9029939b2c35821dec177a264a007e7c391ccdd3ff7401881ce6287b9c8f38b + languageName: node + linkType: hard + "supports-color@npm:^5.3.0": version: 5.5.0 resolution: "supports-color@npm:5.5.0" @@ -2420,7 +3515,7 @@ __metadata: languageName: node linkType: hard -"supports-color@npm:^7.1.0": +"supports-color@npm:^7.1.0, supports-color@npm:^7.2.0": version: 7.2.0 resolution: "supports-color@npm:7.2.0" dependencies: @@ -2429,6 +3524,15 @@ __metadata: languageName: node linkType: hard +"supports-color@npm:^8.0.0": + version: 8.1.1 + resolution: "supports-color@npm:8.1.1" + dependencies: + has-flag: ^4.0.0 + checksum: c052193a7e43c6cdc741eb7f378df605636e01ad434badf7324f17fb60c69a880d8d8fcdcb562cf94c2350e57b937d7425ab5b8326c67c2adc48f7c87c1db406 + languageName: node + linkType: hard + "supports-preserve-symlinks-flag@npm:^1.0.0": version: 1.0.0 resolution: "supports-preserve-symlinks-flag@npm:1.0.0" @@ -2446,6 +3550,49 @@ __metadata: languageName: node linkType: hard +"tapable@npm:^2.1.1, tapable@npm:^2.2.0, tapable@npm:^2.2.1": + version: 2.2.1 + resolution: "tapable@npm:2.2.1" + checksum: 3b7a1b4d86fa940aad46d9e73d1e8739335efd4c48322cb37d073eb6f80f5281889bf0320c6d8ffcfa1a0dd5bfdbd0f9d037e252ef972aca595330538aac4d51 + languageName: node + linkType: hard + +"terser-webpack-plugin@npm:^5.3.10, terser-webpack-plugin@npm:^5.3.7": + version: 5.3.10 + resolution: "terser-webpack-plugin@npm:5.3.10" + dependencies: + "@jridgewell/trace-mapping": ^0.3.20 + jest-worker: ^27.4.5 + schema-utils: ^3.1.1 + serialize-javascript: ^6.0.1 + terser: ^5.26.0 + peerDependencies: + webpack: ^5.1.0 + peerDependenciesMeta: + "@swc/core": + optional: true + esbuild: + optional: true + uglify-js: + optional: true + checksum: bd6e7596cf815f3353e2a53e79cbdec959a1b0276f5e5d4e63e9d7c3c5bb5306df567729da287d1c7b39d79093e56863c569c42c6c24cc34c76aa313bd2cbcea + languageName: node + linkType: hard + +"terser@npm:^5.26.0": + version: 5.36.0 + resolution: "terser@npm:5.36.0" + dependencies: + "@jridgewell/source-map": ^0.3.3 + acorn: ^8.8.2 + commander: ^2.20.0 + source-map-support: ~0.5.20 + bin: + terser: bin/terser + checksum: 489afd31901a2b170f7766948a3aa0e25da0acb41e9e35bd9f9b4751dfa2fc846e485f6fb9d34f0839a96af77f675b5fbf0a20c9aa54e0b8d7c219cf0b55e508 + languageName: node + linkType: hard + "text-table@npm:^0.2.0": version: 0.2.0 resolution: "text-table@npm:0.2.0" @@ -2546,23 +3693,23 @@ __metadata: languageName: node linkType: hard -"typescript@npm:~5.0.2": - version: 5.0.4 - resolution: "typescript@npm:5.0.4" +"typescript@npm:~5.1.6": + version: 5.1.6 + resolution: "typescript@npm:5.1.6" bin: tsc: bin/tsc tsserver: bin/tsserver - checksum: 82b94da3f4604a8946da585f7d6c3025fff8410779e5bde2855ab130d05e4fd08938b9e593b6ebed165bda6ad9292b230984f10952cf82f0a0ca07bbeaa08172 + checksum: b2f2c35096035fe1f5facd1e38922ccb8558996331405eb00a5111cc948b2e733163cc22fab5db46992aba7dd520fff637f2c1df4996ff0e134e77d3249a7350 languageName: node linkType: hard -"typescript@patch:typescript@~5.0.2#~builtin": - version: 5.0.4 - resolution: "typescript@patch:typescript@npm%3A5.0.4#~builtin::version=5.0.4&hash=85af82" +"typescript@patch:typescript@~5.1.6#~builtin": + version: 5.1.6 + resolution: "typescript@patch:typescript@npm%3A5.1.6#~builtin::version=5.1.6&hash=85af82" bin: tsc: bin/tsc tsserver: bin/tsserver - checksum: bb309d320c59a26565fb3793dba550576ab861018ff3fd1b7fccabbe46ae4a35546bc45f342c0a0b6f265c801ccdf64ffd68f548f117ceb7f0eac4b805cd52a9 + checksum: 21e88b0a0c0226f9cb9fd25b9626fb05b4c0f3fddac521844a13e1f30beb8f14e90bd409a9ac43c812c5946d714d6e0dee12d5d02dfc1c562c5aacfa1f49b606 languageName: node linkType: hard @@ -2578,6 +3725,34 @@ __metadata: languageName: node linkType: hard +"undici-types@npm:~6.19.2": + version: 6.19.8 + resolution: "undici-types@npm:6.19.8" + checksum: de51f1b447d22571cf155dfe14ff6d12c5bdaec237c765085b439c38ca8518fc360e88c70f99469162bf2e14188a7b0bcb06e1ed2dc031042b984b0bb9544017 + languageName: node + linkType: hard + +"universalify@npm:^2.0.0": + version: 2.0.1 + resolution: "universalify@npm:2.0.1" + checksum: ecd8469fe0db28e7de9e5289d32bd1b6ba8f7183db34f3bfc4ca53c49891c2d6aa05f3fb3936a81285a905cc509fb641a0c3fc131ec786167eff41236ae32e60 + languageName: node + linkType: hard + +"update-browserslist-db@npm:^1.1.1": + version: 1.1.1 + resolution: "update-browserslist-db@npm:1.1.1" + dependencies: + escalade: ^3.2.0 + picocolors: ^1.1.0 + peerDependencies: + browserslist: ">= 4.21.0" + bin: + update-browserslist-db: cli.js + checksum: 2ea11bd2562122162c3e438d83a1f9125238c0844b6d16d366e3276d0c0acac6036822dc7df65fc5a89c699cdf9f174acf439c39bedf3f9a2f3983976e4b4c3e + languageName: node + linkType: hard + "uri-js@npm:^4.2.2": version: 4.4.1 resolution: "uri-js@npm:4.4.1" @@ -2587,6 +3762,13 @@ __metadata: languageName: node linkType: hard +"util-deprecate@npm:^1.0.2": + version: 1.0.2 + resolution: "util-deprecate@npm:1.0.2" + checksum: 474acf1146cb2701fe3b074892217553dfcf9a031280919ba1b8d651a068c9b15d863b7303cb15bd00a862b498e6cf4ad7b4a08fb134edd5a6f7641681cb54a2 + languageName: node + linkType: hard + "validate-npm-package-license@npm:^3.0.1": version: 3.0.4 resolution: "validate-npm-package-license@npm:3.0.4" @@ -2597,6 +3779,112 @@ __metadata: languageName: node linkType: hard +"watchpack@npm:^2.4.1": + version: 2.4.2 + resolution: "watchpack@npm:2.4.2" + dependencies: + glob-to-regexp: ^0.4.1 + graceful-fs: ^4.1.2 + checksum: 92d9d52ce3d16fd83ed6994d1dd66a4d146998882f4c362d37adfea9ab77748a5b4d1e0c65fa104797928b2d40f635efa8f9b925a6265428a69f1e1852ca3441 + languageName: node + linkType: hard + +"webpack-cli@npm:^5.0.1": + version: 5.1.4 + resolution: "webpack-cli@npm:5.1.4" + dependencies: + "@discoveryjs/json-ext": ^0.5.0 + "@webpack-cli/configtest": ^2.1.1 + "@webpack-cli/info": ^2.0.2 + "@webpack-cli/serve": ^2.0.5 + colorette: ^2.0.14 + commander: ^10.0.1 + cross-spawn: ^7.0.3 + envinfo: ^7.7.3 + fastest-levenshtein: ^1.0.12 + import-local: ^3.0.2 + interpret: ^3.1.1 + rechoir: ^0.8.0 + webpack-merge: ^5.7.3 + peerDependencies: + webpack: 5.x.x + peerDependenciesMeta: + "@webpack-cli/generators": + optional: true + webpack-bundle-analyzer: + optional: true + webpack-dev-server: + optional: true + bin: + webpack-cli: bin/cli.js + checksum: 3a4ad0d0342a6815c850ee4633cc2a8a5dae04f918e7847f180bf24ab400803cf8a8943707ffbed03eb20fe6ce647f996f60a2aade87b0b4a9954da3da172ce0 + languageName: node + linkType: hard + +"webpack-merge@npm:^5.7.3, webpack-merge@npm:^5.8.0": + version: 5.10.0 + resolution: "webpack-merge@npm:5.10.0" + dependencies: + clone-deep: ^4.0.1 + flat: ^5.0.2 + wildcard: ^2.0.0 + checksum: 1fe8bf5309add7298e1ac72fb3f2090e1dfa80c48c7e79fa48aa60b5961332c7d0d61efa8851acb805e6b91a4584537a347bc106e05e9aec87fa4f7088c62f2f + languageName: node + linkType: hard + +"webpack-sources@npm:^1.2.0": + version: 1.4.3 + resolution: "webpack-sources@npm:1.4.3" + dependencies: + source-list-map: ^2.0.0 + source-map: ~0.6.1 + checksum: 37463dad8d08114930f4bc4882a9602941f07c9f0efa9b6bc78738cd936275b990a596d801ef450d022bb005b109b9f451dd087db2f3c9baf53e8e22cf388f79 + languageName: node + linkType: hard + +"webpack-sources@npm:^3.2.3": + version: 3.2.3 + resolution: "webpack-sources@npm:3.2.3" + checksum: 989e401b9fe3536529e2a99dac8c1bdc50e3a0a2c8669cbafad31271eadd994bc9405f88a3039cd2e29db5e6d9d0926ceb7a1a4e7409ece021fe79c37d9c4607 + languageName: node + linkType: hard + +"webpack@npm:^5.76.1": + version: 5.95.0 + resolution: "webpack@npm:5.95.0" + dependencies: + "@types/estree": ^1.0.5 + "@webassemblyjs/ast": ^1.12.1 + "@webassemblyjs/wasm-edit": ^1.12.1 + "@webassemblyjs/wasm-parser": ^1.12.1 + acorn: ^8.7.1 + acorn-import-attributes: ^1.9.5 + browserslist: ^4.21.10 + chrome-trace-event: ^1.0.2 + enhanced-resolve: ^5.17.1 + es-module-lexer: ^1.2.1 + eslint-scope: 5.1.1 + events: ^3.2.0 + glob-to-regexp: ^0.4.1 + graceful-fs: ^4.2.11 + json-parse-even-better-errors: ^2.3.1 + loader-runner: ^4.2.0 + mime-types: ^2.1.27 + neo-async: ^2.6.2 + schema-utils: ^3.2.0 + tapable: ^2.1.1 + terser-webpack-plugin: ^5.3.10 + watchpack: ^2.4.1 + webpack-sources: ^3.2.3 + peerDependenciesMeta: + webpack-cli: + optional: true + bin: + webpack: bin/webpack.js + checksum: 0c3dfe288de4d62f8f3dc25478a618894883cab739121330763b7847e43304630ea2815ae2351a5f8ff6ab7c9642caf530d503d89bda261fe2cd220e524dd5d1 + languageName: node + linkType: hard + "whatwg-mimetype@npm:^2.3.0": version: 2.3.0 resolution: "whatwg-mimetype@npm:2.3.0" @@ -2652,6 +3940,13 @@ __metadata: languageName: node linkType: hard +"wildcard@npm:^2.0.0": + version: 2.0.1 + resolution: "wildcard@npm:2.0.1" + checksum: e0c60a12a219e4b12065d1199802d81c27b841ed6ad6d9d28240980c73ceec6f856771d575af367cbec2982d9ae7838759168b551776577f155044f5a5ba843c + languageName: node + linkType: hard + "word-wrap@npm:^1.2.5": version: 1.2.5 resolution: "word-wrap@npm:1.2.5" @@ -2659,6 +3954,18 @@ __metadata: languageName: node linkType: hard +"worker-loader@npm:^3.0.2": + version: 3.0.8 + resolution: "worker-loader@npm:3.0.8" + dependencies: + loader-utils: ^2.0.0 + schema-utils: ^3.0.0 + peerDependencies: + webpack: ^4.0.0 || ^5.0.0 + checksum: 84f4a7eeb2a1d8b9704425837e017c91eedfae67ac89e0b866a2dcf283323c1dcabe0258196278b7d5fd0041392da895c8a0c59ddf3a94f1b2e003df68ddfec3 + languageName: node + linkType: hard + "wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": version: 7.0.0 resolution: "wrap-ansi@npm:7.0.0"