diff --git a/.storybook/postcss.config.js b/.storybook/postcss.config.js index e4c6d12df1e..7eb67d56f9c 100644 --- a/.storybook/postcss.config.js +++ b/.storybook/postcss.config.js @@ -10,49 +10,68 @@ OF ANY KIND, either express or implied. See the License for the specific languag governing permissions and limitations under the License. */ -const { resolve, basename } = require("path"); +const { resolve, basename, dirname } = require("path"); const { existsSync } = require("fs"); const warnCleaner = require("postcss-warn-cleaner"); -const simpleBuilder = path.dirname( - require.resolve("@spectrum-css/component-builder-simple") -); -const legacyBuilder = path.dirname( - require.resolve("@spectrum-css/component-builder") -); +const simpleBuilder = dirname( + require.resolve("@spectrum-css/component-builder-simple", { + paths: [__dirname, resolve(__dirname, "../")], + }) +) ?? resolve(__dirname, "../tools/component-builder-simple"); + +const legacyBuilder = dirname( + require.resolve("@spectrum-css/component-builder", { + paths: [__dirname, resolve(__dirname, "../")], + }) +) ?? resolve(__dirname, "../tools/component-builder"); const postcssrc = require("postcss-load-config"); -/** - * Determines the package name from a file path - * @param {string} filePath - * @returns {string} - */ -function getPackageFromPath(filePath) { - return filePath.match(`(components|@spectrum-css)\/(.*?)\/`)?.[2]; -} - -module.exports = (ctx) => { - let plugins = []; - const componentPath = resolve(__dirname, "../components"); +module.exports = async (ctx) => { + const file = ctx && Object.keys(ctx) ? ctx.file ?? ctx.to ?? ctx.from : undefined; + + /** + * Determines the package name from a file path + * @param {string} filePath + * @returns {string} + */ + function getPackageFromPath(filePath) { + if (!filePath) return; + + // Capture component name from a local or node_modules syntax + const componentCheck = filePath.match(/(?:components|@spectrum-css)\/(\w+)/); + if (componentCheck && componentCheck?.[1]) return componentCheck[1]; + + // Check local root-level packages such as ui-icons & tokens + const pkgCheck = filePath.match(/\/(ui-icons|tokens)\//); + if (pkgCheck && pkgCheck?.[1]) return pkgCheck[1]; + + return; + } + + const plugins = []; + /** @todo put together a more robust fallback determination */ - const folderName = getPackageFromPath(ctx.file) ?? "tokens"; - const pkgPath = resolve(componentPath, folderName, "package.json"); + const folderName = file && getPackageFromPath(file); + + const componentPath = resolve(__dirname, "../components"); + const pkgPath = folderName && resolve(componentPath, folderName, "package.json"); /** * For our token libraries, include a little extra parsing to allow duplicate * token values to exist in parallel and be toggled using args in storybook. */ - if (["expressvars", "vars", "tokens"].includes(folderName)) { + if (folderName && ["expressvars", "vars"].includes(folderName)) { const isExpress = folderName === "expressvars"; - const modifier = basename(ctx.file, ".css").startsWith("spectrum") - ? basename(ctx.file, ".css") + const modifier = basename(file, ".css").startsWith("spectrum") + ? basename(file, ".css") .replace("spectrum-", "") .replace("global", "") : ""; - plugins = [ + plugins.push( require("postcss-import")(), require("postcss-selector-replace")({ before: [":root"], @@ -74,8 +93,18 @@ module.exports = (ctx) => { }), ] : []), - ]; - } else if (existsSync(pkgPath)) { + ); + } else if (folderName && folderName === "tokens") { + await postcssrc({ + cwd: resolve(componentPath, folderName), + env: process.env.NODE_ENV ?? "development", + from: ctx.from ?? file, + to: ctx.to ?? file, + }).then((result) => { + if (!result?.plugins) return; + plugins.push(...result.plugins); + }); + } else if (pkgPath && existsSync(pkgPath)) { /** * If a path has a package.json, we can assume it's a component and * we want to leverage the correct plugins for it. @@ -92,36 +121,42 @@ module.exports = (ctx) => { ...Object.keys(devDependencies), ])]; - let processors = []; if ( deps.includes("@spectrum-css/vars") ) { - processors = postcssrc({ + await postcssrc({ cwd: resolve(componentPath, folderName), - env: process.env.NODE_ENV || "development", - from: ctx.file, - to: ctx.file, - }, legacyBuilder).then((result) => result.plugins); + env: process.env.NODE_ENV ?? "development", + from: ctx.from ?? file, + to: ctx.to ?? file, + }, legacyBuilder).then((result) => { + if (!result?.plugins) return; + plugins.push(...result.plugins); + }); } else if (ctx.file.split("/").includes("themes")) { - processors = postcssrc({ + await postcssrc({ cwd: resolve(componentPath, folderName), - env: process.env.NODE_ENV || "development", - from: ctx.file, - to: ctx.file, + env: process.env.NODE_ENV ?? "development", + from: ctx.from ?? file, + to: ctx.to ?? file, splitinatorOptions: { noSelectors: false, }, - }, simpleBuilder).then((result) => result.plugins); + }, simpleBuilder).then((result) => { + if (!result?.plugins) return; + plugins.push(...result.plugins); + }); } else { - processors = postcssrc({ + await postcssrc({ cwd: resolve(componentPath, folderName), - env: process.env.NODE_ENV || "development", - from: ctx.file, - to: ctx.file, - }, simpleBuilder).then((result) => result.plugins); + env: process.env.NODE_ENV ?? "development", + from: ctx.from ?? file, + to: ctx.to ?? file, + }, simpleBuilder).then((result) => { + if (!result?.plugins) return; + plugins.push(...result.plugins); + }); } - - plugins.push(...processors); } /** diff --git a/.storybook/project.json b/.storybook/project.json index 38e904d6c94..8b74b710d9e 100644 --- a/.storybook/project.json +++ b/.storybook/project.json @@ -10,7 +10,6 @@ "implicitDependencies": [ "@spectrum-css/*", "!@spectrum-css/generator", - "!@spectrum-css/bundle-builder", "!@spectrum-css/component-builder", "!@spectrum-css/component-builder-simple" ], diff --git a/components/README.md b/components/README.md index 89165cbd128..9268bb54ea9 100644 --- a/components/README.md +++ b/components/README.md @@ -13,8 +13,6 @@ Each component has the following files: - `themes/*.css` - The theme-specific styles for the component. - `stories/*.stories.js` and `stories/template.js` - The storybook assets for rendering components in the Storybook tool and eventually to be used for visual regression testing. -See [documentation generation](/tools/bundle-builder/docs/README.md) documentation for more information on the properties available within the `.yml` files. - ## Editing an existing component 1. Run `gulp dev` in the root of the project to begin developing. diff --git a/components/accordion/gulpfile.js b/components/accordion/index.js similarity index 100% rename from components/accordion/gulpfile.js rename to components/accordion/index.js diff --git a/components/actionbar/gulpfile.js b/components/actionbar/index.js similarity index 100% rename from components/actionbar/gulpfile.js rename to components/actionbar/index.js diff --git a/components/actionbutton/gulpfile.js b/components/actionbutton/index.js similarity index 100% rename from components/actionbutton/gulpfile.js rename to components/actionbutton/index.js diff --git a/components/actiongroup/gulpfile.js b/components/actiongroup/index.js similarity index 100% rename from components/actiongroup/gulpfile.js rename to components/actiongroup/index.js diff --git a/components/actionmenu/gulpfile.js b/components/actionmenu/index.js similarity index 100% rename from components/actionmenu/gulpfile.js rename to components/actionmenu/index.js diff --git a/components/alertbanner/gulpfile.js b/components/alertbanner/index.js similarity index 100% rename from components/alertbanner/gulpfile.js rename to components/alertbanner/index.js diff --git a/components/alertdialog/gulpfile.js b/components/alertdialog/index.js similarity index 100% rename from components/alertdialog/gulpfile.js rename to components/alertdialog/index.js diff --git a/components/asset/gulpfile.js b/components/asset/index.js similarity index 100% rename from components/asset/gulpfile.js rename to components/asset/index.js diff --git a/components/assetcard/gulpfile.js b/components/assetcard/index.js similarity index 100% rename from components/assetcard/gulpfile.js rename to components/assetcard/index.js diff --git a/components/assetlist/gulpfile.js b/components/assetlist/index.js similarity index 100% rename from components/assetlist/gulpfile.js rename to components/assetlist/index.js diff --git a/components/avatar/gulpfile.js b/components/avatar/index.js similarity index 100% rename from components/avatar/gulpfile.js rename to components/avatar/index.js diff --git a/components/badge/gulpfile.js b/components/badge/index.js similarity index 100% rename from components/badge/gulpfile.js rename to components/badge/index.js diff --git a/components/breadcrumb/gulpfile.js b/components/breadcrumb/index.js similarity index 100% rename from components/breadcrumb/gulpfile.js rename to components/breadcrumb/index.js diff --git a/components/button/gulpfile.js b/components/button/index.js similarity index 100% rename from components/button/gulpfile.js rename to components/button/index.js diff --git a/components/buttongroup/gulpfile.js b/components/buttongroup/index.js similarity index 100% rename from components/buttongroup/gulpfile.js rename to components/buttongroup/index.js diff --git a/components/calendar/gulpfile.js b/components/calendar/index.js similarity index 100% rename from components/calendar/gulpfile.js rename to components/calendar/index.js diff --git a/components/card/gulpfile.js b/components/card/index.js similarity index 100% rename from components/card/gulpfile.js rename to components/card/index.js diff --git a/components/checkbox/gulpfile.js b/components/checkbox/index.js similarity index 100% rename from components/checkbox/gulpfile.js rename to components/checkbox/index.js diff --git a/components/clearbutton/gulpfile.js b/components/clearbutton/index.js similarity index 100% rename from components/clearbutton/gulpfile.js rename to components/clearbutton/index.js diff --git a/components/closebutton/gulpfile.js b/components/closebutton/index.js similarity index 100% rename from components/closebutton/gulpfile.js rename to components/closebutton/index.js diff --git a/components/coachindicator/gulpfile.js b/components/coachindicator/index.js similarity index 100% rename from components/coachindicator/gulpfile.js rename to components/coachindicator/index.js diff --git a/components/coachmark/gulpfile.js b/components/coachmark/index.js similarity index 100% rename from components/coachmark/gulpfile.js rename to components/coachmark/index.js diff --git a/components/colorarea/gulpfile.js b/components/colorarea/index.js similarity index 100% rename from components/colorarea/gulpfile.js rename to components/colorarea/index.js diff --git a/components/colorhandle/gulpfile.js b/components/colorhandle/index.js similarity index 100% rename from components/colorhandle/gulpfile.js rename to components/colorhandle/index.js diff --git a/components/colorloupe/gulpfile.js b/components/colorloupe/index.js similarity index 100% rename from components/colorloupe/gulpfile.js rename to components/colorloupe/index.js diff --git a/components/colorslider/gulpfile.js b/components/colorslider/index.js similarity index 100% rename from components/colorslider/gulpfile.js rename to components/colorslider/index.js diff --git a/components/colorwheel/gulpfile.js b/components/colorwheel/index.js similarity index 100% rename from components/colorwheel/gulpfile.js rename to components/colorwheel/index.js diff --git a/components/combobox/gulpfile.js b/components/combobox/index.js similarity index 100% rename from components/combobox/gulpfile.js rename to components/combobox/index.js diff --git a/components/contextualhelp/gulpfile.js b/components/contextualhelp/index.js similarity index 100% rename from components/contextualhelp/gulpfile.js rename to components/contextualhelp/index.js diff --git a/components/cyclebutton/gulpfile.js b/components/cyclebutton/index.js similarity index 100% rename from components/cyclebutton/gulpfile.js rename to components/cyclebutton/index.js diff --git a/components/datepicker/gulpfile.js b/components/datepicker/index.js similarity index 100% rename from components/datepicker/gulpfile.js rename to components/datepicker/index.js diff --git a/components/dial/gulpfile.js b/components/dial/index.js similarity index 100% rename from components/dial/gulpfile.js rename to components/dial/index.js diff --git a/components/dialog/gulpfile.js b/components/dialog/index.js similarity index 100% rename from components/dialog/gulpfile.js rename to components/dialog/index.js diff --git a/components/divider/gulpfile.js b/components/divider/index.js similarity index 100% rename from components/divider/gulpfile.js rename to components/divider/index.js diff --git a/components/dropindicator/gulpfile.js b/components/dropindicator/index.js similarity index 100% rename from components/dropindicator/gulpfile.js rename to components/dropindicator/index.js diff --git a/components/dropzone/gulpfile.js b/components/dropzone/index.js similarity index 100% rename from components/dropzone/gulpfile.js rename to components/dropzone/index.js diff --git a/components/fieldgroup/gulpfile.js b/components/fieldgroup/index.js similarity index 100% rename from components/fieldgroup/gulpfile.js rename to components/fieldgroup/index.js diff --git a/components/fieldlabel/gulpfile.js b/components/fieldlabel/index.js similarity index 100% rename from components/fieldlabel/gulpfile.js rename to components/fieldlabel/index.js diff --git a/components/floatingactionbutton/gulpfile.js b/components/floatingactionbutton/index.js similarity index 100% rename from components/floatingactionbutton/gulpfile.js rename to components/floatingactionbutton/index.js diff --git a/components/helptext/gulpfile.js b/components/helptext/index.js similarity index 100% rename from components/helptext/gulpfile.js rename to components/helptext/index.js diff --git a/components/icon/gulpfile.js b/components/icon/index.js similarity index 100% rename from components/icon/gulpfile.js rename to components/icon/index.js diff --git a/components/illustratedmessage/gulpfile.js b/components/illustratedmessage/index.js similarity index 100% rename from components/illustratedmessage/gulpfile.js rename to components/illustratedmessage/index.js diff --git a/components/infieldbutton/gulpfile.js b/components/infieldbutton/index.js similarity index 100% rename from components/infieldbutton/gulpfile.js rename to components/infieldbutton/index.js diff --git a/components/inlinealert/gulpfile.js b/components/inlinealert/index.js similarity index 100% rename from components/inlinealert/gulpfile.js rename to components/inlinealert/index.js diff --git a/components/link/gulpfile.js b/components/link/index.js similarity index 100% rename from components/link/gulpfile.js rename to components/link/index.js diff --git a/components/logicbutton/gulpfile.js b/components/logicbutton/index.js similarity index 100% rename from components/logicbutton/gulpfile.js rename to components/logicbutton/index.js diff --git a/components/menu/gulpfile.js b/components/menu/index.js similarity index 100% rename from components/menu/gulpfile.js rename to components/menu/index.js diff --git a/components/miller/gulpfile.js b/components/miller/index.js similarity index 100% rename from components/miller/gulpfile.js rename to components/miller/index.js diff --git a/components/modal/gulpfile.js b/components/modal/index.js similarity index 100% rename from components/modal/gulpfile.js rename to components/modal/index.js diff --git a/components/opacitycheckerboard/gulpfile.js b/components/opacitycheckerboard/index.js similarity index 100% rename from components/opacitycheckerboard/gulpfile.js rename to components/opacitycheckerboard/index.js diff --git a/components/page/gulpfile.js b/components/page/index.js similarity index 100% rename from components/page/gulpfile.js rename to components/page/index.js diff --git a/components/pagination/gulpfile.js b/components/pagination/index.js similarity index 100% rename from components/pagination/gulpfile.js rename to components/pagination/index.js diff --git a/components/picker/gulpfile.js b/components/picker/index.js similarity index 100% rename from components/picker/gulpfile.js rename to components/picker/index.js diff --git a/components/pickerbutton/gulpfile.js b/components/pickerbutton/index.js similarity index 100% rename from components/pickerbutton/gulpfile.js rename to components/pickerbutton/index.js diff --git a/components/popover/gulpfile.js b/components/popover/index.js similarity index 100% rename from components/popover/gulpfile.js rename to components/popover/index.js diff --git a/components/progressbar/gulpfile.js b/components/progressbar/index.js similarity index 100% rename from components/progressbar/gulpfile.js rename to components/progressbar/index.js diff --git a/components/progresscircle/gulpfile.js b/components/progresscircle/index.js similarity index 100% rename from components/progresscircle/gulpfile.js rename to components/progresscircle/index.js diff --git a/components/quickaction/gulpfile.js b/components/quickaction/index.js similarity index 100% rename from components/quickaction/gulpfile.js rename to components/quickaction/index.js diff --git a/components/radio/gulpfile.js b/components/radio/index.js similarity index 100% rename from components/radio/gulpfile.js rename to components/radio/index.js diff --git a/components/rating/gulpfile.js b/components/rating/index.js similarity index 100% rename from components/rating/gulpfile.js rename to components/rating/index.js diff --git a/components/search/gulpfile.js b/components/search/index.js similarity index 100% rename from components/search/gulpfile.js rename to components/search/index.js diff --git a/components/searchwithin/gulpfile.js b/components/searchwithin/index.js similarity index 100% rename from components/searchwithin/gulpfile.js rename to components/searchwithin/index.js diff --git a/components/sidenav/gulpfile.js b/components/sidenav/index.js similarity index 100% rename from components/sidenav/gulpfile.js rename to components/sidenav/index.js diff --git a/components/site/gulpfile.js b/components/site/index.js similarity index 100% rename from components/site/gulpfile.js rename to components/site/index.js diff --git a/components/slider/gulpfile.js b/components/slider/index.js similarity index 100% rename from components/slider/gulpfile.js rename to components/slider/index.js diff --git a/components/splitbutton/gulpfile.js b/components/splitbutton/index.js similarity index 100% rename from components/splitbutton/gulpfile.js rename to components/splitbutton/index.js diff --git a/components/splitview/gulpfile.js b/components/splitview/index.js similarity index 100% rename from components/splitview/gulpfile.js rename to components/splitview/index.js diff --git a/components/statuslight/gulpfile.js b/components/statuslight/index.js similarity index 100% rename from components/statuslight/gulpfile.js rename to components/statuslight/index.js diff --git a/components/steplist/gulpfile.js b/components/steplist/index.js similarity index 100% rename from components/steplist/gulpfile.js rename to components/steplist/index.js diff --git a/components/stepper/gulpfile.js b/components/stepper/index.js similarity index 100% rename from components/stepper/gulpfile.js rename to components/stepper/index.js diff --git a/components/swatch/gulpfile.js b/components/swatch/index.js similarity index 100% rename from components/swatch/gulpfile.js rename to components/swatch/index.js diff --git a/components/swatchgroup/gulpfile.js b/components/swatchgroup/index.js similarity index 100% rename from components/swatchgroup/gulpfile.js rename to components/swatchgroup/index.js diff --git a/components/switch/gulpfile.js b/components/switch/index.js similarity index 100% rename from components/switch/gulpfile.js rename to components/switch/index.js diff --git a/components/table/gulpfile.js b/components/table/index.js similarity index 100% rename from components/table/gulpfile.js rename to components/table/index.js diff --git a/components/tabs/gulpfile.js b/components/tabs/index.js similarity index 100% rename from components/tabs/gulpfile.js rename to components/tabs/index.js diff --git a/components/tag/gulpfile.js b/components/tag/index.js similarity index 100% rename from components/tag/gulpfile.js rename to components/tag/index.js diff --git a/components/taggroup/gulpfile.js b/components/taggroup/index.js similarity index 100% rename from components/taggroup/gulpfile.js rename to components/taggroup/index.js diff --git a/components/textfield/gulpfile.js b/components/textfield/index.js similarity index 100% rename from components/textfield/gulpfile.js rename to components/textfield/index.js diff --git a/components/thumbnail/gulpfile.js b/components/thumbnail/index.js similarity index 100% rename from components/thumbnail/gulpfile.js rename to components/thumbnail/index.js diff --git a/components/toast/gulpfile.js b/components/toast/index.js similarity index 100% rename from components/toast/gulpfile.js rename to components/toast/index.js diff --git a/components/tooltip/gulpfile.js b/components/tooltip/index.js similarity index 100% rename from components/tooltip/gulpfile.js rename to components/tooltip/index.js diff --git a/components/tray/gulpfile.js b/components/tray/index.js similarity index 100% rename from components/tray/gulpfile.js rename to components/tray/index.js diff --git a/components/treeview/gulpfile.js b/components/treeview/index.js similarity index 100% rename from components/treeview/gulpfile.js rename to components/treeview/index.js diff --git a/components/typography/gulpfile.js b/components/typography/index.js similarity index 100% rename from components/typography/gulpfile.js rename to components/typography/index.js diff --git a/components/underlay/gulpfile.js b/components/underlay/index.js similarity index 100% rename from components/underlay/gulpfile.js rename to components/underlay/index.js diff --git a/components/well/gulpfile.js b/components/well/index.js similarity index 100% rename from components/well/gulpfile.js rename to components/well/index.js diff --git a/gulpfile.js b/gulpfile.js deleted file mode 100644 index 8c70b0f1e94..00000000000 --- a/gulpfile.js +++ /dev/null @@ -1,17 +0,0 @@ -const gulp = require("gulp"); -const builder = require("./tools/bundle-builder"); -const site = require("./site/gulpfile.js"); - -Object.assign(exports, builder); -Object.assign(exports, site); - -exports.dev = gulp.series(exports.copySiteResources, exports.dev); - -exports.devHeavy = gulp.series(exports.copySiteResources, exports.devHeavy); - -exports["watch-relaunch"] = function () { - process.env["BROWSERSYNC_OPEN"] = true; - exports.watch(); -}; - -exports.buildDocs = gulp.series(builder.buildDocs, site.copySiteResources); diff --git a/nx.json b/nx.json index 04e8a316589..9f55cdf96b1 100644 --- a/nx.json +++ b/nx.json @@ -54,7 +54,7 @@ "executor": "nx:run-commands", "options": { "commands": [ - "gulp --gulpfile {projectRoot}/gulpfile.js", + "node {projectRoot}/index.js", "node ./tasks/mod-extractor.js {projectRoot}" ], "forwardAllArgs": true, diff --git a/package.json b/package.json index 8bcf1628211..2d3d872a270 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,7 @@ "postbuild:all": "test -d .storybook/storybook-static && rimraf dist/preview && mv .storybook/storybook-static dist/preview || exit 0", "build:preview": "nx build storybook", "prebuild:site": "yarn builder tag:component,ui-icons", - "build:site": "gulp buildDocs -LLL", + "build:site": "node ./site/tasks/builder.js", "builder": "nx run-many --target build --projects", "cache:clean": "nx reset", "ci": "yarn build:all", @@ -28,8 +28,8 @@ "clean:preview": "nx clean storybook", "cleaner": "nx run-many --target clean --projects", "compare": "node ./tasks/compare-compiled-output.js", - "predev": "nx run-many --projects ui-icons,tokens --target build", - "dev": "NODE_ENV=development BROWSERSYNC_OPEN=true gulp devHeavy", + "predev": "nx run-many --projects ui-icons,tag:component --target build", + "dev": "node ./site/tasks/server.js", "preinstall": "command -v nvm >/dev/null 2>&1 && nvm use || exit 0", "lint": "yarn linter tag:component --verbose", "linter": "nx run-many --target lint --verbose --projects", @@ -66,16 +66,16 @@ "@nx/devkit": "^17.2.8", "@spectrum-css/expressvars": "^3.0.9", "@spectrum-css/vars": "^9.0.8", + "browser-sync": "^3.0.2", "colors": "^1.4.0", "conventional-changelog-spectrum": "^1.0.2", + "dependency-solver": "^1.0.6", "diff": "^5.1.0", "diff2html": "^3.4.45", "fast-glob": "^3.3.2", "gh-pages": "^6.1.1", - "gulp": "^4.0.0", - "gulp-replace": "^1.0.0", - "gulplog": "^1.0.0", "husky": "^8.0.3", + "js-yaml": "^4.1.0", "lerna": "^6.6.2", "lint-staged": "^14.0.0", "loadicons": "^1.0.0", @@ -89,6 +89,7 @@ "prettier": "^2.8.8", "prettier-package-json": "^2.8.0", "prismjs": "^1.23.0", + "pug": "^3.0.2", "rimraf": "^5.0.5", "semver": "^7.5.1", "stylelint": "^15.11.0", diff --git a/plugins/postcss-dropdupedvars/index.js b/plugins/postcss-dropdupedvars/index.js index 14076640967..1575d5f4f29 100644 --- a/plugins/postcss-dropdupedvars/index.js +++ b/plugins/postcss-dropdupedvars/index.js @@ -25,7 +25,10 @@ module.exports = () => { if (seen[decl.prop]) { decl.warn( result, - `Dropping duplicate variable ${decl.prop}` + `Dropping duplicate variable ${decl.prop}`, { + word: decl.prop, + index: decl.source.index + } ); seen[decl.prop].remove(); } diff --git a/site/gulpfile.js b/site/gulpfile.js deleted file mode 100644 index 9a27ca469ef..00000000000 --- a/site/gulpfile.js +++ /dev/null @@ -1,56 +0,0 @@ -/*! -Copyright 2023 Adobe. All rights reserved. -This file is licensed to you under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. You may obtain a copy -of the License at http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software distributed under -the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS -OF ANY KIND, either express or implied. See the License for the specific language -governing permissions and limitations under the License. -*/ - -const gulp = require("gulp"); -const path = require("path"); - -function buildSite_resources() { - return gulp - .src(path.join(__dirname, "resources/**")) - .pipe(gulp.dest(path.join(__dirname, "../dist/"))); -} - -function buildSite_loadicons() { - return gulp - .src(require.resolve("loadicons")) - .pipe(gulp.dest(path.join(__dirname, "../dist/js/loadicons/"))); -} - -function buildSite_lunr() { - return gulp - .src(require.resolve("lunr")) - .pipe(gulp.dest(path.join(__dirname, "../dist/js/lunr/"))); -} - -function buildSite_prism() { - return gulp - .src([ - `${path.dirname(require.resolve("prismjs"))}/themes/prism.css`, - `${path.dirname(require.resolve("prismjs"))}/themes/prism-dark.css`, - ]) - .pipe(gulp.dest(path.join(__dirname, "../dist/css/prism/"))); -} -function buildSite_tokens() { - return gulp - .src([ - require.resolve("@spectrum-css/tokens"), - ]) - .pipe(gulp.dest(path.join(__dirname, "../dist/components/tokens/"))); -} - -exports.copySiteResources = gulp.parallel( - buildSite_resources, - buildSite_tokens, - buildSite_loadicons, - buildSite_lunr, - buildSite_prism -); diff --git a/site/tasks/builder.js b/site/tasks/builder.js new file mode 100644 index 00000000000..195aa812a7c --- /dev/null +++ b/site/tasks/builder.js @@ -0,0 +1,752 @@ +/*! +Copyright 2023 Adobe. All rights reserved. +This file is licensed to you under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. You may obtain a copy +of the License at http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed under +the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS +OF ANY KIND, either express or implied. See the License for the specific language +governing permissions and limitations under the License. +*/ + +/** + * @typedef {Object} SiteUtilities + * @property {import('markdown-it')} markdown + * @property {import('prismjs').Prism} Prism + * @property {(status: string) => "negative"|"notice"|"positive"|"neutral"} getStatusLightVariant + * @property {(name: string, subName?: string) => string} getSlug + * @property {(component: object, dnaVars: object) => void} populateDNAInfo + */ + +/** + * @typedef Navigation + * @property {string} name + * @property {string} component + * @property {boolean} hide + * @property {string} href + * @property {string} description + */ + +/** + * @typedef {Object} TemplateData + * @property {SiteUtilities} util + * @property {Object} dnaVars + * @property {Navigation[]} nav + * @property {Object} component + * @property {string} pageURL + * @property {string[]} dependencyOrder + * @property {string} releaseDate + * @property {Object} pkg + */ + +const fs = require("fs"); +const fsp = fs.promises; +const path = require("path"); + +const fg = require("fast-glob"); +const pug = require("pug"); +const depSolver = require("dependency-solver"); +const yaml = require("js-yaml"); +const lunr = require("lunr"); +const npmFetch = require("npm-registry-fetch"); + +// Import the component-builder-simple to process the site styles +const { processCSS } = require("@spectrum-css/component-builder-simple"); + +require("colors"); + +const loadicons = require.resolve("loadicons"); +const lunrPath = require.resolve("lunr"); +const prism = require.resolve("prismjs"); +const tokens = require.resolve("@spectrum-css/tokens"); +const vars = require.resolve("@spectrum-css/vars"); +const expressvars = require.resolve("@spectrum-css/expressvars"); +const workflowIcons = require.resolve("@adobe/spectrum-css-workflow-icons"); +const uiIcons = require.resolve("@spectrum-css/ui-icons"); + +/** + * A source of truth for commonly used directories + * @type {object} dirs + * @property {string} dirs.root + * @property {string} dirs.components + * @property {string} dirs.site + * @property {string} dirs.publish + */ +const dirs = { + root: path.join(__dirname, "../.."), + components: path.join(__dirname, "../../components"), + site: path.join(__dirname, "../../site"), + publish: path.join(__dirname, "../../dist"), +}; + +/** @type TemplateData */ +const globalData = { + util: require(`${dirs.site}/util`), + dnaVars: {}, + nav: [], + docs: [], + store: {}, +}; + +/** @type {(string) => string} */ +const relativePrint = (filename) => path.relative(dirs.root, filename); + +/** + * Given a list of package paths, solve the dependency order + * @param {string[]} packages - package directories + * @return {Promise} The solved dependency order + */ +async function solveDependencies(packages = []) { + const packageDependencies = {}; + + await Promise.all( + packages.map(async (package) => { + const { + name, + peerDependencies = {}, + dependencies = {}, + devDependencies = {}, + } = await fsp.readFile(path.join(package, "package.json")).then(JSON.parse); + + packageDependencies[name] = [...new Set([ + ...Object.keys(peerDependencies), + ...Object.keys(dependencies), + ...Object.keys(devDependencies), + ])]; + }) + ); + + return depSolver.solve(packageDependencies); +} + +/** + * Get the list of all packages in given directory + * @param {string} packagesDir - directory of packages + * @return {Promise} An array of package names in dependency order + */ +async function getFolderDependencyOrder(packagesDir) { + const packages = []; + + if (fs.existsSync(path.join(packagesDir, "package.json"))) { + packages.push(packagesDir); + } + + // If no packages identified, see if this is a folder containing packages + if (!packages.length) { + (await fsp.readdir(packagesDir, { withFileTypes: true })) + .forEach((dirent) => { + /* looking for directories that have a package.json */ + if (!dirent.isDirectory() || !dirent.isSymbolicLink()) return; + if (fs.existsSync(path.join(dirent.path, dirent.name, "package.json"))) { + packages.push(path.join(dirent.path, dirent.name)); + } + }); + } + + return await solveDependencies(packages); +} + +/** + * Determines the package name from a file path + * @param {string} filePath + * @returns {string} + */ +function getPackageFromPath(filePath) { + if (!filePath) return; + + // Capture component name from a local or node_modules syntax + const componentCheck = filePath.match(/(?:components|@spectrum-css)\/(\w+)/); + + if (componentCheck && componentCheck?.[1]) return componentCheck[1]; + + // Check local root-level packages such as ui-icons & tokens + const pkgCheck = filePath.match(/\/(ui-icons|tokens)\//); + if (pkgCheck && pkgCheck?.[1]) return pkgCheck[1]; + + return; +} + +/** + * Copy static assets to the publish directory + * @param {(string|RegExp)[]} globs + * @param {object} options + * @param {string} [options.cwd] + * @param {string} outputDir + * @returns {Promise} + */ +async function copyAssets(globs = [], { + cwd, + outputDir, + clean = false, + ...fastGlobOptions +} = {}) { + const files = await fg(globs, { + onlyFiles: true, + allowEmpty: true, + ...fastGlobOptions, + cwd, + }); + + if (!files.length) return Promise.resolve([]); + + return Promise.all( + files.map(async (file) => { + const output = outputDir ? path.join(dirs.publish, outputDir, file) : path.join(dirs.publish, file); + + if (!fs.existsSync(path.dirname(output))) { + await fsp.mkdir(path.dirname(output), { recursive: true }).catch((err) => { + if (!err) return; + console.log(`${"✗".red} problem making ${relativePrint(path.dirname(output)).yellow}`); + return Promise.reject(err); + }); + } + + if (clean && fs.existsSync(output)) { + await fsp.unlink(output).catch((err) => { + if (!err) return; + console.log(`${"✗".red} problem removing ${relativePrint(path.dirname(output)).yellow}`); + return Promise.reject(err); + }); + } + + const input = path.join(cwd, file); + + return fsp.copyFile(input, output).then(() => { + console.log(`${"✓".green} ${relativePrint(input).gray} -> ${relativePrint(output).yellow}`); + }).catch((err) => { + if (!err) return; + console.log(`${"✗".red} ${relativePrint(input).gray} -> ${relativePrint(output).yellow}`); + return Promise.reject(err); + }); + }) + ); +} + +const printHeader = (content, { timerKey, icon }) => { + if (timerKey) console.time(timerKey); + console.log(`\n${timerKey ? `${timerKey} ` : ""}${icon ? `${icon} ` : ""} ${content}`); + console.log(`${"".padStart(30, "-")}`); + return timerKey; +}; + +const printFooter = (timerKey) => { + console.log(`${"".padStart(30, "-")}`); + if (timerKey) console.timeEnd(timerKey); +}; + +/** + * Copy all site resources + * @returns {Promise} + */ +async function copyResources({ clean }) { + const key = printHeader("Site resources", { + timerKey: "[copy]", + icon: "📷" + }); + + return Promise.all([ + copyAssets(["**"], { cwd: path.join(dirs.site, "resources"), clean }), + copyAssets(["index.css"], { + clean, + cwd: path.dirname(tokens), + outputDir: "components/tokens/" + }), + copyAssets(["index.css", "css/**"], { + clean, + cwd: path.dirname(tokens), + outputDir: "tokens/" + }), + copyAssets(["index.js"], { + clean, + cwd: path.dirname(loadicons), + outputDir: "js/loadicons/" + }), + copyAssets(["lunr*.js"], { + clean, + cwd: path.dirname(lunrPath), + outputDir: "js/lunr/" + }), + copyAssets(["prism.css", "prism-dark.css"], { + clean, + cwd: path.join(path.dirname(prism), "themes"), + outputDir: "css/prism/" + }), + copyAssets(["spectrum-icons.svg"], { + clean, + cwd: path.dirname(workflowIcons), + outputDir: "img" + }), + copyAssets(["*.svg"], { + clean, + cwd: path.dirname(uiIcons), + outputDir: "img", + }), + copyAssets(["spectrum-*.css"], { + cwd: path.dirname(vars), + outputDir: "dependencies/@spectrum-css/vars", + }), + copyAssets(["spectrum-*.css"], { + cwd: path.dirname(expressvars), + outputDir: "dependencies/@spectrum-css/expressvars", + }), + copyAssets(["*.{png,jpg,jpeg,svg,ico}"], { + clean, + cwd: path.join(dirs.root, "assets"), + outputDir: "img" + }), + ]).then(() => { + printFooter(key); + }).catch((err) => { + printFooter(key); + return Promise.reject(err); + }); +} + +/** + * Fetch the global data for all rendered pages + * @returns {Promise} + */ +async function fetchGlobalData({ clean = false } = {}) { + /* Only fetch the metadata if we don't already have it */ + if (Object.keys(globalData.dnaVars).length > 0) { + globalData.dnaVars = vars ? await fsp.readFile(vars) + .then(JSON.parse) + .catch(err => Promise.reject(err)) : {}; + } + + /* We're only going to process this data if we haven't already fetched it */ + const hasNav = globalData.nav.length > 0; + const hasDocs = globalData.docs.length > 0; + const hasStore = Object.keys(globalData.store).length > 0; + + if (!hasNav || !hasDocs || !hasStore) { + const files = await fg("*/metadata/*.yml", { + cwd: dirs.components, + allowEmpty: true, + absolute: true, + }); + + await Promise.all(files.map(async (file) => { + const componentData = await fetchComponentData(file); + + if (Object.keys(componentData).length <= 0) { + return Promise.reject(new Error(`${"✗".red} Could not fetch component data for ${relativePrint(file).yellow}`)); + } + + if (!hasNav) { + globalData.nav.push({ + name: componentData.name, + component: componentData.name, + hide: componentData.hide, + href: componentData.pageURL, + description: componentData.description, + }); + } + + if (!hasDocs) { + globalData.docs.push({ + href: componentData.pageURL, + name: componentData.name, + description: componentData.description, + }); + } + + if (!hasStore) { + globalData.store[componentData.pageURL] = { + href: componentData.pageURL, + name: componentData.name, + component: componentData.name, + description: componentData.description, + }; + } + })); + } + + // Resort the navigation + globalData.nav = globalData.nav.sort((a, b) => a.name <= b.name ? -1 : 1); + + const index = lunr(function () { + this.ref("href"); + this.field("name", { boost: 10 }); + this.field("description"); + + globalData.docs.forEach(function (doc) { + this.add(doc); + }, this); + }); + + if (!fs.existsSync(dirs.publish)) { + await fsp.mkdir(dirs.publish, { recursive: true }).catch((err) => { + if (!err) return; + console.log(`${"✗".red} problem making ${relativePrint(path.dirname(output)).yellow}`); + return Promise.reject(err); + }); + } + + const indexPath = path.join(dirs.publish, "index.json"); + const storePath = path.join(dirs.publish, "store.json"); + + await Promise.all( + [indexPath, storePath].map(async (output) => { + if (clean && fs.existsSync(output)) { + await fsp.unlink(output).catch((err) => { + if (!err) return; + console.log(`${"✗".red} problem removing ${relativePrint(path.dirname(output)).yellow}`); + return Promise.reject(err); + }); + } + }) + ); + + return Promise.all([ + fsp.writeFile(indexPath, JSON.stringify(index, null, 2)).then(() => { + console.log(`${"✓".green} ${relativePrint(indexPath).yellow}`); + }).catch((err) => { + if (!err) return; + console.log(`${"✗".red} ${relativePrint(indexPath).gray}`); + return Promise.reject(err); + }), + fsp.writeFile(storePath, JSON.stringify(globalData.store, null, 2)).then(() => { + console.log(`${"✓".green} ${relativePrint(storePath).yellow}`); + }).catch((err) => { + if (!err) return; + console.log(`${"✗".red} ${relativePrint(storePath).gray}`); + return Promise.reject(err); + }), + ]); +} + +/** + * Fetch & interpret the data in yml for the template + * @param {string} file + * @returns {Promise} + */ +async function fetchComponentData(file) { + const data = globalData; + + if (!file) return data; + + // Drop package org + const componentName = getPackageFromPath(file); + + const pkgPath = path.join(dirs.components, componentName, "package.json"); + const dirName = path.dirname(pkgPath); + const basename = path.basename(file, ".yml"); + + const component = await fsp.readFile(file, "utf-8") + .then(yaml.load) + .catch(err => Promise.reject(err)); + + // Use the example file name + if (!component.id) { + component.id = basename ?? componentName; + } + + if (!component.name) { + if (globalData.dnaVars?.[`spectrum-${component.id}-name`]) { + component.name = globalData.dnaVars[`spectrum-${component.id}-name`]; + } else { + component.name = componentName ?? component.id; + } + console.log({component}) + } + + const pkg = await fsp.readFile(pkgPath) + .then(JSON.parse) + .catch(err => Promise.reject(err)); + + const releaseDate = await npmFetch.json(pkg.name).then(npmData => { + if (!npmData || !npmData.time || !npmData.time[pkg.version]) return; + return new Date(npmData.time[pkg.version]) + .toLocaleDateString("en-US", { + year: "numeric", + month: "long", + day: "numeric", + }); + }).catch(() => { + console.log(`${"✗".red} Could not determine date of release for ${pkg.name.cyan}@${pkg.version}`); + return "Unreleased"; + }); + + const dependencyOrder = await getFolderDependencyOrder(dirName); + + return { + ...data, + component, + pageURL: `${basename}.html`, + dependencyOrder: [...new Set([ + ...(dependencyOrder ?? []).map((dep) => dep.split("/").pop()), + componentName, + "icon", + "statuslight", + "link", + "page", + "site", + "typography", + "tooltip", + "sidenav", + "actionbutton", + "button", + "textfield", + "clearbutton", + "search", + "menu", + "fieldlabel", + "picker", + "popover", + "underlay", + "card", + "divider", + "illustratedmessage", + "accordion", + "table", + ])], + releaseDate, + pkg, + }; +} + +/** + * Build yml data into html files for the site + * @param {string} dep + * @returns {Promise} + */ +async function buildDocs_forDependencies(dep, { clean = false } = {}) { + const pkgPath = require.resolve(path.join(dep, "package.json")); + const dirName = path.dirname(pkgPath); + const componentName = getPackageFromPath(dep); + + const files = await fg("metadata/*.yml", { + cwd: dirName, + allowEmpty: true, + absolute: true, + }); + + const key = `${"✓".green} copied ${`@spectrum-css/${componentName}`.cyan} assets`; + console.time(key); + + return Promise.all(files.map(async (file) => { + const data = await fetchComponentData(file); + + // Without a URL, there's nowhere to write this file + if (!data.pageURL) { + return Promise.reject(`${"✗".red} Could not determine a page url for ${relativePrint(file).yellow}.`) + } + + const outputPath = path.join(dirs.publish, data.pageURL); + + const template = path.join(dirs.site, "templates/siteComponent.pug"); + if (!fs.existsSync(template)) { + return Promise.reject(new Error(`${"✗".red} could not find ${relativePrint(template).yellow}`)); + } + + const compiled = pug.renderFile( + path.join(dirs.site, "templates/siteComponent.pug"), + data, + ); + + if (!compiled) { + return Promise.reject(new Error(`${"✗".red} There was a problem compiling the template for ${relativePrint(outputPath).yellow}`)); + } + + if (!fs.existsSync(path.dirname(outputPath))) { + await fsp.mkdir(path.dirname(outputPath), { recursive: true }).catch((err) => { + if (!err) return; + console.log(`${"✗".red} problem making ${relativePrint(path.dirname(output)).yellow}`); + return Promise.reject(err); + }); + } + + if (clean && fs.existsSync(outputPath)) { + await fsp.unlink(outputPath).catch((err) => { + if (!err) return; + console.log(`${"✗".red} problem removing ${relativePrint(path.dirname(outputPath)).yellow}`); + return Promise.reject(err); + }); + } + + return fsp.writeFile(outputPath, compiled).then(() => { + console.log(`${"✓".green} ${relativePrint(outputPath).yellow}`); + }).catch((err) => { + if (!err) return; + console.log(`${"✗".red} ${relativePrint(outputPath).gray}`); + return Promise.reject(err); + }); + })).then(() => { + console.timeEnd(key); + }).catch(err => { + if (!err) return; + if (Array.isArray(err)) err.forEach(e => { + console.trace(e); + }); + else console.trace(err); + console.timeEnd(key); + }); +} + +/** + * Build component pages + * @returns {Promise} + */ +async function buildDocs_forAllDependencies({ clean = false } = {}) { + const packages = (await fsp.readdir(dirs.components, { withFileTypes: true })) + .filter((dirent) => { + /* looking for directories that have a package.json */ + if (!dirent.isDirectory() && !dirent.isSymbolicLink()) return false; + if (!fs.existsSync(path.join(dirent.path, dirent.name, "package.json"))) return false; + return true; + }) + .map((dirent) => path.join(dirent.path, dirent.name)); + + // Build pages for all provided dependencies + return Promise.all( + packages.map(packagePath => { + const componentName = getPackageFromPath(packagePath); + return Promise.all([ + buildDocs_forDependencies(packagePath, { clean }), + copyAssets(["*.css", "themes/*.css", "*.json"], { + cwd: path.join(packagePath, "dist"), + outputDir: path.join("components", componentName), + allowEmpty: true, + absolute: false, + clean, + }), + copyAssets(["*.js"], { + cwd: path.join(packagePath, "stories"), + ignore: ["*.stories.js"], + outputDir: path.join("components", componentName), + clean, + }), + copyAssets(["package.json"], { + cwd: packagePath, + outputDir: path.join("components", componentName), + clean, + }) + ]); + }) + ); +} + +/** + * Build docs pages + * @returns {Promise} + */ +async function buildSite_html({ clean = false } = {}) { + const rootPkg = require(path.join(dirs.root, "package.json")); + + const files = await fg("*.pug", { + cwd: dirs.site, + allowEmpty: true, + }); + + return Promise.all(files.map(async (file) => { + const pageURL = `${path.basename(file, ".pug")}.html`; + const data = { + ...globalData, + pageURL, + dependencyOrder: [ + "icon", + "statuslight", + "link", + "page", + "site", + "typography", + "tooltip", + "sidenav", + "actionbutton", + "button", + "textfield", + "clearbutton", + "search", + "menu", + "fieldlabel", + "picker", + "popover", + "underlay", + "card", + "divider", + "illustratedmessage", + "accordion", + "table", + ], + pkg: rootPkg, + }; + + const outputPath = path.join(dirs.publish, pageURL); + const compiled = pug.renderFile(path.join(dirs.site, file), data); + + if (!compiled) { + return Promise.reject(new Error(`${"✗".red} problem compiling the template for ${relativePrint(outputPath).yellow}`)); + } + + if (!fs.existsSync(path.dirname(outputPath))) { + await fsp.mkdir(path.dirname(outputPath), { recursive: true }).catch((err) => { + if (!err) return; + console.log(`${"✗".red} problem making ${relativePrint(path.dirname(output)).yellow}`); + return Promise.reject(err); + }); + } + + if (clean && fs.existsSync(outputPath)) { + await fsp.unlink(outputPath).catch((err) => { + if (!err) return; + console.log(`${"✗".red} problem removing ${relativePrint(path.dirname(outputPath)).yellow}`); + return Promise.reject(err); + }); + } + + return fsp.writeFile(outputPath, compiled).then(() => { + console.log(`${"✓".green} ${relativePrint(outputPath).yellow}`); + }).catch((err) => { + if (!err) return; + console.log(`${"✗".red} ${relativePrint(outputPath).gray}`); + return Promise.reject(err); + }); + })); +} + +/** + * Build docs styles + * @returns {Promise} + */ +async function buildSite_css({ clean = false } = {}) { + const cwd = path.join(dirs.site, "resources/css"); + const files = await fg("*.css", { + cwd, + allowEmpty: true, + }); + + return Promise.all(files.map(async (file) => { + const outputPath = path.join(dirs.publish, "css", file); + const content = await fsp.readFile(path.join(cwd, file)); + return processCSS(content, path.join(cwd, file), outputPath, { cwd: dirs.root, clean }); + })); +} + +async function main({ clean = false } = {}) { + const key = printHeader("Documentation site", { timerKey: "[build]", icon: "🔨" }); + + await fetchGlobalData({ clean }); + + return Promise.all([ + buildDocs_forAllDependencies({ clean }), + buildSite_html({ clean }), + buildSite_css({ clean }), + ]).then(() => { + printFooter(key); + }).catch((err) => { + printFooter(key); + return Promise.reject(err); + }); +} + +// @todo if I include this, it will run the script on import into server +// main().catch((err) => { +// console.error(err); +// process.exit(1); +// }); + +exports.builder = main; +exports.dirs = dirs; +exports.copyResources = copyResources; diff --git a/site/tasks/server.js b/site/tasks/server.js new file mode 100644 index 00000000000..31944f18459 --- /dev/null +++ b/site/tasks/server.js @@ -0,0 +1,89 @@ +#!/usr/bin/env node + +/*! +Copyright 2023 Adobe. All rights reserved. +This file is licensed to you under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. You may obtain a copy +of the License at http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed under +the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS +OF ANY KIND, either express or implied. See the License for the specific language +governing permissions and limitations under the License. +*/ + +const browserSync = require("browser-sync"); + +require("colors"); + +const { + builder, + dirs, + copyResources, +} = require("./builder"); + +async function main({ clean = false } = {}) { + // @todo could run copy site resources & build docs in parallel + return copyResources({ clean }).then(async () => { + console.log(""); + + // Next build docs + return builder({ clean }).then(() => { + console.log(""); + + //@todo do we want to fail if index.html isn't there? + + // Create the browser-sync instance + const bs = browserSync.create(); + + // Watch component styles + bs.watch(`*/index.css`, { + cwd: dirs.components, + ignoreInitial: true, + }, (event, file) => { + console.log(`A ${event} on ${file}`); + // do the thing + bs.reload(file); + }); + + bs.watch(`*/themes/express.css`, { + cwd: dirs.components, + ignoreInitial: true, + }, (event, file) => { + console.log(`A ${event} on ${file}`); + // do the thing + bs.reload(file); + }); + + bs.watch(`*/themes/!(express).css`, { + cwd: dirs.components, + ignoreInitial: true, + }, (event, file) => { + console.log(`A ${event} on ${file}`); + // do the thing + bs.reload(file); + }); + + // Then spin up the server + return bs.init({ + server: dirs.publish, + startPath: "index.html", + notify: true, + open: true, + port: process.env.PORT ?? 3000, + }, (err, bs) => { + if (err) { + process.stderr.write(err.message ?? err); + bs.exit(); + } + }); + }); + }).catch((err) => { + console.error(err); + process.exit(1); + }); +}; + +main(); + +module.exports = main; diff --git a/site/util.js b/site/util.js index 6ed3ddb29d6..4c1fd196bce 100644 --- a/site/util.js +++ b/site/util.js @@ -10,8 +10,7 @@ OF ANY KIND, either express or implied. See the License for the specific languag governing permissions and limitations under the License. */ -const logger = require("gulplog"); - +/** @type import('markdown-it') */ const md = require("markdown-it")({ html: true, linkify: false, @@ -37,7 +36,7 @@ let ruleClassnames = { for (let [rule, className] of Object.entries(ruleClassnames)) { md.renderer.rules[rule] = (function (className) { - const oldRule = md.renderer.rules[rule] || defaultRenderer; + const oldRule = md.renderer.rules[rule] ?? defaultRenderer; return function (tokens, idx, options, env, self) { tokens[idx].attrPush(["class", className]); return oldRule(tokens, idx, options, env, self); @@ -45,7 +44,7 @@ for (let [rule, className] of Object.entries(ruleClassnames)) { })(className); } -const code_inline = md.renderer.rules.code_inline || defaultRenderer; +const code_inline = md.renderer.rules.code_inline ?? defaultRenderer; md.renderer.rules.code_inline = function (tokens, idx, options, env, self) { const token = tokens[idx]; // ~ indicates markup that should be red @@ -84,128 +83,81 @@ md.renderer.rules.heading_open = function (tokens, idx, options, env, self) { return defaultRenderer(tokens, idx, options, env, self); }; +/* --------- EXPORTS --------- */ + +/** @type import('markdown-it') */ exports.markdown = md; +/** @type import('prismjs').Prism */ exports.Prism = require("prismjs"); -const statusLightVariants = { +/** @type (status: string) => "negative"|"notice"|"positive"|"neutral" */ +exports.getStatusLightVariant = (status) => ({ Deprecated: "negative", - "Beta Contribution": "notice", - Contribution: "notice", Unverified: "notice", - Canon: "positive", Verified: "positive", -}; - -const dnaStatusTranslation = { - Released: "Canon", - Beta: "Contribution", - Precursor: "Contribution", -}; - -const cssStatusTranslation = { - Contribution: "Unverified", - Unverified: "Unverified", - Verified: "Verified", -}; - -exports.getStatusLightVariant = function (status) { - return statusLightVariants[status] || "neutral"; -}; - -exports.getDNAStatus = function (dnaComponentId, dnaStatus, cssStatus) { - if (cssStatus === "Deprecated") { - dnaStatus = "Deprecated"; - } - - if (cssStatus === "Verified") { - if (dnaStatusTranslation[dnaStatus] !== "Canon") { - logger.debug( - `${dnaComponentId} is ${cssStatus} in CSS, but ${dnaStatus} in DNA` - ); - } - } - - if (!dnaStatus) { - logger.debug(`${dnaComponentId} has no DNA status`); - dnaStatus = "Contribution"; - } - - return dnaStatusTranslation[dnaStatus] || dnaStatus; -}; +}[status] ?? "neutral"); -exports.getCSSStatus = function (dnaComponentId, cssStatus) { - if (!cssStatus) { - cssStatus = "Contribution"; - } - return cssStatusTranslation[cssStatus] || cssStatus; -}; - -exports.getSlug = function (name, subName) { - if (subName) { - name += `-${subName}`; - } +exports.getSlug = function (name, subName = undefined) { + if (!name) return; + if (subName) name += `-${subName}`; return name.toLowerCase().replace(/[^a-z\-]/g, ""); }; exports.populateDNAInfo = function (component, dnaVars) { - // Get DNA information - var dnaComponentId = component.id || component.name.toLowerCase(); - - // Get info based on component variation first, then component name second - var dnaComponentTitle = dnaVars["spectrum-" + dnaComponentId + "-name"]; - - var dnaDescription = dnaVars["spectrum-" + dnaComponentId + "-description"]; - - var cssStatus = this.getCSSStatus(dnaComponentId, component.status); - var dnaStatus = this.getDNAStatus( - dnaComponentId, - dnaVars["spectrum-" + dnaComponentId + "-status"] || component.dnaStatus, - cssStatus - ); - - // Store the info - component.name = component.name || dnaComponentTitle; - component.cssStatus = cssStatus; - component.dnaStatus = dnaStatus; - - // Add other data - component.id = dnaComponentId; - try { - component.slug = this.getSlug(component.name); - } catch (err) { - console.error("Could not get slug for:"); - console.log(component); - } - - if (component.examples) { - for (id in component.examples) { - let example = component.examples[id]; + const getDNAStatus = function (dnaStatus) { + if (!dnaStatus) dnaStatus = "Contribution"; + + return { + Released: "Canon", + Beta: "Contribution", + Precursor: "Contribution", + }[dnaStatus] ?? dnaStatus; + }; + + if (!component.id) component.id = component.name?.toLowerCase(); + if (!component.name) component.name = dnaVars[`spectrum-${component.id}-name`]; + if (!component.status) component.status = "Contribution"; + if (!component.slug) component.slug = this.getSlug(component.name); + + component.cssStatus = { + Contribution: "Unverified", + Unverified: "Unverified", + Verified: "Verified", + Deprecated: "Deprecated", + }[component.status]; + + const dnaComponentStatus = component.dnaStatus ?? dnaVars[`spectrum-${component.id}-status`]; + component.dnaStatus = component.cssStatus === "Deprecated" ? "Deprecated" : getDNAStatus(dnaComponentStatus); + + if (!component?.examples) return; + + return Promise.all( + component.examples.map(example => { + const pageData = {}; if (typeof example === "string") { - // Handle markup only examples - example = { - id: id, - markup: example, - }; - component.examples[id] = example; + pageData.id = component.name; + pageData.markup = example; } else { - example.id = example.id || id; + pageData.id = example.id ?? component.name; } // All examples are verified if the outer component is verified if (component.status === "Verified") { - example.status = "Verified"; + pageData.status = "Verified"; } // The example is canon if the component is Canon and Verified if (component.dnaStatus === "Canon" && component.status === "Verified") { - example.dnaStatus = "Canon"; + pageData.dnaStatus = "Canon"; } - this.populateDNAInfo(example, dnaVars); - } - } + component.examples[pageData.id] = pageData; + + this.populateDNAInfo(pageData, dnaVars); + }) + ); }; diff --git a/tasks/mod-extractor.js b/tasks/mod-extractor.js index fe0bff2021c..14e414a5699 100644 --- a/tasks/mod-extractor.js +++ b/tasks/mod-extractor.js @@ -109,10 +109,10 @@ async function main(inputs) { // Write the results to a markdown file in the metadata folder promises.push( writeFile(`${destPath}/mods.md`, finalResult, { encoding: "utf-8" }).then(() => { - console.log(`${`✓`.green} ${"metadata/mods.md".yellow} written`); + console.log(`${"✓".green} ${"metadata/mods.md".yellow} written`); }).catch((err) => { if (!err) return; - console.log(`${`✗`.red} ${"metadata/mods.md".yellow} not written`); + console.log(`${"✗".red} ${"metadata/mods.md".yellow} not written`); return Promise.reject(err); }) ); @@ -130,10 +130,10 @@ async function main(inputs) { // Write the JSON output to the dist folder promises.push( writeFile(`${destPath}/mods.json`, finalResult, { encoding: "utf-8" }).then(() => { - console.log(`${`✓`.green} ${"dist/mods.json".yellow} written`); + console.log(`${"✓".green} ${"dist/mods.json".yellow} written`); }).catch((err) => { if (!err) return; - console.log(`${`✗`.red} ${"dist/mods.json".yellow} not written`); + console.log(`${"✗".red} ${"dist/mods.json".yellow} not written`); return Promise.reject(err); }) ); diff --git a/tools/bundle-builder/CHANGELOG.md b/tools/bundle-builder/CHANGELOG.md deleted file mode 100644 index 3f2442ad3ba..00000000000 --- a/tools/bundle-builder/CHANGELOG.md +++ /dev/null @@ -1,442 +0,0 @@ -# Change Log - -All notable changes to this project will be documented in this file. -See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. - - -#6.2.0 -🗓 -2024-01-29 • 📝 [Commits](https://github.com/adobe/spectrum-css/compare/@spectrum-css/bundle-builder@6.1.2...@spectrum-css/bundle-builder@6.2.0) - -### ✨ Features - -\*migrate build packages to postcss v8 ([#2460](https://github.com/adobe/spectrum-css/issues/2460))([bd6c40e](https://github.com/adobe/spectrum-css/commit/bd6c40e)) - - -##6.1.2 -🗓 -2024-01-16 • 📝 [Commits](https://github.com/adobe/spectrum-css/compare/@spectrum-css/bundle-builder@6.1.1...@spectrum-css/bundle-builder@6.1.2) - -**Note:** Version bump only for package @spectrum-css/bundle-builder - - -##6.1.1 -🗓 -2024-01-16 • 📝 [Commits](https://github.com/adobe/spectrum-css/compare/@spectrum-css/bundle-builder@6.1.0...@spectrum-css/bundle-builder@6.1.1) - -**Note:** Version bump only for package @spectrum-css/bundle-builder - - -#6.1.0 -🗓 -2023-12-12 • 📝 [Commits](https://github.com/adobe/spectrum-css/compare/@spectrum-css/bundle-builder@6.0.0...@spectrum-css/bundle-builder@6.1.0) - -### ✨ Features - -- **ui-icons:**graduate to 1.0 release ([#2366](https://github.com/adobe/spectrum-css/issues/2366))([afd369a](https://github.com/adobe/spectrum-css/commit/afd369a)) - - -#6.0.0 -🗓 -2023-12-12 • 📝 [Commits](https://github.com/adobe/spectrum-css/compare/@spectrum-css/bundle-builder@5.0.1...@spectrum-css/bundle-builder@6.0.0) - -\*feat(icon,ui-icons)!: migrate the icon compiler to a distinct package (#2343)([d73d594](https://github.com/adobe/spectrum-css/commit/d73d594)), closes[#2343](https://github.com/adobe/spectrum-css/issues/2343) - - ### - 🛑 BREAKING CHANGES - - * - - @spectrum-css/icon will no longer contain SVG assets; it will be a purely CSS package with all SVG assets migrated to the new @spectrum-css/ui-icons package. - -- NEW: @spectrum-css/ui-icons package for all SVG icons in the UI set. - - -##5.0.1 -🗓 -2023-12-04 • 📝 [Commits](https://github.com/adobe/spectrum-css/compare/@spectrum-css/bundle-builder@5.0.0...@spectrum-css/bundle-builder@5.0.1) - -### 🐛 Bug fixes - -\*docs watch unable to find package.json([a6d23b9](https://github.com/adobe/spectrum-css/commit/a6d23b9)) - - -#5.0.0 -🗓 -2023-11-15 • 📝 [Commits](https://github.com/adobe/spectrum-css/compare/@spectrum-css/bundle-builder@4.0.13...@spectrum-css/bundle-builder@5.0.0) - -### 🔙 Reverts - -\*gulp and build updates ([#2121](https://github.com/adobe/spectrum-css/issues/2121))([03a37f5](https://github.com/adobe/spectrum-css/commit/03a37f5)), closes[#2099](https://github.com/adobe/spectrum-css/issues/2099) - -\*feat(vars,expressvars)!: deprecate packages (#2244)([5eb391c](https://github.com/adobe/spectrum-css/commit/5eb391c)), closes[#2244](https://github.com/adobe/spectrum-css/issues/2244) - - ### - 🛑 BREAKING CHANGES - - * - as no additional changes have been or are planned to be made to - -these legacy token packages, these assets no longer need to exist in the monorepo -structure for Spectrum CSS. - - -##4.0.14 -🗓 -2023-11-13 • 📝 [Commits](https://github.com/adobe/spectrum-css/compare/@spectrum-css/bundle-builder@4.0.13...@spectrum-css/bundle-builder@4.0.14) - -### 🔙 Reverts - -\*gulp and build updates ([#2121](https://github.com/adobe/spectrum-css/issues/2121))([03a37f5](https://github.com/adobe/spectrum-css/commit/03a37f5)), closes[#2099](https://github.com/adobe/spectrum-css/issues/2099) - - -##4.0.13 -🗓 -2023-08-07 • 📝 [Commits](https://github.com/adobe/spectrum-css/compare/@spectrum-css/bundle-builder@4.0.12...@spectrum-css/bundle-builder@4.0.13) - -**Note:** Version bump only for package @spectrum-css/bundle-builder - - -##4.0.12 -🗓 -2023-07-31 • 📝 [Commits](https://github.com/adobe/spectrum-css/compare/@spectrum-css/bundle-builder@4.0.11...@spectrum-css/bundle-builder@4.0.12) - -**Note:** Version bump only for package @spectrum-css/bundle-builder - - -##4.0.11 -🗓 -2023-07-24 • 📝 [Commits](https://github.com/adobe/spectrum-css/compare/@spectrum-css/bundle-builder@4.0.10...@spectrum-css/bundle-builder@4.0.11) - -**Note:** Version bump only for package @spectrum-css/bundle-builder - - -##4.0.10 -🗓 -2023-06-21 • 📝 [Commits](https://github.com/adobe/spectrum-css/compare/@spectrum-css/bundle-builder@4.0.9...@spectrum-css/bundle-builder@4.0.10) - -**Note:** Version bump only for package @spectrum-css/bundle-builder - - -##4.0.9 -🗓 -2023-06-01 • 📝 [Commits](https://github.com/adobe/spectrum-css/compare/@spectrum-css/bundle-builder@4.0.8...@spectrum-css/bundle-builder@4.0.9) - -**Note:** Version bump only for package @spectrum-css/bundle-builder - - - -## 4.0.8 - -🗓 2023-05-17 • 📝 [Commits](https://github.com/adobe/spectrum-css/compare/@spectrum-css/bundle-builder@4.0.7...@spectrum-css/bundle-builder@4.0.8) - -**Note:** Version bump only for package @spectrum-css/bundle-builder - - - -## 4.0.7 - -🗓 2023-05-09 • 📝 [Commits](https://github.com/adobe/spectrum-css/compare/@spectrum-css/bundle-builder@4.0.6...@spectrum-css/bundle-builder@4.0.7) - -**Note:** Version bump only for package @spectrum-css/bundle-builder - - - -## 4.0.6 - -🗓 2023-05-02 • 📝 [Commits](https://github.com/adobe/spectrum-css/compare/@spectrum-css/bundle-builder@4.0.5...@spectrum-css/bundle-builder@4.0.6) - -**Note:** Version bump only for package @spectrum-css/bundle-builder - - - -## 4.0.5 - -🗓 2023-04-26 • 📝 [Commits](https://github.com/adobe/spectrum-css/compare/@spectrum-css/bundle-builder@4.0.4...@spectrum-css/bundle-builder@4.0.5) - -**Note:** Version bump only for package @spectrum-css/bundle-builder - - - -## 4.0.4 - -🗓 2023-04-25 • 📝 [Commits](https://github.com/adobe/spectrum-css/compare/@spectrum-css/bundle-builder@4.0.2...@spectrum-css/bundle-builder@4.0.4) - -**Note:** Version bump only for package @spectrum-css/bundle-builder - - - -## 4.0.3 - -🗓 2023-04-25 • 📝 [Commits](https://github.com/adobe/spectrum-css/compare/@spectrum-css/bundle-builder@4.0.2...@spectrum-css/bundle-builder@4.0.3) - -**Note:** Version bump only for package @spectrum-css/bundle-builder - - - -## 4.0.2 - -🗓 2023-04-25 • 📝 [Commits](https://github.com/adobe/spectrum-css/compare/@spectrum-css/bundle-builder@4.0.1...@spectrum-css/bundle-builder@4.0.2) - -**Note:** Version bump only for package @spectrum-css/bundle-builder - - - -## 4.0.1 - -🗓 2023-04-17 • 📝 [Commits](https://github.com/adobe/spectrum-css/compare/@spectrum-css/bundle-builder@4.0.0...@spectrum-css/bundle-builder@4.0.1) - -**Note:** Version bump only for package @spectrum-css/bundle-builder - - - -# 4.0.0 - -🗓 2023-04-03 • 📝 [Commits](https://github.com/adobe/spectrum-css/compare/@spectrum-css/bundle-builder@3.4.5...@spectrum-css/bundle-builder@4.0.0) - -- fix(tokens)!: rgb transform to split out rgb values from css attributes (#1590) ([b714db4](https://github.com/adobe/spectrum-css/commit/b714db4)), closes [#1590](https://github.com/adobe/spectrum-css/issues/1590) - -### 🛑 BREAKING CHANGES - -- transforms color tokens to split out their `rgb` values - -Co-authored-by: castastrophe - - - -## 3.4.5 - -🗓 2023-03-13 • 📝 [Commits](https://github.com/adobe/spectrum-css/compare/@spectrum-css/bundle-builder@3.4.4...@spectrum-css/bundle-builder@3.4.5) - -**Note:** Version bump only for package @spectrum-css/bundle-builder - - - -## 3.4.4 - -🗓 2023-01-25 • 📝 [Commits](https://github.com/adobe/spectrum-css/compare/@spectrum-css/bundle-builder@3.4.3...@spectrum-css/bundle-builder@3.4.4) - -**Note:** Version bump only for package @spectrum-css/bundle-builder - - - -## 3.4.3 - -🗓 2023-01-18 • 📝 [Commits](https://github.com/adobe/spectrum-css/compare/@spectrum-css/bundle-builder@3.4.1...@spectrum-css/bundle-builder@3.4.3) - -**Note:** Version bump only for package @spectrum-css/bundle-builder - - - -## 3.4.2 - -🗓 2023-01-13 • 📝 [Commits](https://github.com/adobe/spectrum-css/compare/@spectrum-css/bundle-builder@3.4.1...@spectrum-css/bundle-builder@3.4.2) - -**Note:** Version bump only for package @spectrum-css/bundle-builder - - - -## 3.4.1 - -🗓 2023-01-13 • 📝 [Commits](https://github.com/adobe/spectrum-css/compare/@spectrum-css/bundle-builder@3.4.0...@spectrum-css/bundle-builder@3.4.1) - -**Note:** Version bump only for package @spectrum-css/bundle-builder - - - -# 3.4.0 - -🗓 2022-09-12 • 📝 [Commits](https://github.com/adobe/spectrum-css/compare/@spectrum-css/bundle-builder@3.3.1...@spectrum-css/bundle-builder@3.4.0) - -### ✨ Features - -- adding port customiztion and re-launch for watch ([5c7aeef](https://github.com/adobe/spectrum-css/commit/5c7aeef)) -- watch covers components/commons ([5d1b682](https://github.com/adobe/spectrum-css/commit/5d1b682)) - -### 🐛 Bug fixes - -- dev hanging on yaml error and dev opening browser tabs ([fbfc622](https://github.com/adobe/spectrum-css/commit/fbfc622)) -- made browser open message more perfect ([dad62eb](https://github.com/adobe/spectrum-css/commit/dad62eb)) - - - -## 3.3.1 - -🗓 2022-07-22 • 📝 [Commits](https://github.com/adobe/spectrum-css/compare/@spectrum-css/bundle-builder@3.3.0...@spectrum-css/bundle-builder@3.3.1) - -**Note:** Version bump only for package @spectrum-css/bundle-builder - - - -# 3.3.0 - -🗓 2022-06-16 • 📝 [Commits](https://github.com/adobe/spectrum-css/compare/@spectrum-css/bundle-builder@3.2.0...@spectrum-css/bundle-builder@3.3.0) - -### ✨ Features - -- add core tokens ([d0a07a1](https://github.com/adobe/spectrum-css/commit/d0a07a1)) -- add simple component builder ([535126b](https://github.com/adobe/spectrum-css/commit/535126b)) - - - -# 3.2.0 - -🗓 2022-01-05 • 📝 [Commits](https://github.com/adobe/spectrum-css/compare/@spectrum-css/bundle-builder@3.0.4...@spectrum-css/bundle-builder@3.2.0) - -### ✨ Features - -- break out ClearButton and LogicButton into their own packages ([3cc0a5f](https://github.com/adobe/spectrum-css/commit/3cc0a5f)) - - - -# 3.1.0 - -🗓 2021-12-14 • 📝 [Commits](https://github.com/adobe/spectrum-css/compare/@spectrum-css/bundle-builder@3.0.4...@spectrum-css/bundle-builder@3.1.0) - -### ✨ Features - -- break out ClearButton and LogicButton into their own packages ([a2092ab](https://github.com/adobe/spectrum-css/commit/a2092ab)) - - - -## 3.0.4 - -🗓 2021-11-16 • 📝 [Commits](https://github.com/adobe/spectrum-css/compare/@spectrum-css/bundle-builder@3.0.2-alpha.1...@spectrum-css/bundle-builder@3.0.4) - -### 🐛 Bug fixes - -- actually fail when you fail ([6a49a99](https://github.com/adobe/spectrum-css/commit/6a49a99)) -- fetch package publish date from npm registry ([71fd187](https://github.com/adobe/spectrum-css/commit/71fd187)) - - - -## 3.0.3 - -🗓 2021-10-25 • 📝 [Commits](https://github.com/adobe/spectrum-css/compare/@spectrum-css/bundle-builder@3.0.2-alpha.1...@spectrum-css/bundle-builder@3.0.3) - -### 🐛 Bug fixes - -- fetch package publish date from npm registry ([71fd187](https://github.com/adobe/spectrum-css/commit/71fd187)) - - - -## 3.0.2 - -🗓 2021-09-29 • 📝 [Commits](https://github.com/adobe/spectrum-css/compare/@spectrum-css/bundle-builder@3.0.2-alpha.1...@spectrum-css/bundle-builder@3.0.2) - -**Note:** Version bump only for package @spectrum-css/bundle-builder - - - -## 3.0.2-alpha.1 - -🗓 2021-07-19 • 📝 [Commits](https://github.com/adobe/spectrum-css/compare/@spectrum-css/bundle-builder@3.0.2-alpha.0...@spectrum-css/bundle-builder@3.0.2-alpha.1) - -### 🐛 Bug fixes - -- added expressvars build to release task ([bc447b1](https://github.com/adobe/spectrum-css/commit/bc447b1)) - - - -## 3.0.2-alpha.0 - -🗓 2021-04-27 • 📝 [Commits](https://github.com/adobe/spectrum-css/compare/@spectrum-css/bundle-builder@3.0.1...@spectrum-css/bundle-builder@3.0.2-alpha.0) - -**Note:** Version bump only for package @spectrum-css/bundle-builder - - - -## 3.0.1 - -🗓 2021-03-10 • 📝 [Commits](https://github.com/adobe/spectrum-css/compare/@spectrum-css/bundle-builder@3.0.0...@spectrum-css/bundle-builder@3.0.1) - -**Note:** Version bump only for package @spectrum-css/bundle-builder - - - -# 3.0.0 - -🗓 2021-02-02 • 📝 [Commits](https://github.com/adobe/spectrum-css/compare/@spectrum-css/bundle-builder@3.0.0-beta.0...@spectrum-css/bundle-builder@3.0.0) - -**Note:** Version bump only for package @spectrum-css/bundle-builder - - - -# 3.0.0-beta.0 - -🗓 2020-12-04 • 📝 [Commits](https://github.com/adobe/spectrum-css/compare/@spectrum-css/bundle-builder@2.0.2-beta.0...@spectrum-css/bundle-builder@3.0.0-beta.0) - -### ✨ Features - -- disable legacy build in output ([f1ef983](https://github.com/adobe/spectrum-css/commit/f1ef983)) -- error and warning reporting for variable use ([0460d39](https://github.com/adobe/spectrum-css/commit/0460d39)) -- support FORCE=true environment variable to allow broken components ([f725a17](https://github.com/adobe/spectrum-css/commit/f725a17)) - -### 🐛 Bug fixes - -- correct usage of ActionButton in site templates ([be0c83a](https://github.com/adobe/spectrum-css/commit/be0c83a)) - -### 🛑 BREAKING CHANGES - -- this completely removes legacy build artifacts and IE 11 support - - - -## 2.0.2-beta.0 - -🗓 2020-09-23 • 📝 [Commits](https://github.com/adobe/spectrum-css/compare/@spectrum-css/bundle-builder@2.0.1...@spectrum-css/bundle-builder@2.0.2-beta.0) - -**Note:** Version bump only for package @spectrum-css/bundle-builder - - - -## 2.0.1 - -🗓 2020-06-19 • 📝 [Commits](https://github.com/adobe/spectrum-css/compare/@spectrum-css/bundle-builder@2.0.0...@spectrum-css/bundle-builder@2.0.1) - -**Note:** Version bump only for package @spectrum-css/bundle-builder - - - -# 2.0.0 - -🗓 2020-03-12 • 📝 [Commits](https://github.com/adobe/spectrum-css/compare/@spectrum-css/bundle-builder@1.1.0...@spectrum-css/bundle-builder@2.0.0) - -### ✨ Features - -- remove DecoratedTextfield ([a1017a8](https://github.com/adobe/spectrum-css/commit/a1017a8)) - -### 🛑 BREAKING CHANGES - -- DecoratedTextfield has been removed in favor of Textfield - docs: don't include DecoratedTextfield anymore - - - -# 1.1.0 - -🗓 2020-02-10 • 📝 [Commits](https://github.com/adobe/spectrum-css/compare/@spectrum-css/bundle-builder@1.0.1...@spectrum-css/bundle-builder@1.1.0) - -### ✨ Features - -- adding t-shirt sized typography, fixes [#210](https://github.com/adobe/spectrum-css/issues/210), closes [#416](https://github.com/adobe/spectrum-css/issues/416) ([#408](https://github.com/adobe/spectrum-css/issues/408)) ([3921bcb](https://github.com/adobe/spectrum-css/commit/3921bcb)), closes [#523](https://github.com/adobe/spectrum-css/issues/523) - - - -## 1.0.1 - -🗓 2019-11-07 • 📝 [Commits](https://github.com/adobe/spectrum-css/compare/@spectrum-css/bundle-builder@1.0.0...@spectrum-css/bundle-builder@1.0.1) - -### 🐛 Bug fixes - -- add missing variables to -unique files, closes [#336](https://github.com/adobe/spectrum-css/issues/336) ([3c9337f](https://github.com/adobe/spectrum-css/commit/3c9337f)) - - - -# 1.0.0 - -🗓 2019-10-08 - -### ✨ Features - -- move to individually versioned packages with Lerna ([#265](https://github.com/adobe/spectrum-css/issues/265)) ([cb7fd4b](https://github.com/adobe/spectrum-css/commit/cb7fd4b)), closes [#231](https://github.com/adobe/spectrum-css/issues/231) [#214](https://github.com/adobe/spectrum-css/issues/214) [#229](https://github.com/adobe/spectrum-css/issues/229) [#240](https://github.com/adobe/spectrum-css/issues/240) [#239](https://github.com/adobe/spectrum-css/issues/239) [#161](https://github.com/adobe/spectrum-css/issues/161) [#242](https://github.com/adobe/spectrum-css/issues/242) [#246](https://github.com/adobe/spectrum-css/issues/246) [#219](https://github.com/adobe/spectrum-css/issues/219) [#235](https://github.com/adobe/spectrum-css/issues/235) [#189](https://github.com/adobe/spectrum-css/issues/189) [#248](https://github.com/adobe/spectrum-css/issues/248) [#232](https://github.com/adobe/spectrum-css/issues/232) [#248](https://github.com/adobe/spectrum-css/issues/248) [#218](https://github.com/adobe/spectrum-css/issues/218) [#237](https://github.com/adobe/spectrum-css/issues/237) [#255](https://github.com/adobe/spectrum-css/issues/255) [#256](https://github.com/adobe/spectrum-css/issues/256) [#258](https://github.com/adobe/spectrum-css/issues/258) [#257](https://github.com/adobe/spectrum-css/issues/257) [#259](https://github.com/adobe/spectrum-css/issues/259) -- use linked DNA data for CSS variable generation ([0233a53](https://github.com/adobe/spectrum-css/commit/0233a53)) diff --git a/tools/bundle-builder/README.md b/tools/bundle-builder/README.md deleted file mode 100644 index c5a87ecb27d..00000000000 --- a/tools/bundle-builder/README.md +++ /dev/null @@ -1,56 +0,0 @@ -# @spectrum-css/bundle-builder - -> Build system for Spectrum CSS bundle packages - -This package builds a bundle packages with the versions of components specific in your the bundle's `package.json`. - -## Docs - -See the [docs generation documentation](docs/README.md) for details on documentation generation. - -## Site - -See the [site generation documentation](site/README.md) for details on site generation as well as editing and updating the site. - -## Usage - -Install the package: - -``` -npm install --save-dev @spectrum-css/bundle-builder -``` - -Create a `gulpfile.js` with the following: - -```js -module.exports = require("@spectrum-css/bundle-builder"); -``` - -Add the following scripts to `package.json`: - -```json -{ - "scripts": { - "build": "gulp build", - "prepack": "gulp prePack", - "postpublish": "gulp postPublish" - } -} -``` - -Then you can use the commands below inside of your project to build and release a Spectrum CSS bundle package. - -## CLI - -The following tasks are available: - -- `gulp clean` - Clean everything -- `gulp build` - Build every component, generate the documentation site, generate individual docs for each component -- `gulp buildLite` - Build only the custom properties for every component, generate the documentation site -- `gulp buildHeavy` - Build all CSS for every component, generate the documentation site -- `gulp dev` - Perform a lite build, start a server, and watch for changes -- `gulp devHeavy` - Perform a heavy build, start a server, and watch for changes. -- `gulp watch` - If a build as already been performed, start a server and watch for changes -- `gulp release` - Perform a release - -Build output appears in the `dist/` folder. diff --git a/tools/bundle-builder/dev/index.js b/tools/bundle-builder/dev/index.js deleted file mode 100644 index 59f736ebfdd..00000000000 --- a/tools/bundle-builder/dev/index.js +++ /dev/null @@ -1,214 +0,0 @@ -/*! -Copyright 2023 Adobe. All rights reserved. -This file is licensed to you under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. You may obtain a copy -of the License at http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software distributed under -the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS -OF ANY KIND, either express or implied. See the License for the specific language -governing permissions and limitations under the License. -*/ - -const gulp = require("gulp"); -const logger = require("gulplog"); -const browserSync = require("browser-sync"); -const path = require("path"); -const dirs = require("../lib/dirs"); - -const docs = require("../docs"); -const subrunner = require("../subrunner"); -const bundleBuilder = require("../index.js"); - -function serve() { - let PORT = 3000; - - if (process.env.BROWSERSYNC_PORT) { - PORT = process.env.BROWSERSYNC_PORT; - logger.info( - `Setting '${PORT} as port for browsersync, which hopefully is valid` - ); - } - - if (process.env.BROWSERSYNC_OPEN === "true") { - logger.info("New browser instance will open"); - } - - browserSync({ - startPath: "index.html", - server: `${process.cwd()}/dist/`, - notify: process.env.BROWSERSYNC_NOTIFY === "true" ? true : false, - open: process.env.BROWSERSYNC_OPEN === "true" ? true : false, - port: PORT, - }); -} - -function getPackageFromPath(filePath) { - return filePath.match(`${dirs.components}\/(.*?)\/`)[1]; -} - -/* - Watch for changes to globs matching files within packages, execute task for that package, and copy/inject specified files -*/ -function watchWithinPackages(glob, task, files) { - logger.debug(`Watching ${glob}, will run ${task} and stream ${files}`); - - let watcher = gulp.watch( - glob, - { - // Otherwise we get infinite loops because chokidar gets all crazy with symlinked deps - followSymlinks: false, - }, - function handleChanged(done) { - if (!changedFile) { - done(); - return; - } - - let packageName = getPackageFromPath(changedFile); - let packageDir = path.dirname(require.resolve(`@spectrum-css/${packageName}/package.json`)); - - if (typeof task === "function") { - task(changedFile, packageName, (err) => { - done(err); - changedFile = null; - }); - } else { - subrunner.runComponentTask(packageDir, task, (err) => { - if (err) { - changedFile = null; - return done(err); - } - - // Copy files - gulp - .src(`${packageDir}/dist/${files}`) - .pipe(gulp.dest(`dist/components/${packageName}/`)) - .on("end", () => { - logger.debug(`Injecting files from ${packageName}/:\n ${files}`); - - // Inject - gulp - .src(`dist/components/${packageName}/${files}`) - .pipe(browserSync.stream()); - - changedFile = null; - - done(); - }) - .on("error", (err) => { - changedFile = null; - - done(err); - }); - }); - } - } - ); - - let changedFile = null; - watcher.on("change", (filePath) => { - logger.debug(`Got change for ${filePath}`); - - if (changedFile === null) { - changedFile = filePath; - } - }); -} - -function reload(cb) { - browserSync.reload(); - if (cb) { - cb(); - } -} - -function watchSite() { - gulp.watch(`${dirs.site}/*.pug`, gulp.series(docs.buildSite_pages, reload)); - - gulp.watch( - `${dirs.site}/includes/*.pug`, - gulp.series(gulp.parallel(docs.buildSite_html, docs.buildDocs), reload) - ); - - gulp.watch( - [`${dirs.site}/templates/siteComponent.pug`, `${dirs.site}/util.js`], - gulp.series(gulp.parallel(docs.buildDocs), reload) - ); - - gulp.watch( - [`${dirs.site}/resources/css/*.css`, `${dirs.site}/resources/js/*.js`], - gulp.series( - docs.buildSite_copyFreshResources, - function injectSiteResources() { - return gulp - .src(["dist/css/**/*.css", "dist/js/**/*.js"]) - .pipe(browserSync.stream()); - } - ) - ); -} - -function watchCommons() { - gulp.watch( - [`${dirs.components}/commons/*.css`], - gulp.series( - bundleBuilder.buildDepenenciesOfCommons, - bundleBuilder.copyPackages, - reload - ) - ); -} - -function watch() { - serve(); - - watchCommons(); - - watchWithinPackages( - `${dirs.components}/*/{index,skin}.css`, - "buildMedium", - "*.css" - ); - watchWithinPackages( - `${dirs.components}/*/themes/{spectrum,express}.css`, - "buildMedium", - "*.css" - ); - - watchWithinPackages( - [ - `${dirs.components}/*/metadata/*.yml`, - ], - (changedFile, package, done) => { - // Do this as gulp tasks to avoid premature stream termination - try { - let result = gulp.series( - // Get data first so nav builds - function buildSite_getData() { - logger.debug(`Building nav data for ${package}`); - return docs.buildSite_getData(); - }, - function buildDocs_forDep() { - logger.debug(`Building docs for ${package}`); - let packageDir = path.dirname(require.resolve(`@spectrum-css/${package}/package.json`)); - return docs.buildDocs_forDep(packageDir); - } - )(); - // this catches yaml parsing errors - // should stop the series from running - } catch (error) { - done(error); - } finally { - // we have to do this - // or gulp will get wedged by the error - done(); - reload(); - } - } - ); - - watchSite(); -} - -exports.watch = watch; diff --git a/tools/bundle-builder/docs/README.md b/tools/bundle-builder/docs/README.md deleted file mode 100644 index 5a305f0382d..00000000000 --- a/tools/bundle-builder/docs/README.md +++ /dev/null @@ -1,58 +0,0 @@ -# Spectrum CSS Component Documentation - -Component documentation is built using [Pug templates](https://pugjs.org/api/getting-started.html). - -## Structure - -The top level of the `.yml` files can have the following properties: - -- `id` - If the name of the component doesn't match DNA, provide the DNA ID here. -- `name` - The name of the component (appears in the navigation and as the heading of the page). If not provided, it will be loaded from DNA based on the id. -- `description` - The topmost description of the component. This will be loaded from DNA if something matches the ID of the component. -- `status` - The status of the overall component's design review; one of `Unverified`, `Verified`, or `Deprecated`. This will be pulled from DNA if not provided. -- `examples` - An array of examples which should show each variant of the component (see properties below). -- `examplesHeading` - The heading to use for examples. Default is "Variants" -- `sections` - An optional array of sections to provide additional information (see properties below). - -Each item in the `examples` array supports the following properties: - -- `id` - Provide the DNA ID here to fetch the status of this example. -- `name` - The name of the example. If not provided, it will be loaded from DNA. -- `description` - The example's description, written in markdown. All links, headings, code blocks, and tables will automatically get Spectrum CSS classes applied to them. -- `markup` - The markup example -- `status` - The status of the example's design review; one of `Unverified`, `Verified`, or `Deprecated`. - -Each item in the `sections` array supports the following properties: - -- `name` - The name of the example (appears in the navigation and as the heading of the page). If not provided, it will be loaded from DNA. -- `description` - The content of the section, written in markdown. All links, headings, code blocks, and tables will automatically get Spectrum CSS classes applied to them. -- `markup` - An optional markup example for the section - -## Architecture - -Documentation is built by parsing `.yml` files within component packages that contain examples and their metadata and combining that with ID-matching of DNA data in `@spectrum-css/vars/spectrum-metadata.json`. - -The dependencies for the component's documentation page are determined by parsing the `package.json` and building a dependency graph which is then topologically sorted using [`dependency-solver`](https://www.npmjs.com/package/dependency-solver). This means that all dependencies and dependencies of dependencies will be included in the documentation pages for the component automatically. - -Within each component package, the `metadata.yml` file contains all of the examples that should appear on the main page for a given component. These examples will be printed one after another on the page for that component. - -Additional examples that should appear in the navigation independent of the main component page can be added as `metadata/*.yml`. These are treated as a separate documentation page completely, but they share the same dependencies as the main page. - -See the [site documentation](../site/README.md) for details on dependency lazy-loading when navigating. - -## Viewing documentation - -1. Run `gulp dev` at the top level of the project and the site will build and open up in your browser. - -## Editing documentation - -1. Run `gulp dev` at the top level of the project. -2. Edit the `metadata.yml` and `metadata/*.yml` files within each component package and the site will live reload with your changes. - -## Adding a one-off example page - -See the [site documentation](../site/README.md) for details on adding a one-off example page for a given component. - -## Adding and editing resources - -See the [site documentation](../site/README.md) for details on adding and editing resources. diff --git a/tools/bundle-builder/docs/index.js b/tools/bundle-builder/docs/index.js deleted file mode 100644 index 35732462432..00000000000 --- a/tools/bundle-builder/docs/index.js +++ /dev/null @@ -1,395 +0,0 @@ -/*! -Copyright 2023 Adobe. All rights reserved. -This file is licensed to you under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. You may obtain a copy -of the License at http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software distributed under -the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS -OF ANY KIND, either express or implied. See the License for the specific language -governing permissions and limitations under the License. -*/ -const gulp = require("gulp"); -const fs = require("fs"); -const fsp = fs.promises; -const path = require("path"); -const pugCompiler = require("pug"); -const pug = require("gulp-pug"); -const data = require("gulp-data"); -const rename = require("gulp-rename"); -const yaml = require("js-yaml"); -const through = require("through2"); -const ext = require("replace-ext"); -const logger = require("gulplog"); -const lunr = require("lunr"); - -const dirs = require("../lib/dirs"); -const depUtils = require("../lib/depUtils"); - -const npmFetch = require("npm-registry-fetch"); - -require("colors"); - -let minimumDeps = [ - "icon", - "statuslight", - "link", - "page", - "site", - "typography", - "tooltip", - "sidenav", - "actionbutton", - "button", - "textfield", - "clearbutton", - "search", - "menu", - "fieldlabel", - "picker", - "popover", - "underlay", - "card", - "divider", - "illustratedmessage", - "accordion", - "table", -]; - -let templateData = { - nav: [], - pkg: JSON.parse(fs.readFileSync("package.json", "utf8")), -}; - -async function buildDocs_forDep(dep) { - let metadata = JSON.parse( - await fsp.readFile( - require.resolve("@spectrum-css/vars") - ) - ); - - let dirName = path.dirname(require.resolve(path.join(dep, "package.json"))); - let dependencyOrder = await depUtils.getPackageDependencyOrder(dirName); - - logger.debug(`Will build docs for package in ${dirName}`); - - // Drop package org - dep = dep.split("/").pop(); - - return new Promise((resolve, reject) => { - gulp - .src([`${dirName}/metadata/*.yml`], { - allowEmpty: true, - }) - .pipe( - rename(function (file) { - if (file.basename === "metadata") { - file.basename = dep; - } - }) - ) - .pipe( - data(async function (file) { - let componentDeps = dependencyOrder.map((dep) => - dep.split("/").pop() - ); - componentDeps.push(dep); - - let pkg = JSON.parse( - await fsp.readFile(path.join(dirs.components, dep, "package.json")) - ); - - let docsDeps = minimumDeps.concat(componentDeps); - docsDeps = docsDeps.filter((dep, i) => docsDeps.indexOf(dep) === i); - - let date; - try { - const data = await npmFetch.json(pkg.name); - date = data.time[pkg.version]; - date = new Date(date).toLocaleDateString("en-US", { - year: "numeric", - month: "long", - day: "numeric", - }); - } catch (err) { - date = "Unreleased"; - logger.error( - `Could not determine date of release for ${pkg.name}@${pkg.version}` - ); - } - - return Object.assign( - {}, - { - util: require(`${dirs.site}/util`), - dnaVars: metadata, - }, - templateData, - { - pageURL: path.basename(file.basename, ".yml") + ".html", - dependencyOrder: docsDeps, - releaseDate: date, - pkg: pkg, - } - ); - }) - ) - .pipe( - through.obj(function compilePug(file, enc, cb) { - let component; - var componentName = file.dirname - .replace("/metadata", "") - .split("/") - .pop(); - try { - component = yaml.load(String(file.contents)); - } catch (loadError) { - logger.error( - "Uh, oh... during buildDocs_forDep, yaml loading failed for" - .yellow, - componentName.red - ); - throw loadError; - } - - if (!component.id) { - if (file.basename === "metadata.yml") { - // Use the component's name - component.id = dep; - } else { - // Use the example file name - component.id = path.basename(file.basename, ".yml"); - } - } - let templateData = Object.assign( - {}, - { component: component }, - file.data || {} - ); - - file.path = ext(file.path, ".html"); - - try { - const templatePath = `${dirs.site}/templates/siteComponent.pug`; - let compiled = pugCompiler.renderFile(templatePath, templateData); - file.contents = Buffer.from(compiled); - } catch (err) { - return cb(err); - } - cb(null, file); - }) - ) - .pipe(gulp.dest("dist/")) - .on("end", resolve) - .on("error", reject); - }); -} - -// Combined -async function buildDocs_individualPackages() { - let dependencies = await depUtils.getFolderDependencyOrder(dirs.components); - - return Promise.all(dependencies.map(buildDocs_forDep)); -} - -function buildSite_generateIndex() { - return gulp - .src([ - `${dirs.components}/*/metadata/*.yml`, - ]) - .pipe( - (function () { - let docs = []; - let store = {}; - let latestFile = null; - function readYML(file, enc, cb) { - let componentData; - try { - componentData = yaml.load(String(file.contents)); - } catch (err) { - return cb(err); - } - - var componentName = file.dirname - .replace("/metadata", "") - .split("/") - .pop(); - - if (path.basename(file.basename) === "metadata.yml") { - file.basename = componentName; - } - - var fileName = ext(file.basename, ".html"); - - docs.push({ - href: fileName, - name: componentData.name, - description: componentData.description, - }); - - store[fileName] = { - href: fileName, - name: componentData.name, - component: componentName, - description: componentData.description, - }; - - latestFile = file; - - cb(); - } - - function endStream(cb) { - let indexFile = latestFile.clone({ contents: false }); - indexFile.path = path.join(latestFile.base, "index.json"); - - let index = lunr(function () { - this.ref("href"); - this.field("name", { boost: 10 }); - this.field("description"); - - docs.forEach(function (doc) { - this.add(doc); - }, this); - }); - - // Note: could merge main index here using technique from https://www.garysieling.com/blog/building-a-full-text-index-in-javascript - - indexFile.contents = Buffer.from(JSON.stringify(index)); - this.push(indexFile); - - let storeFile = latestFile.clone({ contents: false }); - storeFile.path = path.join(latestFile.base, "store.json"); - storeFile.contents = Buffer.from(JSON.stringify(store)); - this.push(storeFile); - - cb(); - } - - return through.obj(readYML, endStream); - })() - ) - .pipe(gulp.dest("dist/")); -} - -function buildSite_getData() { - let nav = []; - return gulp - .src([ - `${dirs.components}/*/metadata/*.yml`, - ]) - .pipe( - through.obj(function readYML(file, enc, cb) { - let componentData; - var componentName = file.dirname - .replace("/metadata", "") - .split("/") - .pop(); - try { - componentData = yaml.load(String(file.contents)); - } catch (loadError) { - logger.error( - "Uh, oh... during buildDocs_getData, yaml loading failed for" - .yellow, - componentName.red - ); - throw loadError; - } - - if (path.basename(file.basename) === "metadata.yml") { - file.basename = componentName; - } - - var fileName = ext(file.basename, ".html"); - nav.push({ - name: componentData.name, - component: componentName, - hide: componentData.hide, - fastLoad: componentData.fastLoad, - href: fileName, - description: componentData.description, - }); - - cb(null, file); - }) - ) - .on("end", function () { - templateData.nav = nav.sort(function (a, b) { - return a.name <= b.name ? -1 : 1; - }); - }); -} - -function buildSite_copyResources() { - return gulp.src(`${dirs.site}/dist/**`).pipe(gulp.dest("dist/")); -} - -function buildSite_copyFreshResources() { - return gulp.src(`${dirs.site}/resources/**`).pipe(gulp.dest("dist/")); -} - -function buildSite_html() { - return gulp - .src(`${dirs.site}/*.pug`) - .pipe( - data(function (file) { - return { - util: require(`${dirs.site}/util`), - pageURL: path.basename(file.basename, ".pug") + ".html", - dependencyOrder: minimumDeps, - }; - }) - ) - .pipe( - pug({ - locals: templateData, - }) - ) - .pipe(gulp.dest("dist/")); -} - -function copySiteWorkflowIcons() { - return gulp - .src( - path.join( - path.dirname(require.resolve("@adobe/spectrum-css-workflow-icons")), - "spectrum-icons.svg" - ), - ) - .pipe(gulp.dest("dist/img/")); -} - -function copySiteUIIcons() { - return gulp - .src(require.resolve("@spectrum-css/ui-icons")) - .pipe(gulp.dest("dist/img/")); -} - -let buildSite_pages = gulp.series(buildSite_getData, buildSite_html); - -exports.buildSite = gulp.parallel(buildSite_copyResources, buildSite_pages); - -let buildDocs = gulp.series( - buildSite_getData, - gulp.parallel( - buildSite_generateIndex, - buildDocs_individualPackages, - buildSite_copyResources, - copySiteWorkflowIcons, - copySiteUIIcons - ) -); - -let build = gulp.series( - buildSite_getData, - gulp.parallel(buildDocs, buildSite_html) -); - -exports.buildSite_getData = buildSite_getData; -exports.buildSite_copyResources = buildSite_copyResources; -exports.buildSite_copyFreshResources = buildSite_copyFreshResources; -exports.buildSite_pages = buildSite_pages; -exports.buildSite_html = buildSite_html; -exports.buildDocs_forDep = buildDocs_forDep; -exports.buildDocs = buildDocs; -exports.build = build; diff --git a/tools/bundle-builder/index.js b/tools/bundle-builder/index.js deleted file mode 100644 index 591010d225e..00000000000 --- a/tools/bundle-builder/index.js +++ /dev/null @@ -1,235 +0,0 @@ -/*! -Copyright 2023 Adobe. All rights reserved. -This file is licensed to you under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. You may obtain a copy -of the License at http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software distributed under -the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS -OF ANY KIND, either express or implied. See the License for the specific language -governing permissions and limitations under the License. -*/ - -const gulp = require("gulp"); -const concat = require("gulp-concat"); -const rename = require("gulp-rename"); - -const depUtils = require("./lib/depUtils"); -const dirs = require("./lib/dirs"); - -const docs = require("./docs"); -const dev = require("./dev"); -const subrunner = require("./subrunner"); -const vars = require("./vars"); - -var dependencyOrder = null; - -// Combined -function concatPackageFiles(taskName, input, output, directory) { - let func = function () { - let glob; - if (Array.isArray(input)) { - glob = []; - - dependencyOrder.forEach(function (dep) { - input.forEach(function (file) { - glob.push(dirs.resolve(dep) + `/${file}`); - }); - }); - } else { - glob = dependencyOrder.map(function (dep) { - return dirs.resolve(dep) + `/${input}`; - }); - } - - return gulp - .src(glob, { allowEmpty: true }) - .pipe(concat(output)) - .pipe(gulp.dest(`dist/${directory || ""}`)); - }; - - Object.defineProperty(func, "name", { value: taskName, writable: false }); - - return func; -} - -async function getDependencyOrder(done) { - dependencyOrder = await depUtils.getFolderDependencyOrder(dirs.components); - done(); -} - -let buildCombined = gulp.series( - getDependencyOrder, - gulp.parallel( - concatPackageFiles("buildCombined_core", "index.css", "spectrum-core.css"), - concatPackageFiles( - "buildCombined_large", - "index-lg.css", - "spectrum-core-lg.css" - ), - concatPackageFiles( - "buildCombined_diff", - "index-diff.css", - "spectrum-core-diff.css" - ), - concatPackageFiles( - "buildCombined_light", - "multiStops/light.css", - "spectrum-light.css" - ), - concatPackageFiles( - "buildCombined_lightest", - "multiStops/lightest.css", - "spectrum-lightest.css" - ), - concatPackageFiles( - "buildCombined_dark", - "multiStops/dark.css", - "spectrum-dark.css" - ), - concatPackageFiles( - "buildCombined_darkest", - "multiStops/darkest.css", - "spectrum-darkest.css" - ) - ) -); - -let buildStandalone = gulp.series( - getDependencyOrder, - gulp.parallel( - concatPackageFiles( - "buildStandalone_light", - ["index.css", "colorStops/light.css"], - "spectrum-light.css", - "standalone/" - ), - concatPackageFiles( - "buildStandalone_lightest", - ["index.css", "colorStops/lightest.css"], - "spectrum-lightest.css", - "standalone/" - ), - concatPackageFiles( - "buildStandalone_dark", - ["index.css", "colorStops/dark.css"], - "spectrum-dark.css", - "standalone/" - ), - concatPackageFiles( - "buildStandalone_darkest", - ["index.css", "colorStops/darkest.css"], - "spectrum-darkest.css", - "standalone/" - ), - concatPackageFiles( - "buildStandalone_lightLarge", - ["index-lg.css", "colorStops/light.css"], - "spectrum-light-lg.css", - "standalone/" - ), - concatPackageFiles( - "buildStandalone_lightestLarge", - ["index-lg.css", "colorStops/lightest.css"], - "spectrum-lightest-lg.css", - "standalone/" - ), - concatPackageFiles( - "buildStandalone_darkLarge", - ["index-lg.css", "colorStops/dark.css"], - "spectrum-dark-lg.css", - "standalone/" - ), - concatPackageFiles( - "buildStandalone_darkestLarge", - ["index-lg.css", "colorStops/darkest.css"], - "spectrum-darkest-lg.css", - "standalone/" - ) - ) -); - -// run buildLite on a selected set of packages that depend on commons -// yay: faster than 'rebuild everything' approach -// boo: must add new packages here as commons grows -function buildDepenenciesOfCommons() { - const dependentComponents = [ - `${dirs.components}/actionbutton`, - `${dirs.components}/button`, - `${dirs.components}/clearbutton`, - `${dirs.components}/closebutton`, - `${dirs.components}/infieldbutton`, - `${dirs.components}/logicbutton`, - `${dirs.components}/picker`, - `${dirs.components}/pickerbutton`, - ]; - return subrunner.runTaskOnPackages("buildLite", dependentComponents); -} - -function copyPackages() { - return gulp - .src([ - `${dirs.components}/*/package.json`, - `${dirs.components}/*/dist/**`, - `!${dirs.components}/*/dist/docs/**`, - ]) - .pipe( - rename(function (file) { - file.dirname = file.dirname.replace("/dist", ""); - }) - ) - .pipe(gulp.dest("dist/components/")); -} - -const buildDocs = gulp.parallel(docs.build, vars.copyVars, copyPackages); - -function buildIfTopLevel() { - let builtTasks = gulp.parallel(buildCombined, buildStandalone, buildDocs); - - if (process.cwd() === dirs.topLevel) { - // Run a build for all packages first - return gulp.series(subrunner.buildComponents, builtTasks); - } - - // They're already built, just include the output - return builtTasks; -} - -let build = gulp.series(buildIfTopLevel(), vars.copyVars); - -let buildLite = gulp.series(function buildComponentsLite() { - return subrunner.runTaskOnAllComponents("buildLite"); -}, buildDocs); - -let buildMedium = gulp.series(function buildComponentsLite() { - return subrunner.runTaskOnAllComponents("buildMedium"); -}, buildDocs); - -let buildHeavy = gulp.series(function buildComponentsLite() { - return subrunner.runTaskOnAllComponents("buildHeavy"); -}, buildDocs); - -let devTask; -if (process.cwd() === dirs.topLevel) { - // Build all packages if at the top level - devTask = gulp.series(buildLite, dev.watch); -} else { - // Otherwise, just start watching - devTask = gulp.series(buildDocs, dev.watch); -} - -exports.devHeavy = gulp.series(buildHeavy, dev.watch); - -exports.buildUniqueVars = vars.buildUnique; - -exports.buildComponents = subrunner.buildComponents; -exports.buildCombined = buildCombined; -exports.buildStandalone = buildStandalone; -exports.buildLite = buildLite; -exports.buildDocs = buildDocs; -exports.buildDepenenciesOfCommons = buildDepenenciesOfCommons; -exports.copyPackages = copyPackages; -exports.dev = devTask; -exports.build = build; -exports.watch = dev.watch; -exports.default = buildMedium; diff --git a/tools/bundle-builder/lib/depUtils.js b/tools/bundle-builder/lib/depUtils.js deleted file mode 100644 index 55cc417aec6..00000000000 --- a/tools/bundle-builder/lib/depUtils.js +++ /dev/null @@ -1,114 +0,0 @@ -/*! -Copyright 2023 Adobe. All rights reserved. -This file is licensed to you under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. You may obtain a copy -of the License at http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software distributed under -the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS -OF ANY KIND, either express or implied. See the License for the specific language -governing permissions and limitations under the License. -*/ - -const fsp = require("fs").promises; -const path = require("path"); -const depSolver = require("dependency-solver"); - -/** - * Given a package path, get its dependencies - * @param {string} packages - package directory - * @return {Object} An object mapping the package name to its dependencies, or null if no dependencies - */ -async function getDependencies(package) { - const { - name, - peerDependencies = {}, - dependencies = {}, - devDependencies = {} - } = await fsp.readFile(path.join(package, "package.json")).then(JSON.parse); - - return { - name, - dependencies: [...new Set([ - ...Object.keys(peerDependencies), - ...Object.keys(dependencies), - ...Object.keys(devDependencies), - ])].filter((dep) => ( - dep.indexOf("@spectrum-css") === 0 && - dep !== "@spectrum-css/bundle-builder" && - dep !== "@spectrum-css/component-builder" && - dep !== "@spectrum-css/component-builder-simple" - )) - }; -} - -/** - * Given a list of package paths, solve the dependency order - * @param {string[]} packages - package directories - * @return {string[]} The solved dependency order - */ -async function solveDependencies(packages) { - async function getDependenciesForSolver(package) { - let { name, dependencies } = await getDependencies(package); - - if (dependencies.length === 0) { - return null; - } - - return { [name]: dependencies }; - } - - let depArray = ( - await Promise.all(packages.map(getDependenciesForSolver)) - ).filter(Boolean); - - let dependencies = {}; - depArray.forEach((dep) => { - Object.assign(dependencies, dep); - }); - - return depSolver.solve(dependencies); -} - -/** - * Get the list of all packages in given directory - * @param {string} packageDir - package directory - * @return {Object} An array of package names in dependency order - */ -async function getPackageDependencyOrder(packageDir) { - const { dependencies } = await getDependencies(packageDir); - return solveDependencies( - dependencies.map((dep) => - path.dirname(require.resolve(path.join(dep, "package.json"))) - ) - ); -} - -/** - * Get the list of all packages in given directory - * @param {string} packagesDir - directory of packages - * @return {Object} An array of package names in dependency order - */ -async function getFolderDependencyOrder(packagesDir) { - // Get list of all packages - let packages = (await fsp.readdir(packagesDir, { withFileTypes: true })) - .filter((dirent) => dirent.isDirectory() || dirent.isSymbolicLink()) - .map((dirent) => path.join(packagesDir, dirent.name)); - - let solution = await solveDependencies(packages); - - // Nobody relies on it, so it gets clipped, weird - solution.push("@spectrum-css/expressvars"); - - // Build tokens first - // This is because not every package relies on tokens, but the builder needs tokens to bake vars - solution = solution.filter((p) => p !== "@spectrum-css/tokens"); - solution.unshift("@spectrum-css/tokens"); - - return solution; -} - -exports.getDependencies = getDependencies; -exports.solveDependencies = solveDependencies; -exports.getFolderDependencyOrder = getFolderDependencyOrder; -exports.getPackageDependencyOrder = getPackageDependencyOrder; diff --git a/tools/bundle-builder/lib/dirs.js b/tools/bundle-builder/lib/dirs.js deleted file mode 100644 index dac02646a4c..00000000000 --- a/tools/bundle-builder/lib/dirs.js +++ /dev/null @@ -1,47 +0,0 @@ -/*! -Copyright 2023 Adobe. All rights reserved. -This file is licensed to you under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. You may obtain a copy -of the License at http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software distributed under -the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS -OF ANY KIND, either express or implied. See the License for the specific language -governing permissions and limitations under the License. -*/ - -const path = require("path"); - -exports.builder = path.resolve(__dirname, ".."); -exports.siteResources = path.resolve( - __dirname, - "..", - "node_modules", - "@spectrum-css", - "site" -); -exports.topLevel = path.resolve(exports.builder, "..", ".."); -exports.isTopLevel = process.cwd() === exports.topLevel; -exports.site = path.resolve(exports.topLevel, "site"); - -if (exports.isTopLevel) { - exports.components = path.join(exports.topLevel, "components"); -} else { - exports.components = path.join( - process.cwd(), - "node_modules", - "@spectrum-css" - ); -} - -exports.resolve = function (component) { - if (exports.isTopLevel) { - return path.join(exports.components, component.split("/").pop()); - } - - return path.dirname( - require.resolve(component, { - paths: [path.join(process.cwd(), "node_modules")], - }) - ); -}; diff --git a/tools/bundle-builder/lib/exec.js b/tools/bundle-builder/lib/exec.js deleted file mode 100644 index f1efc648060..00000000000 --- a/tools/bundle-builder/lib/exec.js +++ /dev/null @@ -1,52 +0,0 @@ -/*! -Copyright 2023 Adobe. All rights reserved. -This file is licensed to you under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. You may obtain a copy -of the License at http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software distributed under -the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS -OF ANY KIND, either express or implied. See the License for the specific language -governing permissions and limitations under the License. -*/ - -const cp = require("child_process"); - -function task(taskName, command) { - var func = function (cb) { - runCommand(command, cb); - }; - - Object.defineProperty(func, "name", { value: taskName, writable: false }); - - return func; -} - -function promise(command, options) { - return new Promise((resolve, reject) => { - runCommand( - command, - (err, stdout, stderr) => { - if (err) { - reject(err); - } else { - resolve(stdout); - } - }, - options - ); - }); -} - -function runCommand(command, cb, options = {}) { - let commandProcess = cp.exec(command, cb); - if (options.pipe !== false) { - commandProcess.stdout.pipe(process.stdout); - commandProcess.stderr.pipe(process.stderr); - } - return commandProcess; -} - -exports.promise = promise; -exports.command = runCommand; -exports.task = task; diff --git a/tools/bundle-builder/package.json b/tools/bundle-builder/package.json deleted file mode 100644 index f020e24dbea..00000000000 --- a/tools/bundle-builder/package.json +++ /dev/null @@ -1,50 +0,0 @@ -{ - "name": "@spectrum-css/bundle-builder", - "version": "6.2.0", - "description": "The Spectrum CSS top-level builder", - "license": "Apache-2.0", - "author": "Adobe", - "repository": { - "type": "git", - "url": "https://github.com/adobe/spectrum-css.git", - "directory": "tools/bundle-builder" - }, - "bugs": { - "url": "https://github.com/adobe/spectrum-css/issues" - }, - "dependencies": { - "@adobe/spectrum-css-workflow-icons": "^1.5.4", - "@spectrum-css/expressvars": "^3.0.9", - "@spectrum-css/tokens": "^13.0.9", - "@spectrum-css/ui-icons": "^1.1.1", - "@spectrum-css/vars": "^9.0.8", - "npm-registry-fetch": "^14.0.5" - }, - "peerDependencies": { - "@spectrum-css/expressvars": ">=3", - "@spectrum-css/tokens": ">=13", - "@spectrum-css/vars": ">=9" - }, - "peerDependenciesMeta": { - "@spectrum-css/expressvars": { - "optional": true - } - }, - "devDependencies": { - "browser-sync": "^2.26.14", - "colors": "^1.4.0", - "dependency-solver": "^1.0.6", - "gulp": "^4.0.0", - "gulp-concat": "^2.6.1", - "gulp-conventional-changelog": "^2.0.19", - "gulp-pug": "^4.0.1", - "gulp-rename": "^1.4.0", - "gulplog": "^1.0.0", - "inquirer": "^9.2.10", - "js-yaml": "^4.1.0", - "loadicons": "^1.0.0", - "replace-ext": "^1.0.0", - "semver": "^7.5.1", - "through2": "^3.0.1" - } -} diff --git a/tools/bundle-builder/subrunner/index.js b/tools/bundle-builder/subrunner/index.js deleted file mode 100644 index 628cdae3805..00000000000 --- a/tools/bundle-builder/subrunner/index.js +++ /dev/null @@ -1,136 +0,0 @@ -/*! -Copyright 2023 Adobe. All rights reserved. -This file is licensed to you under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. You may obtain a copy -of the License at http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software distributed under -the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS -OF ANY KIND, either express or implied. See the License for the specific language -governing permissions and limitations under the License. -*/ - -const fs = require("fs"); -const path = require("path"); - -const colors = require("colors"); -const logger = require("gulplog"); -const dirs = require("../lib/dirs"); -const depUtils = require("../lib/depUtils"); - -function chdir(dir) { - process.chdir(dir); - logger.debug(`Working directory changed to ${dir.magenta}`); -} - -/* - Run the specified gulp task for the given package -*/ -function runComponentTask(packageDir, task, callback) { - // Drop org - packageName = packageDir.split("/").pop(); - - var gulpfile = path.join(packageDir, "gulpfile.js"); - - if (!fs.existsSync(gulpfile)) { - logger.warn(`No gulpfile found for ${packageName.yellow}`); - callback(); - return; - } - - let cwd = process.cwd(); - - chdir(packageDir); - - var tasks = require(gulpfile); - - if (tasks[task]) { - logger.warn(`Starting '${packageName.yellow}:${task.yellow}'...`); - - tasks[task](function (err) { - chdir(cwd); - - if (err) { - logger.error( - `Error running '${packageName.yellow}:${task.yellow}': ${err}` - ); - - callback(err); - } else { - logger.warn(`Finished '${packageName.yellow}:${task.yellow}'`); - - callback(); - } - }); - } else { - var err = new Error( - `Task '${packageName.yellow}:${task.yellow}' not found!` - ); - logger.error(err); - - chdir(cwd); - - callback(err); - } -} - -/* - Run a task on every component in dependency order -*/ -async function runTaskOnAllComponents(task) { - const components = await depUtils - .getFolderDependencyOrder(dirs.components) - .then((result) => - // Turn the package names into a path to the component directory - result.map((component) => path.dirname(require.resolve(`${component}/package.json`))) - ) - .catch(console.error); - - return runTaskOnPackages(task, components); -} - -/* - Run a task on every package -*/ -function runTaskOnPackages(task, packages) { - return new Promise(async (resolve, reject) => { - let packageCount = packages.length; - - function getNextPackage() { - return packages.shift(); - } - - function processPackage() { - var packageDir = getNextPackage(); - - if (packageDir) { - runComponentTask(packageDir, task, function (err) { - if (err) { - if (!process.env.FORCE) { - process.exit(1); - } - } - processPackage(); - }); - } else { - logger.warn(`${task} ran on ${packageCount} packages!`.bold.green); - resolve(); - } - } - - // Kick off a gulp build for each package - processPackage(); - }); -} - -/* - Build all components -*/ -function buildComponents() { - return runTaskOnAllComponents("build"); -} - -exports.buildComponents = buildComponents; -exports.runComponentTask = runComponentTask; -exports.runTaskOnPackages = runTaskOnPackages; -exports.runTaskOnAllComponents = runTaskOnAllComponents; diff --git a/tools/bundle-builder/vars/index.js b/tools/bundle-builder/vars/index.js deleted file mode 100644 index f7e47437dc4..00000000000 --- a/tools/bundle-builder/vars/index.js +++ /dev/null @@ -1,200 +0,0 @@ -const gulp = require("gulp"); -const path = require("path"); -const rename = require("gulp-rename"); -const concat = require("gulp-concat"); -const through = require("through2"); -const postcss = require("postcss"); - -const dirs = require("../lib/dirs.js"); - -const destination = path.join(__dirname, "../../../dist"); - -const varDir = path.dirname(require.resolve("@spectrum-css/vars/package.json", { - paths: [process.cwd(), path.join(process.cwd(), "../../")] -})); -const expressVarDir = path.dirname(require.resolve("@spectrum-css/expressvars/package.json", { - paths: [process.cwd(), path.join(process.cwd(), "../../")] -})); -const coreTokensDir = path.dirname(require.resolve("@spectrum-css/tokens/package.json", { - paths: [process.cwd(), path.join(process.cwd(), "../../")] -})) ?? path.dirname(dirs.components, "tokens"); - -// Uhg share this with component-builder -function getVarsFromCSS(css) { - let variableList = {}; - let root = postcss.parse(css); - - root.walkRules((rule) => { - rule.walkDecls((decl) => { - let matches = decl.value.match(/--[\w-]+/g); - if (matches) { - matches.forEach(function (match) { - variableList[match] = true; - }); - } - }); - }); - - return variableList; -} - -function getVarValues(css) { - let root = postcss.parse(css); - let variables = {}; - - root.walkRules((rule) => { - rule.walkDecls((decl) => { - variables[decl.prop] = decl.value; - }); - }); - - return variables; -} - -function getAllVars() { - return new Promise((resolve, reject) => { - let variableList; - - gulp - .src([ - `${varDir}/css/themes/*.css`, - `${varDir}/css/scales/*.css`, - `${varDir}/css/components/*.css`, - `${varDir}/css/globals/*.css`, - `${coreTokensDir}/dist/index.css`, - ]) - .pipe(concat("everything.css")) - .pipe( - through.obj(function getAllVars(file, enc, cb) { - variableList = getVarValues(file.contents.toString()); - - cb(null, file); - }) - ) - .on("finish", () => { - resolve(variableList); - }) - .on("error", reject); - }); -} - -function resolveValue(value, vars) { - if (value) { - let match = value.match(/var\((.+),?.*?\)/); - if (match) { - return match[1]; - } - return value; - } -} - -function getUsedVars() { - return new Promise(async (resolve, reject) => { - let variableArray; - let variableObject; - - let allVars = await getAllVars(); - - gulp - .src(`${dirs.components}/*/dist/index-vars.css`) - .pipe(concat("everything.css")) - .pipe( - through.obj(function getUsedVars(file, enc, cb) { - variableObject = getVarsFromCSS(file.contents.toString()); - - // Resolve each variable to ensure everything it references is available - for (let varName in variableObject) { - let reffedVar = allVars[varName]; - if (reffedVar && reffedVar.startsWith("var")) { - let value = resolveValue(reffedVar); - let curVarName = value; - while (allVars[curVarName]) { - if (!variableObject[curVarName]) { - variableObject[curVarName] = true; - } - curVarName = allVars[curVarName]; - } - } - } - - variableArray = Object.keys(variableObject); - - cb(null, file); - }) - ) - .on("finish", () => { - resolve(variableArray); - }) - .on("error", reject); - }); -} - -function buildUnique() { - return new Promise(async (resolve, reject) => { - // Read in all variables from components - let variableList = await getUsedVars(); - - // For each stop and scale, filter by used variables only - gulp - .src([ - path.join(varDir, "dist/*.css"), - "!" + path.join(varDir, "dist/index.css") - ], { - allowEmpty: true - }) - .pipe( - through.obj(function makeUnique(file, enc, cb) { - let css = file.contents.toString(); - let root = postcss.parse(css); - - root.walkRules((rule) => { - rule.walkDecls((decl) => { - if (variableList.indexOf(decl.prop) === -1) { - decl.remove(); - } - }); - }); - - file.contents = Buffer.from(root.toString()); - - // For each line variable, delete it if its not included - cb(null, file); - }) - ) - .pipe( - rename((file) => { - file.basename += "-unique"; - }) - ) - .pipe(gulp.dest(`${destination}/dependencies/@spectrum-css/vars/`)) - .on("finish", resolve) - .on("error", reject); - }); -} - -function copyVars() { - return gulp - .src(path.join(varDir, "dist/spectrum-*.css")) - .pipe(gulp.dest(`${destination}/dependencies/@spectrum-css/vars/`)); -} - -function copyExpressVars() { - return gulp - .src(path.join(expressVarDir, "dist/spectrum-*.css")) - .pipe(gulp.dest(`${destination}/dependencies/@spectrum-css/expressvars/`)); -} - -function copyCoreTokens() { - return gulp - .src(path.join(coreTokensDir, "dist/**/*.css")) - .pipe(gulp.dest(`${destination}/tokens/`)); -} - -exports.buildUnique = buildUnique; - -exports.copyVars = gulp.parallel( - buildUnique, - copyVars, - copyExpressVars, - copyCoreTokens -); diff --git a/tools/component-builder-simple/css/index.js b/tools/component-builder-simple/css/index.js deleted file mode 100644 index c01faa1a0bc..00000000000 --- a/tools/component-builder-simple/css/index.js +++ /dev/null @@ -1,161 +0,0 @@ -/*! -Copyright 2023 Adobe. All rights reserved. -This file is licensed to you under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. You may obtain a copy -of the License at http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software distributed under -the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS -OF ANY KIND, either express or implied. See the License for the specific language -governing permissions and limitations under the License. -*/ - -const path = require("path"); - -const gulp = require("gulp"); -const postcss = require("gulp-postcss"); -const concat = require("gulp-concat"); -const rename = require("gulp-rename"); - -const postcssrc = require("postcss-load-config"); - -async function buildCSS() { - const processors = await postcssrc({ - cwd: process.cwd(), - env: process.env.NODE_ENV || "development", - from: "index.css", - to: "dist/index.css", - }, path.join(__dirname, "..")).then((result) => result.plugins); - - return gulp - .src([ - "index.css", - "themes/spectrum.css", // spectrum comes first - "themes/*.css", - ], { - allowEmpty: true, - }) - .pipe(concat("index.css")) - .pipe( - postcss(processors, { - from: "./index.css", // gulp-concat sets the file.path wrong, so override here - }) - ) - .pipe(gulp.dest("dist/")); -} - -async function buildCSSWithoutThemes() { - const processors = await postcssrc({ - cwd: process.cwd(), - env: process.env.NODE_ENV || "development", - from: "index.css", - to: "dist/index-base.css", - checkUnused: false, - splitinatorOptions: { - noFlatVariables: true, - }, - }, path.join(__dirname, "..")).then((result) => result.plugins); - - return gulp - .src([ - "index.css", - "themes/spectrum.css", // spectrum comes first - "themes/*.css", - ], { - allowEmpty: true, - }) - .pipe(concat("index-base.css")) - .pipe(postcss(processors)) - .pipe(gulp.dest("dist/")); -} - -async function buildCSSThemeIndex() { - const processors = await postcssrc({ - cwd: process.cwd(), - env: process.env.NODE_ENV || "development", - from: "themes/spectrum.css", - to: "dist/index-theme.css", - checkUnused: false, - splitinatorOptions: { - noSelectors: true, - }, - }, path.join(__dirname, "..")).then((result) => result.plugins); - - return gulp - .src([ - "themes/spectrum.css", // spectrum comes first - "themes/*.css", - ], { - allowEmpty: true, - }) - .pipe(concat("index-theme.css")) - .pipe(postcss(processors)) - .pipe(gulp.dest("dist/")); -} - -async function buildCSSThemes() { - const processors = await postcssrc({ - cwd: process.cwd(), - env: process.env.NODE_ENV || "development", - from: "themes/spectrum.css", - to: "dist/themes/spectrum.css", - checkUnused: false, - splitinatorOptions: { - noSelectors: true, - }, - }, path.join(__dirname, "..")).then((result) => result.plugins); - - return gulp - .src([ - "themes/*.css", - "!themes/express.css", - ], { - allowEmpty: true, - }) - .pipe(postcss(processors)) - .pipe(gulp.dest("dist/themes/")); -} - -/** - Special case for express: it needs Spectrum base vars and needs to override them -*/ -async function buildExpressTheme() { - const processors = await postcssrc({ - cwd: process.cwd(), - env: process.env.NODE_ENV || "development", - from: "themes/express.css", - to: "dist/themes/express.css", - checkUnused: false, - additionalPlugins: [ - require("postcss-combininator") - ], - }, path.join(__dirname, "..")).then((result) => result.plugins); - - return gulp - .src(["dist/index-theme.css"], { - allowEmpty: true, - }) - .pipe(concat("express.css")) - .pipe(postcss(processors)) - .pipe(gulp.dest("dist/themes/")); -} - -function copyIndex() { - // Just copy index.css as index-vars.css to maintain backwards compat - return gulp - .src(["dist/index.css"], { - allowEmpty: true, - }) - .pipe( - rename((file) => { - file.basename = "index-vars"; - }) - ) - .pipe(gulp.dest("dist/")); -} - -module.exports = gulp.parallel( - gulp.series(buildCSS, copyIndex), - buildCSSWithoutThemes, - gulp.series(buildCSSThemes, buildCSSThemeIndex, buildExpressTheme) -); diff --git a/tools/component-builder-simple/index.js b/tools/component-builder-simple/index.js index aff07cdef45..bcbbf634124 100644 --- a/tools/component-builder-simple/index.js +++ b/tools/component-builder-simple/index.js @@ -10,11 +10,290 @@ OF ANY KIND, either express or implied. See the License for the specific languag governing permissions and limitations under the License. */ -const build = require("./css"); - -exports.default = build; -exports.build = build; -exports.buildLite = build; -exports.buildMedium = build; -exports.buildHeavy = build; -exports.buildCSS = build; +const fs = require("fs"); +const fsp = fs.promises; +const path = require("path"); + +const fg = require("fast-glob"); +const postcss = require("postcss"); +const postcssrc = require("postcss-load-config"); + +require("colors"); + +/** + * A source of truth for commonly used directories + * @type {object} dirs + * @property {string} dirs.root + * @property {string} dirs.components + * @property {string} dirs.site + * @property {string} dirs.publish + */ +const dirs = { + root: path.join(__dirname, "../.."), + components: path.join(__dirname, "../../components"), + site: path.join(__dirname, "../../site"), + publish: path.join(__dirname, "../../dist"), +}; + +/** @type {(string) => string} */ +const relativePrint = (filename, { cwd = dirs.root }) => path.relative(cwd, filename); + +/** + * Copy static assets to the publish directory + * @param {string} content + * @param {string} input + * @param {string} output + * @param {object} options + * @param {string} [options.cwd] + * @param {boolean} [options.clean=false] + * @returns {Promise<(string|void)[]>} Returns either the CSS content or void + */ +async function processCSS(content, input, output, { + cwd, + clean = false, + ...postCSSOptions +} = {}) { + if (!content) return Promise.reject(new Error(`This function requires content be provided`)); + + const { plugins, options } = await postcssrc( + { + cwd, + env: process.env.NODE_ENV ?? "development", + from: input, + to: output, + ...postCSSOptions, + }, + __dirname // This is the path to the directory where the postcss.config.js lives + ); + + const result = await postcss(plugins).process(content, options); + + if (result.error) return Promise.reject(result.error); + + if (result.warnings().length) { + result.warnings().forEach((warning) => { + console.log(`${`⚠`.yellow} ${warning}`); + }); + } + + if (!result.css) return Promise.reject(new Error(`No CSS was generated from the provided content for ${relativePrint(input, { cwd })}`)); + + if (!fs.existsSync(path.dirname(output))) { + await fsp.mkdir(path.dirname(output), { recursive: true }).catch((err) => { + if (!err) return; + // @todo pretty print these are relative paths + console.log(`${"✗".red} problem making the ${relativePrint(path.dirname(output), { cwd }).yellow} directory`); + return Promise.reject(err); + }); + } + + if (clean && fs.existsSync(output)) await fsp.unlink(output); + + const promises = [ + fsp.writeFile(output, result.css).then(() => { + console.log(`${"✓".green} ${relativePrint(output, { cwd }).yellow}`); + return result.css; + }).catch((err) => { + if (!err) return; + console.log(`${"✗".red} ${relativePrint(output, { cwd }).yellow} could not be written`); + return Promise.reject(err); + }) + ]; + + if (result.map) { + promises.push( + fsp.writeFile(`${output}.map`, result.map).then(() => { + console.log(`${"✓".green} ${relativePrint(`${output}.map`, { cwd }).yellow}`); + }).catch((err) => { + if (!err) return; + console.log(`${"✗".red} ${relativePrint(`${output}.map`, { cwd }).yellow} could not be written`); + return Promise.reject(err); + }) + ); + } + + return Promise.all(promises); +} + +/** + * Copy static assets to the publish directory + * @param {(string|RegExp)[]} globs + * @param {object} options + * @param {string} [options.cwd] + * @param {string} outputDir + * @returns {Promise<{ content: string, input: string }[]>} + */ +async function fetchContent(globs = [], { + cwd, + shouldCombine = false, + ...fastGlobOptions +} = {}) { + const files = await fg(globs, { + allowEmpty: true, + onlyFiles: true, + ...fastGlobOptions, + cwd, + }); + + if (!files.length) return Promise.resolve([]); + + const fileData = await Promise.all( + files.map(async (file) => ({ + input: path.join(cwd, file), + content: await fsp.readFile(path.join(cwd, file), "utf8") + })) + ); + + // Combine the content into 1 file; @todo do this in future using CSS imports + if (shouldCombine) { + let content = ""; + fileData.forEach(dataset => { + if (dataset.content) content += '\n\n' + dataset.content; + }); + + return Promise.resolve([{ + content, + input: fileData[0].input + }]); + } + + return Promise.all( + files.map(async (file) => ({ + content: await fsp.readFile(path.join(cwd, file), "utf8"), + input: path.join(cwd, file), + })) + ); +} + +async function build({ cwd, clean = false } = {}) { + // This fetches the content of the files and returns an array of objects with the content and input paths + const contentData = await fetchContent(["index.css", "themes/spectrum.css", "themes/*.css"], { + cwd, + shouldCombine: true, + clean, + }); + + return Promise.all( + contentData.map(async ({ content, input }) => { + return Promise.all([ + // This was buildCSS + processCSS(content, input, path.join(cwd, "dist/index.css"), { cwd, clean }).then(async () => { + // Copy index.css to index-vars.css for backwards compat + if (clean && fs.existsSync(path.join(cwd, "dist/index-vars.css"))) { + await fsp.unlink(path.join(cwd, "dist/index-vars.css")); + } + + return fsp.copyFile(path.join(cwd, "dist/index.css"), path.join(cwd, "dist/index-vars.css")).then(() => { + console.log(`${"✓".green} ${"dist/index-vars.css".yellow} (${"deprecated".gray})`); + }).catch((err) => { + if (!err) return; + console.log(`${"✗".red} ${"dist/index.css".gray} could not be copied to ${"dist/index-vars.css".yellow}`); + return Promise.reject(err); + }); + }), + // This was buildCSSWithoutThemes + processCSS(content, input, path.join(cwd, "dist/index-base.css"), { + cwd, + clean, + checkUnused: false, + splitinatorOptions: { + noFlatVariables: true, + }, + }), + ]); + }) + ); +} + +async function buildThemes({ cwd, clean = false } = {}) { + // This fetches the content of the files and returns an array of objects with the content and input paths + const contentData = await fetchContent([ + "themes/*.css", + ], { + cwd, + shouldCombine: false, + clean, + ignore: ["themes/express.css"], + }); + + return Promise.all( + contentData.map(async ({ content, input }) => + processCSS(content, input, path.join(cwd, "dist/themes", path.basename(input)), { + cwd, + clean, + checkUnused: false, + splitinatorOptions: { + noSelectors: true, + }, + }) + ) + ); +} + +async function buildThemeIndex({ cwd, clean = false } = {}) { + // This fetches the content of the files and returns an array of objects with the content and input paths + const contentData = await fetchContent([ + "themes/spectrum.css", // spectrum comes first + "themes/*.css", + ], { + cwd, + shouldCombine: true, + clean, + }); + + return Promise.all( + contentData.map(async ({ content, input }) => + processCSS(content, input, path.join(cwd, "dist/index-theme.css"), { + cwd, + clean, + checkUnused: false, + splitinatorOptions: { + noSelectors: true, + }, + }).then((results) => + Promise.all( + results.filter(Boolean).map((result) => { + // was buildExpressTheme + return processCSS(result, path.join(cwd, "dist/index-theme.css"), path.join(cwd, "dist/themes/express.css"), { + cwd, + clean, + checkUnused: false, + additionalPlugins: [ + require("postcss-combininator") + ], + }); + }) + ) + ) + ) + ); +} + +async function main({ clean = false } = {}) { + const componentName = process.env.NX_TASK_TARGET_PROJECT; + const cwd = path.join(dirs.components, componentName); + + console.time(`[build] ${`@spectrum-css/${componentName}`.cyan}`); + console.log(`[build] 🔨 ${`@spectrum-css/${componentName}`.cyan}`); + console.log(`${"".padStart(30, "-")}`); + + return Promise.all([ + build({ cwd, clean }), + buildThemes({ cwd, clean }), + buildThemeIndex({ cwd, clean }), + ]).then(() => { + console.log(`${"".padStart(30, "-")}`); + console.timeEnd(`[build] ${`@spectrum-css/${componentName}`.cyan}`); + }).catch((err) => { + console.trace(err); + console.log(`${"".padStart(30, "-")}`); + console.timeEnd(`[build] ${`@spectrum-css/${componentName}`.cyan}`); + process.exit(1); + }); +}; + +// main(); + +exports.processCSS = processCSS; +exports.fetchContent = fetchContent; +exports.default = main; diff --git a/tools/component-builder-simple/package.json b/tools/component-builder-simple/package.json index 01fa751d4eb..48992fce4ed 100644 --- a/tools/component-builder-simple/package.json +++ b/tools/component-builder-simple/package.json @@ -1,46 +1,40 @@ { - "name": "@spectrum-css/component-builder-simple", - "version": "4.1.0", - "description": "The Spectrum CSS simple component builder", - "license": "Apache-2.0", - "repository": { - "type": "git", - "url": "https://github.com/adobe/spectrum-css.git", - "directory": "tools/component-builder" - }, - "bugs": { - "url": "https://github.com/adobe/spectrum-css/issues" - }, - "main": "index.js", - "dependencies": { - "@spectrum-css/tokens": "^13.0.9", - "at-rule-packer": "^0.4.2", - "autoprefixer": "^10.4.17", - "fast-glob": "^3.3.2", - "gulp": "^4.0.0", - "gulp-concat": "^2.6.1", - "gulp-postcss": "^9.1.0", - "gulp-rename": "^1.4.0", - "postcss": "^8.4.33", - "postcss-calc": "^9.0.1", - "postcss-combininator": "^2.0.0", - "postcss-custom-properties-passthrough": "^2.0.0", - "postcss-discard-comments": "^6.0.1", - "postcss-discard-empty": "^6.0.1", - "postcss-dropdupedvars": "^2.0.0", - "postcss-dropunusedvars": "^2.0.0", - "postcss-extend": "^1.0.5", - "postcss-hover-media-feature": "1.0.2", - "postcss-import": "^16.0.0", - "postcss-load-config": "^5.0.2", - "postcss-nested": "^6.0.1", - "postcss-splitinator": "^2.0.0", - "postcss-varsonly": "^2.0.0" - }, - "peerDependencies": { - "@spectrum-css/tokens": ">=13" - }, - "publishConfig": { - "access": "public" - } + "name": "@spectrum-css/component-builder-simple", + "version": "4.1.0", + "description": "The Spectrum CSS simple component builder", + "license": "Apache-2.0", + "repository": { + "type": "git", + "url": "https://github.com/adobe/spectrum-css.git", + "directory": "tools/component-builder" + }, + "bugs": { + "url": "https://github.com/adobe/spectrum-css/issues" + }, + "main": "index.js", + "dependencies": { + "@spectrum-css/tokens": "^13.0.9", + "autoprefixer": "^10.4.17", + "fast-glob": "^3.3.2", + "postcss": "^8.4.33", + "postcss-calc": "^9.0.1", + "postcss-combininator": "^2.0.0", + "postcss-custom-properties-passthrough": "^2.0.0", + "postcss-discard-comments": "^6.0.1", + "postcss-discard-empty": "^6.0.1", + "postcss-dropdupedvars": "^2.0.0", + "postcss-dropunusedvars": "^2.0.0", + "postcss-extend": "^1.0.5", + "postcss-import": "^16.0.0", + "postcss-load-config": "^5.0.2", + "postcss-nested": "^6.0.1", + "postcss-splitinator": "^2.0.0", + "postcss-varsonly": "^2.0.0" + }, + "peerDependencies": { + "@spectrum-css/tokens": ">=13" + }, + "publishConfig": { + "access": "public" + } } diff --git a/tools/component-builder/css/index.js b/tools/component-builder/css/index.js deleted file mode 100644 index 79a3ea44b06..00000000000 --- a/tools/component-builder/css/index.js +++ /dev/null @@ -1,218 +0,0 @@ -/*! -Copyright 2023 Adobe. All rights reserved. -This file is licensed to you under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. You may obtain a copy -of the License at http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software distributed under -the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS -OF ANY KIND, either express or implied. See the License for the specific language -governing permissions and limitations under the License. -*/ - -const fsp = require("fs").promises; -const path = require("path"); - -const fg = require("fast-glob"); - -const gulp = require("gulp"); -const concat = require("gulp-concat"); -const rename = require("gulp-rename"); -const through = require("through2"); - -const postcss = require("postcss"); -const postcssrc = require("postcss-load-config"); - -const varDir = path.join( - path.dirname( - require.resolve("@spectrum-css/vars", { - paths: [process.cwd(), path.join(process.cwd(), "../../")], - }) - ), - ".." -); - -const coreTokensFile = require.resolve("@spectrum-css/tokens", { - paths: [process.cwd(), path.join(process.cwd(), "../../")], -}); - -function getVarsFromCSS(css) { - const variableList = new Set(); - - postcss.parse(css).walkRules((rule) => { - rule.walkDecls((decl) => { - const matches = decl.value.match(/var\(.*?\)/g); - if (!matches) return; - - matches.forEach((match) => { - variableList.add( - match.replace(/var\((--[\w\-]+),?.*?\)/, "$1").trim() - ); - }); - }); - }); - - return [...variableList]; -} - -function getVarsDefinedInCSS(css) { - let variableList = []; - let root = postcss.parse(css); - - root.walkRules((rule, ruleIndex) => { - rule.walkDecls((decl) => { - if (decl.prop.startsWith("--")) { - let varName = decl.prop; - if (variableList.indexOf(varName) === -1) { - variableList.push(varName); - } - } - }); - }); - return variableList; -} - -function getClassNames(contents, pkgName) { - if (pkgName === "page") return []; - - const classNames = new Set(); - - postcss.parse(contents).walkRules((rule) => { - if (rule.type !== "rule") return; - - rule.selectors.forEach((fullSelector) => { - // Skip compound selectors, they may not start with the component itself - if (fullSelector.match(/~|\+/)) return true; - - const selector = fullSelector.split(" ").shift(); - - const matches = selector.match(/^\.spectrum-[\w]+/); - if (!matches || !matches[0]) return; - - classNames.add(matches[0]); - }); - }); - - return [...classNames]; -} - -function getVariableDeclarations(classNames = [], vars = {}) { - if (!classNames.length) return ""; - - const varNames = Object.keys(vars); - if (!varNames.length) return ""; - - return ` -${classNames.map((className) => `${className}`).join(",\n")} { -${varNames.map((varName) => ` ${varName}: ${vars[varName]};`).join("\n")} -} -`; -} - -async function getAllVars(fileGlobs) { - const variableList = {}; - - const files = await fg(fileGlobs, { - allowEmpty: true, - }); - - await Promise.all( - files.map(async (file) => { - const css = await fsp.readFile(file, "utf8"); - const vars = getVarsDefinedInCSS(css); - - vars.forEach((varName) => { - variableList[varName] = true; - }); - }) - ); - - return variableList; -} - -// Read in all variables used -// Read in all vars from recent DNA -// Include definitions if they refer to a variable, static if not - -async function buildIndexVars() { - const processors = await postcssrc({ - cwd: process.cwd(), - env: process.env.NODE_ENV || "development", - from: "index.css", - to: "dist/index-vars.css", - }, path.join(__dirname, "..")).then((result) => result.plugins); - - return gulp - .src(["index.css"]) - .pipe(concat("index-vars.css")) - .pipe(require("gulp-postcss")(processors)) - .pipe(gulp.dest("dist/")); -} - -function bakeVars() { - return gulp - .src(["dist/index-vars.css"], { - allowEmpty: true, - }) - .pipe( - through.obj(async (file, _, cb) => { - const pkg = await fsp.readFile("package.json").then(JSON.parse); - const pkgName = pkg.name.split("/").pop(); - const classNames = getClassNames(file.contents, pkgName); - - // Find all custom properties used in the component - const variableList = getVarsFromCSS(file.contents); - - // Get literally all of the possible vars (even overridden vars that are different between themes/scales) - const allVars = await getAllVars([ - `${varDir}/css/themes/*.css`, - `${varDir}/css/scales/*.css`, - `${varDir}/css/components/*.css`, - `${varDir}/css/globals/*.css`, - `${varDir}/custom.css`, - coreTokensFile, - ]); - - // For each color stop and scale, filter the variables for those matching the component - const usedVars = variableList.reduce((usedVars, varName) => { - // Return if the varName is null/undefined or there is no value found in allVars - if (!varName || !allVars[varName]) return usedVars; - - // Check if the variable name matches any of the provided regular expressions - if ([/^--mod/, /^--highcontrast/, /spectrum-global/].some(regex => regex.test(varName))) { - return usedVars; - } - - usedVars[varName] = allVars[varName]; - return usedVars; - }, {}); - - const contents = getVariableDeclarations(classNames, usedVars); - const newFile = file.clone({ contents: false }); - - newFile.path = path.join(file.base, `vars.css`); - newFile.contents = Buffer.from(contents); - - cb(null, newFile); - }) - ) - .pipe(gulp.dest("dist/")); -} - -function copyIndex() { - // Just copy index.vars as index.css to maintain backwards compat - return gulp - .src(["dist/index-vars.css"], { - allowEmpty: true, - }) - .pipe( - rename((file) => { - file.basename = "index"; - }) - ) - .pipe(gulp.dest("dist/")); -} - -exports.buildIndexVars = buildIndexVars; -exports.buildVars = gulp.series(buildIndexVars, bakeVars); -exports.buildCSS = gulp.series(buildIndexVars, gulp.parallel(bakeVars, copyIndex)); diff --git a/tools/component-builder/docs/index.js b/tools/component-builder/docs/index.js deleted file mode 100644 index 638d436414b..00000000000 --- a/tools/component-builder/docs/index.js +++ /dev/null @@ -1,119 +0,0 @@ -/*! -Copyright 2023 Adobe. All rights reserved. -This file is licensed to you under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. You may obtain a copy -of the License at http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software distributed under -the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS -OF ANY KIND, either express or implied. See the License for the specific language -governing permissions and limitations under the License. -*/ - -const fsp = require("fs").promises; -const path = require("path"); - -const gulp = require("gulp"); -const data = require("gulp-data"); -const rename = require("gulp-rename"); -const through = require("through2"); - -const pug = require("pug"); -const yaml = require("js-yaml"); -const ext = require("replace-ext"); - -const sitePath = path.join(__dirname, "../../../site"); -const util = require(`${sitePath}/util`); - -async function readJSONFile(filepath) { - return JSON.parse(await fsp.readFile(filepath)); -} - -async function getDependencies(packagePath = "") { - let package = await readJSONFile(path.join(packagePath, "package.json")); - - let dependencies = []; - - if (package.devDependencies) { - dependencies = Object.keys(package.devDependencies); - - dependencies = dependencies - .filter((dep) => { - return ( - dep.indexOf("@spectrum-css") === 0 && - dep !== "@spectrum-css/bundle-builder" && - dep !== "@spectrum-css/component-builder" && - dep !== "@spectrum-css/component-builder-simple" - ); - }) - .map((dep) => dep.split("/").pop()); - } - - return dependencies; -} - -function buildDocs_html() { - return new Promise(async (resolve, reject) => { - let dependencies; - let package; - try { - package = await readJSONFile("package.json"); - dependencies = await getDependencies(); - } catch (err) { - return reject(err); - } - - let packageName = package.name.split("/").pop(); - - let dnaVars = readJSONFile( - path.join( - path.dirname(require.resolve("@spectrum-css/vars")), - "..", - "dist", - "spectrum-metadata.json" - ) - ); - - gulp - .src(["metadata.yml", "metadata/*.yml"], { allowEmpty: true }) - .pipe( - rename((file) => { - file.basename = packageName; - }) - ) - .pipe( - data(() => ({ - dependencies: dependencies, - dnaVars: dnaVars, - pkg: package, - util: util, - })) - ) - .pipe( - through.obj(function compilePug(file, enc, cb) { - let data = Object.assign( - {}, - { component: yaml.load(String(file.contents)) }, - file.data || {} - ); - - file.path = ext(file.path, ".html"); - - try { - const templatePath = `${sitePath}/templates/individualComponent.pug`; - let compiled = pug.renderFile(templatePath, data); - file.contents = Buffer.from(compiled); - } catch (e) { - return cb(e); - } - cb(null, file); - }) - ) - .pipe(gulp.dest(path.join(__dirname, "../../../dist/"))) - .on("end", resolve) - .on("error", reject); - }); -} - -exports.buildDocs = buildDocs_html; -exports.buildDocs_html = buildDocs_html; diff --git a/tools/component-builder/index.js b/tools/component-builder/index.js index 86c5ccd1a3a..8bdf4c9553a 100644 --- a/tools/component-builder/index.js +++ b/tools/component-builder/index.js @@ -10,27 +10,366 @@ OF ANY KIND, either express or implied. See the License for the specific languag governing permissions and limitations under the License. */ -const gulp = require("gulp"); +const fs = require("fs"); +const fsp = fs.promises; +const path = require("path"); -const css = require("./css"); -const docs = require("./docs"); +const fg = require("fast-glob"); +const postcss = require("postcss"); +const postcssrc = require("postcss-load-config"); -const build = gulp.parallel(css.buildVars, docs.buildDocs); +require("colors"); -const buildLite = css.buildIndexVars; +/** + * A source of truth for commonly used directories + * @type {object} dirs + * @property {string} dirs.root + * @property {string} dirs.components + * @property {string} dirs.site + * @property {string} dirs.publish + */ +const dirs = { + root: path.join(__dirname, "../.."), + components: path.join(__dirname, "../../components"), + site: path.join(__dirname, "../../site"), + publish: path.join(__dirname, "../../dist"), +}; -const buildMedium = css.buildVars; +const varDir = path.join( + path.dirname( + require.resolve("@spectrum-css/vars") + ), + ".." +); -const buildHeavy = css.buildCSS; +const coreTokensFile = require.resolve("@spectrum-css/tokens"); -exports.default = build; -exports.build = build; -exports.buildLite = buildLite; -exports.buildMedium = buildMedium; -exports.buildHeavy = buildHeavy; +/** @type {(string) => string} */ +const relativePrint = (filename, { cwd = dirs.root }) => path.relative(cwd, filename); -exports.buildCSS = css.buildCSS; -exports.buildVars = css.buildVars; +/** + * Determines the package name from a file path + * @param {string} filePath + * @returns {string} + */ +function getPackageFromPath(filePath) { + if (!filePath) return; -exports.buildDocs = docs.buildDocs; -exports.buildDocs_html = docs.buildDocs_html; + // Capture component name from a local or node_modules syntax + const componentCheck = filePath.match(/(?:components|@spectrum-css)\/(\w+)/); + + if (componentCheck && componentCheck?.[1]) return componentCheck[1]; + + // Check local root-level packages such as ui-icons & tokens + const pkgCheck = filePath.match(/\/(ui-icons|tokens)\//); + if (pkgCheck && pkgCheck?.[1]) return pkgCheck[1]; + + return; +} + +/** + * Copy static assets to the publish directory + * @param {string} content + * @param {string} input + * @param {string} output + * @param {object} options + * @param {string} [options.cwd] + * @param {boolean} [options.clean=false] + * @returns {Promise<(string|void)[]>} Returns either the CSS content or void + */ +async function processCSS(content, input, output, { + cwd, + clean = false, + ...postCSSOptions +} = {}) { + // @todo throw a warning that no content was provided + if (!content) return Promise.reject(new Error(`This function requires content be provided`)); + + const { plugins, options } = await postcssrc( + { + cwd: path.dirname(input), + env: process.env.NODE_ENV ?? "development", + from: input, + to: output, + ...postCSSOptions, + }, + __dirname // This is the path to the directory where the postcss.config.js lives + ); + + const result = await postcss(plugins).process(content, options); + + if (result.error) return Promise.reject(result.error); + + if (result.warnings().length) { + result.warnings().forEach((warning) => { + console.log(`${`⚠`.yellow} ${warning}`); + }); + } + + if (!result.css) return Promise.reject(new Error(`No CSS was generated from the provided content for ${input}`)); + + if (!fs.existsSync(path.dirname(output))) { + await fsp.mkdir(path.dirname(output), { recursive: true }).catch((err) => { + if (!err) return; + // @todo pretty print these are relative paths + console.log(`${"✗".red} problem making the ${relativePrint(path.dirname(output), { cwd }).yellow} directory`); + return Promise.reject(err); + }); + } + + if (clean && fs.existsSync(output)) await fsp.unlink(output); + + const promises = [ + fsp.writeFile(output, result.css).then(() => { + console.log(`${"✓".green} ${relativePrint(output, { cwd }).yellow}`); + return result.css; + }).catch((err) => { + if (!err) return; + console.log(`${"✗".red} ${relativePrint(output, { cwd }).yellow} could not be written`); + return Promise.reject(err); + }) + ]; + + if (result.map) { + promises.push( + fsp.writeFile(`${output}.map`, result.map).then(() => { + console.log(`${"✓".green} ${relativePrint(`${output}.map`, { cwd }).yellow}`); + }).catch((err) => { + if (!err) return; + console.log(`${"✗".red} ${relativePrint(`${output}.map`, { cwd }).yellow} could not be written`); + return Promise.reject(err); + }) + ); + } + + return Promise.all(promises); +} + +/** + * Copy static assets to the publish directory + * @param {(string|RegExp)[]} globs + * @param {object} options + * @param {string} [options.cwd] + * @param {string} outputDir + * @returns {Promise<{ content: string, input: string }[]>} + */ +async function fetchContent(globs = [], { + cwd = cwd, + shouldCombine = false, + ...fastGlobOptions +} = {}) { + const files = await fg(globs, { + allowEmpty: true, + onlyFiles: true, + ...fastGlobOptions, + cwd, + }); + + if (!files.length) return Promise.resolve([]); + + const fileData = await Promise.all( + files.map(async (file) => ({ + input: path.join(cwd, file), + content: await fsp.readFile(path.join(cwd, file), "utf8") + })) + ); + + // Combine the content into 1 file; @todo do this in future using CSS imports + if (shouldCombine) { + let content = ""; + fileData.forEach(dataset => { + if (dataset.content) content += '\n\n' + dataset.content; + }); + + return Promise.resolve([{ + content, + input: fileData[0].input + }]); + } + + return Promise.all( + files.map(async (file) => ({ + content: await fsp.readFile(path.join(cwd, file), "utf8"), + input: path.join(cwd, file), + })) + ); +} + +function getVarsFromCSS(css) { + const variableList = new Set(); + + postcss.parse(css).walkRules((rule) => { + rule.walkDecls((decl) => { + const matches = decl.value.match(/var\(.*?\)/g); + if (!matches) return; + + matches.forEach((match) => { + variableList.add( + match.replace(/var\((--[\w\-]+),?.*?\)/, "$1").trim() + ); + }); + }); + }); + + return [...variableList]; +} + +function getVarsDefinedInCSS(css) { + let variableList = []; + let root = postcss.parse(css); + + root.walkRules((rule, ruleIndex) => { + rule.walkDecls((decl) => { + if (decl.prop.startsWith("--")) { + let varName = decl.prop; + if (variableList.indexOf(varName) === -1) { + variableList.push(varName); + } + } + }); + }); + return variableList; +} + +function getClassNames(contents, pkgName) { + if (pkgName === "page") return []; + + const classNames = new Set(); + + postcss.parse(contents).walkRules((rule) => { + if (rule.type !== "rule") return; + + rule.selectors.forEach((fullSelector) => { + // Skip compound selectors, they may not start with the component itself + if (fullSelector.match(/~|\+/)) return true; + + const selector = fullSelector.split(" ").shift(); + + const matches = selector.match(/^\.spectrum-[\w]+/); + if (!matches || !matches[0]) return; + + classNames.add(matches[0]); + }); + }); + + return [...classNames]; +} + +function getVariableDeclarations(classNames = [], vars = {}) { + if (!classNames.length) return ""; + + const varNames = Object.keys(vars); + if (!varNames.length) return ""; + + return ` +${classNames.map((className) => `${className}`).join(",\n")} { +${varNames.map((varName) => ` ${varName}: ${vars[varName]};`).join("\n")} +} +`; +} + +async function getAllVars(fileGlobs) { + const variableList = {}; + + const files = await fg(fileGlobs, { + allowEmpty: true, + }); + + await Promise.all( + files.map(async (file) => { + const css = await fsp.readFile(file, "utf8"); + const vars = getVarsDefinedInCSS(css); + + vars.forEach((varName) => { + variableList[varName] = true; + }); + }) + ); + + return variableList; +} + +// Read in all variables used +// Read in all vars from recent DNA +// Include definitions if they refer to a variable, static if not +async function build({ cwd, clean = false } = {}) { + // This fetches the content of the files and returns an array of objects with the content and input paths + const contentData = await fetchContent(["index.css"], { + cwd, + clean, + allowEmpty: false, + }); + + return Promise.all( + contentData.map(async ({ content, input }) => { + // This was buildIndexVars + return processCSS(content, input, path.join(cwd, "dist/index.css"), { cwd, clean }).then(async (results) => { + // Copy index.css to index-vars.css for backwards compat + if (clean && fs.existsSync(path.join(cwd, "dist/index-vars.css"))) { + await fsp.unlink(path.join(cwd, "dist/index-vars.css")); + } + + return Promise.all([ + fsp.copyFile(path.join(cwd, "dist/index.css"), path.join(cwd, "dist/index-vars.css")).then(() => { + console.log(`${"✓".green} ${"dist/index-vars.css".yellow} (${"deprecated".gray})`); + }).catch((err) => { + if (!err) return; + console.log(`${"✗".red} ${"dist/index.css".gray} could not be copied to ${"dist/index-vars.css".yellow}`); + return Promise.reject(err); + }), + // This was bakeVars + ...results.filter(Boolean).map(async (result) => { + const classNames = getClassNames(result, getPackageFromPath(input)); + // Find all custom properties used in the component + const variableList = getVarsFromCSS(result); + + // Get literally all of the possible vars (even overridden vars that are different between themes/scales) + const allVars = await getAllVars([ + `${varDir}/css/themes/*.css`, + `${varDir}/css/scales/*.css`, + `${varDir}/css/components/*.css`, + `${varDir}/css/globals/*.css`, + `${varDir}/custom.css`, + coreTokensFile, + ]); + + // For each color stop and scale, filter the variables for those matching the component + const usedVars = variableList.reduce((usedVars, varName) => { + // Return if the varName is null/undefined or there is no value found in allVars + if (!varName || !allVars[varName]) return usedVars; + + usedVars[varName] = allVars[varName]; + return usedVars; + }, {}); + + const contents = getVariableDeclarations(classNames, usedVars); + return processCSS(contents, input, path.join(cwd, "dist/vars.css"), { cwd, clean }); + }) + ]); + }); + }) + ); +} + +async function main({ clean = false } = {}) { + const componentName = process.env.NX_TASK_TARGET_PROJECT; + const cwd = path.join(dirs.components, componentName); + + console.time(`[build] ${`@spectrum-css/${componentName}`.cyan}`); + console.log(`[build] 🔨 ${`@spectrum-css/${componentName}`.cyan} (${'legacy'.gray})`); + console.log(`${"".padStart(30, "-")}`); + + return build({ cwd, clean }).then(() => { + console.log(`${"".padStart(30, "-")}`); + console.timeEnd(`[build] ${`@spectrum-css/${componentName}`.cyan}`); + }).catch((err) => { + console.trace(err); + console.log(`${"".padStart(30, "-")}`); + console.timeEnd(`[build] ${`@spectrum-css/${componentName}`.cyan}`); + process.exit(1); + }); +}; + +main(); + +module.exports = main; diff --git a/yarn.lock b/yarn.lock index e46f32118bd..8d70cde6e84 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4354,11 +4354,6 @@ resolved "https://registry.yarnpkg.com/@types/aria-query/-/aria-query-5.0.4.tgz#1a31c3d378850d2778dabb6374d036dcba4ba708" integrity sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw== -"@types/babel-types@*", "@types/babel-types@^7.0.0": - version "7.0.14" - resolved "https://registry.yarnpkg.com/@types/babel-types/-/babel-types-7.0.14.tgz#13e9323162c2684e85d56e76ff96c22cfeeff57f" - integrity sha512-5BC5W3pCoX12SH8nC8ReAOiMBy/rd9xil3es3S6dh83Pl9i4J3ZujfWUu5mXnEwo/WLqcD5+uj9Yk115Dh0obw== - "@types/babel__core@^7.0.0": version "7.20.4" resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.20.4.tgz#26a87347e6c6f753b3668398e34496d6d9ac6ac0" @@ -4392,13 +4387,6 @@ dependencies: "@babel/types" "^7.20.7" -"@types/babylon@^6.16.2": - version "6.16.9" - resolved "https://registry.yarnpkg.com/@types/babylon/-/babylon-6.16.9.tgz#7abf03f6591a921fe3171af91433077cd2666e36" - integrity sha512-sEKyxMVEowhcr8WLfN0jJYe4gS4Z9KC2DGz0vqfC7+MXFbmvOF7jSjALC77thvAO2TLgFUPa9vDeOak+AcUrZA== - dependencies: - "@types/babel-types" "*" - "@types/body-parser@*": version "1.19.5" resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.5.tgz#04ce9a3b677dc8bd681a17da1ab9835dc9d3ede4" @@ -4474,11 +4462,6 @@ resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.5.tgz#a6ce3e556e00fd9895dd872dd172ad0d4bd687f4" integrity sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw== -"@types/expect@^1.20.4": - version "1.20.4" - resolved "https://registry.yarnpkg.com/@types/expect/-/expect-1.20.4.tgz#8288e51737bf7e3ab5d7c77bfa695883745264e5" - integrity sha512-Q5Vn3yjTDyCMV50TB6VRIbQNxSE4OmZR86VSbGaNpfUolm0iePBB4KdEEHmxoY5sT2+2DIvXW0rvMDP2nHZ4Mg== - "@types/express-serve-static-core@^4.17.33": version "4.17.41" resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.41.tgz#5077defa630c2e8d28aa9ffc2c01c157c305bef6" @@ -4681,11 +4664,6 @@ resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.10.tgz#892afc9332c4d62a5ea7e897fe48ed2085bbb08a" integrity sha512-mxSnDQxPqsZxmeShFH+uwQ4kO4gcJcGahjjMFeLbKE95IAZiiZyiEepGZjtXJ7hN/yfu0bu9xN2ajcU0JcxX6A== -"@types/pug@^2.0.4": - version "2.0.9" - resolved "https://registry.yarnpkg.com/@types/pug/-/pug-2.0.9.tgz#97e765bb8eb0b90380524583f1f10838f29822f9" - integrity sha512-Yg4LkgFYvn1faISbDNWmcAC1XoDT8IoMUFspp5mnagKk+UvD2N0IWt5A7GRdMubsNWqgCLmrkf8rXkzNqb4szA== - "@types/q@^1.5.1": version "1.5.8" resolved "https://registry.yarnpkg.com/@types/q/-/q-1.5.8.tgz#95f6c6a08f2ad868ba230ead1d2d7f7be3db3837" @@ -4792,14 +4770,6 @@ resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-9.0.7.tgz#b14cebc75455eeeb160d5fe23c2fcc0c64f724d8" integrity sha512-WUtIVRUZ9i5dYXefDEAI7sh9/O7jGvHg7Df/5O/gtH3Yabe5odI3UWopVR1qbPXQtvOxWu3mM4XxlYeZtMWF4g== -"@types/vinyl@^2.0.4": - version "2.0.10" - resolved "https://registry.yarnpkg.com/@types/vinyl/-/vinyl-2.0.10.tgz#0be9d0750816b945f66dc7b24a5dee8a7bda1574" - integrity sha512-DqN5BjCrmjAtZ1apqzcq2vk2PSW0m1nFfjIafBFkAyddmHxuw3ZAK3omLiSdpuu81+8h07i6U4DtaE38Xsf2xQ== - dependencies: - "@types/expect" "^1.20.4" - "@types/node" "*" - "@types/yargs-parser@*": version "21.0.3" resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-21.0.3.tgz#815e30b786d2e8f0dcd85fd5bcf5e1a04d008f15" @@ -5122,13 +5092,6 @@ accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.8: mime-types "~2.1.34" negotiator "0.6.3" -acorn-globals@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-3.1.0.tgz#fd8270f71fbb4996b004fa880ee5d46573a731bf" - integrity sha512-uWttZCk96+7itPxK8xCzY86PnxKTMrReKDqrHzv42VQY0K30PUO8WY13WMOuI+cOdX4EIdzdvQ8k6jkuGRFMYw== - dependencies: - acorn "^4.0.4" - acorn-import-assertions@^1.9.0: version "1.9.0" resolved "https://registry.yarnpkg.com/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz#507276249d684797c84e0734ef84860334cfb1ac" @@ -5144,16 +5107,6 @@ acorn-walk@^8.3.0: resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.3.2.tgz#7703af9415f1b6db9315d6895503862e231d34aa" integrity sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A== -acorn@^3.1.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-3.3.0.tgz#45e37fb39e8da3f25baee3ff5369e2bb5f22017a" - integrity sha512-OLUyIIZ7mF5oaAUT1w0TFqQS81q3saT46x8t7ukpPjMNk+nbs4ZHhs7ToV8EWnLYLepjETXd4XaCE4uxkMeqUw== - -acorn@^4.0.4, acorn@~4.0.2: - version "4.0.13" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-4.0.13.tgz#105495ae5361d697bd195c825192e1ad7f253787" - integrity sha512-fu2ygVGuMmlzG8ZeRJ0bvR41nsAkxxhbyk8bZ1SS521Z7vmgJFTQQlfz/Mp/nJexGBz+v8sC9bM6+lNgskt4Ug== - acorn@^7.1.1: version "7.4.1" resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" @@ -5252,15 +5205,6 @@ ajv@^8.0.0, ajv@^8.0.1, ajv@^8.11.0, ajv@^8.9.0: require-from-string "^2.0.2" uri-js "^4.2.2" -align-text@^0.1.1, align-text@^0.1.3: - version "0.1.4" - resolved "https://registry.yarnpkg.com/align-text/-/align-text-0.1.4.tgz#0cd90a561093f35d0a99256c22b7069433fad117" - integrity sha512-GrTZLRpmp6wIC2ztrWW9MjjTgSKccffgFagbNDOX95/dcjEcYZibYTeaOntySQLcdw1ztBoFkviiUvTMbb9MYg== - dependencies: - kind-of "^3.0.2" - longest "^1.0.1" - repeat-string "^1.5.2" - ansi-colors@^1.0.1: version "1.1.0" resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-1.1.0.tgz#6374b4dd5d4718ff3ce27a671a3b1cad077132a9" @@ -5874,13 +5818,6 @@ axe-core@^4.2.0: resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.8.2.tgz#2f6f3cde40935825cf4465e3c1c9e77b240ff6ae" integrity sha512-/dlp0fxyM3R8YW7MFzaHWXrf4zzbr0vaYb23VBFCl83R7nWNPg/yaQw2Dc8jzCMmDVLhSdzH8MjrsuIUuvX+6g== -axios@0.21.4: - version "0.21.4" - resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.4.tgz#c67b90dc0568e5c1cf2b0b858c43ba28e2eda575" - integrity sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg== - dependencies: - follow-redirects "^1.14.0" - axios@^1.0.0, axios@^1.5.1: version "1.6.1" resolved "https://registry.yarnpkg.com/axios/-/axios-1.6.1.tgz#76550d644bf0a2d469a01f9244db6753208397d7" @@ -5946,24 +5883,6 @@ babel-plugin-polyfill-regenerator@^0.5.4: dependencies: "@babel/helper-define-polyfill-provider" "^0.4.4" -babel-runtime@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe" - integrity sha512-ITKNuq2wKlW1fJg9sSW52eepoYgZBggvOAHC0u/CYu/qxQ9EVzThCgR69BnSXLHjy2f7SY5zaQ4yt7H9ZVxY2g== - dependencies: - core-js "^2.4.0" - regenerator-runtime "^0.11.0" - -babel-types@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.26.0.tgz#a3b073f94ab49eb6fa55cd65227a334380632497" - integrity sha512-zhe3V/26rCWsEZK8kZN+HaQj5yQ1CilTObixFzKW1UWjqG7618Twz6YEsCnjfg5gBcJh02DrpCkS9h98ZqDY+g== - dependencies: - babel-runtime "^6.26.0" - esutils "^2.0.2" - lodash "^4.17.4" - to-fast-properties "^1.0.3" - babel-walk@3.0.0-canary-5: version "3.0.0-canary-5" resolved "https://registry.yarnpkg.com/babel-walk/-/babel-walk-3.0.0-canary-5.tgz#f66ecd7298357aee44955f235a6ef54219104b11" @@ -5971,11 +5890,6 @@ babel-walk@3.0.0-canary-5: dependencies: "@babel/types" "^7.9.6" -babylon@^6.18.0: - version "6.18.0" - resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3" - integrity sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ== - bach@^1.0.0: version "1.2.0" resolved "https://registry.yarnpkg.com/bach/-/bach-1.2.0.tgz#4b3ce96bf27134f79a1b414a51c14e34c3bd9880" @@ -6079,11 +5993,6 @@ binary@^0.3.0: buffers "~0.1.1" chainsaw "~0.1.0" -binaryextensions@^2.2.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/binaryextensions/-/binaryextensions-2.3.0.tgz#1d269cbf7e6243ea886aa41453c3651ccbe13c22" - integrity sha512-nAihlQsYGyc5Bwq6+EsubvANYGExeJKHDO3RjnvwU042fawQTQfM3Kxn7IHUXQOz4bzfwsGYYHGSvXyW4zOGLg== - bindings@^1.4.0, bindings@^1.5.0: version "1.5.0" resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df" @@ -6192,19 +6101,19 @@ browser-assert@^1.2.1: resolved "https://registry.yarnpkg.com/browser-assert/-/browser-assert-1.2.1.tgz#9aaa5a2a8c74685c2ae05bfe46efd606f068c200" integrity sha512-nfulgvOR6S4gt9UKCeGJOuSGBPGiFT6oQ/2UBnvTY/5aQ1PnksW72fhZkM30DzoRRv2WpwZf1vHHEr3mtuXIWQ== -browser-sync-client@^2.29.3: - version "2.29.3" - resolved "https://registry.yarnpkg.com/browser-sync-client/-/browser-sync-client-2.29.3.tgz#9300b97f42abc2c4f95ca29b5a9781b5c492f14a" - integrity sha512-4tK5JKCl7v/3aLbmCBMzpufiYLsB1+UI+7tUXCCp5qF0AllHy/jAqYu6k7hUF3hYtlClKpxExWaR+rH+ny07wQ== +browser-sync-client@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/browser-sync-client/-/browser-sync-client-3.0.2.tgz#6fbe9a7aada25cf14c824683e089ec9ace91cfe1" + integrity sha512-tBWdfn9L0wd2Pjuz/NWHtNEKthVb1Y67vg8/qyGNtCqetNz5lkDkFnrsx5UhPNPYUO8vci50IWC/BhYaQskDiQ== dependencies: etag "1.8.1" fresh "0.5.2" mitt "^1.1.3" -browser-sync-ui@^2.29.3: - version "2.29.3" - resolved "https://registry.yarnpkg.com/browser-sync-ui/-/browser-sync-ui-2.29.3.tgz#35e2ce3b470dce6b7219307cac7278bf324a0f16" - integrity sha512-kBYOIQjU/D/3kYtUIJtj82e797Egk1FB2broqItkr3i4eF1qiHbFCG6srksu9gWhfmuM/TNG76jMfzAdxEPakg== +browser-sync-ui@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/browser-sync-ui/-/browser-sync-ui-3.0.2.tgz#8136efcff4ec8cc55084b32b91be02094194f0c4" + integrity sha512-V3FwWAI+abVbFLTyJjXJlCMBwjc3GXf/BPGfwO2fMFACWbIGW9/4SrBOFYEOOtqzCjQE0Di+U3VIb7eES4omNA== dependencies: async-each-series "0.1.1" chalk "4.1.2" @@ -6214,13 +6123,13 @@ browser-sync-ui@^2.29.3: socket.io-client "^4.4.1" stream-throttle "^0.1.3" -browser-sync@^2.26.14: - version "2.29.3" - resolved "https://registry.yarnpkg.com/browser-sync/-/browser-sync-2.29.3.tgz#c2a3ff00c659eb87a13cae9d7a427e1b4b580ee1" - integrity sha512-NiM38O6XU84+MN+gzspVmXV2fTOoe+jBqIBx3IBdhZrdeURr6ZgznJr/p+hQ+KzkKEiGH/GcC4SQFSL0jV49bg== +browser-sync@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/browser-sync/-/browser-sync-3.0.2.tgz#cc763cdbf4180193978fe16ebfc506b910225ae4" + integrity sha512-PC9c7aWJFVR4IFySrJxOqLwB9ENn3/TaXCXtAa0SzLwocLN3qMjN+IatbjvtCX92BjNXsY6YWg9Eb7F3Wy255g== dependencies: - browser-sync-client "^2.29.3" - browser-sync-ui "^2.29.3" + browser-sync-client "^3.0.2" + browser-sync-ui "^3.0.2" bs-recipes "1.3.4" chalk "4.1.2" chokidar "^3.5.1" @@ -6234,7 +6143,6 @@ browser-sync@^2.26.14: fs-extra "3.0.1" http-proxy "^1.18.1" immutable "^3" - localtunnel "^2.0.1" micromatch "^4.0.2" opn "5.3.0" portscanner "2.2.0" @@ -6489,11 +6397,6 @@ camelcase-keys@^7.0.0: quick-lru "^5.1.1" type-fest "^1.2.1" -camelcase@^1.0.2: - version "1.2.1" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-1.2.1.tgz#9bb5304d2e0b56698b2c758b08a3eaa9daa58a39" - integrity sha512-wzLkDa4K/mzI1OSITC+DUyjgIl/ETNHE9QvYgy6J6Jvqyyz4C0Xfd+lQhb19sX2jMpZV4IssUn0VDVmglV+s4g== - camelcase@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-3.0.0.tgz#32fc4b9fcdaf845fcdf7e73bb97cac2261f0ab0a" @@ -6555,14 +6458,6 @@ cbor@^9.0.1: dependencies: nofilter "^3.1.0" -center-align@^0.1.1: - version "0.1.3" - resolved "https://registry.yarnpkg.com/center-align/-/center-align-0.1.3.tgz#aa0d32629b6ee972200411cbd4461c907bc2b7ad" - integrity sha512-Baz3aNe2gd2LP2qk5U+sDk/m4oSuwSDcBfayTCTBoWpfIGO5XFxPmjILQII4NGiZjD6DoDI6kf7gKaxkf7s3VQ== - dependencies: - align-text "^0.1.3" - lazy-cache "^1.0.3" - chainsaw@~0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/chainsaw/-/chainsaw-0.1.0.tgz#5eab50b28afe58074d0d58291388828b5e5fbc98" @@ -6647,7 +6542,7 @@ character-entities@^1.0.0: resolved "https://registry.yarnpkg.com/character-entities/-/character-entities-1.2.4.tgz#e12c3939b7eaf4e5b15e7ad4c5e28e1d48c5b16b" integrity sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw== -character-parser@^2.1.1, character-parser@^2.2.0: +character-parser@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/character-parser/-/character-parser-2.2.0.tgz#c7ce28f36d4bcd9744e5ffc2c5fcde1c73261fc0" integrity sha512-+UqJQjFEFaTAs3bNsF2j2kEN1baG/zghZbdqoYEDxGZtJo9LBzl1A+m0D4n3qKx8N2FNv8/Xp6yV9mQmBuptaw== @@ -6807,13 +6702,6 @@ class-utils@^0.3.5: isobject "^3.0.0" static-extend "^0.1.1" -clean-css@^4.1.11: - version "4.2.4" - resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-4.2.4.tgz#733bf46eba4e607c6891ea57c24a989356831178" - integrity sha512-EJUDT7nDVFDvaQgAo2G/PJvxmp1o/c6iXLbswsBbUFXi1Nr+AjA2cKmfbKDMjMvzEe75g3P6JkaDDAKk96A85A== - dependencies: - source-map "~0.6.0" - clean-css@^5.2.2: version "5.3.2" resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-5.3.2.tgz#70ecc7d4d4114921f5d298349ff86a31a9975224" @@ -6885,15 +6773,6 @@ cli-width@^4.1.0: resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-4.1.0.tgz#42daac41d3c254ef38ad8ac037672130173691c5" integrity sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ== -cliui@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-2.1.0.tgz#4b475760ff80264c762c3a1719032e91c7fea0d1" - integrity sha512-GIOYRizG+TGoc7Wgc1LiOTLare95R3mzKgoln+Q/lE4ceiYH19gUpl0l0Ffq4lJDEf3FxujMe6IBfOCs7pfqNA== - dependencies: - center-align "^0.1.1" - right-align "^0.1.1" - wordwrap "0.0.2" - cliui@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/cliui/-/cliui-3.2.0.tgz#120601537a916d29940f934da3b48d585a39213d" @@ -7254,16 +7133,6 @@ constant-case@^3.0.4: tslib "^2.0.3" upper-case "^2.0.2" -constantinople@^3.0.1, constantinople@^3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/constantinople/-/constantinople-3.1.2.tgz#d45ed724f57d3d10500017a7d3a889c1381ae647" - integrity sha512-yePcBqEFhLOqSBtwYOGGS1exHo/s1xjekXiinh4itpNQGCu4KA1euPh1fg07N2wMITZXQkBz75Ntdt1ctGZouw== - dependencies: - "@types/babel-types" "^7.0.0" - "@types/babylon" "^6.16.2" - babel-types "^6.26.0" - babylon "^6.18.0" - constantinople@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/constantinople/-/constantinople-4.0.1.tgz#0def113fa0e4dc8de83331a5cf79c8b325213151" @@ -7297,14 +7166,6 @@ conventional-changelog-angular@5.0.12: compare-func "^2.0.0" q "^1.5.1" -conventional-changelog-angular@^5.0.12: - version "5.0.13" - resolved "https://registry.yarnpkg.com/conventional-changelog-angular/-/conventional-changelog-angular-5.0.13.tgz#896885d63b914a70d4934b59d2fe7bde1832b28c" - integrity sha512-i/gipMxs7s8L/QeuavPF2hLnJgH6pEZAttySB6aiQLWcX3puWDL3ACVmvBhJGxnAy52Qc15ua26BufY6KpmrVA== - dependencies: - compare-func "^2.0.0" - q "^1.5.1" - conventional-changelog-angular@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/conventional-changelog-angular/-/conventional-changelog-angular-7.0.0.tgz#5eec8edbff15aa9b1680a8dcfbd53e2d7eb2ba7a" @@ -7312,29 +7173,6 @@ conventional-changelog-angular@^7.0.0: dependencies: compare-func "^2.0.0" -conventional-changelog-atom@^2.0.8: - version "2.0.8" - resolved "https://registry.yarnpkg.com/conventional-changelog-atom/-/conventional-changelog-atom-2.0.8.tgz#a759ec61c22d1c1196925fca88fe3ae89fd7d8de" - integrity sha512-xo6v46icsFTK3bb7dY/8m2qvc8sZemRgdqLb/bjpBsH2UyOS8rKNTgcb5025Hri6IpANPApbXMg15QLb1LJpBw== - dependencies: - q "^1.5.1" - -conventional-changelog-codemirror@^2.0.8: - version "2.0.8" - resolved "https://registry.yarnpkg.com/conventional-changelog-codemirror/-/conventional-changelog-codemirror-2.0.8.tgz#398e9530f08ce34ec4640af98eeaf3022eb1f7dc" - integrity sha512-z5DAsn3uj1Vfp7po3gpt2Boc+Bdwmw2++ZHa5Ak9k0UKsYAO5mH1UBTN0qSCuJZREIhX6WU4E1p3IW2oRCNzQw== - dependencies: - q "^1.5.1" - -conventional-changelog-conventionalcommits@^4.5.0: - version "4.6.3" - resolved "https://registry.yarnpkg.com/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-4.6.3.tgz#0765490f56424b46f6cb4db9135902d6e5a36dc2" - integrity sha512-LTTQV4fwOM4oLPad317V/QNQ1FY4Hju5qeBIM1uTHbrnCE+Eg4CdRZ3gO2pUeR+tzWdp80M2j3qFFEDWVqOV4g== - dependencies: - compare-func "^2.0.0" - lodash "^4.17.15" - q "^1.5.1" - conventional-changelog-conventionalcommits@^7.0.2: version "7.0.2" resolved "https://registry.yarnpkg.com/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-7.0.2.tgz#aa5da0f1b2543094889e8cf7616ebe1a8f5c70d5" @@ -7342,7 +7180,7 @@ conventional-changelog-conventionalcommits@^7.0.2: dependencies: compare-func "^2.0.0" -conventional-changelog-core@4.2.4, conventional-changelog-core@^4.2.1: +conventional-changelog-core@4.2.4: version "4.2.4" resolved "https://registry.yarnpkg.com/conventional-changelog-core/-/conventional-changelog-core-4.2.4.tgz#e50d047e8ebacf63fac3dc67bf918177001e1e9f" integrity sha512-gDVS+zVJHE2v4SLc6B0sLsPiloR0ygU7HaDW14aNJE1v4SlqJPILPl/aJC7YdtRE4CybBf8gDwObBvKha8Xlyg== @@ -7362,42 +7200,6 @@ conventional-changelog-core@4.2.4, conventional-changelog-core@^4.2.1: read-pkg-up "^3.0.0" through2 "^4.0.0" -conventional-changelog-ember@^2.0.9: - version "2.0.9" - resolved "https://registry.yarnpkg.com/conventional-changelog-ember/-/conventional-changelog-ember-2.0.9.tgz#619b37ec708be9e74a220f4dcf79212ae1c92962" - integrity sha512-ulzIReoZEvZCBDhcNYfDIsLTHzYHc7awh+eI44ZtV5cx6LVxLlVtEmcO+2/kGIHGtw+qVabJYjdI5cJOQgXh1A== - dependencies: - q "^1.5.1" - -conventional-changelog-eslint@^3.0.9: - version "3.0.9" - resolved "https://registry.yarnpkg.com/conventional-changelog-eslint/-/conventional-changelog-eslint-3.0.9.tgz#689bd0a470e02f7baafe21a495880deea18b7cdb" - integrity sha512-6NpUCMgU8qmWmyAMSZO5NrRd7rTgErjrm4VASam2u5jrZS0n38V7Y9CzTtLT2qwz5xEChDR4BduoWIr8TfwvXA== - dependencies: - q "^1.5.1" - -conventional-changelog-express@^2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/conventional-changelog-express/-/conventional-changelog-express-2.0.6.tgz#420c9d92a347b72a91544750bffa9387665a6ee8" - integrity sha512-SDez2f3iVJw6V563O3pRtNwXtQaSmEfTCaTBPCqn0oG0mfkq0rX4hHBq5P7De2MncoRixrALj3u3oQsNK+Q0pQ== - dependencies: - q "^1.5.1" - -conventional-changelog-jquery@^3.0.11: - version "3.0.11" - resolved "https://registry.yarnpkg.com/conventional-changelog-jquery/-/conventional-changelog-jquery-3.0.11.tgz#d142207400f51c9e5bb588596598e24bba8994bf" - integrity sha512-x8AWz5/Td55F7+o/9LQ6cQIPwrCjfJQ5Zmfqi8thwUEKHstEn4kTIofXub7plf1xvFA2TqhZlq7fy5OmV6BOMw== - dependencies: - q "^1.5.1" - -conventional-changelog-jshint@^2.0.9: - version "2.0.9" - resolved "https://registry.yarnpkg.com/conventional-changelog-jshint/-/conventional-changelog-jshint-2.0.9.tgz#f2d7f23e6acd4927a238555d92c09b50fe3852ff" - integrity sha512-wMLdaIzq6TNnMHMy31hql02OEQ8nCQfExw1SE0hYL5KvU+JCTuPaDO+7JiogGT2gJAxiUGATdtYYfh+nT+6riA== - dependencies: - compare-func "^2.0.0" - q "^1.5.1" - conventional-changelog-preset-loader@^2.3.4: version "2.3.4" resolved "https://registry.yarnpkg.com/conventional-changelog-preset-loader/-/conventional-changelog-preset-loader-2.3.4.tgz#14a855abbffd59027fd602581f1f34d9862ea44c" @@ -7418,23 +7220,6 @@ conventional-changelog-writer@^5.0.0: split "^1.0.0" through2 "^4.0.0" -conventional-changelog@^3.1.24: - version "3.1.25" - resolved "https://registry.yarnpkg.com/conventional-changelog/-/conventional-changelog-3.1.25.tgz#3e227a37d15684f5aa1fb52222a6e9e2536ccaff" - integrity sha512-ryhi3fd1mKf3fSjbLXOfK2D06YwKNic1nC9mWqybBHdObPd8KJ2vjaXZfYj1U23t+V8T8n0d7gwnc9XbIdFbyQ== - dependencies: - conventional-changelog-angular "^5.0.12" - conventional-changelog-atom "^2.0.8" - conventional-changelog-codemirror "^2.0.8" - conventional-changelog-conventionalcommits "^4.5.0" - conventional-changelog-core "^4.2.1" - conventional-changelog-ember "^2.0.9" - conventional-changelog-eslint "^3.0.9" - conventional-changelog-express "^2.0.6" - conventional-changelog-jquery "^3.0.11" - conventional-changelog-jshint "^2.0.9" - conventional-changelog-preset-loader "^2.3.4" - conventional-commits-filter@^2.0.7: version "2.0.7" resolved "https://registry.yarnpkg.com/conventional-commits-filter/-/conventional-commits-filter-2.0.7.tgz#f8d9b4f182fce00c9af7139da49365b136c8a0b3" @@ -7536,11 +7321,6 @@ core-js-compat@^3.31.0, core-js-compat@^3.33.1: dependencies: browserslist "^4.22.1" -core-js@^2.4.0: - version "2.6.12" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.12.tgz#d9333dfa7b065e347cc5682219d6f690859cc2ec" - integrity sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ== - core-util-is@~1.0.0: version "1.0.3" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" @@ -7836,13 +7616,6 @@ debug@4, debug@4.3.4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.3, de dependencies: ms "2.1.2" -debug@4.3.2: - version "4.3.2" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.2.tgz#f0a49c18ac8779e31d4a0c6029dfb76873c7428b" - integrity sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw== - dependencies: - ms "2.1.2" - decamelize-keys@^1.1.0: version "1.1.1" resolved "https://registry.yarnpkg.com/decamelize-keys/-/decamelize-keys-1.1.1.tgz#04a2d523b2f18d80d0158a43b895d56dff8d19d8" @@ -7851,7 +7624,7 @@ decamelize-keys@^1.1.0: decamelize "^1.1.0" map-obj "^1.0.0" -decamelize@^1.0.0, decamelize@^1.1.0, decamelize@^1.1.1: +decamelize@^1.1.0, decamelize@^1.1.1: version "1.2.0" resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" integrity sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA== @@ -8656,7 +8429,7 @@ escape-html@~1.0.3: resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow== -escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.3, escape-string-regexp@^1.0.5: +escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== @@ -9347,7 +9120,7 @@ flush-write-stream@^1.0.2: inherits "^2.0.3" readable-stream "^2.3.6" -follow-redirects@^1.0.0, follow-redirects@^1.14.0, follow-redirects@^1.15.0: +follow-redirects@^1.0.0, follow-redirects@^1.15.0: version "1.15.5" resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.5.tgz#54d4d6d062c0fa7d9d17feb008461550e3ba8020" integrity sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw== @@ -10037,19 +9810,6 @@ gulp-concat@^2.6.1: through2 "^2.0.0" vinyl "^2.0.0" -gulp-conventional-changelog@^2.0.19: - version "2.0.35" - resolved "https://registry.yarnpkg.com/gulp-conventional-changelog/-/gulp-conventional-changelog-2.0.35.tgz#4ef5391ea46cca4b35fd262586e99de6d2c7017b" - integrity sha512-9khc2fGUc6qWUoQYnqck6/d28lIgP+49kOyYtOIJtp6pthqikSL1UQ8n+Erg9X/z83+z9OX1HWWuVIXbpxvdkw== - dependencies: - add-stream "^1.0.0" - concat-stream "^2.0.0" - conventional-changelog "^3.1.24" - fancy-log "^1.3.2" - object-assign "^4.0.1" - plugin-error "^1.0.1" - through2 "^4.0.0" - gulp-data@^1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/gulp-data/-/gulp-data-1.3.1.tgz#3304d5d1203d554d3385e42de78ee9204f61c8a2" @@ -10069,34 +9829,11 @@ gulp-postcss@^9.1.0: postcss-load-config "^5.0.0" vinyl-sourcemaps-apply "^0.2.1" -gulp-pug@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/gulp-pug/-/gulp-pug-4.0.1.tgz#5c5bb38303a5a565add8b200e292b4a076cf2efa" - integrity sha512-RsayLPwJtKKMub9bbO4VYlMPVnImUPdK8+BjvkiulkorrjWnahTbI3a3Li/7YkD0xs7ap7ePciNiPwweoVEPMQ== - dependencies: - "@types/pug" "^2.0.4" - fancy-log "^1.3.2" - plugin-error "^1.0.1" - pug "^2.0.3" - replace-ext "^1.0.0" - through2 "^2.0.3" - gulp-rename@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/gulp-rename/-/gulp-rename-1.4.0.tgz#de1c718e7c4095ae861f7296ef4f3248648240bd" integrity sha512-swzbIGb/arEoFK89tPY58vg3Ok1bw+d35PfUNwWqdo7KM4jkmuGA78JiDNqR+JeZFaeeHnRg9N7aihX3YPmsyg== -gulp-replace@^1.0.0: - version "1.1.4" - resolved "https://registry.yarnpkg.com/gulp-replace/-/gulp-replace-1.1.4.tgz#06a0e9ee36f30e343c1e0a2dd760ec32c8a3d3b2" - integrity sha512-SVSF7ikuWKhpAW4l4wapAqPPSToJoiNKsbDoUnRrSgwZHH7lH8pbPeQj1aOVYQrbZKhfSVBxVW+Py7vtulRktw== - dependencies: - "@types/node" "*" - "@types/vinyl" "^2.0.4" - istextorbinary "^3.0.0" - replacestream "^4.0.3" - yargs-parser ">=5.0.0-security.0" - gulp@^4.0.0: version "4.0.2" resolved "https://registry.yarnpkg.com/gulp/-/gulp-4.0.2.tgz#543651070fd0f6ab0a0650c6a3e6ff5a7cb09caa" @@ -10901,14 +10638,6 @@ is-docker@^2.0.0, is-docker@^2.1.1: resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== -is-expression@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-expression/-/is-expression-3.0.0.tgz#39acaa6be7fd1f3471dc42c7416e61c24317ac9f" - integrity sha512-vyMeQMq+AiH5uUnoBfMTwf18tO3bM6k1QXBE9D6ueAAquEfCZe3AJPtud9g6qS0+4X8xA7ndpZiDyeb2l2qOBw== - dependencies: - acorn "~4.0.2" - object-assign "^4.0.1" - is-expression@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/is-expression/-/is-expression-4.0.0.tgz#c33155962abf21d0afd2552514d67d2ec16fd2ab" @@ -11311,14 +11040,6 @@ istanbul-reports@^3.1.6: html-escaper "^2.0.0" istanbul-lib-report "^3.0.0" -istextorbinary@^3.0.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/istextorbinary/-/istextorbinary-3.3.0.tgz#06b1c57d948da11461bd237c00ce09e9902964f2" - integrity sha512-Tvq1W6NAcZeJ8op+Hq7tdZ434rqnMx4CCZ7H0ff83uEloDvVbqAwaMTZcafKGJT0VHkYzuXUiCY4hlXQg6WfoQ== - dependencies: - binaryextensions "^2.2.0" - textextensions "^3.2.0" - jackspeak@^2.3.5: version "2.3.6" resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-2.3.6.tgz#647ecc472238aee4b06ac0e461acc21a8c505ca8" @@ -11456,7 +11177,7 @@ js-string-escape@^1.0.1: resolved "https://registry.yarnpkg.com/js-string-escape/-/js-string-escape-1.0.1.tgz#e2625badbc0d67c7533e9edc1068c587ae4137ef" integrity sha512-Smw4xcfIQ5LVjAOuJCvN/zIodzA/BBSsluuoSykP+lUvScIi4U6RJLfwHet5cxFnCswUjISV8oAXaqaJDY3chg== -js-stringify@^1.0.1, js-stringify@^1.0.2: +js-stringify@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/js-stringify/-/js-stringify-1.0.2.tgz#1736fddfd9724f28a3682adc6230ae7e4e9679db" integrity sha512-rtS5ATOo2Q5k1G+DADISilDA6lv79zIiwFd6CcjuIxGKLFm5C+RLImRscVap9k55i+MOZwgliw+NejvkLuGD5g== @@ -11680,11 +11401,6 @@ last-run@^1.1.0: default-resolution "^2.0.0" es6-weak-map "^2.0.1" -lazy-cache@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-1.0.4.tgz#a1d78fc3a50474cb80845d3b3b6e1da49a446e8e" - integrity sha512-RE2g0b5VGZsOCFOCgP7omTRYFqydmZkBwl5oNnQ1lDYC57uyO9KqNnNVxT7COSHTxrRCWVcAVOcbjk+tvh/rgQ== - lazy-universal-dotenv@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/lazy-universal-dotenv/-/lazy-universal-dotenv-4.0.0.tgz#0b220c264e89a042a37181a4928cdd298af73422" @@ -11994,16 +11710,6 @@ loadicons@^1.0.0: resolved "https://registry.yarnpkg.com/loadicons/-/loadicons-1.0.0.tgz#79fd9b08ef2933988c94068cbd246ef3f21cbd04" integrity sha512-KSywiudfuOK5sTdhNMM8hwRpMxZ5TbQlU4ZijMxUFwRW7jpxUmb9YJoLIzDn7+xuxeLzCZWBmLJS2JDjDWCpsw== -localtunnel@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/localtunnel/-/localtunnel-2.0.2.tgz#528d50087151c4790f89c2db374fe7b0a48501f0" - integrity sha512-n418Cn5ynvJd7m/N1d9WVJISLJF/ellZnfsLnx8WBWGzxv/ntNcFkJ1o6se5quUhCplfLGBNL5tYHiq5WF3Nug== - dependencies: - axios "0.21.4" - debug "4.3.2" - openurl "1.1.1" - yargs "17.1.1" - locate-path@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" @@ -12146,7 +11852,7 @@ lodash.upperfirst@^4.3.1: resolved "https://registry.yarnpkg.com/lodash.upperfirst/-/lodash.upperfirst-4.3.1.tgz#1365edf431480481ef0d1c68957a5ed99d49f7ce" integrity sha512-sReKOYJIJf74dhJONhU4e0/shzi1trVbSWDOhKYE5XV2O+H7Sb2Dihwuc7xWxVl+DgFPyTqIN3zMfT9cq5iWDg== -lodash@>=4.17.21, lodash@^4.17.10, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.17.4: +lodash@>=4.17.21, lodash@^4.17.10, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.20, lodash@^4.17.21: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== @@ -12178,11 +11884,6 @@ log-update@^5.0.1: strip-ansi "^7.0.1" wrap-ansi "^8.0.1" -longest@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/longest/-/longest-1.0.1.tgz#30a0b2da38f73770e8294a0d22e6625ed77d0097" - integrity sha512-k+yt5n3l48JU4k8ftnKG6V7u32wyH2NfKzeMto9F/QRE0amxy/LayxwlvjjkZEIzqR+19IrtFO8p5kB9QaYUFg== - loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" @@ -13266,7 +12967,7 @@ npm-registry-fetch@^13.0.0: npm-package-arg "^9.0.1" proc-log "^2.0.0" -npm-registry-fetch@^14.0.0, npm-registry-fetch@^14.0.3, npm-registry-fetch@^14.0.5: +npm-registry-fetch@^14.0.0, npm-registry-fetch@^14.0.3: version "14.0.5" resolved "https://registry.yarnpkg.com/npm-registry-fetch/-/npm-registry-fetch-14.0.5.tgz#fe7169957ba4986a4853a650278ee02e568d115d" integrity sha512-kIDMIo4aBm6xg7jOttupWZamsZRkAqMqwqqbVXnUqstY5+tapvv6bkH/qMR76jdgV+YljEUCyWx3hRYMrJiAgA== @@ -13481,7 +13182,7 @@ nx@17.2.8, nx@^17.2.8: "@nx/nx-win32-arm64-msvc" "17.2.8" "@nx/nx-win32-x64-msvc" "17.2.8" -object-assign@^4, object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1: +object-assign@^4, object-assign@^4.0.1, object-assign@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== @@ -13632,11 +13333,6 @@ open@^8.0.4, open@^8.4.0: is-docker "^2.1.1" is-wsl "^2.2.0" -openurl@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/openurl/-/openurl-1.1.1.tgz#3875b4b0ef7a52c156f0db41d4609dbb0f94b387" - integrity sha512-d/gTkTb1i1GKz5k3XE3XFV/PxQ1k45zDqGP2OA7YhgsaLoqm6qRvARAZOFer1fcXritWlGBRCu/UgeS4HAnXAA== - opn@5.3.0: version "5.3.0" resolved "https://registry.yarnpkg.com/opn/-/opn-5.3.0.tgz#64871565c863875f052cfdf53d3e3cb5adb53b1c" @@ -14292,16 +13988,6 @@ plugin-error@^0.1.2: arr-union "^2.0.1" extend-shallow "^1.1.2" -plugin-error@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/plugin-error/-/plugin-error-1.0.1.tgz#77016bd8919d0ac377fdcdd0322328953ca5781c" - integrity sha512-L1zP0dk7vGweZME2i+EeakvUNqSrdiI3F91TwEoYiGrAfUXmVv6fJIq4g82PAXxNsWOp0J7ZqQy/3Szz0ajTxA== - dependencies: - ansi-colors "^1.0.1" - arr-diff "^4.0.0" - arr-union "^3.1.0" - extend-shallow "^3.0.2" - plugin-error@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/plugin-error/-/plugin-error-2.0.1.tgz#f2ac92bac8c85e3e23492d76d0c3ca12f30eb00b" @@ -14858,15 +14544,6 @@ proxy-from-env@^1.0.0, proxy-from-env@^1.1.0: resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2" integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg== -pug-attrs@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/pug-attrs/-/pug-attrs-2.0.4.tgz#b2f44c439e4eb4ad5d4ef25cac20d18ad28cc336" - integrity sha512-TaZ4Z2TWUPDJcV3wjU3RtUXMrd3kM4Wzjbe3EWnSsZPsJ3LDI0F3yCnf2/W7PPFF+edUFQ0HgDL1IoxSz5K8EQ== - dependencies: - constantinople "^3.0.1" - js-stringify "^1.0.1" - pug-runtime "^2.0.5" - pug-attrs@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/pug-attrs/-/pug-attrs-3.0.0.tgz#b10451e0348165e31fad1cc23ebddd9dc7347c41" @@ -14876,20 +14553,6 @@ pug-attrs@^3.0.0: js-stringify "^1.0.2" pug-runtime "^3.0.0" -pug-code-gen@^2.0.2: - version "2.0.3" - resolved "https://registry.yarnpkg.com/pug-code-gen/-/pug-code-gen-2.0.3.tgz#122eb9ada9b5bf601705fe15aaa0a7d26bc134ab" - integrity sha512-r9sezXdDuZJfW9J91TN/2LFbiqDhmltTFmGpHTsGdrNGp3p4SxAjjXEfnuK2e4ywYsRIVP0NeLbSAMHUcaX1EA== - dependencies: - constantinople "^3.1.2" - doctypes "^1.1.0" - js-stringify "^1.0.1" - pug-attrs "^2.0.4" - pug-error "^1.3.3" - pug-runtime "^2.0.5" - void-elements "^2.0.1" - with "^5.0.0" - pug-code-gen@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/pug-code-gen/-/pug-code-gen-3.0.2.tgz#ad190f4943133bf186b60b80de483100e132e2ce" @@ -14904,29 +14567,11 @@ pug-code-gen@^3.0.2: void-elements "^3.1.0" with "^7.0.0" -pug-error@^1.3.3: - version "1.3.3" - resolved "https://registry.yarnpkg.com/pug-error/-/pug-error-1.3.3.tgz#f342fb008752d58034c185de03602dd9ffe15fa6" - integrity sha512-qE3YhESP2mRAWMFJgKdtT5D7ckThRScXRwkfo+Erqga7dyJdY3ZquspprMCj/9sJ2ijm5hXFWQE/A3l4poMWiQ== - pug-error@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/pug-error/-/pug-error-2.0.0.tgz#5c62173cb09c34de2a2ce04f17b8adfec74d8ca5" integrity sha512-sjiUsi9M4RAGHktC1drQfCr5C5eriu24Lfbt4s+7SykztEOwVZtbFk1RRq0tzLxcMxMYTBR+zMQaG07J/btayQ== -pug-filters@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/pug-filters/-/pug-filters-3.1.1.tgz#ab2cc82db9eeccf578bda89130e252a0db026aa7" - integrity sha512-lFfjNyGEyVWC4BwX0WyvkoWLapI5xHSM3xZJFUhx4JM4XyyRdO8Aucc6pCygnqV2uSgJFaJWW3Ft1wCWSoQkQg== - dependencies: - clean-css "^4.1.11" - constantinople "^3.0.1" - jstransformer "1.0.0" - pug-error "^1.3.3" - pug-walk "^1.1.8" - resolve "^1.1.6" - uglify-js "^2.6.1" - pug-filters@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/pug-filters/-/pug-filters-4.0.0.tgz#d3e49af5ba8472e9b7a66d980e707ce9d2cc9b5e" @@ -14938,15 +14583,6 @@ pug-filters@^4.0.0: pug-walk "^2.0.0" resolve "^1.15.1" -pug-lexer@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/pug-lexer/-/pug-lexer-4.1.0.tgz#531cde48c7c0b1fcbbc2b85485c8665e31489cfd" - integrity sha512-i55yzEBtjm0mlplW4LoANq7k3S8gDdfC6+LThGEvsK4FuobcKfDAwt6V4jKPH9RtiE3a2Akfg5UpafZ1OksaPA== - dependencies: - character-parser "^2.1.1" - is-expression "^3.0.0" - pug-error "^1.3.3" - pug-lexer@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/pug-lexer/-/pug-lexer-5.0.1.tgz#ae44628c5bef9b190b665683b288ca9024b8b0d5" @@ -14956,14 +14592,6 @@ pug-lexer@^5.0.1: is-expression "^4.0.0" pug-error "^2.0.0" -pug-linker@^3.0.6: - version "3.0.6" - resolved "https://registry.yarnpkg.com/pug-linker/-/pug-linker-3.0.6.tgz#f5bf218b0efd65ce6670f7afc51658d0f82989fb" - integrity sha512-bagfuHttfQOpANGy1Y6NJ+0mNb7dD2MswFG2ZKj22s8g0wVsojpRlqveEQHmgXXcfROB2RT6oqbPYr9EN2ZWzg== - dependencies: - pug-error "^1.3.3" - pug-walk "^1.1.8" - pug-linker@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/pug-linker/-/pug-linker-4.0.0.tgz#12cbc0594fc5a3e06b9fc59e6f93c146962a7708" @@ -14972,14 +14600,6 @@ pug-linker@^4.0.0: pug-error "^2.0.0" pug-walk "^2.0.0" -pug-load@^2.0.12: - version "2.0.12" - resolved "https://registry.yarnpkg.com/pug-load/-/pug-load-2.0.12.tgz#d38c85eb85f6e2f704dea14dcca94144d35d3e7b" - integrity sha512-UqpgGpyyXRYgJs/X60sE6SIf8UBsmcHYKNaOccyVLEuT6OPBIMo6xMPhoJnqtB3Q3BbO4Z3Bjz5qDsUWh4rXsg== - dependencies: - object-assign "^4.1.0" - pug-walk "^1.1.8" - pug-load@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/pug-load/-/pug-load-3.0.0.tgz#9fd9cda52202b08adb11d25681fb9f34bd41b662" @@ -14988,14 +14608,6 @@ pug-load@^3.0.0: object-assign "^4.1.1" pug-walk "^2.0.0" -pug-parser@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/pug-parser/-/pug-parser-5.0.1.tgz#03e7ada48b6840bd3822f867d7d90f842d0ffdc9" - integrity sha512-nGHqK+w07p5/PsPIyzkTQfzlYfuqoiGjaoqHv1LjOv2ZLXmGX1O+4Vcvps+P4LhxZ3drYSljjq4b+Naid126wA== - dependencies: - pug-error "^1.3.3" - token-stream "0.0.1" - pug-parser@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/pug-parser/-/pug-parser-6.0.0.tgz#a8fdc035863a95b2c1dc5ebf4ecf80b4e76a1260" @@ -15004,23 +14616,11 @@ pug-parser@^6.0.0: pug-error "^2.0.0" token-stream "1.0.0" -pug-runtime@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/pug-runtime/-/pug-runtime-2.0.5.tgz#6da7976c36bf22f68e733c359240d8ae7a32953a" - integrity sha512-P+rXKn9un4fQY77wtpcuFyvFaBww7/91f3jHa154qU26qFAnOe6SW1CbIDcxiG5lLK9HazYrMCCuDvNgDQNptw== - pug-runtime@^3.0.0, pug-runtime@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/pug-runtime/-/pug-runtime-3.0.1.tgz#f636976204723f35a8c5f6fad6acda2a191b83d7" integrity sha512-L50zbvrQ35TkpHwv0G6aLSuueDRwc/97XdY8kL3tOT0FmhgG7UypU3VztfV/LATAvmUfYi4wNxSajhSAeNN+Kg== -pug-strip-comments@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/pug-strip-comments/-/pug-strip-comments-1.0.4.tgz#cc1b6de1f6e8f5931cf02ec66cdffd3f50eaf8a8" - integrity sha512-i5j/9CS4yFhSxHp5iKPHwigaig/VV9g+FgReLJWWHEHbvKsbqL0oP/K5ubuLco6Wu3Kan5p7u7qk8A4oLLh6vw== - dependencies: - pug-error "^1.3.3" - pug-strip-comments@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/pug-strip-comments/-/pug-strip-comments-2.0.0.tgz#f94b07fd6b495523330f490a7f554b4ff876303e" @@ -15028,31 +14628,12 @@ pug-strip-comments@^2.0.0: dependencies: pug-error "^2.0.0" -pug-walk@^1.1.8: - version "1.1.8" - resolved "https://registry.yarnpkg.com/pug-walk/-/pug-walk-1.1.8.tgz#b408f67f27912f8c21da2f45b7230c4bd2a5ea7a" - integrity sha512-GMu3M5nUL3fju4/egXwZO0XLi6fW/K3T3VTgFQ14GxNi8btlxgT5qZL//JwZFm/2Fa64J/PNS8AZeys3wiMkVA== - pug-walk@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/pug-walk/-/pug-walk-2.0.0.tgz#417aabc29232bb4499b5b5069a2b2d2a24d5f5fe" integrity sha512-yYELe9Q5q9IQhuvqsZNwA5hfPkMJ8u92bQLIMcsMxf/VADjNtEYptU+inlufAFYcWdHlwNfZOEnOOQrZrcyJCQ== -pug@^2.0.3: - version "2.0.4" - resolved "https://registry.yarnpkg.com/pug/-/pug-2.0.4.tgz#ee7682ec0a60494b38d48a88f05f3b0ac931377d" - integrity sha512-XhoaDlvi6NIzL49nu094R2NA6P37ijtgMDuWE+ofekDChvfKnzFal60bhSdiy8y2PBO6fmz3oMEIcfpBVRUdvw== - dependencies: - pug-code-gen "^2.0.2" - pug-filters "^3.1.1" - pug-lexer "^4.1.0" - pug-linker "^3.0.6" - pug-load "^2.0.12" - pug-parser "^5.0.1" - pug-runtime "^2.0.5" - pug-strip-comments "^1.0.4" - -pug@^3.0.1: +pug@^3.0.1, pug@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/pug/-/pug-3.0.2.tgz#f35c7107343454e43bc27ae0ff76c731b78ea535" integrity sha512-bp0I/hiK1D1vChHh6EfDxtndHji55XP/ZJKwsRqrz6lRia6ZC2OZbdAymlxdVFwd1L70ebrVJw4/eZ79skrIaw== @@ -15578,11 +15159,6 @@ regenerate@^1.4.2: resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.2.tgz#b9346d8827e8f5a32f7ba29637d398b69014848a" integrity sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A== -regenerator-runtime@^0.11.0: - version "0.11.1" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" - integrity sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg== - regenerator-runtime@^0.14.0: version "0.14.0" resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz#5e19d68eb12d486f797e15a3c6a918f7cec5eb45" @@ -15694,7 +15270,7 @@ repeat-element@^1.1.2: resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.4.tgz#be681520847ab58c7568ac75fbfad28ed42d39e9" integrity sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ== -repeat-string@^1.5.2, repeat-string@^1.6.1: +repeat-string@^1.6.1: version "1.6.1" resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" integrity sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w== @@ -15713,15 +15289,6 @@ replace-homedir@^1.0.0: is-absolute "^1.0.0" remove-trailing-separator "^1.1.0" -replacestream@^4.0.3: - version "4.0.3" - resolved "https://registry.yarnpkg.com/replacestream/-/replacestream-4.0.3.tgz#3ee5798092be364b1cdb1484308492cb3dff2f36" - integrity sha512-AC0FiLS352pBBiZhd4VXB1Ab/lh0lEgpP+GGvZqbQh8a5cmXVoTe5EX/YeTFArnp4SRGTHh1qCHu9lGs1qG8sA== - dependencies: - escape-string-regexp "^1.0.3" - object-assign "^4.0.1" - readable-stream "^2.0.2" - require-directory@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" @@ -15839,13 +15406,6 @@ rfdc@^1.3.0: resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.3.0.tgz#d0b7c441ab2720d05dc4cf26e01c89631d9da08b" integrity sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA== -right-align@^0.1.1: - version "0.1.3" - resolved "https://registry.yarnpkg.com/right-align/-/right-align-0.1.3.tgz#61339b722fe6a3515689210d24e14c96148613ef" - integrity sha512-yqINtL/G7vs2v+dFIZmFUDbnVyFUJFKd6gK22Kgo6R4jfJGFtisKyncWDDULgjfqf4ASQuIQyjJ7XZ+3aWpsAg== - dependencies: - align-text "^0.1.1" - rimraf@^2.6.1: version "2.7.1" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" @@ -16440,7 +16000,7 @@ source-map-url@^0.4.0: resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.1.tgz#0af66605a745a5a2f91cf1bbf8a7afbc283dec56" integrity sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw== -source-map@^0.5.1, source-map@^0.5.6, source-map@~0.5.1: +source-map@^0.5.1, source-map@^0.5.6: version "0.5.7" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" integrity sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ== @@ -17255,11 +16815,6 @@ text-extensions@^2.0.0: resolved "https://registry.yarnpkg.com/text-extensions/-/text-extensions-2.4.0.tgz#a1cfcc50cf34da41bfd047cc744f804d1680ea34" integrity sha512-te/NtwBwfiNRLf9Ijqx3T0nlqZiQ2XrrtBvu+cLL8ZRrGkO0NHTug8MYFKyoSrv/sHTaSKfilUkizV6XhxMJ3g== -textextensions@^3.2.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/textextensions/-/textextensions-3.3.0.tgz#03530d5287b86773c08b77458589148870cc71d3" - integrity sha512-mk82dS8eRABNbeVJrEiN5/UMSCliINAuz8mkUwH4SwslkNP//gbEzlWNS5au0z5Dpx40SQxzqZevZkn+WYJ9Dw== - thenby@^1.3.4: version "1.3.4" resolved "https://registry.yarnpkg.com/thenby/-/thenby-1.3.4.tgz#81581f6e1bb324c6dedeae9bfc28e59b1a2201cc" @@ -17355,11 +16910,6 @@ to-absolute-glob@^2.0.0: is-absolute "^1.0.0" is-negated-glob "^1.0.0" -to-fast-properties@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47" - integrity sha512-lxrWP8ejsq+7E3nNjwYmUBMAgjMTZoTI+sdBOpvNyijeDLa29LUn9QaoXAHv4+Z578hbmHHJKZknzxVtvo77og== - to-fast-properties@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" @@ -17419,11 +16969,6 @@ toidentifier@1.0.1: resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== -token-stream@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/token-stream/-/token-stream-0.0.1.tgz#ceeefc717a76c4316f126d0b9dbaa55d7e7df01a" - integrity sha512-nfjOAu/zAWmX9tgwi5NRp7O7zTDUD1miHiB40klUnAh9qnL1iXdgzcz/i5dMaL5jahcBAaSfmNOBBJBLJW8TEg== - token-stream@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/token-stream/-/token-stream-1.0.0.tgz#cc200eab2613f4166d27ff9afc7ca56d49df6eb4" @@ -17682,26 +17227,11 @@ uc.micro@^1.0.1, uc.micro@^1.0.5: resolved "https://registry.yarnpkg.com/uc.micro/-/uc.micro-1.0.6.tgz#9c411a802a409a91fc6cf74081baba34b24499ac" integrity sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA== -uglify-js@^2.6.1: - version "2.8.29" - resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.8.29.tgz#29c5733148057bb4e1f75df35b7a9cb72e6a59dd" - integrity sha512-qLq/4y2pjcU3vhlhseXGGJ7VbFO4pBANu0kwl8VCa9KEI0V8VfZIx2Fy3w01iSTA/pGwKZSmu/+I4etLNDdt5w== - dependencies: - source-map "~0.5.1" - yargs "~3.10.0" - optionalDependencies: - uglify-to-browserify "~1.0.0" - uglify-js@^3.1.4: version "3.17.4" resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.17.4.tgz#61678cf5fa3f5b7eb789bb345df29afb8257c22c" integrity sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g== -uglify-to-browserify@~1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz#6e0924d6bda6b5afe349e39a6d632850a0f882b7" - integrity sha512-vb2s1lYx2xBtUgy+ta+b2J/GLVUR+wmpINwHePmPRhOsIVCG2wDzKJ0n14GslH1BifsqVzSOwQhRaCAsZ/nI4Q== - unbox-primitive@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.2.tgz#29032021057d5e6cdbd08c5129c226dff8ed6f9e" @@ -18182,11 +17712,6 @@ vinyl@^2.0.0: remove-trailing-separator "^1.0.1" replace-ext "^1.0.0" -void-elements@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-2.0.1.tgz#c066afb582bb1cb4128d60ea92392e94d5e9dbec" - integrity sha512-qZKX4RnBzH2ugr8Lxa7x+0V6XD9Sb/ouARtiasEQCHB1EVU4NXtmHsDDrx1dO4ne5fc3J6EW05BP1Dl0z0iung== - void-elements@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-3.1.0.tgz#614f7fbf8d801f0bb5f0661f5b2f5785750e4f09" @@ -18369,19 +17894,6 @@ wide-align@^1.1.2, wide-align@^1.1.5: dependencies: string-width "^1.0.2 || 2 || 3 || 4" -window-size@0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.1.0.tgz#5438cd2ea93b202efa3a19fe8887aee7c94f9c9d" - integrity sha512-1pTPQDKTdd61ozlKGNCjhNRd+KPmgLSGa3mZTHoOliaGcESD8G1PXhh7c1fgiPjVbNVfgy2Faw4BI8/m0cC8Mg== - -with@^5.0.0: - version "5.1.1" - resolved "https://registry.yarnpkg.com/with/-/with-5.1.1.tgz#fa4daa92daf32c4ea94ed453c81f04686b575dfe" - integrity sha512-uAnSsFGfSpF6DNhBXStvlZILfHJfJu4eUkfbRGk94kGO1Ta7bg6FwfvoOhhyHAJuFbCw+0xk4uJ3u57jLvlCJg== - dependencies: - acorn "^3.1.0" - acorn-globals "^3.0.0" - with@^7.0.0: version "7.0.2" resolved "https://registry.yarnpkg.com/with/-/with-7.0.2.tgz#ccee3ad542d25538a7a7a80aad212b9828495bac" @@ -18397,11 +17909,6 @@ wonka@^6.3.2: resolved "https://registry.yarnpkg.com/wonka/-/wonka-6.3.4.tgz#76eb9316e3d67d7febf4945202b5bdb2db534594" integrity sha512-CjpbqNtBGNAeyNS/9W6q3kSkKE52+FjIj7AkFlLr11s/VWGUu6a2CdYSdGxocIhIVjaW/zchesBQUKPVU69Cqg== -wordwrap@0.0.2: - version "0.0.2" - resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.2.tgz#b79669bb42ecb409f83d583cad52ca17eaa1643f" - integrity sha512-xSBsCeh+g+dinoBv3GAOWM4LcVVO68wLXRanibtBSdUvkGWQRGeE9P7IwU9EmDDi4jA6L44lz15CGMwdw9N5+Q== - wordwrap@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" @@ -18588,7 +18095,7 @@ yargs-parser@20.2.4: resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.4.tgz#b42890f14566796f85ae8e3a25290d205f154a54" integrity sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA== -yargs-parser@21.1.1, yargs-parser@>=5.0.0-security.0, yargs-parser@^21.1.1: +yargs-parser@21.1.1, yargs-parser@^21.1.1: version "21.1.1" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35" integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== @@ -18619,19 +18126,6 @@ yargs@16.2.0, yargs@^16.2.0: y18n "^5.0.5" yargs-parser "^20.2.2" -yargs@17.1.1: - version "17.1.1" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.1.1.tgz#c2a8091564bdb196f7c0a67c1d12e5b85b8067ba" - integrity sha512-c2k48R0PwKIqKhPMWjeiF6y2xY/gPMUlro0sgxqXpbOIohWiLNXWslsootttv7E1e73QPAMQSg5FeySbVcpsPQ== - dependencies: - cliui "^7.0.2" - escalade "^3.1.1" - get-caller-file "^2.0.5" - require-directory "^2.1.1" - string-width "^4.2.0" - y18n "^5.0.5" - yargs-parser "^20.2.2" - yargs@^17.0.0, yargs@^17.3.1, yargs@^17.6.2, yargs@^17.7.2: version "17.7.2" resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.2.tgz#991df39aca675a192b816e1e0363f9d75d2aa269" @@ -18664,16 +18158,6 @@ yargs@^7.1.0: y18n "^3.2.1" yargs-parser "^5.0.1" -yargs@~3.10.0: - version "3.10.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-3.10.0.tgz#f7ee7bd857dd7c1d2d38c0e74efbd681d1431fd1" - integrity sha512-QFzUah88GAGy9lyDKGBqZdkYApt63rCXYBGYnEP4xDJPXNqXXnBDACnbrXnViV6jRSqAePwrATi2i8mfYm4L1A== - dependencies: - camelcase "^1.0.2" - cliui "^2.1.0" - decamelize "^1.0.0" - window-size "0.1.0" - yauzl@^2.10.0: version "2.10.0" resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.10.0.tgz#c7eb17c93e112cb1086fa6d8e51fb0667b79a5f9"