From 1054f7f77d15376abf74561b582fd490684266e4 Mon Sep 17 00:00:00 2001 From: Ashley Gibson Date: Fri, 28 Feb 2025 13:11:23 +0000 Subject: [PATCH 01/45] Replace instances of require() with import --- gulpfile.js | 36 +- lib/sake.js | 20 +- package-lock.json | 3072 ++++++++++++++++++++++------------------- package.json | 9 +- pipes/replace.js | 2 +- pipes/scripts.js | 2 +- tasks/build.js | 2 +- tasks/bump.js | 4 +- tasks/bundle.js | 8 +- tasks/clean.js | 4 +- tasks/compile.js | 19 +- tasks/config.js | 4 +- tasks/copy.js | 3 +- tasks/decaffeinate.js | 2 +- tasks/deploy.js | 12 +- tasks/github.js | 18 +- tasks/imagemin.js | 4 +- tasks/lint.js | 6 +- tasks/makepot.js | 4 +- tasks/prerelease.js | 2 +- tasks/prompt.js | 10 +- tasks/shell.js | 10 +- tasks/upfw.js | 6 +- tasks/validate.js | 4 +- tasks/watch.js | 2 +- tasks/wc.js | 12 +- 26 files changed, 1784 insertions(+), 1493 deletions(-) diff --git a/gulpfile.js b/gulpfile.js index 19d580e..b83cb23 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -1,19 +1,23 @@ -'use strict' - -const gulp = require('gulp') -const path = require('path') -const fs = require('fs') -const minimist = require('minimist') -const log = require('fancy-log') -const _ = require('lodash') -const ForwardReference = require('undertaker-forward-reference') +import gulp from 'gulp' +import path from 'node:path' +import fs from 'node:fs' +import minimist from 'minimist' +import log from 'fancy-log' +import _ from 'lodash' +import ForwardReference from 'undertaker-forward-reference' +import dotenv from 'dotenv' +import sakePlugin from './lib/sake' +import gulpPlugins from 'gulp-load-plugins' +import notifier from 'node-notifier' +import stripAnsi from 'strip-ansi' +import browserSync from 'browser-sync' // local .env file, overriding any global env variables let parentEnvPath = path.join('..', '.env') let envPath = fs.existsSync('.env') ? '.env' : (fs.existsSync(parentEnvPath) ? parentEnvPath : null) if (envPath) { - let result = require('dotenv').config({ path: envPath }) + let result = dotenv.config({ path: envPath }) log.warn(`Loading ENV variables from ${path.join(process.cwd(), envPath)}`) @@ -25,7 +29,7 @@ if (envPath) { // development .env file, overriding any global env variables, or repo/plugin specific variables let devEnv = path.join(__dirname, '.env') if (fs.existsSync(devEnv)) { - let result = require('dotenv').config({path: devEnv}) + let result = dotenv.config({path: devEnv}) log.warn('LOADING DEVELOPMENT ENV VARIABLES FROM ' + devEnv) @@ -125,28 +129,26 @@ let options = minimist(process.argv.slice(2), { } }) -const sake = require('./lib/sake')(config, options) +const sake = sakePlugin(config, options) sake.initConfig() -let plugins = require('gulp-load-plugins')() +let plugins = gulpPlugins() // Attach browsersync as a plugin - not really a plugin, but it helps to // pass around the browsersync instance between tasks. Unfortunately, we // always have to load and create an instance of it, because gulp-if does not // support lazy evaluation yet: https://github.com/robrich/gulp-if/issues/75 -plugins.browserSync = require('browser-sync').create() +plugins.browserSync = browserSync.create() // load gulp plugins and tasks -require('fs').readdirSync(path.join(__dirname, 'tasks')).forEach((file) => { +fs.readdirSync(path.join(__dirname, 'tasks')).forEach((file) => { require(path.join(__dirname, 'tasks', file))(gulp, plugins, sake) }) gulp.task('default', gulp.series('compile')) // show notification on task errors -const notifier = require('node-notifier') -const stripAnsi = require('strip-ansi') let loggedErrors = [] gulp.on('error', (event) => { diff --git a/lib/sake.js b/lib/sake.js index 4367b84..822b1bb 100644 --- a/lib/sake.js +++ b/lib/sake.js @@ -1,13 +1,13 @@ -const fs = require('fs') -const path = require('path') -const semver = require('semver') -const parseGitConfig = require('parse-git-config') -const parseGitHubUrl = require('parse-github-url') -const _ = require('lodash') -const _str = require('underscore.string') -const log = require('fancy-log') -const chalk = require('chalk') -const dottie = require('dottie') +import fs from 'node:fs'; +import path from 'node:path'; +import semver from 'semver'; +import parseGitConfig from 'parse-git-config'; +import parseGitHubUrl from 'parse-github-url'; +import _ from 'lodash'; +import _str from 'underscore.string'; +import log from 'fancy-log'; +import chalk from 'chalk'; +import dottie from 'dottie'; module.exports = (config, options) => { const exports = {} diff --git a/package-lock.json b/package-lock.json index 6944c6f..c0b19fc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20,10 +20,10 @@ "axios": "^1.7.9", "babel-loader": "^8.0.6", "browser-sync": "^3.0.3", - "chalk": "^4.0.0", + "chalk": "^5.4.1", "codename": "0.0.6", "cssnano": "^7.0.6", - "dateformat": "^4.6.3", + "dateformat": "^5.0.3", "del": "^6.1.1", "dotenv": "^16.4.7", "dottie": "^2.0.6", @@ -38,7 +38,7 @@ "gulp-eslint": "^4.0.2", "gulp-filter": "^5.1.0", "gulp-if": "^2.0.2", - "gulp-imagemin": "^6.2.0", + "gulp-imagemin": "^9.1.0", "gulp-load-plugins": "^2.0.7", "gulp-phplint": "^0.9.0", "gulp-postcss": "^10.0.0", @@ -63,7 +63,7 @@ "sass": "^1.83.4", "semver": "^7.7.1", "shelljs": "^0.8.5", - "strip-ansi": "^4.0.0", + "strip-ansi": "^7.1.0", "underscore.string": "^3.3.4", "undertaker-forward-reference": "^1.0.2", "webpack-stream": "^7.0.0" @@ -2320,14 +2320,34 @@ "dev": true, "license": "MIT" }, + "node_modules/@sec-ant/readable-stream": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@sec-ant/readable-stream/-/readable-stream-0.4.1.tgz", + "integrity": "sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==", + "license": "MIT" + }, "node_modules/@sindresorhus/is": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.7.0.tgz", - "integrity": "sha512-ONhaKPIufzzrlNbqtWFFd+jlnemX6lJAgq9ZeiZtS7I1PIf/la7CW4m83rTXRnVnsMbW2k56pGYu7AUFJD9Pow==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-6.3.1.tgz", + "integrity": "sha512-FX4MfcifwJyFOI2lPoX7PQxCqx8BG1HCho7WdiXwpEQx1Ycij0JxkfYtGK7yqNScrZGSlt6RE6sw8QYoH7eKnQ==", "license": "MIT", - "optional": true, "engines": { - "node": ">=4" + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" + } + }, + "node_modules/@sindresorhus/merge-streams": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-2.3.0.tgz", + "integrity": "sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/@skyverge/eslint-config": { @@ -2349,6 +2369,12 @@ "integrity": "sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==", "license": "MIT" }, + "node_modules/@tokenizer/token": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@tokenizer/token/-/token-0.3.0.tgz", + "integrity": "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==", + "license": "MIT" + }, "node_modules/@trysound/sax": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz", @@ -2396,15 +2422,11 @@ "license": "MIT", "peer": true }, - "node_modules/@types/glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==", - "license": "MIT", - "dependencies": { - "@types/minimatch": "*", - "@types/node": "*" - } + "node_modules/@types/expect": { + "version": "1.20.4", + "resolved": "https://registry.npmjs.org/@types/expect/-/expect-1.20.4.tgz", + "integrity": "sha512-Q5Vn3yjTDyCMV50TB6VRIbQNxSE4OmZR86VSbGaNpfUolm0iePBB4KdEEHmxoY5sT2+2DIvXW0rvMDP2nHZ4Mg==", + "license": "MIT" }, "node_modules/@types/json-schema": { "version": "7.0.15", @@ -2419,12 +2441,6 @@ "dev": true, "license": "MIT" }, - "node_modules/@types/minimatch": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz", - "integrity": "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==", - "license": "MIT" - }, "node_modules/@types/node": { "version": "22.13.1", "resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.1.tgz", @@ -2434,12 +2450,15 @@ "undici-types": "~6.20.0" } }, - "node_modules/@types/q": { - "version": "1.5.8", - "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.8.tgz", - "integrity": "sha512-hroOstUScF6zhIi+5+x0dzqrHA1EJi+Irri6b1fxolMTqqHIV/Cg77EtnQcZqZCu8hR3mX2BzIxN4/GzI68Kfw==", + "node_modules/@types/vinyl": { + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/@types/vinyl/-/vinyl-2.0.12.tgz", + "integrity": "sha512-Sr2fYMBUVGYq8kj3UthXFAu5UN6ZW+rYr4NACjZQJvHvj+c8lYv0CahmZ2P/r7iUkN44gGUBwqxZkrKXYPb7cw==", "license": "MIT", - "optional": true + "dependencies": { + "@types/expect": "^1.20.4", + "@types/node": "*" + } }, "node_modules/@ungap/structured-clone": { "version": "1.3.0", @@ -2844,12 +2863,15 @@ } }, "node_modules/ansi-regex": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", - "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", "license": "MIT", "engines": { - "node": ">=4" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, "node_modules/ansi-styles": { @@ -3056,16 +3078,6 @@ "node": ">=0.10.0" } }, - "node_modules/array-find-index": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", - "integrity": "sha512-M1HQyIXcBGtVywBt8WVdim+lrNaK7VHp99Qt5pSNziXznKHViIBbXWtfRTpEFpF/c4FdfxNAsCCwPp5phBYJtw==", - "license": "MIT", - "optional": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/array-includes": { "version": "3.1.8", "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.8.tgz", @@ -3199,28 +3211,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/array.prototype.reduce": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/array.prototype.reduce/-/array.prototype.reduce-1.0.7.tgz", - "integrity": "sha512-mzmiUCVwtiD4lgxYP8g7IYy8El8p2CSMePvIbTS7gchKir/L1fgJrk0yDKmAX6mnRQFKNADYIk8nNlTris5H1Q==", - "license": "MIT", - "optional": true, - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-array-method-boxes-properly": "^1.0.0", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", - "is-string": "^1.0.7" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/array.prototype.tosorted": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.4.tgz", @@ -3751,44 +3741,6 @@ "yallist": "^2.1.2" } }, - "node_modules/bin-build/node_modules/npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==", - "license": "MIT", - "optional": true, - "dependencies": { - "path-key": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/bin-build/node_modules/tempfile": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/tempfile/-/tempfile-2.0.0.tgz", - "integrity": "sha512-ZOn6nJUgvgC09+doCEF3oB+r3ag7kUvlsXEGX069QRD60p+P3uP7XG9N2/at+EyIRGSN//ZY3LyEotA1YpmjuA==", - "license": "MIT", - "optional": true, - "dependencies": { - "temp-dir": "^1.0.0", - "uuid": "^3.0.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/bin-build/node_modules/uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", - "license": "MIT", - "optional": true, - "bin": { - "uuid": "bin/uuid" - } - }, "node_modules/bin-build/node_modules/yallist": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", @@ -3852,19 +3804,6 @@ "yallist": "^2.1.2" } }, - "node_modules/bin-check/node_modules/npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==", - "license": "MIT", - "optional": true, - "dependencies": { - "path-key": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/bin-check/node_modules/yallist": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", @@ -3911,51 +3850,6 @@ "semver": "bin/semver" } }, - "node_modules/bin-version/node_modules/execa": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", - "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", - "license": "MIT", - "optional": true, - "dependencies": { - "cross-spawn": "^6.0.0", - "get-stream": "^4.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/bin-version/node_modules/get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "license": "MIT", - "optional": true, - "dependencies": { - "pump": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/bin-version/node_modules/npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==", - "license": "MIT", - "optional": true, - "dependencies": { - "path-key": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/bin-wrapper": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/bin-wrapper/-/bin-wrapper-4.1.0.tgz", @@ -3974,6 +3868,16 @@ "node": ">=6" } }, + "node_modules/bin-wrapper/node_modules/@sindresorhus/is": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.7.0.tgz", + "integrity": "sha512-ONhaKPIufzzrlNbqtWFFd+jlnemX6lJAgq9ZeiZtS7I1PIf/la7CW4m83rTXRnVnsMbW2k56pGYu7AUFJD9Pow==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=4" + } + }, "node_modules/bin-wrapper/node_modules/download": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/download/-/download-7.1.0.tgz", @@ -4116,16 +4020,6 @@ "node": ">=4" } }, - "node_modules/bin-wrapper/node_modules/pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "license": "MIT", - "optional": true, - "engines": { - "node": ">=6" - } - }, "node_modules/bin-wrapper/node_modules/prepend-http": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", @@ -4277,72 +4171,170 @@ "stream-throttle": "^0.1.3" } }, - "node_modules/browserslist": { - "version": "4.24.4", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.4.tgz", - "integrity": "sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], + "node_modules/browser-sync-ui/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "license": "MIT", "dependencies": { - "caniuse-lite": "^1.0.30001688", - "electron-to-chromium": "^1.5.73", - "node-releases": "^2.0.19", - "update-browserslist-db": "^1.1.1" - }, - "bin": { - "browserslist": "cli.js" + "color-convert": "^2.0.1" }, "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/bs-recipes": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/bs-recipes/-/bs-recipes-1.3.4.tgz", - "integrity": "sha512-BXvDkqhDNxXEjeGM8LFkSbR+jzmP/CYpCiVKYn+soB1dDldeU15EBNDkwVXndKuX35wnNUaPd0qSoQEAkmQtMw==", - "license": "ISC" - }, - "node_modules/buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], + "node_modules/browser-sync-ui/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "license": "MIT", "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/buffer-alloc": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz", - "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==", + "node_modules/browser-sync-ui/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/browser-sync-ui/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "license": "MIT" + }, + "node_modules/browser-sync/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/browser-sync/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/browser-sync/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/browser-sync/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "license": "MIT" + }, + "node_modules/browserslist": { + "version": "4.24.4", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.4.tgz", + "integrity": "sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "caniuse-lite": "^1.0.30001688", + "electron-to-chromium": "^1.5.73", + "node-releases": "^2.0.19", + "update-browserslist-db": "^1.1.1" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/bs-recipes": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/bs-recipes/-/bs-recipes-1.3.4.tgz", + "integrity": "sha512-BXvDkqhDNxXEjeGM8LFkSbR+jzmP/CYpCiVKYn+soB1dDldeU15EBNDkwVXndKuX35wnNUaPd0qSoQEAkmQtMw==", + "license": "ISC" + }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/buffer-alloc": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz", + "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==", "license": "MIT", "optional": true, "dependencies": { @@ -4471,28 +4463,16 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/camelcase": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", - "integrity": "sha512-DLIsRzJVBQu72meAKPkWQOLcujdXT32hwdfnkI1frSiSRMK1MofjKHf+MEx0SB6fjEFXL8fBDv1dKymBlOp4Qw==", + "node_modules/callsites": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-4.2.0.tgz", + "integrity": "sha512-kfzR4zzQtAE9PC7CzZsjl3aBNbXWuXiSeOCdLcPpBfGW8YuCqQHcRPFDbr/BPVmd3EEPVpuFzLyuT/cUhPr4OQ==", "license": "MIT", - "optional": true, "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/camelcase-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", - "integrity": "sha512-bA/Z/DERHKqoEOrp+qeGKw1QlvEQkGZSc0XaY6VnTxZr+Kv1G5zFwttpjv8qxZ/sBPT4nthwZaAcsAZTJlSKXQ==", - "license": "MIT", - "optional": true, - "dependencies": { - "camelcase": "^2.0.0", - "map-obj": "^1.0.0" + "node": ">=12.20" }, - "engines": { - "node": ">=0.10.0" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/caniuse-api": { @@ -4544,54 +4524,29 @@ } }, "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.4.1.tgz", + "integrity": "sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==", "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, "engines": { - "node": ">=10" + "node": "^12.17.0 || ^14.13 || >=16.0.0" }, "funding": { "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/chalk/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "node_modules/change-file-extension": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/change-file-extension/-/change-file-extension-0.1.1.tgz", + "integrity": "sha512-lB0j9teu8JtDPDHRfU8pNH33w4wMu5bOaKoT4PxH+AKugBrIfpiJMTTKIm0TErNeJPkeQEgvH31YpccTwOKPRg==", "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, "engines": { - "node": ">=8" + "node": ">=18" }, "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/chalk/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/chalk/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, "node_modules/chardet": { "version": "0.4.2", "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz", @@ -4811,59 +4766,6 @@ "node": ">= 0.12.0" } }, - "node_modules/coa": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/coa/-/coa-2.0.2.tgz", - "integrity": "sha512-q5/jG+YQnSy4nRTV4F7lPepBJZ8qBNJJDBuJdoejDyLXgmL7IEo+Le2JDZudFTFt7mrCqIRaSjws4ygRCTCAXA==", - "license": "MIT", - "optional": true, - "dependencies": { - "@types/q": "^1.5.1", - "chalk": "^2.4.1", - "q": "^1.1.2" - }, - "engines": { - "node": ">= 4.0" - } - }, - "node_modules/coa/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "license": "MIT", - "optional": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/coa/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "license": "MIT", - "optional": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/coa/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "license": "MIT", - "optional": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/code-point-at": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", @@ -5180,12 +5082,6 @@ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "license": "MIT" }, - "node_modules/console-stream": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/console-stream/-/console-stream-0.1.1.tgz", - "integrity": "sha512-QC/8l9e6ofi6nqZ5PawlDgzmMw3OxIXtvolBzap/F4UDBJlDaZRSNbL/lb41C29FcbSJncBFlJFj2WJoNyZRfQ==", - "optional": true - }, "node_modules/content-disposition": { "version": "0.5.4", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", @@ -5199,6 +5095,18 @@ "node": ">= 0.6" } }, + "node_modules/convert-hrtime": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/convert-hrtime/-/convert-hrtime-5.0.0.tgz", + "integrity": "sha512-lOETlkIeYSJWcbbcvjRKGxVMXJR+8+OQb/mTPbA4ObPMytYIsUbuOE0Jzy60hjARYszq1id0j8KgVhC+WGZVTg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/convert-source-map": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", @@ -5275,36 +5183,6 @@ "node": ">=4.8" } }, - "node_modules/cross-spawn-async": { - "version": "2.2.5", - "resolved": "https://registry.npmjs.org/cross-spawn-async/-/cross-spawn-async-2.2.5.tgz", - "integrity": "sha512-snteb3aVrxYYOX9e8BabYFK9WhCDhTlw1YQktfTthBogxri4/2r9U2nQc0ffY73ZAxezDc+U8gvHAeU1wy1ubQ==", - "deprecated": "cross-spawn no longer requires a build toolchain, use it instead", - "license": "MIT", - "optional": true, - "dependencies": { - "lru-cache": "^4.0.0", - "which": "^1.2.8" - } - }, - "node_modules/cross-spawn-async/node_modules/lru-cache": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", - "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", - "license": "ISC", - "optional": true, - "dependencies": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" - } - }, - "node_modules/cross-spawn-async/node_modules/yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==", - "license": "ISC", - "optional": true - }, "node_modules/cross-spawn/node_modules/semver": { "version": "5.7.2", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", @@ -5366,56 +5244,46 @@ } }, "node_modules/css-select": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-2.1.0.tgz", - "integrity": "sha512-Dqk7LQKpwLoH3VovzZnkzegqNSuAziQyNZUcrdDM401iY+R5NkGBXGmtO05/yaXQziALuPogeG0b7UAgjnTJTQ==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz", + "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==", "license": "BSD-2-Clause", "optional": true, "dependencies": { "boolbase": "^1.0.0", - "css-what": "^3.2.1", - "domutils": "^1.7.0", - "nth-check": "^1.0.2" - } - }, - "node_modules/css-select-base-adapter": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz", - "integrity": "sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w==", - "license": "MIT", - "optional": true - }, - "node_modules/css-select/node_modules/css-what": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-3.4.2.tgz", - "integrity": "sha512-ACUm3L0/jiZTqfzRM3Hi9Q8eZqd6IK37mMWPLz9PJxkLWllYeRf+EHUSHYEtFop2Eqytaq1FizFVh7XfBnXCDQ==", - "license": "BSD-2-Clause", - "optional": true, - "engines": { - "node": ">= 6" + "css-what": "^6.0.1", + "domhandler": "^4.3.1", + "domutils": "^2.8.0", + "nth-check": "^2.0.1" }, "funding": { "url": "https://github.com/sponsors/fb55" } }, - "node_modules/css-select/node_modules/nth-check": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz", - "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==", + "node_modules/css-select/node_modules/domhandler": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", + "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", "license": "BSD-2-Clause", "optional": true, "dependencies": { - "boolbase": "~1.0.0" + "domelementtype": "^2.2.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" } }, "node_modules/css-tree": { - "version": "1.0.0-alpha.37", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.37.tgz", - "integrity": "sha512-DMxWJg0rnz7UgxKT0Q1HU/L9BeJI0M6ksor0OgqOnF+aRCDWg/N2641HmVyU9KVIu0OVVWOb2IpC9A+BJRnejg==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", + "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", "license": "MIT", "optional": true, "dependencies": { - "mdn-data": "2.0.4", + "mdn-data": "2.0.14", "source-map": "^0.6.1" }, "engines": { @@ -5554,50 +5422,6 @@ "node": ">=8.0.0" } }, - "node_modules/csso/node_modules/css-tree": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", - "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", - "license": "MIT", - "optional": true, - "dependencies": { - "mdn-data": "2.0.14", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/csso/node_modules/mdn-data": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", - "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==", - "license": "CC0-1.0", - "optional": true - }, - "node_modules/csso/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "license": "BSD-3-Clause", - "optional": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/currently-unhandled": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", - "integrity": "sha512-/fITjgjGU50vjQ4FH6eUoYu+iUoUKIXws2hL15JJpIR+BbTxaXQsMuuyjtNh2WqsSBS5nsaZHFsFecyw5CCAng==", - "license": "MIT", - "optional": true, - "dependencies": { - "array-find-index": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/d": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/d/-/d-1.0.2.tgz", @@ -5669,12 +5493,12 @@ } }, "node_modules/dateformat": { - "version": "4.6.3", - "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-4.6.3.tgz", - "integrity": "sha512-2P0p0pFGzHS5EMnhdxQi7aJN+iMheud0UhG4dlE1DLAlvL8JHjJJTX/CSm4JXwV0Ka5nGk3zC5mcb5bUQUxxMA==", + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-5.0.3.tgz", + "integrity": "sha512-Kvr6HmPXUMerlLcLF+Pwq3K7apHpYmGDVqrxcDasBg86UcKeTSNWbEzU8bwdXnxnR44FtMhJAxI4Bov6Y/KUfA==", "license": "MIT", "engines": { - "node": "*" + "node": ">=12.20" } }, "node_modules/debug": { @@ -5714,16 +5538,6 @@ "ms": "^2.1.1" } }, - "node_modules/decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", - "license": "MIT", - "optional": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/decode-uri-component": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz", @@ -5883,6 +5697,16 @@ "node": ">=0.10.0" } }, + "node_modules/decompress-unzip/node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/decompress/node_modules/make-dir": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", @@ -5906,6 +5730,16 @@ "node": ">=4" } }, + "node_modules/decompress/node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", @@ -6135,14 +5969,34 @@ } }, "node_modules/dom-serializer": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz", - "integrity": "sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", + "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", "license": "MIT", "optional": true, "dependencies": { "domelementtype": "^2.0.1", + "domhandler": "^4.2.0", "entities": "^2.0.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/dom-serializer/node_modules/domhandler": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", + "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", + "license": "BSD-2-Clause", + "optional": true, + "dependencies": { + "domelementtype": "^2.2.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" } }, "node_modules/domelementtype": { @@ -6173,22 +6027,62 @@ } }, "node_modules/domutils": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", - "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", + "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", "license": "BSD-2-Clause", "optional": true, "dependencies": { - "dom-serializer": "0", - "domelementtype": "1" + "dom-serializer": "^1.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" } }, - "node_modules/domutils/node_modules/domelementtype": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", - "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==", + "node_modules/domutils/node_modules/domhandler": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", + "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", "license": "BSD-2-Clause", - "optional": true + "optional": true, + "dependencies": { + "domelementtype": "^2.2.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/dot-prop": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-8.0.2.tgz", + "integrity": "sha512-xaBe6ZT4DHPkg0k4Ytbvn5xoxgpG0jOS1dYxSOwAHPuNLjP3/OzN0gH55SrLqpx8cBfSaVt91lXYkApjb+nYdQ==", + "license": "MIT", + "dependencies": { + "type-fest": "^3.8.0" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/dot-prop/node_modules/type-fest": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-3.13.1.tgz", + "integrity": "sha512-tLq3bSNx+xSpwvAJnzrK0Ep5CLNWjvFTOp71URMaAEWBfRb9nnJiBoUe0tF8bI4ZFO3omgBR6NvnbzVUT3Ly4g==", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, "node_modules/dotenv": { "version": "16.4.7", @@ -6360,6 +6254,18 @@ "node": ">= 4.0.0" } }, + "node_modules/easy-transform-stream": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/easy-transform-stream/-/easy-transform-stream-1.0.1.tgz", + "integrity": "sha512-ktkaa6XR7COAR3oj02CF3IOgz2m1hCaY3SfzvKT4Svt2MhHw9XCt+ncJNWfe2TGz31iqzNGZ8spdKQflj+Rlog==", + "license": "MIT", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/eazy-logger": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/eazy-logger/-/eazy-logger-4.0.1.tgz", @@ -6371,6 +6277,55 @@ "node": ">= 0.8.0" } }, + "node_modules/eazy-logger/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/eazy-logger/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/eazy-logger/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/eazy-logger/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "license": "MIT" + }, "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", @@ -6525,6 +6480,18 @@ "url": "https://github.com/fb55/entities?sponsor=1" } }, + "node_modules/environment": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/environment/-/environment-1.1.0.tgz", + "integrity": "sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/errno": { "version": "0.1.8", "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz", @@ -6541,7 +6508,7 @@ "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "devOptional": true, + "dev": true, "license": "MIT", "dependencies": { "is-arrayish": "^0.2.1" @@ -6608,16 +6575,9 @@ "engines": { "node": ">= 0.4" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/es-array-method-boxes-properly": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz", - "integrity": "sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==", - "license": "MIT", - "optional": true + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, "node_modules/es-define-property": { "version": "1.0.1", @@ -7764,45 +7724,111 @@ } }, "node_modules/exec-buffer": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/exec-buffer/-/exec-buffer-3.0.0.tgz", - "integrity": "sha512-i9jNtQdbwQ+6AScOdzSbjYLlnvZu9XNyrC8m11neHwbEYdXz/QZWriul+KkZ5kIqy89Gx6FrMnZFD450RZ20FQ==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/exec-buffer/-/exec-buffer-3.2.0.tgz", + "integrity": "sha512-wsiD+2Tp6BWHoVv3B+5Dcx6E7u5zky+hUwOHjuH2hKSLR3dvRmX8fk8UD8uqQixHs4Wk6eDmiegVrMPjKj7wpA==", "license": "MIT", "optional": true, "dependencies": { - "execa": "^0.3.0", - "pify": "^2.3.0", - "tempfile": "^1.0.0" + "execa": "^0.7.0", + "p-finally": "^1.0.0", + "pify": "^3.0.0", + "rimraf": "^2.5.4", + "tempfile": "^2.0.0" }, "engines": { "node": ">=4" } }, - "node_modules/execa": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-0.3.0.tgz", - "integrity": "sha512-7evPG+NsML0PuUTKprHnSDKBZXfouIuSLcc5WqJxnKBVpLMwrOZNPssiZIUHE6S7mW2pD+aPuVg4MNUcnqIwnA==", + "node_modules/exec-buffer/node_modules/cross-spawn": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", + "integrity": "sha512-pTgQJ5KC0d2hcY8eyL1IzlBPYjTkyH72XRZPnLyKus2mBfNjQs3klqbJU2VILqZryAZUt9JOb3h/mWMy23/f5A==", "license": "MIT", "optional": true, "dependencies": { - "cross-spawn-async": "^2.1.1", - "npm-run-path": "^1.0.0", - "object-assign": "^4.0.1", - "path-key": "^1.0.0", + "lru-cache": "^4.0.1", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "node_modules/exec-buffer/node_modules/execa": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", + "integrity": "sha512-RztN09XglpYI7aBBrJCPW95jEH7YF1UEPOoX9yDhUTPdp7mK+CQvnLTuD10BNXZ3byLTu2uehZ8EcKT/4CGiFw==", + "license": "MIT", + "optional": true, + "dependencies": { + "cross-spawn": "^5.0.1", + "get-stream": "^3.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", "strip-eof": "^1.0.0" }, "engines": { - "node": ">=0.12" + "node": ">=4" + } + }, + "node_modules/exec-buffer/node_modules/lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "license": "ISC", + "optional": true, + "dependencies": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "node_modules/exec-buffer/node_modules/pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=4" } }, - "node_modules/execa/node_modules/path-key": { + "node_modules/exec-buffer/node_modules/yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==", + "license": "ISC", + "optional": true + }, + "node_modules/execa": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-1.0.0.tgz", - "integrity": "sha512-T3hWy7tyXlk3QvPFnT+o2tmXRzU4GkitkUWLp/WZ0S/FXd7XMx176tRurgTvHTNMJOQzTcesHNpBqetH86mQ9g==", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "license": "MIT", + "optional": true, + "dependencies": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/execa/node_modules/get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", "license": "MIT", "optional": true, + "dependencies": { + "pump": "^3.0.0" + }, "engines": { - "node": ">=0.10.0" + "node": ">=6" } }, "node_modules/executable": { @@ -7818,6 +7844,16 @@ "node": ">=4" } }, + "node_modules/executable/node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/exit-code": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/exit-code/-/exit-code-1.0.2.tgz", @@ -7944,6 +7980,15 @@ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "license": "MIT" }, + "node_modules/fast-equals": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/fast-equals/-/fast-equals-5.2.2.tgz", + "integrity": "sha512-V7/RktU11J3I36Nwq2JnZEM7tNm17eBJz+u25qdxBZeCKiX6BkVSZQjwWIr+IobgnZy+ag73tTZgZi7tr0LrBw==", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/fast-fifo": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", @@ -7996,23 +8041,19 @@ "peer": true }, "node_modules/fast-xml-parser": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.5.1.tgz", - "integrity": "sha512-y655CeyUQ+jj7KBbYMc4FG01V8ZQqjN+gDYGJ50RtfsUB8iG9AmwmwoAgeKLJdmueKKMrH1RJ7yXHTSoczdv5w==", + "version": "4.5.3", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.5.3.tgz", + "integrity": "sha512-RKihhV+SHsIUGXObeVy9AXiBbFwkVk7Syp8XgwN5U3JV416+Gwp/GO9i0JYKmikykgz/UHRrrV4ROuZEo/T0ig==", "funding": [ { "type": "github", "url": "https://github.com/sponsors/NaturalIntelligence" - }, - { - "type": "paypal", - "url": "https://paypal.me/naturalintelligence" } ], "license": "MIT", "optional": true, "dependencies": { - "strnum": "^1.0.5" + "strnum": "^1.1.1" }, "bin": { "fxparser": "src/cli/cli.js" @@ -8071,12 +8112,49 @@ } }, "node_modules/file-type": { - "version": "12.4.2", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-12.4.2.tgz", - "integrity": "sha512-UssQP5ZgIOKelfsaB5CuGAL+Y+q7EmONuiwF3N5HAH0t27rvrttgi6Ra9k/+DVaY9UF6+ybxu5pOXLUdA8N7Vg==", + "version": "19.6.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-19.6.0.tgz", + "integrity": "sha512-VZR5I7k5wkD0HgFnMsq5hOsSc710MJMu5Nc5QYsbe38NN5iPV/XTObYLc/cpttRTf6lX538+5uO1ZQRhYibiZQ==", "license": "MIT", + "dependencies": { + "get-stream": "^9.0.1", + "strtok3": "^9.0.1", + "token-types": "^6.0.0", + "uint8array-extras": "^1.3.0" + }, "engines": { - "node": ">=8" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sindresorhus/file-type?sponsor=1" + } + }, + "node_modules/file-type/node_modules/get-stream": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-9.0.1.tgz", + "integrity": "sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==", + "license": "MIT", + "dependencies": { + "@sec-ant/readable-stream": "^0.4.1", + "is-stream": "^4.0.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/file-type/node_modules/is-stream": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-4.0.1.tgz", + "integrity": "sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/filename-reserved-regex": { @@ -8437,6 +8515,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/function-timeout": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/function-timeout/-/function-timeout-1.0.2.tgz", + "integrity": "sha512-939eZS4gJ3htTHAldmyyuzlrD58P03fHG49v2JfFXbV6OhvZKRC9j2yAtdHw/zrp2zXHuv05zMIy40F0ge7spA==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/function.prototype.name": { "version": "1.1.8", "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.8.tgz", @@ -8552,128 +8642,235 @@ "node": ">= 0.4" } }, - "node_modules/get-proxy": { + "node_modules/get-proxy": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/get-proxy/-/get-proxy-2.1.0.tgz", + "integrity": "sha512-zmZIaQTWnNQb4R4fJUEp/FC51eZsc6EkErspy3xtIYStaq8EB/hDIWipxsal+E8rz0qD7f2sL/NA9Xee4RInJw==", + "license": "MIT", + "optional": true, + "dependencies": { + "npm-conf": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/get-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "integrity": "sha512-GlhdIUuVakc8SJ6kK0zAFbiGzRFzNnY4jUuEbV9UROo4Y+0Ny4fjvcZFVTeDA4odpFyOQzaw6hXukJSq/f28sQ==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/get-symbol-description": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz", + "integrity": "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gettext-parser": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/gettext-parser/-/gettext-parser-1.4.0.tgz", + "integrity": "sha512-sedZYLHlHeBop/gZ1jdg59hlUEcpcZJofLq2JFwJT1zTqAU3l2wFv6IsuwFHGqbiT9DWzMUW4/em2+hspnmMMA==", + "license": "MIT", + "dependencies": { + "encoding": "^0.1.12", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/gifsicle": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/gifsicle/-/gifsicle-5.3.0.tgz", + "integrity": "sha512-FJTpgdj1Ow/FITB7SVza5HlzXa+/lqEY0tHQazAJbuAdvyJtkH4wIdsR2K414oaTwRXHFLLF+tYbipj+OpYg+Q==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "dependencies": { + "bin-build": "^3.0.0", + "bin-wrapper": "^4.0.0", + "execa": "^5.0.0" + }, + "bin": { + "gifsicle": "cli.js" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/imagemin/gisicle-bin?sponsor=1" + } + }, + "node_modules/gifsicle/node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "license": "MIT", + "optional": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/gifsicle/node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "license": "MIT", + "optional": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/gifsicle/node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/gifsicle/node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/gifsicle/node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "license": "MIT", + "optional": true + }, + "node_modules/gifsicle/node_modules/mimic-fn": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/get-proxy/-/get-proxy-2.1.0.tgz", - "integrity": "sha512-zmZIaQTWnNQb4R4fJUEp/FC51eZsc6EkErspy3xtIYStaq8EB/hDIWipxsal+E8rz0qD7f2sL/NA9Xee4RInJw==", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", "license": "MIT", "optional": true, - "dependencies": { - "npm-conf": "^1.1.0" - }, "engines": { - "node": ">=4" + "node": ">=6" } }, - "node_modules/get-stdin": { + "node_modules/gifsicle/node_modules/npm-run-path": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", - "integrity": "sha512-F5aQMywwJ2n85s4hJPTT9RPxGmubonuB10MNYo17/xph174n2MIR33HRguhzVag10O/npM7SPk73LMZNP+FaWw==", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", "license": "MIT", "optional": true, + "dependencies": { + "path-key": "^3.0.0" + }, "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/get-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", - "integrity": "sha512-GlhdIUuVakc8SJ6kK0zAFbiGzRFzNnY4jUuEbV9UROo4Y+0Ny4fjvcZFVTeDA4odpFyOQzaw6hXukJSq/f28sQ==", - "license": "MIT", - "engines": { - "node": ">=4" + "node": ">=8" } }, - "node_modules/get-symbol-description": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz", - "integrity": "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==", + "node_modules/gifsicle/node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", "license": "MIT", + "optional": true, "dependencies": { - "call-bound": "^1.0.3", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.6" + "mimic-fn": "^2.1.0" }, "engines": { - "node": ">= 0.4" + "node": ">=6" }, "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/gettext-parser": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/gettext-parser/-/gettext-parser-1.4.0.tgz", - "integrity": "sha512-sedZYLHlHeBop/gZ1jdg59hlUEcpcZJofLq2JFwJT1zTqAU3l2wFv6IsuwFHGqbiT9DWzMUW4/em2+hspnmMMA==", - "license": "MIT", - "dependencies": { - "encoding": "^0.1.12", - "safe-buffer": "^5.1.1" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/gifsicle": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/gifsicle/-/gifsicle-4.0.1.tgz", - "integrity": "sha512-A/kiCLfDdV+ERV/UB+2O41mifd+RxH8jlRG8DMxZO84Bma/Fw0htqZ+hY2iaalLRNyUu7tYZQslqUBJxBggxbg==", - "hasInstallScript": true, + "node_modules/gifsicle/node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "license": "MIT", "optional": true, - "dependencies": { - "bin-build": "^3.0.0", - "bin-wrapper": "^4.0.0", - "execa": "^1.0.0", - "logalot": "^2.0.0" - }, - "bin": { - "gifsicle": "cli.js" - }, "engines": { - "node": ">=6" + "node": ">=8" } }, - "node_modules/gifsicle/node_modules/execa": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", - "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "node_modules/gifsicle/node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "license": "MIT", "optional": true, "dependencies": { - "cross-spawn": "^6.0.0", - "get-stream": "^4.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" + "shebang-regex": "^3.0.0" }, "engines": { - "node": ">=6" + "node": ">=8" } }, - "node_modules/gifsicle/node_modules/get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "node_modules/gifsicle/node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "license": "MIT", "optional": true, - "dependencies": { - "pump": "^3.0.0" - }, "engines": { - "node": ">=6" + "node": ">=8" } }, - "node_modules/gifsicle/node_modules/npm-run-path": { + "node_modules/gifsicle/node_modules/which": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==", - "license": "MIT", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "license": "ISC", "optional": true, "dependencies": { - "path-key": "^2.0.0" + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" }, "engines": { - "node": ">=4" + "node": ">= 8" } }, "node_modules/git-config-path": { @@ -8851,33 +9048,58 @@ } }, "node_modules/globby": { - "version": "10.0.2", - "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.2.tgz", - "integrity": "sha512-7dUi7RvCoT/xast/o/dLN53oqND4yk0nsHkhRgn9w65C4PofCLOoJ39iSOg+qVDdWQPIEj+eszMHQ+aLVwwQSg==", + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-14.1.0.tgz", + "integrity": "sha512-0Ia46fDOaT7k4og1PDW4YbodWWr3scS2vAr2lTbsplOt2WkKp0vQbkI9wKis/T5LV/dqPjO3bpS/z6GTJB82LA==", "license": "MIT", "dependencies": { - "@types/glob": "^7.1.1", - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.0.3", - "glob": "^7.1.3", - "ignore": "^5.1.1", - "merge2": "^1.2.3", - "slash": "^3.0.0" + "@sindresorhus/merge-streams": "^2.1.0", + "fast-glob": "^3.3.3", + "ignore": "^7.0.3", + "path-type": "^6.0.0", + "slash": "^5.1.0", + "unicorn-magic": "^0.3.0" }, "engines": { - "node": ">=8" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/globby/node_modules/ignore": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", - "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.3.tgz", + "integrity": "sha512-bAH5jbK/F3T3Jls4I0SO1hmPR0dKU0a7+SY6n1yzRtG54FLO8d6w/nxLFX2Nb7dBu6cCWXPaAME6cYqFUMmuCA==", "license": "MIT", "engines": { "node": ">= 4" } }, + "node_modules/globby/node_modules/path-type": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-6.0.0.tgz", + "integrity": "sha512-Vj7sf++t5pBD637NSfkxpHSMfWaeig5+DKWLhcqIYx6mWQz5hdJTGDVMQiJcw1ZYkhs7AazKDGpRVji1LJCZUQ==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globby/node_modules/slash": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz", + "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==", + "license": "MIT", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/globule": { "version": "1.3.4", "resolved": "https://registry.npmjs.org/globule/-/globule-1.3.4.tgz", @@ -9095,6 +9317,37 @@ "node": ">=8" } }, + "node_modules/gulp-cli/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/gulp-cli/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, "node_modules/gulp-cli/node_modules/cliui": { "version": "7.0.4", "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", @@ -9106,6 +9359,24 @@ "wrap-ansi": "^7.0.0" } }, + "node_modules/gulp-cli/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/gulp-cli/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "license": "MIT" + }, "node_modules/gulp-cli/node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", @@ -9420,6 +9691,15 @@ "ajv": "^5.0.0" } }, + "node_modules/gulp-eslint/node_modules/ansi-regex": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", + "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, "node_modules/gulp-eslint/node_modules/chalk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", @@ -9686,6 +9966,18 @@ "node": ">=4" } }, + "node_modules/gulp-eslint/node_modules/strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/gulp-eslint/node_modules/strip-json-comments": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", @@ -9835,107 +10127,61 @@ "node": ">= 0.10.0" } }, - "node_modules/gulp-imagemin": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/gulp-imagemin/-/gulp-imagemin-6.2.0.tgz", - "integrity": "sha512-luHT+8kUz60KGzjJLUFzaPjl4b38UQLj8BJGkpJACRjiVEuzjohMOmLagkgXs+Rs4vYaUBr9tt1F/vLizaxgGg==", - "license": "MIT", - "dependencies": { - "chalk": "^2.4.1", - "fancy-log": "^1.3.2", - "imagemin": "^7.0.0", - "plugin-error": "^1.0.1", - "plur": "^3.0.1", - "pretty-bytes": "^5.3.0", - "through2-concurrent": "^2.0.0" - }, - "engines": { - "node": ">=8" - }, - "optionalDependencies": { - "imagemin-gifsicle": "^6.0.1", - "imagemin-jpegtran": "^6.0.0", - "imagemin-optipng": "^7.0.0", - "imagemin-svgo": "^7.0.0" - }, - "peerDependencies": { - "gulp": ">=4" - }, - "peerDependenciesMeta": { - "gulp": { - "optional": true - } - } - }, - "node_modules/gulp-imagemin/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/gulp-imagemin/node_modules/fancy-log": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/fancy-log/-/fancy-log-1.3.3.tgz", - "integrity": "sha512-k9oEhlyc0FrVh25qYuSELjr8oxsCoc4/LEZfg2iJJrfEk/tZL9bCoJE47gqAvI2m/AUjluCS4+3I0eTx8n3AEw==", - "license": "MIT", - "dependencies": { - "ansi-gray": "^0.1.1", - "color-support": "^1.1.3", - "parse-node-version": "^1.0.0", - "time-stamp": "^1.0.0" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/gulp-imagemin/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "node_modules/gulp-imagemin": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/gulp-imagemin/-/gulp-imagemin-9.1.0.tgz", + "integrity": "sha512-PmzTWoNrVMYVN4ObRdHyt6oer4mqxV53IbCDi3Q8EHeDZW0OzAuh6RlOtpd/R7PFmbDUk64q5P+L04fD9I5cVA==", "license": "MIT", + "dependencies": { + "chalk": "^5.3.0", + "gulp-plugin-extras": "^1.0.0", + "imagemin": "^9.0.0", + "plur": "^5.1.0", + "pretty-bytes": "^6.1.1" + }, "engines": { - "node": ">=4" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + }, + "optionalDependencies": { + "imagemin-gifsicle": "^7.0.0", + "imagemin-mozjpeg": "^10.0.0", + "imagemin-optipng": "^8.0.0", + "imagemin-svgo": "^10.0.1" + }, + "peerDependencies": { + "gulp": ">=4" + }, + "peerDependenciesMeta": { + "gulp": { + "optional": true + } } }, "node_modules/gulp-imagemin/node_modules/irregular-plurals": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/irregular-plurals/-/irregular-plurals-2.0.0.tgz", - "integrity": "sha512-Y75zBYLkh0lJ9qxeHlMjQ7bSbyiSqNW/UOPWDmzC7cXskL1hekSITh1Oc6JV0XCWWZ9DE8VYSB71xocLk3gmGw==", + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/irregular-plurals/-/irregular-plurals-3.5.0.tgz", + "integrity": "sha512-1ANGLZ+Nkv1ptFb2pa8oG8Lem4krflKuX/gINiHJHjJUKaJHk/SXk5x6K3J+39/p0h1RQ2saROclJJ+QLvETCQ==", "license": "MIT", "engines": { - "node": ">=6" + "node": ">=8" } }, "node_modules/gulp-imagemin/node_modules/plur": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/plur/-/plur-3.1.1.tgz", - "integrity": "sha512-t1Ax8KUvV3FFII8ltczPn2tJdjqbd1sIzu6t4JL7nQ3EyeL/lTrj5PWKb06ic5/6XYDr65rQ4uzQEGN70/6X5w==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/plur/-/plur-5.1.0.tgz", + "integrity": "sha512-VP/72JeXqak2KiOzjgKtQen5y3IZHn+9GOuLDafPv0eXa47xq0At93XahYBs26MsifCQ4enGKwbjBTKgb9QJXg==", "license": "MIT", "dependencies": { - "irregular-plurals": "^2.0.0" + "irregular-plurals": "^3.3.0" }, "engines": { - "node": ">=6" - } - }, - "node_modules/gulp-imagemin/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "license": "MIT", - "dependencies": { - "has-flag": "^3.0.0" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, - "engines": { - "node": ">=4" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/gulp-load-plugins": { @@ -10171,6 +10417,23 @@ "node": ">=4" } }, + "node_modules/gulp-plugin-extras": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/gulp-plugin-extras/-/gulp-plugin-extras-1.1.0.tgz", + "integrity": "sha512-T0AXOEVoKYzLIBlwEZ7LtAx2w4ExIozIoxVeYEVLFbdxI7i0sWvFDq0F8mm47djixDF3vAqDPoyGwh3Sg/PWtQ==", + "license": "MIT", + "dependencies": { + "@types/vinyl": "^2.0.12", + "chalk": "^5.3.0", + "easy-transform-stream": "^1.0.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/gulp-postcss": { "version": "10.0.0", "resolved": "https://registry.npmjs.org/gulp-postcss/-/gulp-postcss-10.0.0.tgz", @@ -10900,13 +11163,6 @@ "node": ">=0.10.0" } }, - "node_modules/hosted-git-info": { - "version": "2.8.9", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", - "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", - "license": "ISC", - "optional": true - }, "node_modules/http-cache-semantics": { "version": "3.8.1", "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz", @@ -10953,6 +11209,16 @@ "node": ">=8.0.0" } }, + "node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "license": "Apache-2.0", + "optional": true, + "engines": { + "node": ">=10.17.0" + } + }, "node_modules/iconv-lite": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", @@ -10965,6 +11231,21 @@ "node": ">=0.10.0" } }, + "node_modules/identifier-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/identifier-regex/-/identifier-regex-1.0.0.tgz", + "integrity": "sha512-Rcy5cjBOM9iTR+Vwy0Llyip9u0cA99T1yiWOhDW/+PDaTQhyski0tMovsipQ/FRNDkudjLWusJ/IMVIlG5WZnQ==", + "license": "MIT", + "dependencies": { + "reserved-identifiers": "^1.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/ieee754": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", @@ -10995,92 +11276,305 @@ } }, "node_modules/imagemin": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/imagemin/-/imagemin-7.0.1.tgz", - "integrity": "sha512-33AmZ+xjZhg2JMCe+vDf6a9mzWukE7l+wAtesjE7KyteqqKjzxv7aVQeWnul1Ve26mWvEQqyPwl0OctNBfSR9w==", + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/imagemin/-/imagemin-9.0.0.tgz", + "integrity": "sha512-oFlmioXTIrDCNYiKUVPjzUzm8M/7X74WEO6v8NFjn3ZtxjArdVJiRRdbPpq/OG4BdwaHMUz8ej9Fp4AcaDzMnA==", "license": "MIT", "dependencies": { - "file-type": "^12.0.0", - "globby": "^10.0.0", - "graceful-fs": "^4.2.2", - "junk": "^3.1.0", - "make-dir": "^3.0.0", - "p-pipe": "^3.0.0", - "replace-ext": "^1.0.0" + "change-file-extension": "^0.1.1", + "environment": "^1.0.0", + "file-type": "^19.0.0", + "globby": "^14.0.1", + "junk": "^4.0.1", + "ow": "^2.0.0", + "p-pipe": "^4.0.0", + "slash": "^5.1.0", + "uint8array-extras": "^1.1.0" }, "engines": { - "node": ">=8" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/imagemin-gifsicle": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/imagemin-gifsicle/-/imagemin-gifsicle-6.0.1.tgz", - "integrity": "sha512-kuu47c6iKDQ6R9J10xCwL0lgs0+sMz3LRHqRcJ2CRBWdcNmo3T5hUaM8hSZfksptZXJLGKk8heSAvwtSdB1Fng==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/imagemin-gifsicle/-/imagemin-gifsicle-7.0.0.tgz", + "integrity": "sha512-LaP38xhxAwS3W8PFh4y5iQ6feoTSF+dTAXFRUEYQWYst6Xd+9L/iPk34QGgK/VO/objmIlmq9TStGfVY2IcHIA==", "license": "MIT", "optional": true, "dependencies": { - "exec-buffer": "^3.0.0", - "gifsicle": "^4.0.0", + "execa": "^1.0.0", + "gifsicle": "^5.0.0", "is-gif": "^3.0.0" }, "engines": { - "node": ">=6" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/imagemin/imagemin-gifsicle?sponsor=1" + } + }, + "node_modules/imagemin-mozjpeg": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/imagemin-mozjpeg/-/imagemin-mozjpeg-10.0.0.tgz", + "integrity": "sha512-DK85QNOjS3/GzWYfNB3CACMZD10sIQgFDv1+WTOnZljgltQTEyATjdyUVyjKu5q4sCESQdwvwq7WEZzJ5fFjlg==", + "license": "MIT", + "optional": true, + "dependencies": { + "execa": "^6.0.0", + "is-jpg": "^3.0.0", + "mozjpeg": "^8.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/imagemin-mozjpeg/node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "license": "MIT", + "optional": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/imagemin-mozjpeg/node_modules/execa": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-6.1.0.tgz", + "integrity": "sha512-QVWlX2e50heYJcCPG0iWtf8r0xjEYfz/OYLGDYH+IyjWezzPNxz63qNFOu0l4YftGWuizFVZHHs8PrLU5p2IDA==", + "license": "MIT", + "optional": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.1", + "human-signals": "^3.0.1", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^3.0.7", + "strip-final-newline": "^3.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/imagemin-mozjpeg/node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/imagemin-jpegtran": { + "node_modules/imagemin-mozjpeg/node_modules/human-signals": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-3.0.1.tgz", + "integrity": "sha512-rQLskxnM/5OCldHo+wNXbpVgDn5A17CUoKX+7Sokwaknlq7CdSnphy0W39GU8dw59XiCXmFXDg4fRuckQRKewQ==", + "license": "Apache-2.0", + "optional": true, + "engines": { + "node": ">=12.20.0" + } + }, + "node_modules/imagemin-mozjpeg/node_modules/is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", + "license": "MIT", + "optional": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imagemin-mozjpeg/node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "license": "MIT", + "optional": true + }, + "node_modules/imagemin-mozjpeg/node_modules/mimic-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imagemin-mozjpeg/node_modules/npm-run-path": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", + "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "path-key": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imagemin-mozjpeg/node_modules/npm-run-path/node_modules/path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imagemin-mozjpeg/node_modules/onetime": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/imagemin-jpegtran/-/imagemin-jpegtran-6.0.0.tgz", - "integrity": "sha512-Ih+NgThzqYfEWv9t58EItncaaXIHR0u9RuhKa8CtVBlMBvY0dCIxgQJQCfwImA4AV1PMfmUKlkyIHJjb7V4z1g==", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", "license": "MIT", "optional": true, "dependencies": { - "exec-buffer": "^3.0.0", - "is-jpg": "^2.0.0", - "jpegtran-bin": "^4.0.0" + "mimic-fn": "^4.0.0" }, "engines": { - "node": ">=6" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imagemin-mozjpeg/node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/imagemin-mozjpeg/node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "license": "MIT", + "optional": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/imagemin-mozjpeg/node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/imagemin-mozjpeg/node_modules/strip-final-newline": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imagemin-mozjpeg/node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "license": "ISC", + "optional": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" } }, "node_modules/imagemin-optipng": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/imagemin-optipng/-/imagemin-optipng-7.1.0.tgz", - "integrity": "sha512-JNORTZ6j6untH7e5gF4aWdhDCxe3ODsSLKs/f7Grewy3ebZpl1ZsU+VUTPY4rzeHgaFA8GSWOoA8V2M3OixWZQ==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/imagemin-optipng/-/imagemin-optipng-8.0.0.tgz", + "integrity": "sha512-CUGfhfwqlPjAC0rm8Fy+R2DJDBGjzy2SkfyT09L8rasnF9jSoHFqJ1xxSZWK6HVPZBMhGPMxCTL70OgTHlLF5A==", "license": "MIT", "optional": true, "dependencies": { "exec-buffer": "^3.0.0", "is-png": "^2.0.0", - "optipng-bin": "^6.0.0" + "optipng-bin": "^7.0.0" }, "engines": { - "node": ">=8" + "node": ">=10" } }, "node_modules/imagemin-svgo": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/imagemin-svgo/-/imagemin-svgo-7.1.0.tgz", - "integrity": "sha512-0JlIZNWP0Luasn1HT82uB9nU9aa+vUj6kpT+MjPW11LbprXC+iC4HDwn1r4Q2/91qj4iy9tRZNsFySMlEpLdpg==", + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/imagemin-svgo/-/imagemin-svgo-10.0.1.tgz", + "integrity": "sha512-v27/UTGkb3vrm5jvjsMGQ2oxaDfSOTBfJOgmFO2fYepx05bY1IqWCK13aDytVR+l9w9eOlq0NMCLbxJlghYb2g==", "license": "MIT", "optional": true, "dependencies": { - "is-svg": "^4.2.1", - "svgo": "^1.3.2" + "is-svg": "^4.3.1", + "svgo": "^2.5.0" }, "engines": { - "node": ">=6" + "node": ">=12.20" }, "funding": { "url": "https://github.com/sindresorhus/imagemin-svgo?sponsor=1" } }, - "node_modules/imagemin/node_modules/replace-ext": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.1.tgz", - "integrity": "sha512-yD5BHCe7quCgBph4rMQ+0KkIRKwWCrHDOX1p1Gp6HwjPM5kVoCdKGNhN7ydqqsX6lJEnQDKZ/tFMiEdQ1dvPEw==", + "node_modules/imagemin/node_modules/slash": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz", + "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==", "license": "MIT", "engines": { - "node": ">= 0.10" + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/immutable": { @@ -11127,19 +11621,6 @@ "node": ">=0.8.19" } }, - "node_modules/indent-string": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", - "integrity": "sha512-aqwDFWSgSgfRaEwao5lg5KEcVd/2a+D1rvoG7NdilmYz0NwRk6StWpWdz/Hpk34MKPpx7s8XxUqimfcQK6gGlg==", - "license": "MIT", - "optional": true, - "dependencies": { - "repeating": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -11228,6 +11709,22 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/inquirer/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, "node_modules/inquirer/node_modules/chardet": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", @@ -11514,7 +12011,7 @@ "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", - "devOptional": true, + "dev": true, "license": "MIT" }, "node_modules/is-async-function": { @@ -11702,19 +12199,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-finite": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.1.0.tgz", - "integrity": "sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w==", - "license": "MIT", - "optional": true, - "engines": { - "node": ">=0.10.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/is-fullwidth-code-point": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", @@ -11777,6 +12261,22 @@ "node": ">=0.10.0" } }, + "node_modules/is-identifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-identifier/-/is-identifier-1.0.1.tgz", + "integrity": "sha512-HQ5v4rEJ7REUV54bCd2l5FaD299SGDEn2UPoVXaTHAyGviLq2menVUD2udi3trQ32uvB6LdAh/0ck2EuizrtpA==", + "license": "MIT", + "dependencies": { + "identifier-regex": "^1.0.0", + "super-regex": "^1.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-interactive": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", @@ -11787,13 +12287,16 @@ } }, "node_modules/is-jpg": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-jpg/-/is-jpg-2.0.0.tgz", - "integrity": "sha512-ODlO0ruzhkzD3sdynIainVP5eoOFNN85rxA1+cwwnPe4dKyX0r5+hxNO5XpCrxlHcmb9vkOit9mhRD2JVuimHg==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-jpg/-/is-jpg-3.0.0.tgz", + "integrity": "sha512-Vcd67KWHZblEKEBrtP25qLZ8wN9ICoAhl1pKUqD7SM7hf2qtuRl7loDgP5Zigh2oN/+7uj+KVyC0eRJvgOEFeQ==", "license": "MIT", "optional": true, "engines": { - "node": ">=6" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/is-map": { @@ -12137,13 +12640,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/is-utf8": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", - "integrity": "sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q==", - "license": "MIT", - "optional": true - }, "node_modules/is-valid-glob": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-valid-glob/-/is-valid-glob-1.0.0.tgz", @@ -12320,25 +12816,6 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, - "node_modules/jpegtran-bin": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jpegtran-bin/-/jpegtran-bin-4.0.0.tgz", - "integrity": "sha512-2cRl1ism+wJUoYAYFt6O/rLBfpXNWG2dUWbgcEkTt5WGMnqI46eEro8T4C5zGROxKRqyKpCBSdHPvt5UYCtxaQ==", - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "dependencies": { - "bin-build": "^3.0.0", - "bin-wrapper": "^4.0.0", - "logalot": "^2.0.0" - }, - "bin": { - "jpegtran": "cli.js" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -12492,12 +12969,15 @@ } }, "node_modules/junk": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/junk/-/junk-3.1.0.tgz", - "integrity": "sha512-pBxcB3LFc8QVgdggvZWyeys+hnrNWg4OcZIU/1X59k5jQdLBlCsYGRQaz234SqoRLTCgMH00fY0xRJH+F9METQ==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/junk/-/junk-4.0.1.tgz", + "integrity": "sha512-Qush0uP+G8ZScpGMZvHUiRfI0YBWuB3gVBYlI0v0vvOJt5FLicco+IkP0a50LqTTQhmts/m6tP5SWE+USyIvcQ==", "license": "MIT", "engines": { - "node": ">=8" + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/keyv": { @@ -12624,23 +13104,6 @@ "resolved": "https://registry.npmjs.org/limiter/-/limiter-1.1.5.tgz", "integrity": "sha512-FWWMIEOxz3GwUI4Ts/IvgVy6LPvoMPgjMdQ185nN6psJyBJ4yOpzqm695/h5umdLJg2vW3GR5iG11MAkR2AzJA==" }, - "node_modules/load-json-file": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", - "integrity": "sha512-cy7ZdNRXdablkXYNI049pthVeXFurRyb9+hA/dZzerZ0pGTx42z+y+ssxBaVV2l70t1muq5IdKhn4UtcoGUY9A==", - "license": "MIT", - "optional": true, - "dependencies": { - "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0", - "strip-bom": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/loader-runner": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", @@ -12881,44 +13344,55 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/logalot": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/logalot/-/logalot-2.1.0.tgz", - "integrity": "sha512-Ah4CgdSRfeCJagxQhcVNMi9BfGYyEKLa6d7OA6xSbld/Hg3Cf2QiOa1mDpmG7Ve8LOH6DN3mdttzjQAvWTyVkw==", + "node_modules/log-symbols/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "license": "MIT", - "optional": true, "dependencies": { - "figures": "^1.3.5", - "squeak": "^1.0.0" + "color-convert": "^2.0.1" }, "engines": { - "node": ">=0.10.0" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/logalot/node_modules/figures": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", - "integrity": "sha512-UxKlfCRuCBxSXU4C6t9scbDyWZ4VlaFFdojKtzJuSkuOBQ5CNFum+zZXFwHjo+CxBC1t6zlYPgHIgFjL8ggoEQ==", + "node_modules/log-symbols/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "license": "MIT", - "optional": true, "dependencies": { - "escape-string-regexp": "^1.0.5", - "object-assign": "^4.1.0" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, "engines": { - "node": ">=0.10.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/longest": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", - "integrity": "sha512-k+yt5n3l48JU4k8ftnKG6V7u32wyH2NfKzeMto9F/QRE0amxy/LayxwlvjjkZEIzqR+19IrtFO8p5kB9QaYUFg==", + "node_modules/log-symbols/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "license": "MIT", - "optional": true, + "dependencies": { + "color-name": "~1.1.4" + }, "engines": { - "node": ">=0.10.0" + "node": ">=7.0.0" } }, + "node_modules/log-symbols/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "license": "MIT" + }, "node_modules/loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -12931,20 +13405,6 @@ "loose-envify": "cli.js" } }, - "node_modules/loud-rejection": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", - "integrity": "sha512-RPNliZOFkqFumDhvYqOaNY4Uz9oJM2K9tC6JWsJJsNdhuONW4LQHRBpb0qf4pJApVffI5N39SwzWZJuEhfd7eQ==", - "license": "MIT", - "optional": true, - "dependencies": { - "currently-unhandled": "^0.4.1", - "signal-exit": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/lowercase-keys": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", @@ -12955,25 +13415,6 @@ "node": ">=0.10.0" } }, - "node_modules/lpad-align": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/lpad-align/-/lpad-align-1.1.2.tgz", - "integrity": "sha512-MMIcFmmR9zlGZtBcFOows6c2COMekHCIFJz3ew/rRpKZ1wR4mXDPzvcVqLarux8M33X4TPSq2Jdw8WJj0q0KbQ==", - "license": "MIT", - "optional": true, - "dependencies": { - "get-stdin": "^4.0.1", - "indent-string": "^2.1.0", - "longest": "^1.0.0", - "meow": "^3.3.0" - }, - "bin": { - "lpad-align": "cli.js" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/lru-cache": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", @@ -13040,16 +13481,6 @@ "node": ">=0.10.0" } }, - "node_modules/map-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", - "integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==", - "license": "MIT", - "optional": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/map-stream": { "version": "0.0.7", "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.0.7.tgz", @@ -13082,9 +13513,9 @@ } }, "node_modules/mdn-data": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.4.tgz", - "integrity": "sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA==", + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", + "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==", "license": "CC0-1.0", "optional": true }, @@ -13120,28 +13551,6 @@ "node": ">=4.3.0 <5.0.0 || >=5.10" } }, - "node_modules/meow": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", - "integrity": "sha512-TNdwZs0skRlpPpCUK25StC4VH+tP5GgeY1HQOOGP+lQ2xtdkN2VtT/5tiX9k3IWpkBPV9b3LsAWXn4GGi/PrSA==", - "license": "MIT", - "optional": true, - "dependencies": { - "camelcase-keys": "^2.0.0", - "decamelize": "^1.1.2", - "loud-rejection": "^1.0.0", - "map-obj": "^1.0.1", - "minimist": "^1.1.3", - "normalize-package-data": "^2.3.4", - "object-assign": "^4.0.1", - "read-pkg-up": "^1.0.1", - "redent": "^1.0.0", - "trim-newlines": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/merge": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/merge/-/merge-1.2.1.tgz", @@ -13280,6 +13689,24 @@ "mkdirp": "bin/cmd.js" } }, + "node_modules/mozjpeg": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/mozjpeg/-/mozjpeg-8.0.0.tgz", + "integrity": "sha512-Ca2Yhah9hG0Iutgsn8MOrAl37P9ThnKsJatjXoWdUO+8X8GeG/6ahvHZrTyqvbs6leMww1SauWUCao/L9qBuFQ==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "dependencies": { + "bin-build": "^3.0.0", + "bin-wrapper": "^4.0.0" + }, + "bin": { + "mozjpeg": "cli.js" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -13444,29 +13871,6 @@ "node": ">=0.4.0" } }, - "node_modules/normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", - "license": "BSD-2-Clause", - "optional": true, - "dependencies": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - } - }, - "node_modules/normalize-package-data/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "license": "ISC", - "optional": true, - "bin": { - "semver": "bin/semver" - } - }, "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", @@ -13560,26 +13964,16 @@ } }, "node_modules/npm-run-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-1.0.0.tgz", - "integrity": "sha512-PrGAi1SLlqNvKN5uGBjIgnrTb8fl0Jz0a3JJmeMcGnIBh7UE9Gc4zsAMlwDajOMg2b1OgP6UPvoLUboTmMZPFA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==", "license": "MIT", "optional": true, "dependencies": { - "path-key": "^1.0.0" + "path-key": "^2.0.0" }, "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npm-run-path/node_modules/path-key": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-1.0.0.tgz", - "integrity": "sha512-T3hWy7tyXlk3QvPFnT+o2tmXRzU4GkitkUWLp/WZ0S/FXd7XMx176tRurgTvHTNMJOQzTcesHNpBqetH86mQ9g==", - "license": "MIT", - "optional": true, - "engines": { - "node": ">=0.10.0" + "node": ">=4" } }, "node_modules/nth-check": { @@ -13700,28 +14094,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/object.getownpropertydescriptors": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.8.tgz", - "integrity": "sha512-qkHIGe4q0lSYMv0XI4SsBTJz3WaURhLvd0lKSgtVuOsJ2krg4SgMw3PIRQFMp07yi++UR3se2mkcLqsBNpBb/A==", - "license": "MIT", - "optional": true, - "dependencies": { - "array.prototype.reduce": "^1.0.6", - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-object-atoms": "^1.0.0", - "gopd": "^1.0.1", - "safe-array-concat": "^1.1.2" - }, - "engines": { - "node": ">= 0.8" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/object.groupby": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz", @@ -13860,22 +14232,21 @@ } }, "node_modules/optipng-bin": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/optipng-bin/-/optipng-bin-6.0.0.tgz", - "integrity": "sha512-95bB4y8IaTsa/8x6QH4bLUuyvyOoGBCLDA7wOgDL8UFqJpSUh1Hob8JRJhit+wC1ZLN3tQ7mFt7KuBj0x8F2Wg==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/optipng-bin/-/optipng-bin-7.0.1.tgz", + "integrity": "sha512-W99mpdW7Nt2PpFiaO+74pkht7KEqkXkeRomdWXfEz3SALZ6hns81y/pm1dsGZ6ItUIfchiNIP6ORDr1zETU1jA==", "hasInstallScript": true, "license": "MIT", "optional": true, "dependencies": { "bin-build": "^3.0.0", - "bin-wrapper": "^4.0.0", - "logalot": "^2.0.0" + "bin-wrapper": "^4.0.0" }, "bin": { "optipng": "cli.js" }, "engines": { - "node": ">=8" + "node": ">=10" } }, "node_modules/ora": { @@ -13910,15 +14281,46 @@ "node": ">=8" } }, + "node_modules/ora/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, "node_modules/ora/node_modules/bl": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", "license": "MIT", "dependencies": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/ora/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/ora/node_modules/cli-cursor": { @@ -13933,6 +14335,24 @@ "node": ">=8" } }, + "node_modules/ora/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/ora/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "license": "MIT" + }, "node_modules/ora/node_modules/mimic-fn": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", @@ -14027,6 +14447,26 @@ "node": ">=0.10.0" } }, + "node_modules/ow": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ow/-/ow-2.0.0.tgz", + "integrity": "sha512-ESUigmGrdhUZ2nQSFNkeKSl6ZRPupXzprMs3yF9DYlNVpJ8XAjM/fI9RUZxA7PI1K9HQDCCvBo1jr/GEIo9joQ==", + "license": "MIT", + "dependencies": { + "@sindresorhus/is": "^6.3.0", + "callsites": "^4.1.0", + "dot-prop": "^8.0.2", + "environment": "^1.0.0", + "fast-equals": "^5.0.1", + "is-identifier": "^1.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/own-keys": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.1.tgz", @@ -14143,12 +14583,12 @@ } }, "node_modules/p-pipe": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-pipe/-/p-pipe-3.1.0.tgz", - "integrity": "sha512-08pj8ATpzMR0Y80x50yJHn37NF6vjrqHutASaX5LiH5npS9XPvrUmscd9MF5R4fuYRHOxQR1FfMIlF7AzwoPqw==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-pipe/-/p-pipe-4.0.0.tgz", + "integrity": "sha512-HkPfFklpZQPUKBFXzKFB6ihLriIHxnmuQdK9WmLDwe4hf2PdhhfWT/FJa+pc3bA1ywvKXtedxIRmd4Y7BTXE4w==", "license": "MIT", "engines": { - "node": ">=8" + "node": ">=12" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -14247,19 +14687,6 @@ "node": ">= 0.10" } }, - "node_modules/parse-json": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha512-QR/GGaKCkhwk1ePQNYDRKYZ3mwU9ypsKhB0XyFnLQdomyEqk3e8wpW3V5Jp88zbxK4n5ST1nqo+g9juTpownhQ==", - "license": "MIT", - "optional": true, - "dependencies": { - "error-ex": "^1.2.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/parse-node-version": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parse-node-version/-/parse-node-version-1.0.1.tgz", @@ -14362,6 +14789,19 @@ "node": ">=8" } }, + "node_modules/peek-readable": { + "version": "5.4.2", + "resolved": "https://registry.npmjs.org/peek-readable/-/peek-readable-5.4.2.tgz", + "integrity": "sha512-peBp3qZyuS6cNIJ2akRNG1uo1WJ1d0wTxg/fxMdZ0BqCVhx242bSFHM9eNqflfJVS9SsgkzgT/1UgnsurBOTMg==", + "license": "MIT", + "engines": { + "node": ">=14.16" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, "node_modules/pend": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", @@ -14394,13 +14834,13 @@ } }, "node_modules/pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "devOptional": true, "license": "MIT", - "optional": true, "engines": { - "node": ">=0.10.0" + "node": ">=6" } }, "node_modules/pinkie": { @@ -14521,16 +14961,6 @@ "node": ">=4" } }, - "node_modules/pkg-conf/node_modules/pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/pkg-conf/node_modules/strip-bom": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", @@ -15342,12 +15772,12 @@ } }, "node_modules/pretty-bytes": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", - "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==", + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-6.1.1.tgz", + "integrity": "sha512-mQUvGU6aUFQ+rNvTIAcZuWGRT9a6f6Yrg9bHs4ImKF+HZCEK+plBvnAZYSIQztknZF2qnzNtr6F8s0+IuptdlQ==", "license": "MIT", "engines": { - "node": ">=6" + "node": "^14.13.1 || >=16.0.0" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -15424,18 +15854,6 @@ "node": ">=6" } }, - "node_modules/q": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", - "integrity": "sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==", - "deprecated": "You or someone you depend on is using Q, the JavaScript Promise library that gave JavaScript developers strong feelings about promises. They can almost certainly migrate to the native JavaScript promise now. Thank you literally everyone for joining me in this bet against the odds. Be excellent to each other.\n\n(For a CapTP with native promises, see @endo/eventual-send and @endo/captp)", - "license": "MIT", - "optional": true, - "engines": { - "node": ">=0.6.0", - "teleport": ">=0.2.0" - } - }, "node_modules/query-string": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/query-string/-/query-string-5.1.1.tgz", @@ -15523,77 +15941,6 @@ "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", "license": "MIT" }, - "node_modules/read-pkg": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", - "integrity": "sha512-7BGwRHqt4s/uVbuyoeejRn4YmFnYZiFl4AuaeXHlgZf3sONF0SOGlxs2Pw8g6hCKupo08RafIO5YXFNOKTfwsQ==", - "license": "MIT", - "optional": true, - "dependencies": { - "load-json-file": "^1.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/read-pkg-up": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", - "integrity": "sha512-WD9MTlNtI55IwYUS27iHh9tK3YoIVhxis8yKhLpTqWtml739uXc9NWTpxoHkfZf3+DkCCsXox94/VWZniuZm6A==", - "license": "MIT", - "optional": true, - "dependencies": { - "find-up": "^1.0.0", - "read-pkg": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/read-pkg-up/node_modules/find-up": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", - "integrity": "sha512-jvElSjyuo4EMQGoTwo1uJU5pQMwTW5lS1x05zzfJuTIyLR3zwO27LYrxNg+dlvKpGOuGy/MzBdXh80g0ve5+HA==", - "license": "MIT", - "optional": true, - "dependencies": { - "path-exists": "^2.0.0", - "pinkie-promise": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/read-pkg-up/node_modules/path-exists": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", - "integrity": "sha512-yTltuKuhtNeFJKa1PiRzfLAU5182q1y4Eb4XCJ3PBqyzEDkAZRzBrKKBct682ls9reBVHf9udYLN5Nd+K1B9BQ==", - "license": "MIT", - "optional": true, - "dependencies": { - "pinkie-promise": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/read-pkg/node_modules/path-type": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", - "integrity": "sha512-S4eENJz1pkiQn9Znv33Q+deTOKmbl+jj1Fl+qiP/vYezj+S8x+J3Uo0ISrx/QoEvIlOaDWJhPaRd1flJ9HXZqg==", - "license": "MIT", - "optional": true, - "dependencies": { - "graceful-fs": "^4.1.2", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/readable-stream": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", @@ -15667,20 +16014,6 @@ "node": ">= 0.10" } }, - "node_modules/redent": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", - "integrity": "sha512-qtW5hKzGQZqKoh6JNSD+4lfitfPKGz42e6QwiRmPM5mmKtR0N41AbJRYu0xJi7nhOJ4WDgRkKvAk6tw4WIwR4g==", - "license": "MIT", - "optional": true, - "dependencies": { - "indent-string": "^2.1.0", - "strip-indent": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/reflect.getprototypeof": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz", @@ -15818,19 +16151,6 @@ "integrity": "sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==", "license": "ISC" }, - "node_modules/repeating": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", - "integrity": "sha512-ZqtSMuVybkISo2OWvqvm7iHSWngvdaW3IpsT9/uP8v4gMi591LY6h35wdOfvQdWCKFWZWm2Y1Opp4kV7vQKT6A==", - "license": "MIT", - "optional": true, - "dependencies": { - "is-finite": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/replace-ext": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-0.0.1.tgz", @@ -15935,6 +16255,18 @@ "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", "license": "MIT" }, + "node_modules/reserved-identifiers": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/reserved-identifiers/-/reserved-identifiers-1.0.0.tgz", + "integrity": "sha512-h0bP2Katmvf3hv4Z3WtDl4+6xt/OglQ2Xa6TnhZ/Rm9/7IH1crXQqMwD4J2ngKBonVv+fB55zfGgNDAmsevLVQ==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/resolve": { "version": "1.22.10", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", @@ -16750,13 +17082,6 @@ "url": "https://paulmillr.com/funding/" } }, - "node_modules/sax": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", - "license": "ISC", - "optional": true - }, "node_modules/schema-utils": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz", @@ -17489,131 +17814,20 @@ "license": "MIT" }, "node_modules/sparkles": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/sparkles/-/sparkles-1.0.1.tgz", - "integrity": "sha512-dSO0DDYUahUt/0/pD/Is3VIm5TGJjludZ0HVymmhYF6eNA53PVLhnUk0znSYbH8IYBuJdCE+1luR22jNLMaQdw==", - "license": "MIT", - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/spdx-correct": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", - "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", - "license": "Apache-2.0", - "optional": true, - "dependencies": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/spdx-exceptions": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", - "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", - "license": "CC-BY-3.0", - "optional": true - }, - "node_modules/spdx-expression-parse": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", - "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", - "license": "MIT", - "optional": true, - "dependencies": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/spdx-license-ids": { - "version": "3.0.21", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.21.tgz", - "integrity": "sha512-Bvg/8F5XephndSK3JffaRqdT+gyhfqIPwDHpX80tJrF8QQRYMo8sNMeaZ2Dp5+jhwKnUmIOyFFQfHRkjJm5nXg==", - "license": "CC0-1.0", - "optional": true - }, - "node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", - "license": "BSD-3-Clause" - }, - "node_modules/squeak": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/squeak/-/squeak-1.3.0.tgz", - "integrity": "sha512-YQL1ulInM+ev8nXX7vfXsCsDh6IqXlrremc1hzi77776BtpWgYJUMto3UM05GSAaGzJgWekszjoKDrVNB5XG+A==", - "license": "MIT", - "optional": true, - "dependencies": { - "chalk": "^1.0.0", - "console-stream": "^0.1.1", - "lpad-align": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/squeak/node_modules/ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", - "license": "MIT", - "optional": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/squeak/node_modules/ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==", - "license": "MIT", - "optional": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/squeak/node_modules/chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==", - "license": "MIT", - "optional": true, - "dependencies": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/squeak/node_modules/strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", - "license": "MIT", - "optional": true, - "dependencies": { - "ansi-regex": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/squeak/node_modules/supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sparkles/-/sparkles-1.0.1.tgz", + "integrity": "sha512-dSO0DDYUahUt/0/pD/Is3VIm5TGJjludZ0HVymmhYF6eNA53PVLhnUk0znSYbH8IYBuJdCE+1luR22jNLMaQdw==", "license": "MIT", - "optional": true, "engines": { - "node": ">=0.8.0" + "node": ">= 0.10" } }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "license": "BSD-3-Clause" + }, "node_modules/stable": { "version": "0.1.8", "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz", @@ -17726,6 +17940,22 @@ "node": ">=8" } }, + "node_modules/standard/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, "node_modules/standard/node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -17733,6 +17963,43 @@ "dev": true, "license": "Python-2.0" }, + "node_modules/standard/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/standard/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/standard/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, "node_modules/standard/node_modules/cross-spawn": { "version": "7.0.6", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", @@ -18424,6 +18691,27 @@ "node": ">=4" } }, + "node_modules/string-width/node_modules/ansi-regex": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", + "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/string-width/node_modules/strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/string.prototype.includes": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/string.prototype.includes/-/string.prototype.includes-2.0.1.tgz", @@ -18547,28 +18835,18 @@ } }, "node_modules/strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", "license": "MIT", "dependencies": { - "ansi-regex": "^3.0.0" + "ansi-regex": "^6.0.1" }, "engines": { - "node": ">=4" - } - }, - "node_modules/strip-bom": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", - "integrity": "sha512-kwrX1y7czp1E69n2ajbG65mIo9dqvJ+8aBQXOGVxqwvNbsXdFM6Lq37dLAY3mknUwru8CfcCbfOLL/gMo+fi3g==", - "license": "MIT", - "optional": true, - "dependencies": { - "is-utf8": "^0.2.0" + "node": ">=12" }, - "engines": { - "node": ">=0.10.0" + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, "node_modules/strip-bom-string": { @@ -18600,20 +18878,14 @@ "node": ">=0.10.0" } }, - "node_modules/strip-indent": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", - "integrity": "sha512-I5iQq6aFMM62fBEAIB/hXzwJD6EEZ0xEGCX2t7oXqaKPIRgt4WruAQ285BISgdkP+HLGWyeGmNJcpIwFeRYRUA==", + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", "license": "MIT", "optional": true, - "dependencies": { - "get-stdin": "^4.0.1" - }, - "bin": { - "strip-indent": "cli.js" - }, "engines": { - "node": ">=0.10.0" + "node": ">=6" } }, "node_modules/strip-json-comments": { @@ -18642,12 +18914,35 @@ } }, "node_modules/strnum": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz", - "integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.1.2.tgz", + "integrity": "sha512-vrN+B7DBIoTTZjnPNewwhx6cBA/H+IS7rfW68n7XxC1y7uoiGQBxaKzqucGUgavX15dJgiGztLJ8vxuEzwqBdA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], "license": "MIT", "optional": true }, + "node_modules/strtok3": { + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/strtok3/-/strtok3-9.1.1.tgz", + "integrity": "sha512-FhwotcEqjr241ZbjFzjlIYg6c5/L/s4yBGWSMvJ9UoExiSqL+FnFA/CaeZx17WGaZMS/4SOZp8wH18jSS4R4lw==", + "license": "MIT", + "dependencies": { + "@tokenizer/token": "^0.3.0", + "peek-readable": "^5.3.1" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, "node_modules/stylehacks": { "version": "7.0.4", "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-7.0.4.tgz", @@ -18677,6 +18972,22 @@ "node": ">=4" } }, + "node_modules/super-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/super-regex/-/super-regex-1.0.0.tgz", + "integrity": "sha512-CY8u7DtbvucKuquCmOFEKhr9Besln7n9uN8eFbwcoGYWXOMW07u2o8njWaiXt11ylS3qoGF55pILjRmPlbodyg==", + "license": "MIT", + "dependencies": { + "function-timeout": "^1.0.1", + "time-span": "^5.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -18721,70 +19032,35 @@ } }, "node_modules/svgo": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/svgo/-/svgo-1.3.2.tgz", - "integrity": "sha512-yhy/sQYxR5BkC98CY7o31VGsg014AKLEPxdfhora76l36hD9Rdy5NZA/Ocn6yayNPgSamYdtX2rFJdcv07AYVw==", - "deprecated": "This SVGO version is no longer supported. Upgrade to v2.x.x.", + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-2.8.0.tgz", + "integrity": "sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg==", "license": "MIT", "optional": true, "dependencies": { - "chalk": "^2.4.1", - "coa": "^2.0.2", - "css-select": "^2.0.0", - "css-select-base-adapter": "^0.1.1", - "css-tree": "1.0.0-alpha.37", - "csso": "^4.0.2", - "js-yaml": "^3.13.1", - "mkdirp": "~0.5.1", - "object.values": "^1.1.0", - "sax": "~1.2.4", - "stable": "^0.1.8", - "unquote": "~1.1.1", - "util.promisify": "~1.0.0" + "@trysound/sax": "0.2.0", + "commander": "^7.2.0", + "css-select": "^4.1.3", + "css-tree": "^1.1.3", + "csso": "^4.2.0", + "picocolors": "^1.0.0", + "stable": "^0.1.8" }, "bin": { "svgo": "bin/svgo" }, "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/svgo/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "license": "MIT", - "optional": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/svgo/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "license": "MIT", - "optional": true, - "engines": { - "node": ">=4" + "node": ">=10.13.0" } }, - "node_modules/svgo/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "node_modules/svgo/node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", "license": "MIT", "optional": true, - "dependencies": { - "has-flag": "^3.0.0" - }, "engines": { - "node": ">=4" + "node": ">= 10" } }, "node_modules/table": { @@ -18892,26 +19168,29 @@ } }, "node_modules/tempfile": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/tempfile/-/tempfile-1.1.1.tgz", - "integrity": "sha512-NjT12fW6pSEKz1eVcADgaKfeM+XZ4+zSaqVz46XH7+CiEwcelnwtGWRRjF1p+xyW2PVgKKKS2UUw1LzRelntxg==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/tempfile/-/tempfile-2.0.0.tgz", + "integrity": "sha512-ZOn6nJUgvgC09+doCEF3oB+r3ag7kUvlsXEGX069QRD60p+P3uP7XG9N2/at+EyIRGSN//ZY3LyEotA1YpmjuA==", "license": "MIT", "optional": true, "dependencies": { - "os-tmpdir": "^1.0.0", - "uuid": "^2.0.1" + "temp-dir": "^1.0.0", + "uuid": "^3.0.1" }, "engines": { - "node": ">=0.10.0" + "node": ">=4" } }, "node_modules/tempfile/node_modules/uuid": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.3.tgz", - "integrity": "sha512-FULf7fayPdpASncVy4DLh3xydlXEJJpvIELjYjNeQWYUZ9pclcpvCZSr2gkmN2FrrGcI7G/cJsIEwk5/8vfXpg==", + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", "license": "MIT", - "optional": true + "optional": true, + "bin": { + "uuid": "bin/uuid" + } }, "node_modules/ternary-stream": { "version": "2.1.1", @@ -19120,15 +19399,6 @@ "xtend": "~4.0.1" } }, - "node_modules/through2-concurrent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/through2-concurrent/-/through2-concurrent-2.0.0.tgz", - "integrity": "sha512-R5/jLkfMvdmDD+seLwN7vB+mhbqzWop5fAjx5IX8/yQq7VhBhzDmhXgaHAOnhnWkCpRMM7gToYHycB0CS/pd+A==", - "license": "MIT", - "dependencies": { - "through2": "^2.0.0" - } - }, "node_modules/tildify": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/tildify/-/tildify-1.2.0.tgz", @@ -19142,6 +19412,21 @@ "node": ">=0.10.0" } }, + "node_modules/time-span": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/time-span/-/time-span-5.1.0.tgz", + "integrity": "sha512-75voc/9G4rDIJleOo4jPvN4/YC4GRZrY8yy1uU4lwrB3XEQbWve8zXoO5No4eFrGcTAMYyoY67p8jRQdtA1HbA==", + "license": "MIT", + "dependencies": { + "convert-hrtime": "^5.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/time-stamp": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/time-stamp/-/time-stamp-1.1.0.tgz", @@ -19226,14 +19511,21 @@ "node": ">=0.6" } }, - "node_modules/trim-newlines": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", - "integrity": "sha512-Nm4cF79FhSTzrLKGDMi3I4utBtFv8qKy4sq1enftf2gMdpqI8oVQTAfySkTz5r49giVzDj88SVZXP4CeYQwjaw==", + "node_modules/token-types": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/token-types/-/token-types-6.0.0.tgz", + "integrity": "sha512-lbDrTLVsHhOMljPscd0yitpozq7Ga2M5Cvez5AjGg8GASBjtt6iERCAJ93yommPmz62fb45oFIXHEZ3u9bfJEA==", "license": "MIT", - "optional": true, + "dependencies": { + "@tokenizer/token": "^0.3.0", + "ieee754": "^1.2.1" + }, "engines": { - "node": ">=0.10.0" + "node": ">=14.16" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" } }, "node_modules/trim-repeated": { @@ -19449,6 +19741,18 @@ "node": ">=0.8.0" } }, + "node_modules/uint8array-extras": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/uint8array-extras/-/uint8array-extras-1.4.0.tgz", + "integrity": "sha512-ZPtzy0hu4cZjv3z5NW9gfKnNLjoz4y6uv4HlelAjDK7sY/xOkKZv9xK/WQpcsBB3jEybChz9DPC2U/+cusjJVQ==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/unbox-primitive": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz", @@ -19606,6 +19910,18 @@ "node": ">=4" } }, + "node_modules/unicorn-magic": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.3.0.tgz", + "integrity": "sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/universal-user-agent": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz", @@ -19630,13 +19946,6 @@ "node": ">= 0.8" } }, - "node_modules/unquote": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/unquote/-/unquote-1.1.1.tgz", - "integrity": "sha512-vRCqFv6UhXpWxZPyGDh/F3ZpNv8/qo7w6iufLpQg9aKnQ71qM4B5KiI7Mia9COcjEhrO9LueHpMYjYzsWH3OIg==", - "license": "MIT", - "optional": true - }, "node_modules/update-browserslist-db": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.2.tgz", @@ -19733,22 +20042,6 @@ "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", "license": "MIT" }, - "node_modules/util.promisify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.1.tgz", - "integrity": "sha512-g9JpC/3He3bm38zsLupWryXHoEcS22YHthuPQSJdMy6KNrzIRzWqcsHzD/WUnqe45whVou4VIsPew37DoXWNrA==", - "license": "MIT", - "optional": true, - "dependencies": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.2", - "has-symbols": "^1.0.1", - "object.getownpropertydescriptors": "^2.1.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/util/node_modules/inherits": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", @@ -19788,17 +20081,6 @@ "node": ">= 10.13.0" } }, - "node_modules/validate-npm-package-license": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", - "license": "Apache-2.0", - "optional": true, - "dependencies": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, "node_modules/value-or-function": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/value-or-function/-/value-or-function-4.0.0.tgz", diff --git a/package.json b/package.json index 043c797..bc804a4 100644 --- a/package.json +++ b/package.json @@ -5,6 +5,7 @@ "homepage": "https://www.skyverge.com/", "license": "GPL-3.0", "description": "SkyVerge WP/WC plugin build & deploy tool, a.k.a SkyMake", + "type": "module", "repository": { "type": "git", "url": "https://github.com/skyverge/sake.git" @@ -30,10 +31,10 @@ "axios": "^1.7.9", "babel-loader": "^8.0.6", "browser-sync": "^3.0.3", - "chalk": "^4.0.0", + "chalk": "^5.4.1", "codename": "0.0.6", "cssnano": "^7.0.6", - "dateformat": "^4.6.3", + "dateformat": "^5.0.3", "del": "^6.1.1", "dotenv": "^16.4.7", "dottie": "^2.0.6", @@ -48,7 +49,7 @@ "gulp-eslint": "^4.0.2", "gulp-filter": "^5.1.0", "gulp-if": "^2.0.2", - "gulp-imagemin": "^6.2.0", + "gulp-imagemin": "^9.1.0", "gulp-load-plugins": "^2.0.7", "gulp-phplint": "^0.9.0", "gulp-postcss": "^10.0.0", @@ -73,7 +74,7 @@ "sass": "^1.83.4", "semver": "^7.7.1", "shelljs": "^0.8.5", - "strip-ansi": "^4.0.0", + "strip-ansi": "^7.1.0", "underscore.string": "^3.3.4", "undertaker-forward-reference": "^1.0.2", "webpack-stream": "^7.0.0" diff --git a/pipes/replace.js b/pipes/replace.js index 839d972..a9a3ff5 100644 --- a/pipes/replace.js +++ b/pipes/replace.js @@ -1,4 +1,4 @@ -const lazypipe = require('lazypipe') +import lazypipe from 'lazypipe'; // these pipes are not meant to be reusable - rather, they existy so that the bump:minreqs task would // be easier to maintain without wrapping each individual replacement in gulp-if diff --git a/pipes/scripts.js b/pipes/scripts.js index 9586fc4..ecc4d10 100644 --- a/pipes/scripts.js +++ b/pipes/scripts.js @@ -1,4 +1,4 @@ -const lazypipe = require('lazypipe') +import lazypipe from 'lazypipe'; module.exports = (plugins, sake) => { const pipes = {} diff --git a/tasks/build.js b/tasks/build.js index cf3ddac..d566240 100644 --- a/tasks/build.js +++ b/tasks/build.js @@ -1,4 +1,4 @@ -const _ = require('lodash') +import _ from 'lodash'; module.exports = (gulp, plugins, sake) => { // main task for building the plugin: diff --git a/tasks/bump.js b/tasks/bump.js index 8f706db..67992db 100644 --- a/tasks/bump.js +++ b/tasks/bump.js @@ -1,5 +1,7 @@ +import replace from '../pipes/replace.js'; + module.exports = (gulp, plugins, sake) => { - const pipes = require('../pipes/replace.js')(plugins, sake) + const pipes = replace(plugins, sake) // bumps the version in the main plugin file to match changelog.txt gulp.task('bump', () => { diff --git a/tasks/bundle.js b/tasks/bundle.js index eed919e..272f4bf 100644 --- a/tasks/bundle.js +++ b/tasks/bundle.js @@ -1,7 +1,7 @@ -const log = require('fancy-log') -const fs = require('fs') -const path = require('path') -const shell = require('shelljs') +import log from 'fancy-log'; +import fs from 'node:fs'; +import path from 'node:path'; +import shell from 'shelljs'; module.exports = (gulp, plugins, sake) => { diff --git a/tasks/clean.js b/tasks/clean.js index 6bb8f6d..154c34a 100644 --- a/tasks/clean.js +++ b/tasks/clean.js @@ -1,5 +1,5 @@ -const path = require('path') -const del = require('del') +import path from 'node:path'; +import del from 'del'; module.exports = (gulp, plugins, sake) => { let defaultOptions = { read: false, allowEmpty: true } diff --git a/tasks/compile.js b/tasks/compile.js index 5d7c92a..4903c98 100644 --- a/tasks/compile.js +++ b/tasks/compile.js @@ -1,10 +1,15 @@ -const webpack = require('webpack-stream') -const fs = require('fs') -const path = require('path') -const sass = require('gulp-sass')(require('sass')) +import webpack from 'webpack-stream'; +import fs from 'node:fs'; +import path from 'node:path'; +import dartSaas from 'sass'; +import gulpSaas from 'gulp-sass'; +import autoprefixer from 'autoprefixer'; +import cssnano from 'cssnano'; +import scripts from '../pipes/scripts.js'; +const sass = gulpSaas(dartSaas); module.exports = (gulp, plugins, sake) => { - const pipes = require('../pipes/scripts.js')(plugins, sake) + const pipes = scripts(plugins, sake) // compile plugin assets gulp.task('compile', (done) => { @@ -115,10 +120,10 @@ module.exports = (gulp, plugins, sake) => { return Promise.resolve() } - let cssPlugins = [require('autoprefixer')()] + let cssPlugins = [autoprefixer()] if (sake.options.minify) { - cssPlugins.push(require('cssnano')({ zindex: false })) + cssPlugins.push(cssnano({ zindex: false })) } return gulp.src([ diff --git a/tasks/config.js b/tasks/config.js index c31c64e..0fe9c50 100644 --- a/tasks/config.js +++ b/tasks/config.js @@ -1,9 +1,9 @@ -const dottie = require('dottie') +import dottie from 'dottie'; module.exports = (gulp, plugins, sake) => { // prints current sake.configuration gulp.task('config', (done) => { - // pass --property=deploy.production to only see sake.config values for that propery + // pass --property=deploy.production to only see sake.config values for that property if (sake.options.property) { console.log(dottie.get(sake.config, sake.options.property)) } else { diff --git a/tasks/copy.js b/tasks/copy.js index 709347e..f260890 100644 --- a/tasks/copy.js +++ b/tasks/copy.js @@ -1,5 +1,4 @@ -const path = require('path') -const semver = require('semver') +import path from 'node:path'; module.exports = (gulp, plugins, sake) => { // copy files from source to build diff --git a/tasks/decaffeinate.js b/tasks/decaffeinate.js index ee96a1e..07f70f8 100644 --- a/tasks/decaffeinate.js +++ b/tasks/decaffeinate.js @@ -1,4 +1,4 @@ -const path = require('path') +import path from 'node:path'; module.exports = (gulp, plugins, sake) => { // converts CoffeeScripts to ES6 JavaScript without minification or further handling: diff --git a/tasks/deploy.js b/tasks/deploy.js index 39bb2e2..fd6f92a 100644 --- a/tasks/deploy.js +++ b/tasks/deploy.js @@ -1,9 +1,9 @@ -const fs = require('fs') -const log = require('fancy-log') -const dateFormat = require('dateformat') -const _ = require('lodash') -const chalk = require('chalk') -const axios = require('axios') +import fs from 'node:fs'; +import dateFormat from 'dateformat'; +import _ from 'lodash'; +import axios from 'axios'; +import log from 'fancy-log'; +import chalk from 'chalk'; module.exports = (gulp, plugins, sake) => { let validatedEnvVariables = false diff --git a/tasks/github.js b/tasks/github.js index b76b67e..d05fa3a 100644 --- a/tasks/github.js +++ b/tasks/github.js @@ -1,12 +1,12 @@ -const { Octokit: GitHub } = require('@octokit/rest') -const inquirer = require('inquirer') -const fs = require('fs') -const path = require('path') -const async = require('async') -const chalk = require('chalk') -const codename = require('codename')() -const dateFormat = require('dateformat') -const log = require('fancy-log') +import { Octokit as GitHub } from '@octokit/rest'; +import inquirer from 'inquirer'; +import fs from 'node:fs'; +import path from 'node:path'; +import async from 'async'; +import chalk from 'chalk'; +import codename from 'codename'; // @TODO check this? old was: const codename = require('codename')() +import dateFormat from 'dateformat'; +import log from 'fancy-log'; module.exports = (gulp, plugins, sake) => { let githubInstances = {} diff --git a/tasks/imagemin.js b/tasks/imagemin.js index b2c637c..af05737 100644 --- a/tasks/imagemin.js +++ b/tasks/imagemin.js @@ -1,5 +1,5 @@ -const fs = require('fs') -const log = require('fancy-log') +import fs from 'node:fs'; +import log from 'fancy-log'; module.exports = (gulp, plugins, sake) => { // optimize images diff --git a/tasks/lint.js b/tasks/lint.js index f0022fd..189ca19 100644 --- a/tasks/lint.js +++ b/tasks/lint.js @@ -1,6 +1,6 @@ -const path = require('path') -const dottie = require('dottie') -const fs = require('fs') +import path from 'node:path' +import dottie from 'dottie' +import fs from 'node:fs' module.exports = (gulp, plugins, sake) => { gulp.task('lint', gulp.parallel('lint:php', 'lint:scripts', 'lint:styles')) diff --git a/tasks/makepot.js b/tasks/makepot.js index 7ae0251..e9e4bbe 100644 --- a/tasks/makepot.js +++ b/tasks/makepot.js @@ -1,5 +1,5 @@ -const log = require('fancy-log') -const shell = require('shelljs') +import log from 'fancy-log' +import shell from 'shelljs' // generate POT files using wp cli module.exports = (gulp, plugins, sake) => { diff --git a/tasks/prerelease.js b/tasks/prerelease.js index 84b9518..60c56ed 100644 --- a/tasks/prerelease.js +++ b/tasks/prerelease.js @@ -1,4 +1,4 @@ -const fs = require('fs') +import fs from 'node:fs' module.exports = (gulp, plugins, sake) => { // validate env variables before deploying a prerelease diff --git a/tasks/prompt.js b/tasks/prompt.js index 39fde3b..aeceefd 100644 --- a/tasks/prompt.js +++ b/tasks/prompt.js @@ -1,8 +1,8 @@ -const inquirer = require('inquirer') -const semver = require('semver') -const log = require('fancy-log') -const chalk = require('chalk') -const _ = require('lodash') +import inquirer from 'inquirer' +import semver from 'semver' +import log from 'fancy-log' +import chalk from 'chalk' +import _ from 'lodash' module.exports = (gulp, plugins, sake) => { // internal task for prompting the deploy version diff --git a/tasks/shell.js b/tasks/shell.js index 7b15759..deac903 100644 --- a/tasks/shell.js +++ b/tasks/shell.js @@ -1,8 +1,8 @@ -const fs = require('fs') -const path = require('path') -const log = require('fancy-log') -const shell = require('shelljs') -const _str = require('underscore.string') +import fs from 'node:fs' +import path from 'node:path' +import log from 'fancy-log' +import shell from 'shelljs' +import _str from 'underscore.string' module.exports = (gulp, plugins, sake) => { const awk = process.platform === 'win32' ? 'gawk' : 'awk' diff --git a/tasks/upfw.js b/tasks/upfw.js index 8b76fb7..8cd306e 100644 --- a/tasks/upfw.js +++ b/tasks/upfw.js @@ -1,6 +1,6 @@ -const fs = require('fs') -const path = require('path') -const dottie = require('dottie') +import fs from 'node:fs' +import path from 'node:path' +import dottie from 'dottie' module.exports = (gulp, plugins, sake) => { // reload the framework version after updating the framework diff --git a/tasks/validate.js b/tasks/validate.js index ad2d2a3..f8aa1ed 100644 --- a/tasks/validate.js +++ b/tasks/validate.js @@ -1,5 +1,5 @@ -const fs = require('fs') -const log = require('fancy-log') +import fs from 'node:fs' +import log from 'fancy-log' module.exports = (gulp, plugins, sake) => { gulp.task('validate:readme_headers', (done) => { diff --git a/tasks/watch.js b/tasks/watch.js index 870bd97..9caac6c 100644 --- a/tasks/watch.js +++ b/tasks/watch.js @@ -1,4 +1,4 @@ -const log = require('fancy-log') +import log from 'fancy-log' // watch files for changes and compile assets necessary module.exports = (gulp, plugins, sake) => { diff --git a/tasks/wc.js b/tasks/wc.js index 3fd0392..705653a 100644 --- a/tasks/wc.js +++ b/tasks/wc.js @@ -1,9 +1,9 @@ -const axios = require('axios') -const log = require('fancy-log') -const path = require('path') -const fs = require('fs') -const FormData = require('form-data'); -const semver = require('semver') +import axios from 'axios' +import log from 'fancy-log' +import path from 'node:path' +import fs from 'node:fs' +import FormData from 'form-data' +import semver from 'semver' module.exports = (gulp, plugins, sake) => { const wcRoot = 'https://woocommerce.com/wp-json/wc/submission/runner/v1' From f1be39f86633d39bcae46e39608b419a1a9206f8 Mon Sep 17 00:00:00 2001 From: Ashley Gibson Date: Wed, 12 Mar 2025 14:50:20 +0000 Subject: [PATCH 02/45] Move config to separate file that we can export --- bin/sake.js | 10 +++-- gulpfile.js | 113 +++++--------------------------------------------- lib/config.js | 91 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 109 insertions(+), 105 deletions(-) create mode 100644 lib/config.js diff --git a/bin/sake.js b/bin/sake.js index 317d661..b8e856d 100755 --- a/bin/sake.js +++ b/bin/sake.js @@ -1,6 +1,10 @@ #!/usr/bin/env node -const { spawn } = require('child_process') -const path = require('path') +import { spawn } from 'node:child_process' +import path from 'node:path' +import { fileURLToPath } from 'node:url' +import resolve from 'resolve-bin' +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); /** * `sake` is simply a nice wrapper around `gulp`, designed to simplify using gulp @@ -17,7 +21,7 @@ const path = require('path') // The concat portion passes in any optional CLI args as well as the gulpfile from sake and // current workind directory. const args = [ - require('resolve-bin').sync('gulp') + resolve.sync('gulp') ].concat(process.argv.splice(2).concat([ '--gulpfile', path.join(__dirname, '../gulpfile.js'), '--cwd', process.cwd() diff --git a/gulpfile.js b/gulpfile.js index b83cb23..2530fb1 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -1,16 +1,16 @@ import gulp from 'gulp' import path from 'node:path' import fs from 'node:fs' -import minimist from 'minimist' import log from 'fancy-log' -import _ from 'lodash' import ForwardReference from 'undertaker-forward-reference' import dotenv from 'dotenv' -import sakePlugin from './lib/sake' import gulpPlugins from 'gulp-load-plugins' import notifier from 'node-notifier' import stripAnsi from 'strip-ansi' import browserSync from 'browser-sync' +import { fileURLToPath } from 'node:url' +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); // local .env file, overriding any global env variables let parentEnvPath = path.join('..', '.env') @@ -41,113 +41,17 @@ if (fs.existsSync(devEnv)) { // enable forward-referencing tasks, see https://github.com/gulpjs/gulp/issues/1028 gulp.registry(ForwardReference()) -// define default config -let defaults = { - // sets up the plugin folder structure - paths: { - // Path to plugin source files - this is where the main plugin entry file is located. Set this to a dot (.) if the - // main plugin file and sake.config.js are in teh same directory. The path is relative to the current working directory. - // Mostly, this is the only path a plugin/repo needs to explicitly set - src: '.', - // where plugin assets are located, relative to `src` - assets: 'assets', - // where plugin CSS/SCSS assets are located, relative to `src` - css: 'assets/css', - // where plugin JS/COFFEE assets are located, relative to `src` - js: 'assets/js', - // where plugin image assets are located, relative to `src` - images: 'assets/img', - // where plugin font assets are located, relative to `src` - fonts: 'assets/fonts', - // the directory where plugin files are copied during the build task, relative to current working directory - build: 'build', - // path to the directory where production (WC and WP.org SVN) repos are cloned, may be an absolute path or relative to current working directory - tmp: '/tmp/sake', - // array of paths that should be excluded from the build - exclude: [] - }, - - // Task-specific settings, set the key to task name and provide any settings as needed. Since sake uses Gulp behind the scenes - // and Gulp prefers code over configuration, there isn't a lot to do here. As you can see, some of these values can be defined - // as environment variables, as this makes more sense - ie whether you want to use browsersync or not is specific tp your local - // dev environment and workflow, not to a particular repo. - tasks: { - makepot: { - reportBugsTo: 'https://woocommerce.com/my-account/marketplace-ticket-form/', - domainPath: 'i18n/languages' - }, - watch: { - useBrowserSync: process.env.USE_BROWSERSYNC || false - }, - browserSync: { - url: process.env.BROWSERSYNC_URL || 'plugins-skyverge.test' - } - }, - - // which framework version this plugin uses - valid values: 'v5', 'v4', or pass boolean `false` to indicate a non-frameworked plugin - framework: 'v5', - // which deploy type does this plugin use - either 'wc' or 'wp', defaults to 'wc', specify `null` or `false` for no automated deploy - deploy: 'wc', - // the e-commerce platform this plugin is for, 'wc' or 'edd' - platform: 'wc' -} - -// load local configuration -// TODO: allow passing in config file path or config as string (for multi-plugin repos?) -let localConfig = {} - -// support supplying a single / parent config file in multi-plugin repos -let parentConfigPath = path.join(process.cwd(), '../sake.config.js') -let found = false - -if (fs.existsSync(parentConfigPath)) { - log.warn('Found config file in parent folder') - localConfig = require(parentConfigPath) - found = true -} - -// load local, plugin-specific config file -let configFilePath = path.join(process.cwd(), 'sake.config.js') - -if (fs.existsSync(configFilePath)) { - localConfig = _.merge(localConfig, require(configFilePath)) - found = true -} - -if (!found) { - log.warn('Could not find local config file, using default config values.') -} - -let config = _.merge(defaults, localConfig) - -// parse CLI options -let options = minimist(process.argv.slice(2), { - boolean: ['minify'], - default: { - minify: true, - debug: false - } +// @link https://github.com/jackfranklin/gulp-load-plugins/issues/141#issuecomment-2373391177 +let plugins = gulpPlugins({ + config: path.resolve(__dirname, 'package.json') }) -const sake = sakePlugin(config, options) - -sake.initConfig() - -let plugins = gulpPlugins() - // Attach browsersync as a plugin - not really a plugin, but it helps to // pass around the browsersync instance between tasks. Unfortunately, we // always have to load and create an instance of it, because gulp-if does not // support lazy evaluation yet: https://github.com/robrich/gulp-if/issues/75 plugins.browserSync = browserSync.create() -// load gulp plugins and tasks -fs.readdirSync(path.join(__dirname, 'tasks')).forEach((file) => { - require(path.join(__dirname, 'tasks', file))(gulp, plugins, sake) -}) - -gulp.task('default', gulp.series('compile')) - // show notification on task errors let loggedErrors = [] @@ -163,3 +67,8 @@ gulp.on('error', (event) => { loggedErrors.push(event.error) } }) + +/************** Task Exports */ + +export * from './tasks/bump.js' +export * from './tasks/validate.js' diff --git a/lib/config.js b/lib/config.js new file mode 100644 index 0000000..6a9b681 --- /dev/null +++ b/lib/config.js @@ -0,0 +1,91 @@ +import path from 'node:path' +import fs from 'node:fs' +import log from 'fancy-log' +import _ from 'lodash' +import { createRequire } from 'node:module' +const require = createRequire(import.meta.url); + +const buildSakeConfig = () => { + // define default config + let defaults = { + // sets up the plugin folder structure + paths: { + // Path to plugin source files - this is where the main plugin entry file is located. Set this to a dot (.) if the + // main plugin file and sake.config.js are in teh same directory. The path is relative to the current working directory. + // Mostly, this is the only path a plugin/repo needs to explicitly set + src: '.', + // where plugin assets are located, relative to `src` + assets: 'assets', + // where plugin CSS/SCSS assets are located, relative to `src` + css: 'assets/css', + // where plugin JS/COFFEE assets are located, relative to `src` + js: 'assets/js', + // where plugin image assets are located, relative to `src` + images: 'assets/img', + // where plugin font assets are located, relative to `src` + fonts: 'assets/fonts', + // the directory where plugin files are copied during the build task, relative to current working directory + build: 'build', + // path to the directory where production (WC and WP.org SVN) repos are cloned, may be an absolute path or relative to current working directory + tmp: '/tmp/sake', + // array of paths that should be excluded from the build + exclude: [] + }, + + // Task-specific settings, set the key to task name and provide any settings as needed. Since sake uses Gulp behind the scenes + // and Gulp prefers code over configuration, there isn't a lot to do here. As you can see, some of these values can be defined + // as environment variables, as this makes more sense - ie whether you want to use browsersync or not is specific tp your local + // dev environment and workflow, not to a particular repo. + tasks: { + makepot: { + reportBugsTo: 'https://woocommerce.com/my-account/marketplace-ticket-form/', + domainPath: 'i18n/languages' + }, + watch: { + useBrowserSync: process.env.USE_BROWSERSYNC || false + }, + browserSync: { + url: process.env.BROWSERSYNC_URL || 'plugins-skyverge.test' + } + }, + + // which framework version this plugin uses - valid values: 'v5', 'v4', or pass boolean `false` to indicate a non-frameworked plugin + framework: 'v5', + // which deploy type does this plugin use - either 'wc' or 'wp', defaults to 'wc', specify `null` or `false` for no automated deploy + deploy: 'wc', + // the e-commerce platform this plugin is for, 'wc' or 'edd' + platform: 'wc' + } + + // load local configuration + // TODO: allow passing in config file path or config as string (for multi-plugin repos?) + let localConfig = {} + + // support supplying a single / parent config file in multi-plugin repos + let parentConfigPath = path.join(process.cwd(), '../sake.config.js') + let found = false + + if (fs.existsSync(parentConfigPath)) { + log.warn('Found config file in parent folder') + localConfig = require(parentConfigPath) + found = true + } + + // load local, plugin-specific config file + let configFilePath = path.join(process.cwd(), 'sake.config.js') + + if (fs.existsSync(configFilePath)) { + localConfig = _.merge(localConfig, require(configFilePath)) + found = true + } + + if (!found) { + log.warn('Could not find local config file, using default config values.') + } + + return _.merge(defaults, localConfig) +} + +const sakeConfig = buildSakeConfig(); + +export default sakeConfig; From 67e1f65532dd36416695186109e9a7181bef7b0f Mon Sep 17 00:00:00 2001 From: Ashley Gibson Date: Wed, 12 Mar 2025 14:50:41 +0000 Subject: [PATCH 03/45] Initialize config from inside sake file --- lib/sake.js | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/lib/sake.js b/lib/sake.js index 822b1bb..8966fab 100644 --- a/lib/sake.js +++ b/lib/sake.js @@ -8,8 +8,28 @@ import _str from 'underscore.string'; import log from 'fancy-log'; import chalk from 'chalk'; import dottie from 'dottie'; +import { createRequire } from 'node:module'; +const require = createRequire(import.meta.url); +import sakeConfig from './config.js' +import minimist from 'minimist' + +// parse CLI options +let options = minimist(process.argv.slice(2), { + boolean: ['minify'], + default: { + minify: true, + debug: false + } +}) + + +const sake = initializeSake(sakeConfig, options); +sake.initConfig(); + +export default sake; -module.exports = (config, options) => { +function initializeSake(config, options) { + console.log('initializing sake'); const exports = {} // current task(s) from CLI, ie for `npx sake clean build` this will result in ['clean', 'build'] const cliTasks = process.argv.slice(2, -4) @@ -363,7 +383,7 @@ module.exports = (config, options) => { lines = contents.split('== Changelog ==')[1].trim().split('\n') } - // get the plugin name from changelog - asuuming it will be on the 1st line + // get the plugin name from changelog - assuming it will be on the 1st line if (fileName === 'changelog.txt') { changelog.plugin_name = lines[0].replace(/\*/g, '').replace(/Changelog/, '').trim() } else { From ea38b7a014797437cc3b14e5cff994333c59738c Mon Sep 17 00:00:00 2001 From: Ashley Gibson Date: Wed, 12 Mar 2025 14:51:05 +0000 Subject: [PATCH 04/45] Refactor replacement pipes --- package.json | 2 +- pipes/replace.js | 97 +++++++++++++++++++++++++----------------------- 2 files changed, 52 insertions(+), 47 deletions(-) diff --git a/package.json b/package.json index bc804a4..f080a88 100644 --- a/package.json +++ b/package.json @@ -50,7 +50,7 @@ "gulp-filter": "^5.1.0", "gulp-if": "^2.0.2", "gulp-imagemin": "^9.1.0", - "gulp-load-plugins": "^2.0.7", + "gulp-load-plugins": "^2.0.8", "gulp-phplint": "^0.9.0", "gulp-postcss": "^10.0.0", "gulp-rename": "^1.4.0", diff --git a/pipes/replace.js b/pipes/replace.js index a9a3ff5..29f6b4b 100644 --- a/pipes/replace.js +++ b/pipes/replace.js @@ -1,47 +1,52 @@ import lazypipe from 'lazypipe'; - -// these pipes are not meant to be reusable - rather, they existy so that the bump:minreqs task would -// be easier to maintain without wrapping each individual replacement in gulp-if -module.exports = (plugins, sake) => { - const pipes = {} - - // replace minimum PHP version - pipes.minimum_php_version = lazypipe() - .pipe(plugins.replace, /MINIMUM_PHP_VERSION = .*\n/, `MINIMUM_PHP_VERSION = '${sake.options.minimum_php_version}';\n`) - - // replace minimum WP version - pipes.minimum_wp_version = lazypipe() - .pipe(plugins.replace, /('minimum_wp_version'[\s]*=>[\s]*)'([^']*)'/, (match, m) => `${m}'${sake.options.minimum_wp_version}'`) - .pipe(plugins.replace, /Requires at least: .*/, () => `Requires at least: ${sake.options.minimum_wp_version}`) - .pipe(plugins.replace, /MINIMUM_WP_VERSION = .*\n/, () => `MINIMUM_WP_VERSION = '${sake.options.minimum_wp_version}';\n`) - - // replace tested up to WP version - pipes.tested_up_to_wp_version = lazypipe() - .pipe(plugins.replace, /Tested up to: .*/, () => `Tested up to: ${sake.options.tested_up_to_wp_version}`) - - // replace minimum WC version - pipes.minimum_wc_version = lazypipe() - .pipe(plugins.replace, /('minimum_wc_version'[\s]*=>[\s]*)'([^']*)'/, (match, m) => `${m}'${sake.options.minimum_wc_version}'`) - .pipe(plugins.replace, /WC requires at least: .*/, () => `WC requires at least: ${sake.options.minimum_wc_version}`) - .pipe(plugins.replace, /MINIMUM_WC_VERSION = .*\n/, () => `MINIMUM_WC_VERSION = '${sake.options.minimum_wc_version}';\n`) - - // replace tested up to WC version - pipes.tested_up_to_wc_version = lazypipe() - .pipe(plugins.replace, /WC tested up to: .*/, () => `WC tested up to: ${sake.options.tested_up_to_wc_version}`) - - // replace FW version - pipes.framework_version = lazypipe() - .pipe(plugins.replace, /SkyVerge\\WooCommerce\\PluginFramework\\v[0-9]+_[0-9]+_[0-9]+/g, (match) => 'SkyVerge\\WooCommerce\\PluginFramework\\v' + sake.options.framework_version.replace(/\./g, '_')) - .pipe(plugins.replace, /SkyVerge\\\\WooCommerce\\\\PluginFramework\\\\v[0-9]+_[0-9]+_[0-9]+/g, (match) => 'SkyVerge\\\\WooCommerce\\\\PluginFramework\\\\v' + sake.options.framework_version.replace(/\./g, '_')) - - // replace FW version v4 and v5 - pipes.framework_version = lazypipe() - .pipe(plugins.replace, /SV_WC_Framework_Bootstrap::instance\(\)->register_plugin\( '([^']*)'/, () => `SV_WC_Framework_Bootstrap::instance()->register_plugin( '${sake.options.framework_version}'`) - .pipe(plugins.replace, /FRAMEWORK_VERSION = .*\n/, () => `FRAMEWORK_VERSION = '${sake.options.framework_version}';\n`) - - // replace FW backwards compatibility - pipes.backwards_compatible = lazypipe() - .pipe(plugins.replace, /('backwards_compatible'[\s]*=>[\s]*)'([^']*)'/, (match, m) => `${m}'${sake.options.backwards_compatible}'`) - - return pipes -} +import replace from 'gulp-replace'; +import sake from '../lib/sake.js' + +/** + * Replaces the minimum PHP version + */ +export const replaceMinimumPhpVersion = lazypipe() + .pipe(replace, /MINIMUM_PHP_VERSION = .*\n/, `MINIMUM_PHP_VERSION = '${sake.options.minimum_php_version}';\n`) + +/** + * Replaces the minimum WP version + */ +export const replaceMinimumWpVersion = lazypipe() + .pipe(replace, /('minimum_wp_version'[\s]*=>[\s]*)'([^']*)'/, (match, m) => `${m}'${sake.options.minimum_wp_version}'`) + .pipe(replace, /Requires at least: .*/, () => `Requires at least: ${sake.options.minimum_wp_version}`) + .pipe(replace, /MINIMUM_WP_VERSION = .*\n/, () => `MINIMUM_WP_VERSION = '${sake.options.minimum_wp_version}';\n`) + +/** + * Replaces the tested-up-to WP version + */ +export const replaceTestedUptoWpVersion = lazypipe() + .pipe(replace, /Tested up to: .*/, () => `Tested up to: ${sake.options.tested_up_to_wp_version}`) + +/** + * Replaces the minimum WooCommerce version + */ +export const replaceMinimumWcVersion = lazypipe() + .pipe(replace, /('minimum_wc_version'[\s]*=>[\s]*)'([^']*)'/, (match, m) => `${m}'${sake.options.minimum_wc_version}'`) + .pipe(replace, /WC requires at least: .*/, () => `WC requires at least: ${sake.options.minimum_wc_version}`) + .pipe(replace, /MINIMUM_WC_VERSION = .*\n/, () => `MINIMUM_WC_VERSION = '${sake.options.minimum_wc_version}';\n`) + +/** + * Replaces the tested-up-to WooCommerce version + */ +export const replaceTestedUpToWcVersion = lazypipe() + .pipe(replace, /WC tested up to: .*/, () => `WC tested up to: ${sake.options.tested_up_to_wc_version}`) + +/** + * Replaces the framework version + */ +export const replaceFrameworkVersion = lazypipe() + .pipe(replace, /SkyVerge\\WooCommerce\\PluginFramework\\v[0-9]+_[0-9]+_[0-9]+/g, (match) => 'SkyVerge\\WooCommerce\\PluginFramework\\v' + sake.options.framework_version.replace(/\./g, '_')) + .pipe(replace, /SkyVerge\\\\WooCommerce\\\\PluginFramework\\\\v[0-9]+_[0-9]+_[0-9]+/g, (match) => 'SkyVerge\\\\WooCommerce\\\\PluginFramework\\\\v' + sake.options.framework_version.replace(/\./g, '_')) + .pipe(replace, /SV_WC_Framework_Bootstrap::instance\(\)->register_plugin\( '([^']*)'/, () => `SV_WC_Framework_Bootstrap::instance()->register_plugin( '${sake.options.framework_version}'`) + .pipe(replace, /FRAMEWORK_VERSION = .*\n/, () => `FRAMEWORK_VERSION = '${sake.options.framework_version}';\n`) + +/** + * Replaces the framework backwards compatible version + */ +export const replaceBackwardsCompatibleVersion = lazypipe() + .pipe(replace, /('backwards_compatible'[\s]*=>[\s]*)'([^']*)'/, (match, m) => `${m}'${sake.options.backwards_compatible}'`) From b9ad28df01ce121017d75082c6c02dcaaee37ad0 Mon Sep 17 00:00:00 2001 From: Ashley Gibson Date: Wed, 12 Mar 2025 14:51:26 +0000 Subject: [PATCH 05/45] Export scripts --- pipes/scripts.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pipes/scripts.js b/pipes/scripts.js index ecc4d10..b2d199f 100644 --- a/pipes/scripts.js +++ b/pipes/scripts.js @@ -1,6 +1,6 @@ import lazypipe from 'lazypipe'; -module.exports = (plugins, sake) => { +export default function scripts(plugins, sake) { const pipes = {} // transpile, minify and write sourcemaps From d05267bd6557157a5503bc4e012f1d0bd14da0b6 Mon Sep 17 00:00:00 2001 From: Ashley Gibson Date: Wed, 12 Mar 2025 14:51:43 +0000 Subject: [PATCH 06/45] Refactor validation task --- tasks/validate.js | 47 ++++++++++++++++++++++++++--------------------- 1 file changed, 26 insertions(+), 21 deletions(-) diff --git a/tasks/validate.js b/tasks/validate.js index f8aa1ed..fb01bb7 100644 --- a/tasks/validate.js +++ b/tasks/validate.js @@ -1,31 +1,36 @@ import fs from 'node:fs' import log from 'fancy-log' +import sake from '../lib/sake.js' -module.exports = (gulp, plugins, sake) => { - gulp.task('validate:readme_headers', (done) => { - fs.readFile(`${sake.config.paths.src}/readme.txt`, 'utf8', (err, data) => { - if (err) sake.throwError(err) +const validateReadmeHeaders = (done) => { + fs.readFile(`${sake.config.paths.src}/readme.txt`, 'utf8', (err, data) => { + if (err) sake.throwError(err) - let requiredHeaders = [ - 'License', - 'License URI', - ] + let requiredHeaders = [ + 'License', + 'License URI', + ] - if (sake.config.deploy.type === 'wp') { - requiredHeaders.push('Stable tag') - } - - requiredHeaders.forEach(headerName => { - log.info(`Validating readme.txt header ${headerName}`) - const regex = new RegExp(headerName + ':(.+)', 'ig') - const headerValue = data.match(regex) + if (sake.config.deploy.type === 'wp') { + requiredHeaders.push('Stable tag') + } - if (! headerValue) { - sake.throwError('Missing required header in readme.txt: ' + headerName) - } - }) + requiredHeaders.forEach(headerName => { + log.info(`Validating readme.txt header ${headerName}`) + const regex = new RegExp(headerName + ':(.+)', 'ig') + const headerValue = data.match(regex) - done() + if (! headerValue) { + sake.throwError('Missing required header in readme.txt: ' + headerName) + } }) + + done() }) } + +validateReadmeHeaders.displayName = 'validate:readme_headers' + +export { + validateReadmeHeaders +} From 95ae9eddad4ac5f8e462a5a95da1895b612a95f4 Mon Sep 17 00:00:00 2001 From: Ashley Gibson Date: Wed, 12 Mar 2025 14:52:07 +0000 Subject: [PATCH 07/45] Refactor bump task --- tasks/bump.js | 104 ++++++++++++++++++++++++++++---------------------- 1 file changed, 59 insertions(+), 45 deletions(-) diff --git a/tasks/bump.js b/tasks/bump.js index 67992db..62a8362 100644 --- a/tasks/bump.js +++ b/tasks/bump.js @@ -1,54 +1,68 @@ -import replace from '../pipes/replace.js'; +import gulp from 'gulp' +import gulpif from 'gulp-if' +import replace from 'gulp-replace' +import * as sakeReplace from '../pipes/replace.js' +import sake from '../lib/sake.js' -module.exports = (gulp, plugins, sake) => { - const pipes = replace(plugins, sake) +/** + * Bumps the version in the main plugin file to match changelog.txt + */ +const bump = (done) => { + let pluginFiles = [`${sake.config.paths.src}/${sake.config.plugin.mainFile}`] - // bumps the version in the main plugin file to match changelog.txt - gulp.task('bump', () => { - let pluginFiles = [`${sake.config.paths.src}/${sake.config.plugin.mainFile}`] + // also include the main Plugin class file + if (sake.config.framework === 'v5') { + pluginFiles.push(`${sake.config.paths.src}/includes/Plugin.php`) + } - // also include the main Plugin class file - if (sake.config.framework === 'v5') { - pluginFiles.push(`${sake.config.paths.src}/includes/Plugin.php`) - } + return gulp.src(pluginFiles, { base: sake.config.paths.src, allowEmpty: true }) + .pipe(replace(/ \* Version: [0-9]*.[0-9]*.[0-9]*(-[a-z]+.[0-9]+)*\n/, () => ' * Version: ' + sake.getPluginVersion() + '\n')) + .pipe(replace(/const VERSION = '[0-9]*.[0-9]*.[0-9]*(-[a-z]+.[0-9]+)*';/, () => "const VERSION = '" + sake.getPluginVersion() + "';")) + .pipe(gulp.dest(sake.config.paths.src)) +} - return gulp.src(pluginFiles, { base: sake.config.paths.src, allowEmpty: true }) - .pipe(plugins.replace(/ \* Version: [0-9]*.[0-9]*.[0-9]*(-[a-z]+.[0-9]+)*\n/, () => ' * Version: ' + sake.getPluginVersion() + '\n')) - .pipe(plugins.replace(/const VERSION = '[0-9]*.[0-9]*.[0-9]*(-[a-z]+.[0-9]+)*';/, () => "const VERSION = '" + sake.getPluginVersion() + "';")) - .pipe(gulp.dest(sake.config.paths.src)) - }) +/** + * Bumps the minimum requirements for the plugin. + */ +const bumpMinReqs = (done) => { + // helper to determine if a number is an integer + let isInt = (n) => { + return n % 1 === 0 + } - // bumps the minimum requirements for the plugin - gulp.task('bump:minreqs', () => { - // helper to determine if a number is an integer - let isInt = (n) => { - return n % 1 === 0 + // semver-ify versions passed in as integers + ['minimum_wp_version', 'tested_up_to_wp_version', 'minimum_wc_version', 'tested_up_to_wc_version', 'framework_version', 'backwards_compatible'].forEach((option) => { + if (sake.options[option] && isInt(sake.options[option])) { + sake.options[option] = parseFloat(sake.options[option]).toFixed(1) } - - // semver-ify versions passed in as integers - ['minimum_wp_version', 'tested_up_to_wp_version', 'minimum_wc_version', 'tested_up_to_wc_version', 'framework_version', 'backwards_compatible'].forEach((option) => { - if (sake.options[option] && isInt(sake.options[option])) { - sake.options[option] = parseFloat(sake.options[option]).toFixed(1) - } - }) - - return gulp.src([`${sake.config.paths.src}/${sake.config.plugin.mainFile}`, `${sake.config.paths.src}/readme.txt`]) - // note the need to cast the version optiosn to boolean, as passing a string version, - // such as '4.4.0' will not evaluate to true in gulp-if - .pipe(plugins.if(Boolean(sake.options.minimum_php_version), pipes.minimum_php_version())) - .pipe(plugins.if(Boolean(sake.options.minimum_wp_version), pipes.minimum_wp_version())) - .pipe(plugins.if(Boolean(sake.options.tested_up_to_wp_version), pipes.tested_up_to_wp_version())) - .pipe(plugins.if(Boolean(sake.options.minimum_wc_version), pipes.minimum_wc_version())) - .pipe(plugins.if(Boolean(sake.options.tested_up_to_wc_version), pipes.tested_up_to_wc_version())) - .pipe(plugins.if(Boolean(sake.options.framework_version), pipes.framework_version())) - .pipe(plugins.if(Boolean(sake.options.backwards_compatible && sake.config.framework === 'v4'), pipes.backwards_compatible())) - .pipe(gulp.dest(sake.config.paths.src)) }) - // bumps the v5 framework version in plugin files - gulp.task('bump:framework_version', () => { - return gulp.src([`${sake.config.paths.src}/**/*.php`, `!${sake.config.paths.src}/${sake.config.paths.framework.base}`]) - .pipe(plugins.if(Boolean(sake.options.framework_version), pipes.framework_version())) - .pipe(gulp.dest(sake.config.paths.src)) - }) + return gulp.src([`${sake.config.paths.src}/${sake.config.plugin.mainFile}`, `${sake.config.paths.src}/readme.txt`]) + // note the need to cast the version options to boolean, as passing a string version, + // such as '4.4.0' will not evaluate to true in gulp-if + .pipe(gulpif(Boolean(sake.options.minimum_php_version), sakeReplace.replaceMinimumPhpVersion())) + .pipe(gulpif(Boolean(sake.options.minimum_wp_version), sakeReplace.replaceMinimumWpVersion())) + .pipe(gulpif(Boolean(sake.options.tested_up_to_wp_version), sakeReplace.replaceTestedUptoWpVersion())) + .pipe(gulpif(Boolean(sake.options.minimum_wc_version), sakeReplace.replaceMinimumWcVersion())) + .pipe(gulpif(Boolean(sake.options.tested_up_to_wc_version), sakeReplace.replaceTestedUpToWcVersion())) + .pipe(gulpif(Boolean(sake.options.framework_version), sakeReplace.replaceFrameworkVersion())) + .pipe(gulpif(Boolean(sake.options.backwards_compatible && sake.config.framework === 'v4'), sakeReplace.replaceBackwardsCompatibleVersion())) + .pipe(gulp.dest(sake.config.paths.src)) +} +bumpMinReqs.displayName = 'bump:minreqs' + +/** + * Bumps the v5 framework version in plugin files + */ +const bumpFrameworkVersion = (done) => { + return gulp.src([`${sake.config.paths.src}/**/*.php`, `!${sake.config.paths.src}/${sake.config.paths.framework.base}`]) + .pipe(gulpif(Boolean(sake.options.framework_version), sakeReplace.replaceFrameworkVersion())) + .pipe(gulp.dest(sake.config.paths.src)) +} +bumpFrameworkVersion.displayName = 'bump:framework_version' + +export { + bump, + bumpMinReqs, + bumpFrameworkVersion } From d6cb231da92739e9ad309f77daf79660ebe40f4e Mon Sep 17 00:00:00 2001 From: Ashley Gibson Date: Thu, 13 Mar 2025 16:12:14 +0000 Subject: [PATCH 08/45] Rework wc tasks --- gulpfile.js | 1 + tasks/wc.js | 247 ++++++++++++++++++++++++++++------------------------ 2 files changed, 133 insertions(+), 115 deletions(-) diff --git a/gulpfile.js b/gulpfile.js index 2530fb1..a237a7c 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -72,3 +72,4 @@ gulp.on('error', (event) => { export * from './tasks/bump.js' export * from './tasks/validate.js' +export * from './tasks/wc.js' diff --git a/tasks/wc.js b/tasks/wc.js index 705653a..c681113 100644 --- a/tasks/wc.js +++ b/tasks/wc.js @@ -4,136 +4,153 @@ import path from 'node:path' import fs from 'node:fs' import FormData from 'form-data' import semver from 'semver' +import sake from '../lib/sake.js' +import { series as gulpSeries } from 'gulp' -module.exports = (gulp, plugins, sake) => { - const wcRoot = 'https://woocommerce.com/wp-json/wc/submission/runner/v1' +const wcRoot = 'https://woocommerce.com/wp-json/wc/submission/runner/v1' - let apiOptions = { - username: process.env.WC_USERNAME, - password: process.env.WC_APPLICATION_PASSWORD, - product_id: sake.config.deploy.wooId - } +let apiOptions = { + username: process.env.WC_USERNAME, + password: process.env.WC_APPLICATION_PASSWORD, + product_id: sake.config.deploy.wooId +} - let getApiURL = (endpoint) => { - return `${wcRoot}/product/${endpoint}` - } +let getApiURL = (endpoint) => { + return `${wcRoot}/product/${endpoint}` +} - let formatError = (err) => { - return err.response ? `WC API: ${err.response.data.message} (${err.response.data.code})` : err - } +let formatError = (err) => { + return err.response ? `WC API: ${err.response.data.message} (${err.response.data.code})` : err +} - // internal task to validate whether the plugin can be deployed to woocommerce.com - gulp.task('wc:validate', done => { - log.info('Making sure plugin is deployable...') - - let url = getApiURL('deploy/status') - - if (sake.options.debug) { - log.info('GET: ', url) - } - - // record whether we've logged the response, to avoid logging it in both the `then()` and `catch()` blocks - let hasLoggedResponse = false; - - axios.post(url, apiOptions) - .then(res => { - if (sake.options.debug && ! hasLoggedResponse) { - log.info('Response:') - console.debug(res.data) - hasLoggedResponse = true; - } - - /* - * Note: We'll only end up here if there was a previous deployment in progress. If there's no deployment at - * all then we'll end up in the `catch()` block because Woo sends back a 400 status code for that, which is - * actually an error state. - */ - - if (res.data.code) { - throw `Unexpected response code from WC API (${res.data.code})` - } - - if (res.data.version && semver.gte(res.data.version, sake.getPluginVersion())) { - throw `Queued version for plugin is already higher than or equal to ${sake.getPluginVersion()}` - } - - log.info('Plugin can be deployed') - - done() - }) - .catch(err => { - if (sake.options.debug && err.response && ! hasLoggedResponse) { - log.info('Response:') - console.debug(err.response.data) - hasLoggedResponse = true; - } - - // NOTE: if there's no deployment in progress then it's a 400 status code, which is why we end up in this catch block! - if (err.response && err.response.data.code === 'submission_runner_no_deploy_in_progress') { - log.info('No previous upload in queue') - return done() - } - - sake.throwDeferredError(formatError(err)) - }) - }) +/** + * Internal task to validate whether the plugin can be deployed to WooCommerce.com + */ +const wcValidate = (done) => { + log.info('Making sure plugin is deployable...') - // internal task that handles the zip file upload - gulp.task('wc:upload', (done) => { - let version = sake.getPluginVersion() - let zipPath = path.join(process.cwd(), sake.config.paths.build, `${sake.config.plugin.id}.${version}.zip`) + let url = getApiURL('deploy/status') - log.info('Uploading plugin to woocommerce.com...') + if (sake.options.debug) { + log.info('GET: ', url) + } - let url = getApiURL('deploy') + // record whether we've logged the response, to avoid logging it in both the `then()` and `catch()` blocks + let hasLoggedResponse = false; - // record whether we've logged the response, to avoid logging it in both the `then()` and `catch()` blocks - let hasLoggedResponse = false; + axios.post(url, apiOptions) + .then(res => { + if (sake.options.debug && ! hasLoggedResponse) { + log.info('Response:') + console.debug(res.data) + hasLoggedResponse = true; + } - if (sake.options.debug) { - log.info('POST: ', url) - log.info('Using ZIP file: %s as %s', zipPath, `${sake.config.plugin.id}.zip`) - } + /* + * Note: We'll only end up here if there was a previous deployment in progress. If there's no deployment at + * all then we'll end up in the `catch()` block because Woo sends back a 400 status code for that, which is + * actually an error state. + */ - const formData = new FormData(); + if (res.data.code) { + throw `Unexpected response code from WC API (${res.data.code})` + } - // add all API options to the form - Object.keys(apiOptions) - .forEach(key => formData.append(key, apiOptions[key])); + if (res.data.version && semver.gte(res.data.version, sake.getPluginVersion())) { + throw `Queued version for plugin is already higher than or equal to ${sake.getPluginVersion()}` + } - // add file data - formData.append('file', fs.createReadStream(zipPath)); - formData.append('version', version); + log.info('Plugin can be deployed') - axios.post(url, formData, { - headers: formData.getHeaders() + done() }) - .then(res => { - if (sake.options.debug && ! hasLoggedResponse) { - log.info('Response:'); - console.debug(res.data); - hasLoggedResponse = true; - } - - if (! res.data.success) { - throw `WC API did not return a deployment status or deployment has failed` - } - - log.info('Plugin deployment created successfully') - - done() - }) - .catch(err => { - if (sake.options.debug && err.response && ! hasLoggedResponse) { - log.info('Response:') - console.debug(err.response.data) - hasLoggedResponse = true; - } - - throw err; - }) + .catch(err => { + if (sake.options.debug && err.response && ! hasLoggedResponse) { + log.info('Response:') + console.debug(err.response.data) + hasLoggedResponse = true; + } + + // NOTE: if there's no deployment in progress then it's a 400 status code, which is why we end up in this catch block! + if (err.response && err.response.data.code === 'submission_runner_no_deploy_in_progress') { + log.info('No previous upload in queue') + return done() + } + + sake.throwDeferredError(formatError(err)) + }) +} + +wcValidate.displayName = 'wc:validate' + +/** + * Internal task the handles the zip file upload + */ +const wcUpload = (done) => { + let version = sake.getPluginVersion() + let zipPath = path.join(process.cwd(), sake.config.paths.build, `${sake.config.plugin.id}.${version}.zip`) + + log.info('Uploading plugin to woocommerce.com...') + + let url = getApiURL('deploy') + + // record whether we've logged the response, to avoid logging it in both the `then()` and `catch()` blocks + let hasLoggedResponse = false; + + if (sake.options.debug) { + log.info('POST: ', url) + log.info('Using ZIP file: %s as %s', zipPath, `${sake.config.plugin.id}.zip`) + } + + const formData = new FormData(); + + // add all API options to the form + Object.keys(apiOptions) + .forEach(key => formData.append(key, apiOptions[key])); + + // add file data + formData.append('file', fs.createReadStream(zipPath)); + formData.append('version', version); + + axios.post(url, formData, { + headers: formData.getHeaders() }) + .then(res => { + if (sake.options.debug && ! hasLoggedResponse) { + log.info('Response:'); + console.debug(res.data); + hasLoggedResponse = true; + } + + if (! res.data.success) { + throw `WC API did not return a deployment status or deployment has failed` + } + + log.info('Plugin deployment created successfully') + + done() + }) + .catch(err => { + if (sake.options.debug && err.response && ! hasLoggedResponse) { + log.info('Response:') + console.debug(err.response.data) + hasLoggedResponse = true; + } + + throw err; + }) +} + +wcUpload.displayName = 'wc:upload' + +/** + * The main task to deploy woocommerce.com plugins + */ +const wcDeploy = gulpSeries(wcValidate, wcUpload) +wcDeploy.displayName = 'wc:deploy' - // the main task to deploy woocommerce.com plugins - gulp.task('wc:deploy', gulp.series('wc:validate', 'wc:upload')) +export { + wcValidate, + wcUpload, + wcDeploy } From a6a6826c24b64bd77c95d9d55b683e01ddf7e061 Mon Sep 17 00:00:00 2001 From: Ashley Gibson Date: Thu, 13 Mar 2025 16:12:30 +0000 Subject: [PATCH 09/45] Only import the fs function we use --- lib/config.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/config.js b/lib/config.js index 6a9b681..5f8e2e7 100644 --- a/lib/config.js +++ b/lib/config.js @@ -1,5 +1,5 @@ import path from 'node:path' -import fs from 'node:fs' +import { existsSync } from 'node:fs' import log from 'fancy-log' import _ from 'lodash' import { createRequire } from 'node:module' @@ -65,7 +65,7 @@ const buildSakeConfig = () => { let parentConfigPath = path.join(process.cwd(), '../sake.config.js') let found = false - if (fs.existsSync(parentConfigPath)) { + if (existsSync(parentConfigPath)) { log.warn('Found config file in parent folder') localConfig = require(parentConfigPath) found = true @@ -74,7 +74,7 @@ const buildSakeConfig = () => { // load local, plugin-specific config file let configFilePath = path.join(process.cwd(), 'sake.config.js') - if (fs.existsSync(configFilePath)) { + if (existsSync(configFilePath)) { localConfig = _.merge(localConfig, require(configFilePath)) found = true } From 742c38a081dfebd652c62e98d7223cbf957ca56e Mon Sep 17 00:00:00 2001 From: Ashley Gibson Date: Thu, 13 Mar 2025 16:14:41 +0000 Subject: [PATCH 10/45] Rework config task --- gulpfile.js | 1 + tasks/config.js | 20 +++++++++----------- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/gulpfile.js b/gulpfile.js index a237a7c..440ed40 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -71,5 +71,6 @@ gulp.on('error', (event) => { /************** Task Exports */ export * from './tasks/bump.js' +export * from './tasks/config.js' export * from './tasks/validate.js' export * from './tasks/wc.js' diff --git a/tasks/config.js b/tasks/config.js index 0fe9c50..ebd9f67 100644 --- a/tasks/config.js +++ b/tasks/config.js @@ -1,15 +1,13 @@ import dottie from 'dottie'; +import sake from '../lib/sake.js' -module.exports = (gulp, plugins, sake) => { - // prints current sake.configuration - gulp.task('config', (done) => { - // pass --property=deploy.production to only see sake.config values for that property - if (sake.options.property) { - console.log(dottie.get(sake.config, sake.options.property)) - } else { - console.log(sake.config) - } +export const config = (done) => { + // pass --property=deploy.production to only see sake.config values for that property + if (sake.options.property) { + console.log(dottie.get(sake.config, sake.options.property)) + } else { + console.log(sake.config) + } - done() - }) + done() } From b20d28722fc88c796c48933c3e87e4c9c88dca23 Mon Sep 17 00:00:00 2001 From: Ashley Gibson Date: Thu, 13 Mar 2025 16:27:28 +0000 Subject: [PATCH 11/45] Rework linting --- gulpfile.js | 1 + tasks/lint.js | 166 ++++++++++++++++++++++++++++---------------------- 2 files changed, 94 insertions(+), 73 deletions(-) diff --git a/gulpfile.js b/gulpfile.js index 440ed40..320d570 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -72,5 +72,6 @@ gulp.on('error', (event) => { export * from './tasks/bump.js' export * from './tasks/config.js' +export * from './tasks/lint.js' export * from './tasks/validate.js' export * from './tasks/wc.js' diff --git a/tasks/lint.js b/tasks/lint.js index 189ca19..57a38d5 100644 --- a/tasks/lint.js +++ b/tasks/lint.js @@ -1,91 +1,111 @@ import path from 'node:path' import dottie from 'dottie' import fs from 'node:fs' +import * as gulp from 'gulp' +import sake from '../lib/sake.js' +import phplint from 'gulp-phplint' +import coffeelint from 'gulp-coffeelint' +import eslint from 'gulp-eslint' +import sassLint from 'gulp-sass-lint' +import { fileURLToPath } from 'node:url' +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); -module.exports = (gulp, plugins, sake) => { - gulp.task('lint', gulp.parallel('lint:php', 'lint:scripts', 'lint:styles')) +const lintPhp = (done) => { + let paths = [ + `${sake.config.paths.src}/**/*.php`, + `!${sake.config.paths.vendor}/**/*.php`, + `!**/node_modules/**/*.php` + ] - gulp.task('lint:php', (done) => { - let paths = [ - `${sake.config.paths.src}/**/*.php`, - `!${sake.config.paths.vendor}/**/*.php`, - `!**/node_modules/**/*.php` - ] + // skip composer paths + if (sake.config.composer) { + let installerPaths = dottie.get(sake.config.composer, 'extra.installer-paths') - // skip composer paths - if (sake.config.composer) { - let installerPaths = dottie.get(sake.config.composer, 'extra.installer-paths') + if (installerPaths) { + Object.keys(installerPaths).forEach((vendorPath) => { + paths.push(`!${vendorPath}/**/*.php`) + }) + } + } - if (installerPaths) { - Object.keys(installerPaths).forEach((vendorPath) => { - paths.push(`!${vendorPath}/**/*.php`) - }) + return gulp.src(paths) + .pipe(phplint('', { skipPassedFiles: true, notify: false })) + .pipe(phplint.reporter((file) => { + let report = file.phplintReport || {} + // make sure to fail on first error + if (report.error) { + sake.throwError(`${report.message} on line ${report.line} of ${report.filename}`) } - } + })) +} +lintPhp.displayName = 'lint:php' - return gulp.src(paths) - .pipe(plugins.phplint('', { skipPassedFiles: true, notify: false })) - .pipe(plugins.phplint.reporter((file) => { - let report = file.phplintReport || {} - // make sure to fail on first error - if (report.error) { - sake.throwError(`${report.message} on line ${report.line} of ${report.filename}`) - } - })) - }) - - // the main task to lint scripts - gulp.task('lint:scripts', gulp.parallel('lint:coffee', 'lint:js')) - - // lint coffee - gulp.task('lint:coffee', (done) => { - if (! fs.existsSync(sake.config.paths.assetPaths.js)) { - return Promise.resolve() - } +const lintCoffee = (done) => { + if (! fs.existsSync(sake.config.paths.assetPaths.js)) { + return Promise.resolve() + } - let coffeeLintFile = sake.options['coffeelint-file'] ? path.join(process.cwd(), sake.options['coffeelint-file']) : path.join(__dirname, '../lib/lintfiles/coffeelint.json') + let coffeeLintFile = sake.options['coffeelint-file'] ? path.join(process.cwd(), sake.options['coffeelint-file']) : path.join(__dirname, '../lib/lintfiles/coffeelint.json') - return gulp.src(`${sake.config.paths.assetPaths.js}/**/*.coffee`) - .pipe(plugins.coffeelint(coffeeLintFile)) - .pipe(plugins.coffeelint.reporter()) - .pipe(plugins.coffeelint.reporter('fail')) // fail task on errors - .on('end', done) - .on('error', done) - }) + return gulp.src(`${sake.config.paths.assetPaths.js}/**/*.coffee`) + .pipe(coffeelint(coffeeLintFile)) + .pipe(coffeelint.reporter()) + .pipe(coffeelint.reporter('fail')) // fail task on errors + .on('end', done) + .on('error', done) +} +lintCoffee.displayName = 'lint:coffee' - // lint plain JS - gulp.task('lint:js', () => { - if (! fs.existsSync(sake.config.paths.assetPaths.js)) { - return Promise.resolve() - } +const lintJs = (done) => { + if (! fs.existsSync(sake.config.paths.assetPaths.js)) { + return Promise.resolve() + } - // use WordPress standards - overrideable by individual plugins that provide a .eslintrc file - // see https://github.com/WordPress-Coding-Standards/eslint-config-wordpress/blob/master/index.js - let esLintFile = sake.options['eslint-configFile'] ? path.join(process.cwd(), sake.options['eslint-configFile']) : path.join(__dirname, '../lib/lintfiles/.eslintrc') - let esLintOptions = { - configFile: esLintFile, - quiet: false - } + // use WordPress standards - overrideable by individual plugins that provide a .eslintrc file + // see https://github.com/WordPress-Coding-Standards/eslint-config-wordpress/blob/master/index.js + let esLintFile = sake.options['eslint-configFile'] ? path.join(process.cwd(), sake.options['eslint-configFile']) : path.join(__dirname, '../lib/lintfiles/.eslintrc') + let esLintOptions = { + configFile: esLintFile, + quiet: false + } - return gulp.src(sake.config.paths.assetPaths.javascriptSources) - .pipe(plugins.eslint(esLintOptions)) - .pipe(plugins.eslint.format('table')) - }) + return gulp.src(sake.config.paths.assetPaths.javascriptSources) + .pipe(eslint(esLintOptions)) + .pipe(eslint.format('table')) +} +lintJs.displayName = 'lint:js' - // main task for linting styles - gulp.task('lint:styles', gulp.parallel('lint:scss')) +const lintScss = (done) => { + if (! fs.existsSync(sake.config.paths.assetPaths.css)) { + return Promise.resolve() + } - // lint SCSS - gulp.task('lint:scss', (done) => { - if (! fs.existsSync(sake.config.paths.assetPaths.css)) { - return Promise.resolve() - } + return gulp.src(`${sake.config.paths.assetPaths.css}/**/*.scss`) + .pipe(sassLint()) + .pipe(sassLint.failOnError()) // fail task on errors + // explicitly setting end and error event handlers will give us cleaner error logging + .on('end', done) + .on('error', done) +} +lintScss.displayName = 'lint:scss' + +// the main task to lint scripts +const lintScripts = gulp.parallel(lintCoffee, lintJs) +lintScripts.displayName = 'lint:scripts' + +// the main task to lint styles +const lintStyles = gulp.parallel(lintScss) +lintStyles.displayName = 'lint:styles' + +const lint = gulp.parallel(lintPhp, lintScripts, lintStyles) - return gulp.src(`${sake.config.paths.assetPaths.css}/**/*.scss`) - .pipe(plugins.sassLint()) - .pipe(plugins.sassLint.failOnError()) // fail task on errors - // explicitly setting end and error event handlers will give us cleaner error logging - .on('end', done) - .on('error', done) - }) +export { + lint, + lintScripts, + lintPhp, + lintCoffee, + lintJs, + lintScss, + lintStyles } From c87cc194109be196e7bd037a1867365a700f84ae Mon Sep 17 00:00:00 2001 From: Ashley Gibson Date: Thu, 13 Mar 2025 16:32:43 +0000 Subject: [PATCH 12/45] Rework imagemin --- gulpfile.js | 1 + tasks/imagemin.js | 32 ++++++++++++++++++++------------ 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/gulpfile.js b/gulpfile.js index 320d570..b5555f6 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -72,6 +72,7 @@ gulp.on('error', (event) => { export * from './tasks/bump.js' export * from './tasks/config.js' +export * from './tasks/imagemin.js' export * from './tasks/lint.js' export * from './tasks/validate.js' export * from './tasks/wc.js' diff --git a/tasks/imagemin.js b/tasks/imagemin.js index af05737..a59d2e7 100644 --- a/tasks/imagemin.js +++ b/tasks/imagemin.js @@ -1,17 +1,25 @@ import fs from 'node:fs'; import log from 'fancy-log'; +import imagemin from 'gulp-imagemin' +import * as gulp from 'gulp' +import * as gulpif from 'gulp-if' +import sake from '../lib/sake.js' +import browserSync from 'browser-sync' -module.exports = (gulp, plugins, sake) => { - // optimize images - gulp.task('imagemin', () => { - if (! fs.existsSync(sake.config.paths.assetPaths.images)) { - log.info(`The directory ${sake.config.paths.assetPaths.images} does not exist.`) - return Promise.resolve() - } +const minifyImages = (done) => { + if (! fs.existsSync(sake.config.paths.assetPaths.images)) { + log.info(`The directory ${sake.config.paths.assetPaths.images} does not exist.`) + return Promise.resolve() + } - return gulp.src(`${sake.config.paths.assetPaths.images}/**.*{png,jpg,gif,svg}`) - .pipe(plugins.imagemin()) - .pipe(gulp.dest(sake.config.paths.assetPaths.images)) - .pipe(plugins.if(() => sake.isWatching && sake.config.tasks.watch.useBrowserSync, plugins.browserSync.stream())) - }) + return gulp.src(`${sake.config.paths.assetPaths.images}/**.*{png,jpg,gif,svg}`) + .pipe(imagemin()) + .pipe(gulp.dest(sake.config.paths.assetPaths.images)) + .pipe(gulpif(() => sake.isWatching && sake.config.tasks.watch.useBrowserSync, browserSync.stream())) +} + +minifyImages.displayName = 'imagemin' + +export { + minifyImages } From a8d9bd30166b8f81a2bc67991c30aea0e6ebd159 Mon Sep 17 00:00:00 2001 From: Ashley Gibson Date: Fri, 14 Mar 2025 10:17:38 +0000 Subject: [PATCH 13/45] Adjust gulpif import --- tasks/imagemin.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasks/imagemin.js b/tasks/imagemin.js index a59d2e7..2fb6b65 100644 --- a/tasks/imagemin.js +++ b/tasks/imagemin.js @@ -2,7 +2,7 @@ import fs from 'node:fs'; import log from 'fancy-log'; import imagemin from 'gulp-imagemin' import * as gulp from 'gulp' -import * as gulpif from 'gulp-if' +import gulpif from 'gulp-if' import sake from '../lib/sake.js' import browserSync from 'browser-sync' From 8f118fecd9891886a14af508fd9364dcf13afc5a Mon Sep 17 00:00:00 2001 From: Ashley Gibson Date: Fri, 14 Mar 2025 10:45:00 +0000 Subject: [PATCH 14/45] Rework shell tasks --- gulpfile.js | 1 + tasks/shell.js | 461 +++++++++++++++++++++++++++---------------------- 2 files changed, 259 insertions(+), 203 deletions(-) diff --git a/gulpfile.js b/gulpfile.js index b5555f6..609938f 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -74,5 +74,6 @@ export * from './tasks/bump.js' export * from './tasks/config.js' export * from './tasks/imagemin.js' export * from './tasks/lint.js' +export * from './tasks/shell.js' export * from './tasks/validate.js' export * from './tasks/wc.js' diff --git a/tasks/shell.js b/tasks/shell.js index deac903..b295d74 100644 --- a/tasks/shell.js +++ b/tasks/shell.js @@ -3,261 +3,316 @@ import path from 'node:path' import log from 'fancy-log' import shell from 'shelljs' import _str from 'underscore.string' +import sake from '../lib/sake.js' +import gulp from 'gulp' -module.exports = (gulp, plugins, sake) => { - const awk = process.platform === 'win32' ? 'gawk' : 'awk' - const noRunIfEmpty = process.platform !== 'darwin' ? '--no-run-if-empty ' : '' +const awk = process.platform === 'win32' ? 'gawk' : 'awk' +const noRunIfEmpty = process.platform !== 'darwin' ? '--no-run-if-empty ' : '' - // run a shell command, preserving output and failing the task on errors - const exec = (command, opts, done) => { - log.info('$ ' + command) +// run a shell command, preserving output and failing the task on errors +const exec = (command, opts, done) => { + log.info('$ ' + command) - if (typeof opts === 'function') { - done = opts - opts = {} - } - - shell.exec(command, opts, (code) => done(code > 0 ? 'Command failed [exit code ' + code + ']: ' + command : null)) + if (typeof opts === 'function') { + done = opts + opts = {} } - // update framework subtree - gulp.task('shell:update_framework', (done) => { - if (!sake.config.framework) { - sake.throwError('Not a frameworked plugin, aborting') - } - - let command = '' - - if (sake.config.framework === 'v4') { - let frameworkPath = path.join(process.cwd(), sake.config.paths.src, sake.config.paths.framework.base) - - if (fs.existsSync(frameworkPath)) { - let branch = sake.options.branch || 'legacy-v4' - let prefix = path.join((sake.config.multiPluginRepo ? sake.config.plugin.id : '.'), sake.config.paths.framework.base) - - command = [ - 'git fetch wc-plugin-framework ' + branch, - 'git status', - 'git subtree pull --prefix ' + prefix + ' wc-plugin-framework ' + branch + ' --squash', - 'echo subtree up to date!' - ] - - if (sake.config.multiPluginRepo) { - command.unshift('cd ../') - } + shell.exec(command, opts, (code) => done(code > 0 ? 'Command failed [exit code ' + code + ']: ' + command : null)) +} - command = command.join(' && ') - } else { - command = 'echo no subtree to update' - } - } +/** + * Update framework subtree + */ +const shellUpdateFramework = (done) => { + if (!sake.config.framework) { + sake.throwError('Not a frameworked plugin, aborting') + } - exec(command, done) - }) + let command = '' - // commit framework update - gulp.task('shell:update_framework_commit', (done) => { + if (sake.config.framework === 'v4') { let frameworkPath = path.join(process.cwd(), sake.config.paths.src, sake.config.paths.framework.base) - let command = '' if (fs.existsSync(frameworkPath)) { + let branch = sake.options.branch || 'legacy-v4' + let prefix = path.join((sake.config.multiPluginRepo ? sake.config.plugin.id : '.'), sake.config.paths.framework.base) + command = [ - 'git add -A', - 'git diff-index --quiet --cached HEAD || git commit -m "' + sake.config.plugin.name + ': Update framework to v' + sake.config.plugin.frameworkVersion + '"' - ].join(' && ') - } else { - // TODO: is this still necessary? {IT 2018-03-21} - command = [ - 'git add -A', - 'git diff-index --quiet --cached HEAD || git commit -m "' + sake.config.plugin.name + ': Update readme.txt"' + 'git fetch wc-plugin-framework ' + branch, + 'git status', + 'git subtree pull --prefix ' + prefix + ' wc-plugin-framework ' + branch + ' --squash', + 'echo subtree up to date!' ] - } - exec(command, done) - }) + if (sake.config.multiPluginRepo) { + command.unshift('cd ../') + } - // ensure the working copy (git tree) has no uncommited changes - gulp.task('shell:git_ensure_clean_working_copy', (done) => { - let command = [ - 'git diff-index --quiet HEAD' - ].join(' && ') + command = command.join(' && ') + } else { + command = 'echo no subtree to update' + } + } - shell.exec(command, (code) => { - if (!code) return done() + exec(command, done) +} +shellUpdateFramework.displayName = 'shell:update_framework' - shell.exec('git status', () => { - sake.throwError('Working copy is not clean!') - }) - }) - }) +/** + * Commit framework update + */ +const shellUpdateFrameworkCommit = (done) => { + let frameworkPath = path.join(process.cwd(), sake.config.paths.src, sake.config.paths.framework.base) + let command = '' - // commit and push update - gulp.task('shell:git_push_update', (done) => { - let command = [ + if (fs.existsSync(frameworkPath)) { + command = [ 'git add -A', - 'git commit -m "' + sake.config.plugin.name + ': ' + sake.getPluginVersion() + ' Versioning"' + (sake.options.release_issue_to_close ? ' -m "Closes #' + sake.options.release_issue_to_close + '"' : ''), - 'git push', - 'echo git up to date!' + 'git diff-index --quiet --cached HEAD || git commit -m "' + sake.config.plugin.name + ': Update framework to v' + sake.config.plugin.frameworkVersion + '"' ].join(' && ') + } else { + // TODO: is this still necessary? {IT 2018-03-21} + command = [ + 'git add -A', + 'git diff-index --quiet --cached HEAD || git commit -m "' + sake.config.plugin.name + ': Update readme.txt"' + ] + } - exec(command, done) - }) + exec(command, done) +} +shellUpdateFrameworkCommit.displayName = 'shell:update_framework_commit' - // pull updates from WC repo, or clone repo, if deploying for the first time - gulp.task('shell:git_pull_wc_repo', (done) => { - let command = [] +/** + * Ensure the working copy (git tree) has no uncommitted changes + */ +const shellGitEnsureCleanWorkingCopy = (done) => { + let command = [ + 'git diff-index --quiet HEAD' + ].join(' && ') - if (!fs.existsSync(sake.getProductionRepoPath())) { - // ensure that the tmp dir exists - if (!fs.existsSync(sake.config.paths.tmp)) { - shell.mkdir('-p', sake.config.paths.tmp) - } + shell.exec(command, (code) => { + if (!code) return done() - // repo does not exist yet - command = [ - 'cd ' + sake.config.paths.tmp, - 'git clone ' + sake.config.deploy.production.url - ] - } else { - // repo already exists - command = [ - 'cd ' + sake.getProductionRepoPath(), - 'git pull && git push' - ] - } - - shell.exec(command.join(' && '), (code, stdout, stderr) => { - // ignore missing ref error - this will happen when the remote repo is empty (for example, a new WC plugin) - // and we try to `git pull` - if (code === 1 && stderr.indexOf('Your configuration specifies to merge with the ref') > -1) { - return done() - } else { - return done(code > 0 ? 'Command failed [exit code ' + code + ']: ' + command : null) - } + shell.exec('git status', () => { + sake.throwError('Working copy is not clean!') }) }) +} +shellGitEnsureCleanWorkingCopy.displayName = 'shell:git_ensure_clean_working_copy' + +/** + * Commit and push update + */ +const shellGitPushUpdate = (done) => { + const command = [ + 'git add -A', + 'git commit -m "' + sake.config.plugin.name + ': ' + sake.getPluginVersion() + ' Versioning"' + (sake.options.release_issue_to_close ? ' -m "Closes #' + sake.options.release_issue_to_close + '"' : ''), + 'git push', + 'echo git up to date!' + ].join(' && ') + + exec(command, done) +} +shellGitPushUpdate.displayName = 'shell:git_push_update' - // commit and push update to WC repo - gulp.task('shell:git_push_wc_repo', (done) => { - let closeIssues = '' +/** + * Pull updates from WC repo, or clone repo, if deploying for the first time + * @deprecated We no longer use WC mirror repos + */ +const shellGitPullWcRepo = (done) => { + let command = [] - if (sake.options.wc_issues_to_close) { - closeIssues = ' -m "' + _str.capitalize(sake.options.wc_issues_to_close.map((issue) => `closes #${issue}`).join(', ')) + '"' + if (!fs.existsSync(sake.getProductionRepoPath())) { + // ensure that the tmp dir exists + if (!fs.existsSync(sake.config.paths.tmp)) { + shell.mkdir('-p', sake.config.paths.tmp) } - // always ensure to pull the repo, but bypass the missing ref error - gulp.series('shell:git_pull_wc_repo')((err) => { - if (err) sake.throwError(err) - - let command = [ - 'cd ' + sake.getProductionRepoPath(), - 'git add -A', - 'git commit -m "Update ' + sake.config.plugin.name + ' to ' + sake.getPluginVersion() + '"' + closeIssues, - 'git push' - ].join(' && ') + // repo does not exist yet + command = [ + 'cd ' + sake.config.paths.tmp, + 'git clone ' + sake.config.deploy.production.url + ] + } else { + // repo already exists + command = [ + 'cd ' + sake.getProductionRepoPath(), + 'git pull && git push' + ] + } - exec(command, done) - }) + shell.exec(command.join(' && '), (code, stdout, stderr) => { + // ignore missing ref error - this will happen when the remote repo is empty (for example, a new WC plugin) + // and we try to `git pull` + if (code === 1 && stderr.indexOf('Your configuration specifies to merge with the ref') > -1) { + return done() + } else { + return done(code > 0 ? 'Command failed [exit code ' + code + ']: ' + command : null) + } }) +} +shellGitPullWcRepo.displayName = 'shell:git_pull_wc_repo' + +/** + * Commit and push update to WC repo + * @deprecated We no longer use WC mirror repos + */ +const shellGitPushWcRepo = (done) => { + let closeIssues = '' + + if (sake.options.wc_issues_to_close) { + closeIssues = ' -m "' + _str.capitalize(sake.options.wc_issues_to_close.map((issue) => `closes #${issue}`).join(', ')) + '"' + } + + // always ensure to pull the repo, but bypass the missing ref error + gulp.series('shell:git_pull_wc_repo')((err) => { + if (err) sake.throwError(err) - // TODO: do we need this anymore? - // commit and push update, ver 2 - gulp.task('shell:git_update_wc_repo', (done) => { let command = [ 'cd ' + sake.getProductionRepoPath(), - 'git pull', 'git add -A', - 'git diff-index --quiet --cached HEAD || git commit -m "Updating ' + sake.config.plugin.name + '"', - 'git push', - 'echo WooCommerce repo up to date!' + 'git commit -m "Update ' + sake.config.plugin.name + ' to ' + sake.getPluginVersion() + '"' + closeIssues, + 'git push' ].join(' && ') exec(command, done) }) +} +shellGitPushWcRepo.displayName = 'shell:git_push_wc_repo' + +/** + * Commit and push update to WC repo, version 2 + * @deprecated We no longer use WooCommerce mirror repos + */ +const shellGitUpdateWcRepo = (done) => { + let command = [ + 'cd ' + sake.getProductionRepoPath(), + 'git pull', + 'git add -A', + 'git diff-index --quiet --cached HEAD || git commit -m "Updating ' + sake.config.plugin.name + '"', + 'git push', + 'echo WooCommerce repo up to date!' + ].join(' && ') + + exec(command, done) +} +shellGitUpdateWcRepo.displayName = 'shell:git_update_wc_repo' - // stash uncommitted changes - gulp.task('shell:git_stash', (done) => { - exec('git stash', done) - }) - - // apply latest stash - gulp.task('shell:git_stash_apply', (done) => { - exec('git stash apply', done) - }) - - gulp.task('shell:composer_status', (done) => { - if (fs.existsSync(path.join(process.cwd(), 'composer.json'))) { - exec('composer status -v', done) - } else { - log.info('No composer.json found, skipping composer status') - done() - } - }) - - gulp.task('shell:composer_install', (done) => { - if (fs.existsSync(path.join(process.cwd(), 'composer.json'))) { - exec('composer install --no-dev', done) - } else { - log.info('No composer.json found, skipping composer install') - done() - } - }) +/** + * Stash uncommitted changes + */ +const shellGitStash = (done) => { + exec('git stash', done) +} +shellGitStash.displayName = 'shell:git_stash' - gulp.task('shell:composer_update', (done) => { - if (fs.existsSync(path.join(process.cwd(), 'composer.json'))) { - exec('composer update --no-dev', done) - } else { - log.info('No composer.json found, skipping composer update') - done() - } - }) +/** + * Apply latest stash + */ +const shellGitStashApply = (done) => { + exec('git stash apply', done) +} +shellGitStashApply.displayName = 'shell:git_stash_apply' + +const shellComposerStatus = (done) => { + if (fs.existsSync(path.join(process.cwd(), 'composer.json'))) { + exec('composer status -v', done) + } else { + log.info('No composer.json found, skipping composer status') + done() + } +} +shellComposerStatus.displayName = 'shell:composer_status' + +const shellComposerInstall = (done) => { + if (fs.existsSync(path.join(process.cwd(), 'composer.json'))) { + exec('composer install --no-dev', done) + } else { + log.info('No composer.json found, skipping composer install') + done() + } +} +shellComposerInstall.displayName = 'shell:composer_install' + +const shellComposerUpdate = (done) => { + if (fs.existsSync(path.join(process.cwd(), 'composer.json'))) { + exec('composer update --no-dev', done) + } else { + log.info('No composer.json found, skipping composer update') + done() + } +} +shellComposerUpdate.displayName = 'shell:composer_update' - gulp.task('shell:svn_checkout', (done) => { - // ensure that the tmp dir exists - if (!fs.existsSync(sake.config.paths.tmp)) { - shell.mkdir('-p', sake.config.paths.tmp) - } +const shellSvnCheckout = (done) => { + // ensure that the tmp dir exists + if (!fs.existsSync(sake.config.paths.tmp)) { + shell.mkdir('-p', sake.config.paths.tmp) + } - let command = 'svn co --force-interactive ' + sake.config.deploy.production.url + ' ' + sake.getProductionRepoPath() + let command = 'svn co --force-interactive ' + sake.config.deploy.production.url + ' ' + sake.getProductionRepoPath() - exec(command, done) - }) + exec(command, done) +} +shellSvnCheckout.displayName = 'shell:svn_checkout' - gulp.task('shell:svn_commit_trunk', (done) => { - const commitMsg = 'Committing ' + sake.getPluginVersion() + ' to trunk' +const shellSvnCommitTrunk = (done) => { + const commitMsg = 'Committing ' + sake.getPluginVersion() + ' to trunk' - let command = [ - 'cd ' + path.join(sake.getProductionRepoPath(), 'trunk'), - 'svn status | ' + awk + " '/^[?]/{print $2}' | xargs " + noRunIfEmpty + 'svn add', - 'svn status | ' + awk + " '/^[!]/{print $2}' | xargs " + noRunIfEmpty + 'svn delete', - 'svn commit --force-interactive --username="' + sake.config.deploy.production.user + '" -m "' + commitMsg + '"' - ].join(' && ') + let command = [ + 'cd ' + path.join(sake.getProductionRepoPath(), 'trunk'), + 'svn status | ' + awk + " '/^[?]/{print $2}' | xargs " + noRunIfEmpty + 'svn add', + 'svn status | ' + awk + " '/^[!]/{print $2}' | xargs " + noRunIfEmpty + 'svn delete', + 'svn commit --force-interactive --username="' + sake.config.deploy.production.user + '" -m "' + commitMsg + '"' + ].join(' && ') - exec(command, done) - }) + exec(command, done) +} +shellSvnCommitTrunk.displayName = 'shell:svn_commit_trunk' - gulp.task('shell:svn_commit_tag', (done) => { - const commitMsg = 'Tagging ' + sake.getPluginVersion() +const shellSvnCommitTag = (done) => { + const commitMsg = 'Tagging ' + sake.getPluginVersion() - let command = [ - 'cd ' + path.join(sake.getProductionRepoPath(), 'tags', sake.getPluginVersion()), - 'svn add .', - 'svn commit --force-interactive --username="' + sake.config.deploy.production.user + '" -m "' + commitMsg + '"' - ].join(' && ') + let command = [ + 'cd ' + path.join(sake.getProductionRepoPath(), 'tags', sake.getPluginVersion()), + 'svn add .', + 'svn commit --force-interactive --username="' + sake.config.deploy.production.user + '" -m "' + commitMsg + '"' + ].join(' && ') - exec(command, done) - }) + exec(command, done) +} +shellSvnCommitTag.displayName = 'shell:svn_commit_tag' - gulp.task('shell:svn_commit_assets', (done) => { - const commitMsg = 'Committing assets for ' + sake.getPluginVersion() +const shellSvnCommitAssets = (done) => { + const commitMsg = 'Committing assets for ' + sake.getPluginVersion() - let command = [ - 'cd ' + path.join(sake.getProductionRepoPath(), 'assets'), - 'svn status | ' + awk + " '/^[?]/{print $2}' | xargs " + noRunIfEmpty + 'svn add', - 'svn status | ' + awk + " '/^[!]/{print $2}' | xargs " + noRunIfEmpty + 'svn delete', - 'svn commit --force-interactive --username="' + sake.config.deploy.production.user + '" -m "' + commitMsg + '"' - ].join(' && ') + let command = [ + 'cd ' + path.join(sake.getProductionRepoPath(), 'assets'), + 'svn status | ' + awk + " '/^[?]/{print $2}' | xargs " + noRunIfEmpty + 'svn add', + 'svn status | ' + awk + " '/^[!]/{print $2}' | xargs " + noRunIfEmpty + 'svn delete', + 'svn commit --force-interactive --username="' + sake.config.deploy.production.user + '" -m "' + commitMsg + '"' + ].join(' && ') - exec(command, done) - }) + exec(command, done) +} +shellSvnCommitAssets.displayName = 'shell:svn_commit_assets' + +export { + shellUpdateFramework, + shellUpdateFrameworkCommit, + shellGitEnsureCleanWorkingCopy, + shellGitPushUpdate, + shellGitPullWcRepo, + shellGitPushWcRepo, + shellGitUpdateWcRepo, + shellGitStash, + shellGitStashApply, + shellComposerStatus, + shellComposerInstall, + shellComposerUpdate, + shellSvnCheckout, + shellSvnCommitTrunk, + shellSvnCommitTag, + shellSvnCommitAssets } From 47a42968bdfc4ff229b9935cb97b705a86c602f8 Mon Sep 17 00:00:00 2001 From: Ashley Gibson Date: Fri, 14 Mar 2025 10:48:32 +0000 Subject: [PATCH 15/45] Rework watch --- gulpfile.js | 1 + tasks/watch.js | 74 ++++++++++++++++++++++++++------------------------ 2 files changed, 40 insertions(+), 35 deletions(-) diff --git a/gulpfile.js b/gulpfile.js index 609938f..341f82f 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -76,4 +76,5 @@ export * from './tasks/imagemin.js' export * from './tasks/lint.js' export * from './tasks/shell.js' export * from './tasks/validate.js' +export * from './tasks/watch.js' export * from './tasks/wc.js' diff --git a/tasks/watch.js b/tasks/watch.js index 9caac6c..25775aa 100644 --- a/tasks/watch.js +++ b/tasks/watch.js @@ -1,43 +1,47 @@ import log from 'fancy-log' +import browserSync from 'browser-sync' +import sake from '../lib/sake.js' +import gulp from 'gulp' -// watch files for changes and compile assets necessary -module.exports = (gulp, plugins, sake) => { - gulp.task('watch', () => { - // start browsersync if enabled - if (sake.config.tasks.watch.useBrowserSync) { - let port = null +const watch = (done) => { + // start browsersync if enabled + if (sake.config.tasks.watch.useBrowserSync) { + let port = null - const getPort = () => { - return port + const getPort = () => { + return port + } + + browserSync.init({ + proxy: { + target: sake.config.tasks.browserSync.url, + proxyReq: [(proxyReq) => { + proxyReq.setHeader('X-Forwarded-Host', 'localhost:' + getPort()) + }] + } + }, (err, bs) => { + if (err) { + log.error(err) } + port = bs.options.get('port') + }) + } - plugins.browserSync.init({ - proxy: { - target: sake.config.tasks.browserSync.url, - proxyReq: [(proxyReq) => { - proxyReq.setHeader('X-Forwarded-Host', 'localhost:' + getPort()) - }] - } - }, (err, bs) => { - if (err) { - log.error(err) - } - port = bs.options.get('port') - }) - } + // allow other tasks to check if the watch task is running + sake.isWatching = true - // allow other tasks to check if the watch task is running - sake.isWatching = true + // kick off the watchers + // TODO: consider breaking the pipes apart, so that we can only lint and compile the + // files that were actually changed (ie not all coffee files when only a single one was changed) {IT 2018-03-21} + gulp.watch(sake.config.paths.assetPaths.javascriptSources, gulp.parallel('scripts:js')) + gulp.watch(`${sake.config.paths.assetPaths.js}/**/*.coffee`, gulp.parallel('scripts:coffee')) + gulp.watch(`${sake.config.paths.assetPaths.css}/**/*.scss`, gulp.parallel('styles')) + // watching images will result in an endless loop, because imagemin changes the original files - a possible + // workaround would be to place all original images in a separate directory + // gulp.watch(`${sake.config.paths.assetPaths.images}/**.*{png,jpg,gif,svg}`, gulp.parallel('imagemin')) + // TODO: should we also watch for changes in PHP files and regenerate POT files and reload the browser? +} - // kick off the watchers - // TODO: consider breaking the pipes apart, so that we can only lint and compile the - // files that were actually changed (ie not all coffee files when only a single one was changed) {IT 2018-03-21} - gulp.watch(sake.config.paths.assetPaths.javascriptSources, gulp.parallel('scripts:js')) - gulp.watch(`${sake.config.paths.assetPaths.js}/**/*.coffee`, gulp.parallel('scripts:coffee')) - gulp.watch(`${sake.config.paths.assetPaths.css}/**/*.scss`, gulp.parallel('styles')) - // watching images will result in an endless loop, because imagemin changes the original files - a possible - // workaround would be to place all original images in a separate directory - // gulp.watch(`${sake.config.paths.assetPaths.images}/**.*{png,jpg,gif,svg}`, gulp.parallel('imagemin')) - // TODO: should we also watch for changes in PHP files and regenerate POT files and reload the browser? - }) +export { + watch } From 6e429df496614178247d245aedea1a1a7210816b Mon Sep 17 00:00:00 2001 From: Ashley Gibson Date: Fri, 14 Mar 2025 11:57:27 +0000 Subject: [PATCH 16/45] Rework styles --- gulpfile.js | 7 +------ tasks/styles.js | 29 +++++++++++++++++------------ 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/gulpfile.js b/gulpfile.js index 341f82f..a46ed45 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -46,12 +46,6 @@ let plugins = gulpPlugins({ config: path.resolve(__dirname, 'package.json') }) -// Attach browsersync as a plugin - not really a plugin, but it helps to -// pass around the browsersync instance between tasks. Unfortunately, we -// always have to load and create an instance of it, because gulp-if does not -// support lazy evaluation yet: https://github.com/robrich/gulp-if/issues/75 -plugins.browserSync = browserSync.create() - // show notification on task errors let loggedErrors = [] @@ -75,6 +69,7 @@ export * from './tasks/config.js' export * from './tasks/imagemin.js' export * from './tasks/lint.js' export * from './tasks/shell.js' +export * from './tasks/styles.js' export * from './tasks/validate.js' export * from './tasks/watch.js' export * from './tasks/wc.js' diff --git a/tasks/styles.js b/tasks/styles.js index 52cc70c..517d560 100644 --- a/tasks/styles.js +++ b/tasks/styles.js @@ -1,13 +1,18 @@ -module.exports = (gulp, plugins, sake) => { - // main task for (optionally) linting and compiling styles - gulp.task('styles', (done) => { - let tasks = ['lint:styles', 'compile:styles'] - - // don't lint styles if they have already been linted, unless we're watching - if (!sake.isWatching && gulp.lastRun('lint:styles')) { - tasks.shift() - } - - gulp.series(tasks)(done) - }) +import gulp from 'gulp' +import sake from '../lib/sake.js' +import { lintStyles } from './lint.js' + +const styles = (done) => { + let tasks = [lintStyles, 'compile:styles'] // @TODO + + // don't lint styles if they have already been linted, unless we're watching + if (!sake.isWatching && gulp.lastRun(lintStyles)) { + tasks.shift() + } + + gulp.series(tasks)(done) +} + +export { + styles } From 975f55e6d1a536a117e25b713a14f651bb020109 Mon Sep 17 00:00:00 2001 From: Ashley Gibson Date: Fri, 14 Mar 2025 11:58:50 +0000 Subject: [PATCH 17/45] Rework makepot --- gulpfile.js | 1 + tasks/makepot.js | 40 +++++++++++++++++++++------------------- 2 files changed, 22 insertions(+), 19 deletions(-) diff --git a/gulpfile.js b/gulpfile.js index a46ed45..4127d5d 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -68,6 +68,7 @@ export * from './tasks/bump.js' export * from './tasks/config.js' export * from './tasks/imagemin.js' export * from './tasks/lint.js' +export * from './tasks/makepot.js' export * from './tasks/shell.js' export * from './tasks/styles.js' export * from './tasks/validate.js' diff --git a/tasks/makepot.js b/tasks/makepot.js index e9e4bbe..db8aa3c 100644 --- a/tasks/makepot.js +++ b/tasks/makepot.js @@ -1,26 +1,28 @@ import log from 'fancy-log' import shell from 'shelljs' +import sake from '../lib/sake.js' -// generate POT files using wp cli -module.exports = (gulp, plugins, sake) => { - gulp.task('makepot', (done) => { - const options = sake.config.tasks.makepot - const domainPath = ( options.domainPath || 'i18n/languages' ) + '/' + sake.config.plugin.id + '.pot' - const excludedPaths = ['.github/.*', 'lib/.*', 'vendor/.*', 'tests/.*', 'node_modules/.*'] - const excluded = excludedPaths.map((path) => `--exclude="${path}"`).join(' ') - const headers = options.reportBugsTo ? `--headers='{"Report-Msgid-Bugs-To": "${options.reportBugsTo}"}'` : '' +const makepot = (done) => { + const options = sake.config.tasks.makepot + const domainPath = ( options.domainPath || 'i18n/languages' ) + '/' + sake.config.plugin.id + '.pot' + const excludedPaths = ['.github/.*', 'lib/.*', 'vendor/.*', 'tests/.*', 'node_modules/.*'] + const excluded = excludedPaths.map((path) => `--exclude="${path}"`).join(' ') + const headers = options.reportBugsTo ? `--headers='{"Report-Msgid-Bugs-To": "${options.reportBugsTo}"}'` : '' - log.info('Generating POT file...') + log.info('Generating POT file...') - let result = shell.exec(`wp i18n make-pot . ${domainPath} ${headers} ${excluded}`) + let result = shell.exec(`wp i18n make-pot . ${domainPath} ${headers} ${excluded}`) - if (result.code !== 0) { - sake.throwError(`Error while generating POT file: ${result.stderr ?? 'unknown error.'}`) - done(result.stderr) - } else { - log.info(result.stdout) - log.error(result.stderr) - done() - } - }) + if (result.code !== 0) { + sake.throwError(`Error while generating POT file: ${result.stderr ?? 'unknown error.'}`) + done(result.stderr) + } else { + log.info(result.stdout) + log.error(result.stderr) + done() + } +} + +export { + makepot } From 0a99b85c807959b2a612169afefb93a09c5efb98 Mon Sep 17 00:00:00 2001 From: Ashley Gibson Date: Fri, 14 Mar 2025 12:03:35 +0000 Subject: [PATCH 18/45] Rework decaffeinate --- gulpfile.js | 2 +- tasks/decaffeinate.js | 53 +++++++++++++++++++++++++++---------------- 2 files changed, 34 insertions(+), 21 deletions(-) diff --git a/gulpfile.js b/gulpfile.js index 4127d5d..3ce590d 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -7,7 +7,6 @@ import dotenv from 'dotenv' import gulpPlugins from 'gulp-load-plugins' import notifier from 'node-notifier' import stripAnsi from 'strip-ansi' -import browserSync from 'browser-sync' import { fileURLToPath } from 'node:url' const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); @@ -67,6 +66,7 @@ gulp.on('error', (event) => { export * from './tasks/bump.js' export * from './tasks/config.js' export * from './tasks/imagemin.js' +export * from './tasks/decaffeinate.js' export * from './tasks/lint.js' export * from './tasks/makepot.js' export * from './tasks/shell.js' diff --git a/tasks/decaffeinate.js b/tasks/decaffeinate.js index 07f70f8..9b854f9 100644 --- a/tasks/decaffeinate.js +++ b/tasks/decaffeinate.js @@ -1,24 +1,37 @@ import path from 'node:path'; +import sake from '../lib/sake.js' +import gulp from 'gulp' +import browserSync from 'browser-sync' +import coffee from 'gulp-coffee' +import gulpif from 'gulp-if' +import eslint from 'gulp-eslint' +import { fileURLToPath } from 'node:url' +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); -module.exports = (gulp, plugins, sake) => { - // converts CoffeeScripts to ES6 JavaScript without minification or further handling: - // this command should only be run once when converting an existing plugin CoffeeScript codebase to plain ES6 - gulp.task('decaffeinate', () => { - // use WordPress standards - overrideable by individual plugins that provide a .eslintrc file - // see https://github.com/WordPress-Coding-Standards/eslint-config-wordpress/blob/master/index.js - let esLintFile = sake.options['eslint-configFile'] ? path.join(process.cwd(), sake.options['eslint-configFile']) : path.join(__dirname, '../lib/lintfiles/.eslintrc') - let esLintOptions = { - configFile: esLintFile, - quiet: false, - fix: true - } +/** + * Converts CoffeeScripts to ES6 JavaScript without minification or further handling. + * This command should only be run once when converting an existing plugin CoffeeScript codebase to plain SE6. + */ +const decaffeinate = (done) => { + // use WordPress standards - overrideable by individual plugins that provide a .eslintrc file + // see https://github.com/WordPress-Coding-Standards/eslint-config-wordpress/blob/master/index.js + let esLintFile = sake.options['eslint-configFile'] ? path.join(process.cwd(), sake.options['eslint-configFile']) : path.join(__dirname, '../lib/lintfiles/.eslintrc') + let esLintOptions = { + configFile: esLintFile, + quiet: false, + fix: true + } - return gulp.src(`${sake.config.paths.assetPaths.js}/**/*.coffee`) - .pipe(plugins.coffee({ bare: true })) - .pipe(gulp.dest(sake.config.paths.assetPaths.js)) - .pipe(plugins.eslint(esLintOptions)) - .pipe(plugins.eslint.format('table')) - .pipe(gulp.dest(sake.config.paths.assetPaths.js)) - .pipe(plugins.if(() => sake.isWatching && sake.config.tasks.watch.useBrowserSync, plugins.browserSync.stream.apply({ match: '**/*.js' }))) - }) + return gulp.src(`${sake.config.paths.assetPaths.js}/**/*.coffee`) + .pipe(coffee({ bare: true })) + .pipe(gulp.dest(sake.config.paths.assetPaths.js)) + .pipe(eslint(esLintOptions)) + .pipe(eslint.format('table')) + .pipe(gulp.dest(sake.config.paths.assetPaths.js)) + .pipe(gulpif(() => sake.isWatching && sake.config.tasks.watch.useBrowserSync, browserSync.stream.apply({ match: '**/*.js' }))) +} + +export { + decaffeinate } From 08d14e172788cc25ebd74e436d23f800b3f20541 Mon Sep 17 00:00:00 2001 From: Ashley Gibson Date: Fri, 14 Mar 2025 12:08:30 +0000 Subject: [PATCH 19/45] Rework clean tasks --- gulpfile.js | 1 + tasks/clean.js | 136 +++++++++++++++++++++++++++++-------------------- 2 files changed, 83 insertions(+), 54 deletions(-) diff --git a/gulpfile.js b/gulpfile.js index 3ce590d..c0bd80d 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -64,6 +64,7 @@ gulp.on('error', (event) => { /************** Task Exports */ export * from './tasks/bump.js' +export * from './tasks/clean.js' export * from './tasks/config.js' export * from './tasks/imagemin.js' export * from './tasks/decaffeinate.js' diff --git a/tasks/clean.js b/tasks/clean.js index 154c34a..7e17b2c 100644 --- a/tasks/clean.js +++ b/tasks/clean.js @@ -1,58 +1,86 @@ import path from 'node:path'; import del from 'del'; +import sake from '../lib/sake.js' -module.exports = (gulp, plugins, sake) => { - let defaultOptions = { read: false, allowEmpty: true } - - // clean dev dir from map files - gulp.task('clean:dev', () => { - return del([ - `${sake.config.paths.src}/${sake.config.paths.assets}/**/*.map` - ]) - }) - - // clean composer packages - gulp.task('clean:composer', () => { - return del([ - `${sake.config.paths.vendor}` - ]) - }) - - // clean (empty) build dir - gulp.task('clean:build', () => { - return del([ - `${sake.config.paths.build}/${sake.config.plugin.id}`, - `${sake.config.paths.build}/${sake.config.plugin.id}.*.zip` - ]) - }) - - // clean WooCommerce repo dir - gulp.task('clean:wc_repo', () => { - // this will automatically exclude any dotfiles, such as the .git directory - return del([ - sake.getProductionRepoPath() + '**/*' - ]) - }) - - // delete prerelease - gulp.task('clean:prerelease', () => { - return del([ - sake.getPrereleasesPath() + sake.config.plugin.id + '*.zip', - sake.getPrereleasesPath() + sake.config.plugin.id + '*.txt' - ]) - }) - - // clear wp repo trunk - gulp.task('clean:wp_trunk', () => { - return del([ - path.join(sake.getProductionRepoPath(), 'trunk') - ]) - }) - - // clear wp repo trunk - gulp.task('clean:wp_assets', () => { - return del([ - path.join(sake.getProductionRepoPath(), 'assets') - ]) - }) +/** + * Clean dev directory from map files + */ +const cleanDev = (done) => { + return del([ + `${sake.config.paths.src}/${sake.config.paths.assets}/**/*.map` + ]) +} +cleanDev.displayName = 'clean:dev' + +/** + * Clean composer packages + */ +const cleanComposer = (done) => { + return del([ + `${sake.config.paths.vendor}` + ]) +} +cleanComposer.displayName = 'clean:composer' + +/** + * Clean/empty the build directory + */ +const cleanBuild = (done) => { + return del([ + `${sake.config.paths.build}/${sake.config.plugin.id}`, + `${sake.config.paths.build}/${sake.config.plugin.id}.*.zip` + ]) +} +cleanBuild.displayName = 'clean:build' + +/** + * Clean the WooCommerce repo directory + * This will automatically exclude any dotfiles, such as the .git directory + */ +const cleanWcRepo = (done) => { + return del([ + sake.getProductionRepoPath() + '**/*' + ]) +} +cleanWcRepo.displayName = 'clean:wc_repo' + +/** + * Delete prerelease + */ +const cleanPrerelease = (done) => { + return del([ + sake.getPrereleasesPath() + sake.config.plugin.id + '*.zip', + sake.getPrereleasesPath() + sake.config.plugin.id + '*.txt' + ]) +} +cleanPrerelease.displayName = 'clean:prerelease' + +/** + * Clear WP repo trunk + */ +const cleanWpTrunk = (done) => { + return del([ + path.join(sake.getProductionRepoPath(), 'trunk') + ]) +} +cleanWpTrunk.displayName = 'clean:wp_trunk' + +/** + * Clear WP repo assets + */ +const cleanWpAssets = (done) => { + return del([ + path.join(sake.getProductionRepoPath(), 'assets') + ]) +} +cleanWpAssets.displayName = 'clean:wp_assets' + +export { + cleanDev, + cleanComposer, + cleanBuild, + cleanWcRepo, + cleanPrerelease, + cleanWpTrunk, + cleanWpAssets } From 2182c8716e40849bb79d7335c91fffd7cb67462f Mon Sep 17 00:00:00 2001 From: Ashley Gibson Date: Fri, 14 Mar 2025 12:31:31 +0000 Subject: [PATCH 20/45] Rework compile task --- gulpfile.js | 1 + pipes/scripts.js | 20 +++- tasks/compile.js | 297 ++++++++++++++++++++++++++--------------------- 3 files changed, 178 insertions(+), 140 deletions(-) diff --git a/gulpfile.js b/gulpfile.js index c0bd80d..ea1939d 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -65,6 +65,7 @@ gulp.on('error', (event) => { export * from './tasks/bump.js' export * from './tasks/clean.js' +export * from './tasks/compile.js' export * from './tasks/config.js' export * from './tasks/imagemin.js' export * from './tasks/decaffeinate.js' diff --git a/pipes/scripts.js b/pipes/scripts.js index b2d199f..bc36f1a 100644 --- a/pipes/scripts.js +++ b/pipes/scripts.js @@ -1,6 +1,14 @@ import lazypipe from 'lazypipe'; +import babel from 'gulp-babel' +import gulpif from 'gulp-if' +import uglify from 'gulp-uglify' +import rename from 'gulp-rename' +import sourcemaps from 'gulp-sourcemaps' +import sake from '../lib/sake.js' +import { createRequire } from 'node:module'; +const require = createRequire(import.meta.url); -export default function scripts(plugins, sake) { +export function scriptPipes() { const pipes = {} // transpile, minify and write sourcemaps @@ -10,16 +18,16 @@ export default function scripts(plugins, sake) { // 3. We need to tell Babel to find the preset from this project, not from the current working directory, // see https://github.com/babel/babel-loader/issues/299#issuecomment-259713477. pipes.compileJs = lazypipe() - .pipe(plugins.babel, { presets: ['@babel/preset-env', '@babel/preset-react'].map(require.resolve) }) + .pipe(babel, { presets: ['@babel/preset-env', '@babel/preset-react'].map(require.resolve) }) .pipe(() => { // see https://github.com/OverZealous/lazypipe#using-with-more-complex-function-arguments-such-as-gulp-if - return plugins.if(sake.options.minify, plugins.uglify()) + return gulpif(sake.options.minify, uglify()) }) - .pipe(plugins.rename, { suffix: '.min' }) + .pipe(rename, { suffix: '.min' }) // ensure admin/ and frontend/ are removed from the source paths // see https://www.npmjs.com/package/gulp-sourcemaps#alter-sources-property-on-sourcemaps - .pipe(plugins.sourcemaps.mapSources, (sourcePath) => '../' + sourcePath) - .pipe(plugins.sourcemaps.write, '.', { includeContent: false }) + .pipe(sourcemaps.mapSources, (sourcePath) => '../' + sourcePath) + .pipe(sourcemaps.write, '.', { includeContent: false }) return pipes } diff --git a/tasks/compile.js b/tasks/compile.js index 4903c98..d50a0c7 100644 --- a/tasks/compile.js +++ b/tasks/compile.js @@ -4,141 +4,170 @@ import path from 'node:path'; import dartSaas from 'sass'; import gulpSaas from 'gulp-sass'; import autoprefixer from 'autoprefixer'; -import cssnano from 'cssnano'; -import scripts from '../pipes/scripts.js'; +import gulp from 'gulp' +import gulpif from 'gulp-if' +import coffee from 'gulp-coffee' +import sourcemaps from 'gulp-sourcemaps' +import cssnano from 'cssnano' +import postcss from 'gulp-postcss' +import browserSync from 'browser-sync' +import { scriptPipes } from '../pipes/scripts.js'; +import sake from '../lib/sake.js' +import rename from 'gulp-rename' +import { lintPhp } from './lint.js' +import { minifyImages } from './imagemin.js' +import { makepot } from './makepot.js' +import { styles } from './styles.js' const sass = gulpSaas(dartSaas); -module.exports = (gulp, plugins, sake) => { - const pipes = scripts(plugins, sake) - - // compile plugin assets - gulp.task('compile', (done) => { - // default compile tasks - let tasks = ['lint:php', 'scripts', 'styles', 'imagemin'] - - // unless exclusively told not to, generate the POT file as well - if (!sake.options.skip_pot) { - tasks.push('makepot') - } - - gulp.parallel(tasks)(done) - }) - - /** Scripts */ - - // the main task to compile scripts - gulp.task('compile:scripts', gulp.parallel('compile:coffee', 'compile:js', 'compile:blocks')) - - // Note: ideally, we would only open a single stream of the script files, linting and compiling in the same - // stream/task, but unfortunately it looks like this is not possible, ast least not when reporting the - // lint errors - it results in no more files being passed down the stream, even if there were no lint errors. {IT 2018-03-14} - - // compile, transpile and minify coffee files - gulp.task('compile:coffee', () => { - if (! fs.existsSync(sake.config.paths.assetPaths.js)) { - return Promise.resolve() - } - - return gulp.src(`${sake.config.paths.assetPaths.js}/**/*.coffee`) - // plugins.if(() => sake.isWatching, plugins.newer({dest: sake.config.paths.assetPaths.js + '/**', ext: 'min.js'})), - .pipe(plugins.sourcemaps.init()) - // compile coffee files to JS - .pipe(plugins.coffee({ bare: false })) - // transpile & minify, write sourcemaps - .pipe(pipes.compileJs()) - .pipe(gulp.dest(sake.config.paths.assetPaths.js)) - .pipe(plugins.if(() => sake.isWatching && sake.config.tasks.watch.useBrowserSync, plugins.browserSync.stream.apply({ match: '**/*.js' }))) - }) - - // transpile and minify js files - gulp.task('compile:js', () => { - if (! fs.existsSync(sake.config.paths.assetPaths.js)) { - return Promise.resolve() - } - - return gulp.src(sake.config.paths.assetPaths.javascriptSources) - // plugins.if(() => sake.isWatching, plugins.newer({dest: sake.config.paths.assetPaths.js + '/**', ext: 'min.js'})), - .pipe(plugins.sourcemaps.init()) - // transpile & minify, write sourcemaps - .pipe(pipes.compileJs()) - .pipe(gulp.dest(sake.config.paths.assetPaths.js)) - .pipe(plugins.if(() => sake.isWatching && sake.config.tasks.watch.useBrowserSync, plugins.browserSync.stream.apply({ match: '**/*.js' }))) - }) - - // this task is specific for plugins that add one or more self-contained Gutenberg blocks in their assets to be transpiled from ES6 - gulp.task('compile:blocks', () => { - const i18nPath = `${process.cwd()}/i18n/languages/blocks/` - const blockPath = `${sake.config.paths.assetPaths.js}/blocks/src/` - const blockSrc = fs.existsSync(blockPath) ? fs.readdirSync(blockPath).filter(function (file) { - return file.match(/.*\.js$/) - }) : false - - if (!blockSrc || blockSrc[0].length <= 0) { - return Promise.resolve() - } else { - return gulp.src(sake.config.paths.assetPaths.blockSources) - .pipe(plugins.sourcemaps.init()) - .pipe(webpack({ - mode: 'production', - entry: `${blockPath}/${blockSrc[0]}`, - output: { - filename: path.basename(blockSrc[0], '.js') + '.min.js' - }, - externals: { - 'react': 'React', - 'react-dom': 'ReactDOM' - }, - module: { - rules: [{ - test: /\.js$/, - exclude: /node_modules/, - use: { - loader: 'babel-loader', - options: { - presets: ['@babel/preset-env', '@babel/preset-react'], - plugins: [ - ['@wordpress/babel-plugin-makepot', { 'output': `${i18nPath}${blockSrc[0].replace('.js', '.pot')}` }] - ] - } +/************************** Scripts */ + +/** + * Compile, transpile, and minify coffee scripts + */ +const compileCoffee = (done) => { + if (! fs.existsSync(sake.config.paths.assetPaths.js)) { + return Promise.resolve() + } + + return gulp.src(`${sake.config.paths.assetPaths.js}/**/*.coffee`) + .pipe(sourcemaps.init()) + // compile coffee files to JS + .pipe(coffee({ bare: false })) + // transpile & minify, write sourcemaps + .pipe(scriptPipes().compileJs()) + .pipe(gulp.dest(sake.config.paths.assetPaths.js)) + .pipe(gulpif(() => sake.isWatching && sake.config.tasks.watch.useBrowserSync, browserSync.stream.apply({ match: '**/*.js' }))) +} +compileCoffee.displayName = 'compile:coffee' + +/** + * Transpile and minify JS files + */ +const compileJs = (done) => { + if (! fs.existsSync(sake.config.paths.assetPaths.js)) { + return Promise.resolve() + } + + return gulp.src(sake.config.paths.assetPaths.javascriptSources) + // plugins.if(() => sake.isWatching, plugins.newer({dest: sake.config.paths.assetPaths.js + '/**', ext: 'min.js'})), + .pipe(sourcemaps.init()) + // transpile & minify, write sourcemaps + .pipe(scriptPipes().compileJs()) + .pipe(gulp.dest(sake.config.paths.assetPaths.js)) + .pipe(gulpif(() => sake.isWatching && sake.config.tasks.watch.useBrowserSync, browserSync.stream.apply({ match: '**/*.js' }))) +} +compileJs.displayName = 'compile:js' + +/** + * This task is specific for plugins that add one or more self-contained Gutenberg blocks in their assets to be transpiled from ES6 + */ +const compileBlocks = (done) => { + const i18nPath = `${process.cwd()}/i18n/languages/blocks/` + const blockPath = `${sake.config.paths.assetPaths.js}/blocks/src/` + const blockSrc = fs.existsSync(blockPath) ? fs.readdirSync(blockPath).filter(function (file) { + return file.match(/.*\.js$/) + }) : false + + if (!blockSrc || blockSrc[0].length <= 0) { + return Promise.resolve() + } else { + return gulp.src(sake.config.paths.assetPaths.blockSources) + .pipe(sourcemaps.init()) + .pipe(webpack({ + mode: 'production', + entry: `${blockPath}/${blockSrc[0]}`, + output: { + filename: path.basename(blockSrc[0], '.js') + '.min.js' + }, + externals: { + 'react': 'React', + 'react-dom': 'ReactDOM' + }, + module: { + rules: [{ + test: /\.js$/, + exclude: /node_modules/, + use: { + loader: 'babel-loader', + options: { + presets: ['@babel/preset-env', '@babel/preset-react'], + plugins: [ + ['@wordpress/babel-plugin-makepot', { 'output': `${i18nPath}${blockSrc[0].replace('.js', '.pot')}` }] + ] } - }] - } - })) - .pipe(gulp.dest(`${sake.config.paths.assetPaths.js}/blocks/`)) - .pipe(plugins.if(() => sake.isWatching && sake.config.tasks.watch.useBrowserSync, plugins.browserSync.stream.apply({ match: '**/*.js' }))) - } - }) - - /** Styles */ - - // main task for compiling styles - gulp.task('compile:styles', gulp.parallel('compile:scss')) - - // compile SCSS to CSS - gulp.task('compile:scss', () => { - if (! fs.existsSync(sake.config.paths.assetPaths.css)) { - return Promise.resolve() - } - - let cssPlugins = [autoprefixer()] - - if (sake.options.minify) { - cssPlugins.push(cssnano({ zindex: false })) - } - - return gulp.src([ - `${sake.config.paths.assetPaths.css}/**/*.scss`, - `!${sake.config.paths.assetPaths.css}/**/mixins.scss` // don't compile any mixins by themselves - ]) - .pipe(plugins.sourcemaps.init()) - .pipe(sass({ outputStyle: 'expanded' })) - .pipe(plugins.postcss(cssPlugins)) - .pipe(plugins.rename({ suffix: '.min' })) - // ensure admin/ and frontend/ are removed from the source paths - // see https://www.npmjs.com/package/gulp-sourcemaps#alter-sources-property-on-sourcemaps - .pipe(plugins.sourcemaps.mapSources((sourcePath) => '../' + sourcePath)) - .pipe(plugins.sourcemaps.write('.', { includeContent: false })) - .pipe(gulp.dest(`${sake.config.paths.src}/${sake.config.paths.css}`)) - .pipe(plugins.if(() => sake.isWatching && sake.config.tasks.watch.useBrowserSync, plugins.browserSync.stream({match: '**/*.css'}))) - }) + } + }] + } + })) + .pipe(gulp.dest(`${sake.config.paths.assetPaths.js}/blocks/`)) + .pipe(gulpif(() => sake.isWatching && sake.config.tasks.watch.useBrowserSync, browserSync.stream.apply({ match: '**/*.js' }))) + } +} +compileBlocks.displayName = 'compile:blocks' + +/************************** Styles */ + +/** + * Compile SCSS to CSS + */ +const compileScss = (done) => { + if (! fs.existsSync(sake.config.paths.assetPaths.css)) { + return Promise.resolve() + } + + let cssPlugins = [autoprefixer()] + + if (sake.options.minify) { + cssPlugins.push(cssnano({ zindex: false })) + } + + return gulp.src([ + `${sake.config.paths.assetPaths.css}/**/*.scss`, + `!${sake.config.paths.assetPaths.css}/**/mixins.scss` // don't compile any mixins by themselves + ]) + .pipe(sourcemaps.init()) + .pipe(sass({ outputStyle: 'expanded' })) + .pipe(postcss(cssPlugins)) + .pipe(rename({ suffix: '.min' })) + // ensure admin/ and frontend/ are removed from the source paths + // see https://www.npmjs.com/package/gulp-sourcemaps#alter-sources-property-on-sourcemaps + .pipe(sourcemaps.mapSources((sourcePath) => '../' + sourcePath)) + .pipe(sourcemaps.write('.', { includeContent: false })) + .pipe(gulp.dest(`${sake.config.paths.src}/${sake.config.paths.css}`)) + .pipe(gulpif(() => sake.isWatching && sake.config.tasks.watch.useBrowserSync, browserSync.stream({match: '**/*.css'}))) +} +compileScss.displayName = 'compile:scss' + +/************************** Parallels */ + +// The main task to compile scripts +const compileScripts = gulp.parallel(compileCoffee, compileJs, compileBlocks) +compileScripts.displayName = 'compile:scripts' + +// The main task to compile styles +const compileStyles = gulp.parallel(compileScss) +compileStyles.displayName = 'compile:styles' + +// Compile all plugin assets +const compile = (done) => { + // default compile tasks + let tasks = [lintPhp, 'scripts', styles, minifyImages] // @TODO replace `scripts` + + // unless exclusively told not to, generate the POT file as well + if (!sake.options.skip_pot) { + tasks.push(makepot) + } + + gulp.parallel(tasks)(done) +} + +export { + compileCoffee, + compileJs, + compileBlocks, + compileScss, + compileScripts, + compileStyles, + compile } From f1ff8e8851007395e2b0768f5f5bbb02fc1a6dfb Mon Sep 17 00:00:00 2001 From: Ashley Gibson Date: Fri, 14 Mar 2025 12:47:25 +0000 Subject: [PATCH 21/45] Rework scripts --- gulpfile.js | 1 + tasks/compile.js | 2 +- tasks/scripts.js | 52 ++++++++++++++++++++++++++++++++---------------- tasks/styles.js | 3 ++- 4 files changed, 39 insertions(+), 19 deletions(-) diff --git a/gulpfile.js b/gulpfile.js index ea1939d..8c6506d 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -71,6 +71,7 @@ export * from './tasks/imagemin.js' export * from './tasks/decaffeinate.js' export * from './tasks/lint.js' export * from './tasks/makepot.js' +export * from './tasks/scripts.js' export * from './tasks/shell.js' export * from './tasks/styles.js' export * from './tasks/validate.js' diff --git a/tasks/compile.js b/tasks/compile.js index d50a0c7..e8de547 100644 --- a/tasks/compile.js +++ b/tasks/compile.js @@ -152,7 +152,7 @@ compileStyles.displayName = 'compile:styles' // Compile all plugin assets const compile = (done) => { // default compile tasks - let tasks = [lintPhp, 'scripts', styles, minifyImages] // @TODO replace `scripts` + let tasks = [lintPhp, 'scripts', styles, minifyImages] // NOTE: do not import the `scripts` constant here, otherwise it creates a circular dependency // unless exclusively told not to, generate the POT file as well if (!sake.options.skip_pot) { diff --git a/tasks/scripts.js b/tasks/scripts.js index 216baf3..d6f0f23 100644 --- a/tasks/scripts.js +++ b/tasks/scripts.js @@ -1,18 +1,36 @@ -module.exports = (gulp, plugins, sake) => { - // main task for (optionally) linting and compiling scripts - gulp.task('scripts', (done) => { - let tasks = ['lint:scripts', 'compile:scripts'] - - // don't lint styles if they have already been linted, unless we're watching - if (!sake.isWatching && gulp.lastRun('lint:scripts')) { - tasks.shift() - } - - gulp.series(tasks)(done) - }) - - // type-specific script tasks - lints and then compiles - gulp.task('scripts:coffee', gulp.series('lint:coffee', 'compile:coffee')) - gulp.task('scripts:js', gulp.series('lint:js', 'compile:js')) - gulp.task('scripts:blocks', gulp.series('compile:blocks')) +import gulp from 'gulp' +import { lintCoffee, lintJs, lintScripts } from './lint.js' +import { compileBlocks, compileCoffee, compileJs, compileScripts } from './compile.js' +import sake from '../lib/sake.js' + +/** + * The main task + */ +const scripts = (done) => { + let tasks = [lintScripts, compileScripts] + + // don't lint styles if they have already been linted, unless we're watching + if (! sake.isWatching && gulp.lastRun(lintScripts)) { + tasks.shift() + } + + gulp.series(tasks)(done) +} + +/** type-specific script tasks - lints and then compiles */ + +const scriptsCoffee = gulp.series(lintCoffee, compileCoffee) +scriptsCoffee.displayName = 'scripts:coffee' + +const scriptsJs = gulp.series(lintJs, compileJs) +scriptsJs.displayName = 'scripts:js' + +const scriptsBlocks = gulp.series(compileBlocks) +scriptsBlocks.displayName = 'compile:blocks' + +export { + scripts, + scriptsCoffee, + scriptsJs, + scriptsBlocks } diff --git a/tasks/styles.js b/tasks/styles.js index 517d560..79751cf 100644 --- a/tasks/styles.js +++ b/tasks/styles.js @@ -1,9 +1,10 @@ import gulp from 'gulp' import sake from '../lib/sake.js' import { lintStyles } from './lint.js' +import { compileStyles } from './compile.js' const styles = (done) => { - let tasks = [lintStyles, 'compile:styles'] // @TODO + let tasks = [lintStyles, compileStyles] // don't lint styles if they have already been linted, unless we're watching if (!sake.isWatching && gulp.lastRun(lintStyles)) { From 0f201692d094f9b5cdf143980773a802e1e085b9 Mon Sep 17 00:00:00 2001 From: Ashley Gibson Date: Fri, 14 Mar 2025 12:58:30 +0000 Subject: [PATCH 22/45] Rework github tasks --- gulpfile.js | 1 + tasks/github.js | 532 +++++++++++++++++++++++++----------------------- 2 files changed, 278 insertions(+), 255 deletions(-) diff --git a/gulpfile.js b/gulpfile.js index 8c6506d..0aa095f 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -69,6 +69,7 @@ export * from './tasks/compile.js' export * from './tasks/config.js' export * from './tasks/imagemin.js' export * from './tasks/decaffeinate.js' +export * from './tasks/github.js' export * from './tasks/lint.js' export * from './tasks/makepot.js' export * from './tasks/scripts.js' diff --git a/tasks/github.js b/tasks/github.js index d05fa3a..510f828 100644 --- a/tasks/github.js +++ b/tasks/github.js @@ -1,320 +1,342 @@ -import { Octokit as GitHub } from '@octokit/rest'; -import inquirer from 'inquirer'; -import fs from 'node:fs'; -import path from 'node:path'; -import async from 'async'; -import chalk from 'chalk'; -import codename from 'codename'; // @TODO check this? old was: const codename = require('codename')() -import dateFormat from 'dateformat'; -import log from 'fancy-log'; - -module.exports = (gulp, plugins, sake) => { - let githubInstances = {} - - let getGithub = (target = 'dev') => { - if (!githubInstances[target]) { - githubInstances[target] = new GitHub({ - debug: false, - auth: process.env[`SAKE_${target.toUpperCase()}_GITHUB_API_KEY`] || process.env.GITHUB_API_KEY - }) - } +import { Octokit as GitHub } from '@octokit/rest' +import inquirer from 'inquirer' +import fs from 'node:fs' +import path from 'node:path' +import async from 'async' +import chalk from 'chalk' +import codename from 'codename' // @TODO check this? old was: const codename = require('codename')() +import dateFormat from 'dateformat' +import log from 'fancy-log' +import sake from '../lib/sake.js' +import gulp from 'gulp' + +let githubInstances = {} + +let getGithub = (target = 'dev') => { + if (! githubInstances[target]) { + githubInstances[target] = new GitHub({ + debug: false, + auth: process.env[`SAKE_${target.toUpperCase()}_GITHUB_API_KEY`] || process.env.GITHUB_API_KEY + }) + } + + return githubInstances[target] +} + +const gitHubGetReleaseIssue = (done) => { + let owner = sake.config.deploy.dev.owner + let repo = sake.config.deploy.dev.name + let github = getGithub('dev') - return githubInstances[target] + let labels = ['release'] + + if (sake.config.multiPluginRepo) { + labels.push(sake.config.plugin.id.replace('woocommerce-', '')) } - gulp.task('github:get_rissue', (done) => { - let owner = sake.config.deploy.dev.owner - let repo = sake.config.deploy.dev.name - let github = getGithub('dev') + github.issues.listForRepo({ + owner: owner, + repo: repo, + state: 'open', + labels: labels.join(',') + }).then((result) => { + if (! result.data.length) { + log.info('No labels found') + done() + } else { + inquirer.prompt([{ + type: 'list', + name: 'issues_to_close', + message: 'Release issues exist for ' + sake.getPluginName() + '. Select an issue this release should close.', + choices: function () { + let choices = result.data.filter((result) => !result.pull_request).map((result) => { + return { + value: result.number, + name: 'Close issue #' + result.number + ': ' + result.html_url + } + }) - let labels = ['release'] + choices.push({ + value: 'none', + name: 'None'.red + }) - if (sake.config.multiPluginRepo) { - labels.push(sake.config.plugin.id.replace('woocommerce-', '')) + return choices + } + }]).then(function (answers) { + if (answers.issues_to_close === 'none') { + log.warn(chalk.yellow('No issues will be closed for release of ' + sake.getPluginName())) + } else { + sake.options.release_issue_to_close = answers.issues_to_close + } + done() + }) } + }).catch((err) => { + log.error(chalk.red('Could not get release issue: ' + err.toString())) + done() + }) +} +gitHubGetReleaseIssue.displayName = 'github:get_rissue' - github.issues.listForRepo({ - owner: owner, - repo: repo, - state: 'open', - labels: labels.join(',') - }).then((result) => { - if (!result.data.length) { +const gitHubGetWcIssues = (done) => { + if (!sake.config.deploy.production) { + log.warn(chalk.yellow('No WC (production) repo configured for ' + sake.getPluginName() + ', skipping')) + return done() + } + + let owner = sake.config.deploy.production.owner + let repo = sake.config.deploy.production.name + let github = getGithub('production') + + github.issues.listForRepo({ + owner: owner, + repo: repo, + state: 'open' + }) + .then((result) => { + if (! result.data.length) { done() } else { inquirer.prompt([{ - type: 'list', + type: 'checkbox', name: 'issues_to_close', - message: 'Release issues exist for ' + sake.getPluginName() + '. Select an issue this release should close.', + message: 'Issues on WC repo exist for ' + sake.getPluginName() + '. Select an issue this release should close. To skip, press Enter without selecting anything.', choices: function () { - let choices = result.data.filter((result) => !result.pull_request).map((result) => { + return result.data.filter((result) => !result.pull_request).sort().map((result) => { return { value: result.number, name: 'Close issue #' + result.number + ': ' + result.html_url } }) - - choices.push({ - value: 'none', - name: 'None'.red - }) - - return choices } }]).then(function (answers) { if (answers.issues_to_close === 'none') { - log.warn(chalk.yellow('No issues will be closed for release of ' + sake.getPluginName())) + log.warn('No issues will be closed for release of ' + sake.getPluginName()) } else { - sake.options.release_issue_to_close = answers.issues_to_close + sake.options.wc_issues_to_close = answers.issues_to_close } done() }) } - }).catch((err) => { - log.error(chalk.red('Could not get release issue: ' + err.toString())) - done() }) - }) - - gulp.task('github:get_wc_issues', (done) => { - if (!sake.config.deploy.production) { - log.warn(chalk.yellow('No WC (production) repo configured for ' + sake.getPluginName() + ', skipping')) - return done() - } - - let owner = sake.config.deploy.production.owner - let repo = sake.config.deploy.production.name - let github = getGithub('production') - - github.issues.listForRepo({ - owner: owner, - repo: repo, - state: 'open' + .catch((err) => { + log.error(chalk.red('Could not get issues for WC repo: ' + err.toString())) + done() }) - .then((result) => { - if (!result.data.length) { - done() - } else { - inquirer.prompt([{ - type: 'checkbox', - name: 'issues_to_close', - message: 'Issues on WC repo exist for ' + sake.getPluginName() + '. Select an issue this release should close. To skip, press Enter without selecting anything.', - choices: function () { - let choices = result.data.filter((result) => !result.pull_request).sort().map((result) => { - return { - value: result.number, - name: 'Close issue #' + result.number + ': ' + result.html_url - } - }) - - return choices - } - }]).then(function (answers) { - if (answers.issues_to_close === 'none') { - log.warn('No issues will be closed for release of ' + sake.getPluginName()) - } else { - sake.options.wc_issues_to_close = answers.issues_to_close - } - done() - }) - } - }) - .catch((err) => { - log.error(chalk.red('Could not get issues for WC repo: ' + err.toString())) - done() - }) - }) - - // creates a docs issue for the plugin - gulp.task('github:docs_issue', (done) => { - if (!sake.config.deploy.docs) { - log.warn(chalk.yellow('No docs repo configured for ' + sake.getPluginName() + ', skipping')) - return done() - } +} +gitHubGetWcIssues.displayName = 'github:get_wc_issues' + +/** + * Creates a docs issue for the plugin + */ +const gitHubCreateDocsIssue = (done) => { + if (! sake.config.deploy.docs) { + log.warn(chalk.yellow('No docs repo configured for ' + sake.getPluginName() + ', skipping')) + return done() + } - let owner = sake.config.deploy.docs.owner - let repo = sake.config.deploy.docs.name - let github = getGithub('docs') + let owner = sake.config.deploy.docs.owner + let repo = sake.config.deploy.docs.name + let github = getGithub('docs') - let message = 'Should a Docs issue be created for ' + sake.getPluginName() + '?' + let message = 'Should a Docs issue be created for ' + sake.getPluginName() + '?' - if (sake.pluginHasNewFeatures()) { - message += chalk.yellow('\n\nThe changelog below contains new features and/or tweaks.\nA docs issue should always be created for releases with new features or user-facing changes.') - } + if (sake.pluginHasNewFeatures()) { + message += chalk.yellow('\n\nThe changelog below contains new features and/or tweaks.\nA docs issue should always be created for releases with new features or user-facing changes.') + } - inquirer.prompt([{ - type: 'list', - name: 'create_docs_issue', - message: message + '\n\nChangelog: \n\n' + sake.getPluginChanges() + '\n\n', - choices: [{ - value: 1, - name: 'Yes -- create a docs issue' - }, { - value: 0, - name: "No -- don't create a docs issue!" - }], - default: sake.pluginHasNewFeatures() ? 0 : 1 - }]).then(function (answers) { - if (answers.create_docs_issue) { - github.issues.create({ - owner: owner, - repo: repo, - title: sake.getPluginName() + ': Updated to ' + sake.getPluginVersion(), - body: sake.getPluginChanges() + (sake.options.release_issue_to_close ? '\r\n\r\nSee ' + sake.config.deploy.dev.owner + '/' + sake.config.deploy.dev.name + '#' + sake.options.release_issue_to_close : ''), - labels: [sake.config.plugin.id.replace('woocommerce-', ''), 'docs', 'sales'] - }).then((result) => { - log(result) - log('Docs issue created!') + inquirer.prompt([{ + type: 'list', + name: 'create_docs_issue', + message: message + '\n\nChangelog: \n\n' + sake.getPluginChanges() + '\n\n', + choices: [{ + value: 1, + name: 'Yes -- create a docs issue' + }, { + value: 0, + name: "No -- don't create a docs issue!" + }], + default: sake.pluginHasNewFeatures() ? 0 : 1 + }]).then(function (answers) { + if (answers.create_docs_issue) { + github.issues.create({ + owner: owner, + repo: repo, + title: sake.getPluginName() + ': Updated to ' + sake.getPluginVersion(), + body: sake.getPluginChanges() + (sake.options.release_issue_to_close ? '\r\n\r\nSee ' + sake.config.deploy.dev.owner + '/' + sake.config.deploy.dev.name + '#' + sake.options.release_issue_to_close : ''), + labels: [sake.config.plugin.id.replace('woocommerce-', ''), 'docs', 'sales'] + }).then((result) => { + log(result) + log('Docs issue created!') - done() - }).catch(sake.throwError) - } else { - log.warn('No docs issue was created for ' + sake.getPluginName()) done() - } - }) - }) - - // creates a release for the plugin, attaching the build zip to it - gulp.task('github:create_release', (done) => { - let owner = sake.options.owner - let repo = sake.options.repo || sake.config.plugin.id - - if (!owner || !repo) { - log.warn(chalk.yellow('The owner or the slug of the repo for ' + sake.getPluginName() + ' are missing, skipping')) - return done() + }).catch(sake.throwError) + } else { + log.warn('No docs issue was created for ' + sake.getPluginName()) + done() } + }) +} +gitHubCreateDocsIssue.displayName = 'github:docs_issue' + +/** + * Creates a release for the plugin, attaching the build zip to it + */ +const gitHubCreateRelease = (done) => { + let owner = sake.options.owner + let repo = sake.options.repo || sake.config.plugin.id + + if (! owner || ! repo) { + log.warn(chalk.yellow('The owner or the slug of the repo for ' + sake.getPluginName() + ' are missing, skipping')) + return done() + } - let github = getGithub(sake.options.owner === sake.config.deploy.production.owner ? 'production' : 'dev') + let github = getGithub(sake.options.owner === sake.config.deploy.production.owner ? 'production' : 'dev') - let version = sake.getPluginVersion() - let zipName = `${sake.config.plugin.id}.${version}.zip` - let zipPath = path.join(process.cwd(), sake.config.paths.build, zipName) - let tasks = [] + let version = sake.getPluginVersion() + let zipName = `${sake.config.plugin.id}.${version}.zip` + let zipPath = path.join(process.cwd(), sake.config.paths.build, zipName) + let tasks = [] - // prepare a zip if it doesn't already exist - if (!fs.existsSync(zipPath)) { - tasks.push(sake.options.deploy ? 'compress' : 'zip') - } + // prepare a zip if it doesn't already exist + if (! fs.existsSync(zipPath)) { + tasks.push(sake.options.deploy ? 'compress' : 'zip') + } - log(`Creating GH release ${version} for ${owner}/${repo}`) + log(`Creating GH release ${version} for ${owner}/${repo}`) - tasks.push(function (cb) { - github.repos.createRelease({ - owner: owner, - repo: repo, - tag_name: sake.options.prefix_release_tag ? sake.config.plugin.id + '-' + version : version, - name: sake.getPluginName(false) + ' v' + version, - body: sake.getPluginChanges() - }).then((result) => { - log('GH release created') + tasks.push(function (cb) { + github.repos.createRelease({ + owner: owner, + repo: repo, + tag_name: sake.options.prefix_release_tag ? sake.config.plugin.id + '-' + version : version, + name: sake.getPluginName(false) + ' v' + version, + body: sake.getPluginChanges() + }).then((result) => { + log('GH release created') - sake.options.release_url = result.data.html_url + sake.options.release_url = result.data.html_url - github.repos.uploadReleaseAsset({ - url: result.data.upload_url, - name: zipName, - data: fs.readFileSync(zipPath), - headers: { - 'content-type': 'application/zip', - 'content-length': fs.statSync(zipPath).size - } - }).then(() => { - log('Plugin zip uploaded') - cb() - }).catch((err) => { - sake.throwError('Uploading release ZIP failed: ' + err.toString()) - }) + github.repos.uploadReleaseAsset({ + url: result.data.upload_url, + name: zipName, + data: fs.readFileSync(zipPath), + headers: { + 'content-type': 'application/zip', + 'content-length': fs.statSync(zipPath).size + } + }).then(() => { + log('Plugin zip uploaded') + cb() }).catch((err) => { - sake.throwError('Creating GH release failed: ' + err.toString()) + sake.throwError('Uploading release ZIP failed: ' + err.toString()) }) + }).catch((err) => { + sake.throwError('Creating GH release failed: ' + err.toString()) }) - - gulp.series(tasks)(done) }) - // create release milestones for each tuesday - gulp.task('github:create_release_milestones', (done) => { - let year = sake.options.year || new Date().getFullYear() - let tuesdays = getTuesdays(year) + gulp.series(tasks)(done) +} +gitHubCreateRelease.displayName = 'github:create_release' - createMilestones(tuesdays, done) +/** + * Create release milestones for each Tuesday + */ +const gitHubCreateReleaseMilestones = (done) => { + let year = sake.options.year || new Date().getFullYear() + let tuesdays = getTuesdays(year) - // helper function to get all tuesdays of a year - function getTuesdays (y) { - // ensure year is an integer - y = parseInt(y, 10) + createMilestones(tuesdays, done) - let d = new Date(y, 0, 1) - let tuesdays = [] + // helper function to get all tuesdays of a year + function getTuesdays (y) { + // ensure year is an integer + y = parseInt(y, 10) - // get the first Tuesday in January - d.setDate(d.getDate() + (9 - d.getDay()) % 7) + let d = new Date(y, 0, 1) + let tuesdays = [] - while (y === d.getFullYear()) { - let date = new Date(d.getTime()) - tuesdays.push({ date: date, name: `Deploy on ${dateFormat(date, 'mm/dd')}` }) - d.setDate(d.getDate() + 7) - } + // get the first Tuesday in January + d.setDate(d.getDate() + (9 - d.getDay()) % 7) - return tuesdays + while (y === d.getFullYear()) { + let date = new Date(d.getTime()) + tuesdays.push({ date: date, name: `Deploy on ${dateFormat(date, 'mm/dd')}` }) + d.setDate(d.getDate() + 7) } - }) - // create monthly milestones - gulp.task('github:create_month_milestones', (done) => { - let year = sake.options.year || new Date().getFullYear() + return tuesdays + } +} +gitHubCreateReleaseMilestones.displayName = 'github:create_release_milestones' - createMilestones(getMonthlyMilestones(year), done) +/** + * Create monthly milestones + */ +const gitHubCreateMonthMilestones = (done) => { + let year = sake.options.year || new Date().getFullYear() - // helper to get all months in a year - function getMonthlyMilestones (y) { - // ensure year is an integer - y = parseInt(y, 10) + createMilestones(getMonthlyMilestones(year), done) - let months = [] + // helper to get all months in a year + function getMonthlyMilestones (y) { + // ensure year is an integer + y = parseInt(y, 10) - for (let i = 0; i < 12; i++) { - let d = new Date(y, i + 1, 0) - months.push({ date: d, name: dateFormat(d, 'mmmm yyyy') }) - } + let months = [] - return months + for (let i = 0; i < 12; i++) { + let d = new Date(y, i + 1, 0) + months.push({ date: d, name: dateFormat(d, 'mmmm yyyy') }) } - }) - // create a milestone for each date passed in - const createMilestones = (milestones, done) => { - let owner = sake.options.owner || sake.config.deploy.dev.owner - let repo = sake.options.repo || sake.config.deploy.dev.name - let github = getGithub(sake.options.owner === sake.config.deploy.production.owner ? 'production' : 'dev') + return months + } +} +gitHubCreateMonthMilestones.displayName = 'github:create_month_milestones' - async.eachLimit(milestones, 5, function (milestone, cb) { - let description = codename.generate(['unique', 'alliterative', 'random'], ['adjectives', 'animals']).join(' ') - let formattedDate = dateFormat(milestone.date, 'yyyy-mm-dd') +// create a milestone for each date passed in +const createMilestones = (milestones, done) => { + let owner = sake.options.owner || sake.config.deploy.dev.owner + let repo = sake.options.repo || sake.config.deploy.dev.name + let github = getGithub(sake.options.owner === sake.config.deploy.production.owner ? 'production' : 'dev') - github.issues.createMilestone({ - owner: owner, - repo: repo, - title: milestone.name, - description: description, - due_on: milestone.date - }).then((result) => { - log.info(chalk.green(`Milestone ${description} for ${formattedDate} created!`)) - cb() - }).catch((err) => { - // format the error for readability - let formattedError = err - try { - if (err.message) { - err = JSON.parse(err.message) - } - formattedError = JSON.stringify(err, null, 2) - } catch (e) { } - log.error(chalk.red(`Error creating milestone ${description} for ${formattedDate}:`) + '\n' + formattedError) - }) - }, function (error) { - done(error) + async.eachLimit(milestones, 5, function (milestone, cb) { + let description = codename.generate(['unique', 'alliterative', 'random'], ['adjectives', 'animals']).join(' ') + let formattedDate = dateFormat(milestone.date, 'yyyy-mm-dd') + + github.issues.createMilestone({ + owner: owner, + repo: repo, + title: milestone.name, + description: description, + due_on: milestone.date + }).then((result) => { + log.info(chalk.green(`Milestone ${description} for ${formattedDate} created!`)) + cb() + }).catch((err) => { + // format the error for readability + let formattedError = err + try { + if (err.message) { + err = JSON.parse(err.message) + } + formattedError = JSON.stringify(err, null, 2) + } catch (e) { } + log.error(chalk.red(`Error creating milestone ${description} for ${formattedDate}:`) + '\n' + formattedError) }) - } + }, function (error) { + done(error) + }) +} + +export { + gitHubGetReleaseIssue, + gitHubGetWcIssues, + gitHubCreateDocsIssue, + gitHubCreateRelease, + gitHubCreateReleaseMilestones, + gitHubCreateMonthMilestones } From d235325db3c618802d5c646e01c0932bb293f847 Mon Sep 17 00:00:00 2001 From: Ashley Gibson Date: Fri, 14 Mar 2025 13:01:14 +0000 Subject: [PATCH 23/45] Rework zip --- gulpfile.js | 1 + tasks/zip.js | 34 +++++++++++++++++++++------------- 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/gulpfile.js b/gulpfile.js index 0aa095f..5317761 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -78,3 +78,4 @@ export * from './tasks/styles.js' export * from './tasks/validate.js' export * from './tasks/watch.js' export * from './tasks/wc.js' +export * from './tasks/zip.js' diff --git a/tasks/zip.js b/tasks/zip.js index 9962b0f..eaee109 100644 --- a/tasks/zip.js +++ b/tasks/zip.js @@ -1,17 +1,25 @@ -module.exports = (gulp, plugins, sake) => { - gulp.task('compress', () => { - let zipDest = sake.options.zipDest || sake.config.paths.build - let zipFileName = sake.config.plugin.id + '.' + sake.getPluginVersion() + '.zip' +import sake from '../lib/sake.js' +import gulp from 'gulp' +import zip from 'gulp-zip' - sake.config.paths.zipDest = sake.resolvePath(zipDest) +const compress = (done) => { + let zipDest = sake.options.zipDest || sake.config.paths.build + let zipFileName = sake.config.plugin.id + '.' + sake.getPluginVersion() + '.zip' - return gulp.src([ - `${sake.config.paths.build}/${sake.config.plugin.id}/**`, - `!${sake.config.paths.build}/${sake.config.plugin.id}/**/*.zip` - ], { nodir: true, base: sake.config.paths.build }) // exclude empty directories, include plugin dir in zip - .pipe(plugins.zip(zipFileName)) - .pipe(gulp.dest(sake.config.paths.zipDest)) - }) + sake.config.paths.zipDest = sake.resolvePath(zipDest) - gulp.task('zip', gulp.series('build', 'compress')) + return gulp.src([ + `${sake.config.paths.build}/${sake.config.plugin.id}/**`, + `!${sake.config.paths.build}/${sake.config.plugin.id}/**/*.zip` + ], { nodir: true, base: sake.config.paths.build }) // exclude empty directories, include plugin dir in zip + .pipe(zip(zipFileName)) + .pipe(gulp.dest(sake.config.paths.zipDest)) +} + +const buildAndZip = gulp.series('build', compress) // @TODO replace "build" +buildAndZip.displayName = 'zip' + +export { + compress, + buildAndZip } From 75f1ebb1d44105a28517008596321a740dc83a88 Mon Sep 17 00:00:00 2001 From: Ashley Gibson Date: Fri, 14 Mar 2025 13:15:51 +0000 Subject: [PATCH 24/45] Rework prompt --- gulpfile.js | 3 + tasks/build.js | 30 ++-- tasks/copy.js | 396 ++++++++++++++++++++++++++---------------------- tasks/prompt.js | 226 ++++++++++++++------------- 4 files changed, 358 insertions(+), 297 deletions(-) diff --git a/gulpfile.js b/gulpfile.js index 5317761..7663c58 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -63,15 +63,18 @@ gulp.on('error', (event) => { /************** Task Exports */ +export * from './tasks/build.js' export * from './tasks/bump.js' export * from './tasks/clean.js' export * from './tasks/compile.js' export * from './tasks/config.js' +export * from './tasks/copy.js' export * from './tasks/imagemin.js' export * from './tasks/decaffeinate.js' export * from './tasks/github.js' export * from './tasks/lint.js' export * from './tasks/makepot.js' +export * from './tasks/prompt.js' export * from './tasks/scripts.js' export * from './tasks/shell.js' export * from './tasks/styles.js' diff --git a/tasks/build.js b/tasks/build.js index d566240..62570b0 100644 --- a/tasks/build.js +++ b/tasks/build.js @@ -1,16 +1,28 @@ import _ from 'lodash'; +import gulp from 'gulp' +import sake from '../lib/sake.js' +import { cleanBuild, cleanComposer } from './clean.js' +import { shellComposerInstall, shellComposerStatus } from './shell.js' +import { compile } from './compile.js' +import { copyBuild } from './copy.js' -module.exports = (gulp, plugins, sake) => { - // main task for building the plugin: - // - cleans the build directory - // - compiles the plugin assets (linting where necessary) - // - bundles any external dependencies to the plugin assets - // - copies plugin files to the build directory - let tasks = ['clean:build', 'shell:composer_status', 'clean:composer', 'shell:composer_install', 'compile', 'bundle', 'copy:build'] +/** + * The main task for building the plugin: + * - Cleans the build directory + * - Compiles the plugin assets (linting where necessary) + * - Bundles any external dependencies to the plugin assets + * - Copies plugin files to the build directory + */ +const build = (done) => { + let tasks = [cleanBuild, shellComposerStatus, cleanComposer, shellComposerInstall, compile, 'bundle', copyBuild] // @TODO replace remaining if (sake.options['skip-composer']) { - tasks = _.without(tasks, 'shell:composer_status', 'clean:composer', 'shell:composer_install') + tasks = _.without(tasks, shellComposerStatus, cleanComposer, shellComposerInstall) } - gulp.task('build', gulp.series(tasks)) + return gulp.series(tasks) +} + +export { + build } diff --git a/tasks/copy.js b/tasks/copy.js index f260890..5c668d4 100644 --- a/tasks/copy.js +++ b/tasks/copy.js @@ -1,196 +1,226 @@ import path from 'node:path'; +import sake from '../lib/sake.js' +import gulp from 'gulp' +import replace from 'gulp-replace' +import rename from 'gulp-rename' +import gulpFilter from 'gulp-filter' + +/** + * Copy files from source to build + */ +const copyBuild = (done) => { + const filter = gulpFilter(['**/*.min.css', '**/*.min.js'], { restore: true }) + + let paths = [ + `${sake.config.paths.src}/**/*`, + + // skip the directory we're building everything into! + `!${sake.config.paths.build}{,/**}`, + + // skip .map files + `!${sake.config.paths.src}/${sake.config.paths.js}/**/*.map`, + `!${sake.config.paths.src}/${sake.config.paths.css}/**/*.map`, + + // skip coffee and unminified js files + `!${sake.config.paths.src}/${sake.config.paths.js}/**/*.coffee`, + `!${sake.config.paths.src}/${sake.config.paths.js}/**/*(!.min).js`, + `!${sake.config.paths.src}/${sake.config.paths.js}/blocks/src{,/**}`, + + // skip scss and unminified css files + `!${sake.config.paths.src}/${sake.config.paths.css}/**/*.scss`, + `!${sake.config.paths.src}/${sake.config.paths.css}/**/*(!.min).css`, + + // skip test files + `!${sake.config.paths.src}/**/tests{,/**}`, + `!${sake.config.paths.src}/**/.travis.yml`, + `!${sake.config.paths.src}/**/phpunit.xml`, + `!${sake.config.paths.src}/**/phpunit.travis.xml`, + `!${sake.config.paths.src}/**/docker-compose*.yml`, + `!${sake.config.paths.src}/**/wp-bootstrap.sh`, + `!${sake.config.paths.src}/phpcs.xml`, + + // skip composer and npm files + `!${sake.config.paths.src}/**/composer.json`, + `!${sake.config.paths.src}/**/composer.lock`, + `!${sake.config.paths.src}/**/options.json`, + `!${sake.config.paths.src}/**/package.json`, + `!${sake.config.paths.src}/**/package-lock.json`, + `!${sake.config.paths.src}/**/node_modules{,/**}`, + `!${sake.config.paths.src}/**/grunt{,/**}`, + + // skip misc files + `!${sake.config.paths.src}/**/modman`, + `!${sake.config.paths.src}/**/Gruntfile.js`, + `!${sake.config.paths.src}/**/sake.options.json`, + `!${sake.config.paths.src}/**/codeception*.*`, + `!${sake.config.paths.src}/**/*.zip`, + `!${sake.config.paths.src}/**/*.iml`, // IDE configuration + `!${sake.config.paths.src}/**/test.sh`, + `!${sake.config.paths.src}/**/readme.md`, + `!${sake.config.paths.src}/**/.{*}`, // any file starting with a dot + + // skip tartufo files + `!${sake.config.paths.src}/**/tool.tartufo`, + `!${sake.config.paths.src}/**/tartufo.toml`, + `!${sake.config.paths.src}/**/exclude-patterns.txt`, + + // skip codeowners files + `!${sake.config.paths.src}/**/CODEOWNERS`, + `!${sake.config.paths.src}/**/codeowners`, + + // skip whitesource files + `!${sake.config.paths.src}/**/.whitesource`, + + // skip manifest.xml + `!${sake.config.paths.src}/**/manifest.xml`, + + // skip build config files + `!${sake.config.paths.src}/**/sake.config.js`, + `!${sake.config.paths.src}/**/postcss.config.js`, + ] + + if (sake.config.framework) { + // skip common framework files + paths = paths.concat([ + `!${sake.config.paths.src}/${sake.config.paths.framework.base}/*`, + `!${sake.config.paths.src}/${sake.config.paths.framework.base}/grunt{,/**}`, + `${sake.config.paths.src}/${sake.config.paths.framework.base}/license.txt` + ]) -module.exports = (gulp, plugins, sake) => { - // copy files from source to build - gulp.task('copy:build', () => { - const filter = plugins.filter(['**/*.min.css', '**/*.min.js'], { restore: true }) - - let paths = [ - `${sake.config.paths.src}/**/*`, - - // skip the directory we're building everything into! - `!${sake.config.paths.build}{,/**}`, - - // skip .map files - `!${sake.config.paths.src}/${sake.config.paths.js}/**/*.map`, - `!${sake.config.paths.src}/${sake.config.paths.css}/**/*.map`, - - // skip coffee and unminified js files - `!${sake.config.paths.src}/${sake.config.paths.js}/**/*.coffee`, - `!${sake.config.paths.src}/${sake.config.paths.js}/**/*(!.min).js`, - `!${sake.config.paths.src}/${sake.config.paths.js}/blocks/src{,/**}`, - - // skip scss and unminified css files - `!${sake.config.paths.src}/${sake.config.paths.css}/**/*.scss`, - `!${sake.config.paths.src}/${sake.config.paths.css}/**/*(!.min).css`, - - // skip test files - `!${sake.config.paths.src}/**/tests{,/**}`, - `!${sake.config.paths.src}/**/.travis.yml`, - `!${sake.config.paths.src}/**/phpunit.xml`, - `!${sake.config.paths.src}/**/phpunit.travis.xml`, - `!${sake.config.paths.src}/**/docker-compose*.yml`, - `!${sake.config.paths.src}/**/wp-bootstrap.sh`, - `!${sake.config.paths.src}/phpcs.xml`, - - // skip composer and npm files - `!${sake.config.paths.src}/**/composer.json`, - `!${sake.config.paths.src}/**/composer.lock`, - `!${sake.config.paths.src}/**/options.json`, - `!${sake.config.paths.src}/**/package.json`, - `!${sake.config.paths.src}/**/package-lock.json`, - `!${sake.config.paths.src}/**/node_modules{,/**}`, - `!${sake.config.paths.src}/**/grunt{,/**}`, - - // skip misc files - `!${sake.config.paths.src}/**/modman`, - `!${sake.config.paths.src}/**/Gruntfile.js`, - `!${sake.config.paths.src}/**/sake.options.json`, - `!${sake.config.paths.src}/**/codeception*.*`, - `!${sake.config.paths.src}/**/*.zip`, - `!${sake.config.paths.src}/**/*.iml`, // IDE configuration - `!${sake.config.paths.src}/**/test.sh`, - `!${sake.config.paths.src}/**/readme.md`, - `!${sake.config.paths.src}/**/.{*}`, // any file starting with a dot - - // skip tartufo files - `!${sake.config.paths.src}/**/tool.tartufo`, - `!${sake.config.paths.src}/**/tartufo.toml`, - `!${sake.config.paths.src}/**/exclude-patterns.txt`, - - // skip codeowners files - `!${sake.config.paths.src}/**/CODEOWNERS`, - `!${sake.config.paths.src}/**/codeowners`, - - // skip whitesource files - `!${sake.config.paths.src}/**/.whitesource`, - - // skip manifest.xml - `!${sake.config.paths.src}/**/manifest.xml`, - - // skip build config files - `!${sake.config.paths.src}/**/sake.config.js`, - `!${sake.config.paths.src}/**/postcss.config.js`, - ] - - if (sake.config.framework) { - // skip common framework files - paths = paths.concat([ - `!${sake.config.paths.src}/${sake.config.paths.framework.base}/*`, - `!${sake.config.paths.src}/${sake.config.paths.framework.base}/grunt{,/**}`, - `${sake.config.paths.src}/${sake.config.paths.framework.base}/license.txt` - ]) - - if (sake.config.framework === 'v5') { - // skip sample loader file - paths.push(`!${sake.config.paths.src}/${sake.config.paths.framework.base}/woocommerce/woocommerce-framework-plugin-loader-sample.php`) - } - - paths = paths.concat([ - // skip framework .map files - `!${sake.config.paths.src}/${sake.config.paths.framework.base}/${sake.config.paths.framework.general.js}/**/*.map`, - `!${sake.config.paths.src}/${sake.config.paths.framework.base}/${sake.config.paths.framework.gateway.js}/**/*.map`, - `!${sake.config.paths.src}/${sake.config.paths.framework.base}/${sake.config.paths.framework.general.css}/**/*.map`, - `!${sake.config.paths.src}/${sake.config.paths.framework.base}/${sake.config.paths.framework.gateway.css}/**/*.map`, - - // skip framework coffee files - `!${sake.config.paths.src}/${sake.config.paths.framework.base}/${sake.config.paths.framework.general.js}/**/*.coffee`, - `!${sake.config.paths.src}/${sake.config.paths.framework.base}/${sake.config.paths.framework.gateway.js}/**/*.coffee`, - - // skip framework scss files - `!${sake.config.paths.src}/${sake.config.paths.framework.base}/${sake.config.paths.framework.general.css}/**/*.scss`, - `!${sake.config.paths.src}/${sake.config.paths.framework.base}/${sake.config.paths.framework.gateway.css}/**/*.scss` - ]) + if (sake.config.framework === 'v5') { + // skip sample loader file + paths.push(`!${sake.config.paths.src}/${sake.config.paths.framework.base}/woocommerce/woocommerce-framework-plugin-loader-sample.php`) } paths = paths.concat([ - // skip misc jilt promotions files - `!${sake.config.paths.vendor}/skyverge/wc-jilt-promotions/gulpfile.js`, - `!${sake.config.paths.vendor}/skyverge/wc-jilt-promotions/README.md` + // skip framework .map files + `!${sake.config.paths.src}/${sake.config.paths.framework.base}/${sake.config.paths.framework.general.js}/**/*.map`, + `!${sake.config.paths.src}/${sake.config.paths.framework.base}/${sake.config.paths.framework.gateway.js}/**/*.map`, + `!${sake.config.paths.src}/${sake.config.paths.framework.base}/${sake.config.paths.framework.general.css}/**/*.map`, + `!${sake.config.paths.src}/${sake.config.paths.framework.base}/${sake.config.paths.framework.gateway.css}/**/*.map`, + + // skip framework coffee files + `!${sake.config.paths.src}/${sake.config.paths.framework.base}/${sake.config.paths.framework.general.js}/**/*.coffee`, + `!${sake.config.paths.src}/${sake.config.paths.framework.base}/${sake.config.paths.framework.gateway.js}/**/*.coffee`, + + // skip framework scss files + `!${sake.config.paths.src}/${sake.config.paths.framework.base}/${sake.config.paths.framework.general.css}/**/*.scss`, + `!${sake.config.paths.src}/${sake.config.paths.framework.base}/${sake.config.paths.framework.gateway.css}/**/*.scss` ]) + } - // skip copying composer dev packages - if (sake.config.composer) { - if (sake.config.composer['require-dev']) { - Object.keys(sake.config.composer['require-dev']).forEach((pkg) => { - // skip copying the dev package directory - let packagePath = path.join(sake.config.paths.vendor, pkg) - - // if there are no other non-dev packages from the same vendor, skip the folder for the vendor itself as well - let vendor = pkg.split('/')[0] - - if (!(sake.config.composer.require && Object.keys(sake.config.composer.require).some((pkg) => pkg.indexOf(vendor) > -1))) { - packagePath = path.join(sake.config.paths.vendor, vendor) - } - - paths.push(`!${packagePath}{,/**}`) - }) - } - - // skip copying binaries - paths.push(`!${sake.config.paths.vendor}/bin{,/**}`) - - // skip composer autoloader, unless required - if (!sake.config.autoload) { - paths = paths.concat([ - `!${sake.config.paths.vendor}/composer{,/**}`, - `!${sake.config.paths.vendor}/autoload.php` - ]) - } - } + paths = paths.concat([ + // skip misc jilt promotions files + `!${sake.config.paths.vendor}/skyverge/wc-jilt-promotions/gulpfile.js`, + `!${sake.config.paths.vendor}/skyverge/wc-jilt-promotions/README.md` + ]) - // skip the WP assets dir if it's in the root - if (sake.config.deploy.type === 'wp' && sake.config.paths.wpAssets) { - paths.push(`!${sake.config.paths.wpAssets}{,/**}`) - } + // skip copying composer dev packages + if (sake.config.composer) { + if (sake.config.composer['require-dev']) { + Object.keys(sake.config.composer['require-dev']).forEach((pkg) => { + // skip copying the dev package directory + let packagePath = path.join(sake.config.paths.vendor, pkg) - // skip any custom paths - if (Array.isArray(sake.config.paths.exclude) && sake.config.paths.exclude.length) { - sake.config.paths.exclude.forEach((path) => { - paths.push(`!${path}{,/**}`) + // if there are no other non-dev packages from the same vendor, skip the folder for the vendor itself as well + let vendor = pkg.split('/')[0] + + if (!(sake.config.composer.require && Object.keys(sake.config.composer.require).some((pkg) => pkg.indexOf(vendor) > -1))) { + packagePath = path.join(sake.config.paths.vendor, vendor) + } + + paths.push(`!${packagePath}{,/**}`) }) } - return gulp.src(paths, { base: sake.config.paths.src, allowEmpty: true }) - .pipe(filter) - .pipe(plugins.replace(/\/\*# sourceMappingURL=.*?\*\/$/mg, '')) // remove source mapping references - TODO: consider skipping sourcemaps in compilers instead when running build/deploy tasks - .pipe(plugins.replace('\n', '')) // remove an extra line added by libsass/node-sass - .pipe(filter.restore) - .pipe(gulp.dest(`${sake.config.paths.build}/${sake.config.plugin.id}`)) - }) - - // copy plugin zip and changelog to prereleases folder - gulp.task('copy:prerelease', () => { - let filename = sake.config.deploy.type === 'wp' ? 'readme' : 'changelog' - - const filter = plugins.filter([`**/${filename}.txt`], { restore: true }) - - return gulp.src([ - `${sake.config.paths.build}/${sake.config.plugin.id}*.zip`, - `${sake.config.paths.build}/${sake.config.plugin.id}/${filename}.txt` - ]).pipe(filter) - .pipe(plugins.rename({ prefix: sake.config.plugin.id + '_' })) - .pipe(filter.restore) - .pipe(gulp.dest(sake.getPrereleasesPath())) - }) - - // copy files from build to WC repo folder - gulp.task('copy:wc_repo', () => { - return gulp.src(`${sake.config.paths.build}/${sake.config.plugin.id}/**/*`).pipe(gulp.dest(sake.getProductionRepoPath())) - }) - - // copy files from build to WP trunk folder - gulp.task('copy:wp_trunk', () => { - return gulp.src(`${sake.config.paths.build}/${sake.config.plugin.id}/**/*`).pipe(gulp.dest(path.join(sake.getProductionRepoPath(), 'trunk'))) - }) - - // copy files from build to WP assets folder - gulp.task('copy:wp_assets', () => { - return gulp.src(`${sake.config.paths.wpAssets}/**/*`).pipe(gulp.dest(path.join(sake.getProductionRepoPath(), 'assets'))) - }) - - // copy files from WP trunk to tag - gulp.task('copy:wp_tag', () => { - return gulp.src(path.join(sake.getProductionRepoPath(), 'trunk/**/*')).pipe(gulp.dest(path.join(sake.getProductionRepoPath(), 'tags', sake.getPluginVersion()))) - }) + // skip copying binaries + paths.push(`!${sake.config.paths.vendor}/bin{,/**}`) + + // skip composer autoloader, unless required + if (!sake.config.autoload) { + paths = paths.concat([ + `!${sake.config.paths.vendor}/composer{,/**}`, + `!${sake.config.paths.vendor}/autoload.php` + ]) + } + } + + // skip the WP assets dir if it's in the root + if (sake.config.deploy.type === 'wp' && sake.config.paths.wpAssets) { + paths.push(`!${sake.config.paths.wpAssets}{,/**}`) + } + + // skip any custom paths + if (Array.isArray(sake.config.paths.exclude) && sake.config.paths.exclude.length) { + sake.config.paths.exclude.forEach((path) => { + paths.push(`!${path}{,/**}`) + }) + } + + return gulp.src(paths, { base: sake.config.paths.src, allowEmpty: true }) + .pipe(filter) + .pipe(replace(/\/\*# sourceMappingURL=.*?\*\/$/mg, '')) // remove source mapping references - TODO: consider skipping sourcemaps in compilers instead when running build/deploy tasks + .pipe(replace('\n', '')) // remove an extra line added by libsass/node-sass + .pipe(filter.restore) + .pipe(gulp.dest(`${sake.config.paths.build}/${sake.config.plugin.id}`)) +} +copyBuild.displayName = 'copy:build' + +/** + * Copy plugin zip and changelog to prereleases folder + */ +const copyPrerelease = (done) => { + let filename = sake.config.deploy.type === 'wp' ? 'readme' : 'changelog' + + const filter = gulpFilter([`**/${filename}.txt`], { restore: true }) + + return gulp.src([ + `${sake.config.paths.build}/${sake.config.plugin.id}*.zip`, + `${sake.config.paths.build}/${sake.config.plugin.id}/${filename}.txt` + ]).pipe(filter) + .pipe(rename({ prefix: sake.config.plugin.id + '_' })) + .pipe(filter.restore) + .pipe(gulp.dest(sake.getPrereleasesPath())) +} +copyPrerelease.displayName = 'copy:prerelease' + +/** + * Copy files from build to WC repo folder + */ +const copyWcRepo = (done) => { + return gulp.src(`${sake.config.paths.build}/${sake.config.plugin.id}/**/*`).pipe(gulp.dest(sake.getProductionRepoPath())) +} +copyWcRepo.displayName = 'copy:wc_repo' + +/** + * Copy files from build to WP trunk folder + */ +const copyWpTrunk = (done) => { + return gulp.src(`${sake.config.paths.build}/${sake.config.plugin.id}/**/*`).pipe(gulp.dest(path.join(sake.getProductionRepoPath(), 'trunk'))) +} +copyWpTrunk.displayName = 'copy:wp_trunk' + +/** + * Copy files from build to WP assets folder + */ +const copyWpAssets = (done) => { + return gulp.src(`${sake.config.paths.wpAssets}/**/*`).pipe(gulp.dest(path.join(sake.getProductionRepoPath(), 'assets'))) +} +copyWpAssets.displayName = 'copy:wp_assets' + +/** + * Copy files from WP trunk to tag + */ +const copyWpTag = (done) => { + return gulp.src(path.join(sake.getProductionRepoPath(), 'trunk/**/*')).pipe(gulp.dest(path.join(sake.getProductionRepoPath(), 'tags', sake.getPluginVersion()))) +} +copyWpTag.displayName = 'copy:wp_tag' + +export { + copyBuild, + copyPrerelease, + copyWcRepo, + copyWpTrunk, + copyWpAssets, + copyWpTag } diff --git a/tasks/prompt.js b/tasks/prompt.js index aeceefd..9de2bb2 100644 --- a/tasks/prompt.js +++ b/tasks/prompt.js @@ -3,124 +3,140 @@ import semver from 'semver' import log from 'fancy-log' import chalk from 'chalk' import _ from 'lodash' +import sake from '../lib/sake.js' +import gulp from 'gulp' +import { wcDeploy } from './wc.js' -module.exports = (gulp, plugins, sake) => { - // internal task for prompting the deploy version - gulp.task('prompt:deploy', (done) => { - let currentVersion = sake.getPluginVersion() +function filterIncrement (value) { + if (value[1] === 'custom') { + return 'custom' + } + + if (value[1] === 'skip') { + return 'skip' + } + + return semver.inc(value[0], value[1]) +} + +function getDefault () { + let value = 1 + + switch (sake.getDefaultIncrement()) { + case 'minor': + value = 2 + break + + case 'major': + value = 3 + break + } + + return value +} + +/** + * Internal task for prompting the deploy action + */ +const promptDeploy = (done) => { + let currentVersion = sake.getPluginVersion() - inquirer.prompt([ - { - name: 'version', - type: 'list', - message: 'Plugin Changelog: \n' + sake.readChangelog() + '\n\nBump version from ' + chalk.cyan(currentVersion) + ' to:', - 'default': getDefault(), - choices: [ - { - value: [ currentVersion, 'prerelease' ], - name: chalk.yellow('Build: ' + sake.getPluginVersion('prerelease')) + + inquirer.prompt([ + { + name: 'version', + type: 'list', + message: 'Plugin Changelog: \n' + sake.readChangelog() + '\n\nBump version from ' + chalk.cyan(currentVersion) + ' to:', + 'default': getDefault(), + choices: [ + { + value: [ currentVersion, 'prerelease' ], + name: chalk.yellow('Build: ' + sake.getPluginVersion('prerelease')) + ' Unstable, betas, and release candidates.' - }, - { - value: [ currentVersion, 'patch' ], - name: chalk.yellow('Patch: ' + sake.getPluginVersion('patch')) + + }, + { + value: [ currentVersion, 'patch' ], + name: chalk.yellow('Patch: ' + sake.getPluginVersion('patch')) + ' Backwards-compatible bug fixes.' - }, - { - value: [ currentVersion, 'minor' ], - name: chalk.yellow('Minor: ' + sake.getPluginVersion('minor')) + + }, + { + value: [ currentVersion, 'minor' ], + name: chalk.yellow('Minor: ' + sake.getPluginVersion('minor')) + ' Add functionality in a backwards-compatible manner.' - }, - { - value: [ currentVersion, 'major' ], - name: chalk.yellow('Major: ' + sake.getPluginVersion('major')) + + }, + { + value: [ currentVersion, 'major' ], + name: chalk.yellow('Major: ' + sake.getPluginVersion('major')) + ' Incompatible API changes.' - }, - { - value: [ currentVersion, 'custom' ], - name: chalk.yellow('Custom: ?.?.?') + ' Specify version...' - }, - { - value: [ currentVersion, 'skip' ], - name: chalk.red('Skip this plugin') + ' This plugin will not be deployed' - } - ], - filter: filterIncrement - }, - { - name: 'version_custom', - type: 'input', - message: 'What specific version would you like', - when: function (answers) { - return _.values(answers).shift() === 'custom' }, - validate: function (value) { - var valid = semver.valid(value) && true - return valid || 'Must be a valid semver, such as 1.2.3-rc1. See ' + chalk.underline.blue('http://semver.org/') + ' for more details.' + { + value: [ currentVersion, 'custom' ], + name: chalk.yellow('Custom: ?.?.?') + ' Specify version...' + }, + { + value: [ currentVersion, 'skip' ], + name: chalk.red('Skip this plugin') + ' This plugin will not be deployed' } + ], + filter: filterIncrement + }, + { + name: 'version_custom', + type: 'input', + message: 'What specific version would you like', + when: function (answers) { + return _.values(answers).shift() === 'custom' + }, + validate: function (value) { + const valid = semver.valid(value) && true + return valid || 'Must be a valid semver, such as 1.2.3-rc1. See ' + chalk.underline.blue('https://semver.org/') + ' for more details.' } - ]).then(function (answers) { - sake.options = _.merge(sake.options, answers) - done() - }) - }) - - // internal task for prompting whether to upload the plugin to woo - gulp.task('prompt:wc_upload', (done) => { - inquirer.prompt([{ - type: 'confirm', - name: 'upload_to_wc', - message: 'Upload plugin to WooCommerce.com?' - }]).then((answers) => { - if (answers.upload_to_wc) { - gulp.series('wc:deploy')(done) - } else { - log.error(chalk.red('Skipped uploading to WooCommerce.com')) - done() - } - }) - }) - - // internal task for prompting whether the release has been tested - gulp.task('prompt:tested_release_zip', (done) => { - inquirer.prompt([{ - type: 'confirm', - name: 'tested_release_zip', - message: 'Has the generated zip file for this release been tested?' - }]).then((answers) => { - if (answers.tested_release_zip) { - done() - } else { - sake.throwError('Run npx sake zip to generate a zip of this release and test it on a WordPress installation.') - } - }) - }) - - function filterIncrement (value) { - if (value[1] === 'custom') { - return 'custom' } + ]).then(function (answers) { + sake.options = _.merge(sake.options, answers) + done() + }) +} +promptDeploy.displayName = 'prompt:deploy' - if (value[1] === 'skip') { - return 'skip' +/** + * Internal task for prompting whether to upload the plugin to WooCommerce + */ +const promptWcUpload = (done) => { + inquirer.prompt([{ + type: 'confirm', + name: 'upload_to_wc', + message: 'Upload plugin to WooCommerce.com?' + }]).then((answers) => { + if (answers.upload_to_wc) { + gulp.series(wcDeploy)(done) + } else { + log.error(chalk.red('Skipped uploading to WooCommerce.com')) + done() } + }) +} +promptWcUpload.displayName = 'prompt:wc_upload' - return semver.inc(value[0], value[1]) - } - - function getDefault () { - var value = 1 - - switch (sake.getDefaultIncrement()) { - case 'minor': - value = 2 - break - - case 'major': - value = 3 - break +/** + * Internal task for prompting whether the release has been tested + */ +const promptTestedReleaseZip = (done) => { + inquirer.prompt([{ + type: 'confirm', + name: 'tested_release_zip', + message: 'Has the generated zip file for this release been tested?' + }]).then((answers) => { + if (answers.tested_release_zip) { + done() + } else { + sake.throwError('Run npx sake zip to generate a zip of this release and test it on a WordPress installation.') } + }) +} +promptTestedReleaseZip.displayName = 'prompt:tested_release_zip' - return value - } +export { + promptDeploy, + promptWcUpload, + promptTestedReleaseZip } From 40a5a5507db377546937146ba0805815564ffcd6 Mon Sep 17 00:00:00 2001 From: Ashley Gibson Date: Fri, 14 Mar 2025 14:07:51 +0000 Subject: [PATCH 25/45] Rework bundle --- gulpfile.js | 1 + tasks/bundle.js | 138 +++++++++++++++++++++++++----------------------- 2 files changed, 73 insertions(+), 66 deletions(-) diff --git a/gulpfile.js b/gulpfile.js index 7663c58..2ae1e91 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -65,6 +65,7 @@ gulp.on('error', (event) => { export * from './tasks/build.js' export * from './tasks/bump.js' +export * from './tasks/bundle.js' export * from './tasks/clean.js' export * from './tasks/compile.js' export * from './tasks/config.js' diff --git a/tasks/bundle.js b/tasks/bundle.js index 272f4bf..2db61dd 100644 --- a/tasks/bundle.js +++ b/tasks/bundle.js @@ -1,85 +1,91 @@ -import log from 'fancy-log'; -import fs from 'node:fs'; -import path from 'node:path'; -import shell from 'shelljs'; +import log from 'fancy-log' +import fs from 'node:fs' +import path from 'node:path' +import shell from 'shelljs' +import sake from '../lib/sake.js' +import gulp from 'gulp' + +const processBundle = (bundleType, bundleArray, done) => { + // bail if no items to bundle + if (!bundleArray || !Array.isArray(bundleArray) || bundleArray.length === 0) { + log.info(`No external ${bundleType} to bundle.`) + done() + return + } + + log.info(`Bundling ${bundleType} dependencies.`) -module.exports = (gulp, plugins, sake) => { + // loop through each item and copy it over the designated destination folder in the local plugin file path + bundleArray.forEach((item) => { + const { source: packageName, file, destination } = item - gulp.task('bundle', (done) => { - let tasks = ['bundle:scripts', 'bundle:styles'] + // fetch the package name from node_modules + const packagePath = path.join('node_modules', packageName) - if (sake?.config?.bundle) { - // if there are items to bundle, make sure the dependencies are installed, or bail on error - log.info('Installing external dependencies...') + // check if the package exists + if (!fs.existsSync(packagePath)) { + sake.throwError(`Package '${packageName}' not found in node_modules.`) + done(`Package '${packageName}' not found in node_modules.`) + return + } - let npmInstall = shell.exec('npm install') + // copy the specified file to the destination path + const destinationFolder = path.join(destination) + const sourceFilePath = path.join(packagePath, file) + const destinationFilePath = path.join(destination, file) - if (npmInstall.code !== 0) { - sake.throwError(`Error during npm install: ${result.stderr ?? 'unknown error.'}`) - done(result.stderr) + try { + // create folder if it does not exist + if (!fs.existsSync(destinationFolder)) { + fs.mkdirSync(destinationFolder, { recursive: true }) + log.info(`Created destination folder for '${file}: '${destinationFolder}'.`) } - } - gulp.parallel(tasks)(done) + // copy into destination folder + fs.copyFileSync(sourceFilePath, destinationFilePath) + log.info(`Bundled '${file}' from '${packageName}' to '${destination}'.`) + } catch (error) { + sake.throwError(`Error copying '${file}' from '${sourceFilePath}' to '${destinationFilePath}': ${error.message ?? 'unknown error.'}`) + done(error) + } }) - const processBundle = (bundleType, bundleArray, done) => { - // bail if no items to bundle - if (!bundleArray || !Array.isArray(bundleArray) || bundleArray.length === 0) { - log.info(`No external ${bundleType} to bundle.`) - done() - return - } + done() +} - log.info(`Bundling ${bundleType} dependencies.`) +const bundleScriptsTask = (done) => { + const bundle = sake?.config?.bundle + processBundle('scripts', bundle?.scripts, done) +} +bundleScriptsTask.displayName = 'bundle:scripts' - // loop through each item and copy it over the designated destination folder in the local plugin file path - bundleArray.forEach((item) => { - const { source: packageName, file, destination } = item +const bundleStylesTask = (done) => { + const bundle = sake?.config?.bundle + processBundle('styles', bundle?.styles, done) +} +bundleStylesTask.displayName = 'bundle:styles' - // fetch the package name from node_modules - const packagePath = path.join('node_modules', packageName) +const bundleTask = (done) => { + let tasks = [bundleScriptsTask, bundleStylesTask] - // check if the package exists - if (!fs.existsSync(packagePath)) { - sake.throwError(`Package '${packageName}' not found in node_modules.`) - done(`Package '${packageName}' not found in node_modules.`) - return - } + if (sake?.config?.bundle) { + // if there are items to bundle, make sure the dependencies are installed, or bail on error + log.info('Installing external dependencies...') - // copy the specified file to the destination path - const destinationFolder = path.join(destination) - const sourceFilePath = path.join(packagePath, file) - const destinationFilePath = path.join(destination, file) - - try { - // create folder if it does not exist - if (!fs.existsSync(destinationFolder)) { - fs.mkdirSync(destinationFolder, { recursive: true }) - log.info(`Created destination folder for '${file}: '${destinationFolder}'.`) - } - - // copy into destination folder - fs.copyFileSync(sourceFilePath, destinationFilePath) - log.info(`Bundled '${file}' from '${packageName}' to '${destination}'.`) - } catch (error) { - sake.throwError(`Error copying '${file}' from '${sourceFilePath}' to '${destinationFilePath}': ${error.message ?? 'unknown error.'}`) - done(error) - } - }) + let npmInstall = shell.exec('npm install') - done() + if (npmInstall.code !== 0) { + sake.throwError(`Error during npm install: ${npmInstall.stderr ?? 'unknown error.'}`) + done(npmInstall.stderr) + } } - gulp.task('bundle:scripts', (done) => { - const bundle = sake?.config?.bundle - const scripts = bundle?.scripts - processBundle('scripts', scripts, done) - }) + gulp.parallel(tasks)(done) +} +bundleTask.displayName = 'bundle' - gulp.task('bundle:styles', (done) => { - const bundle = sake?.config?.bundle - const styles = bundle?.styles - processBundle('styles', styles, done) - }) +export { + bundleScriptsTask, + bundleStylesTask, + bundleTask } From 06141a6482c627f648c081048777550bbe3ed6d7 Mon Sep 17 00:00:00 2001 From: Ashley Gibson Date: Fri, 14 Mar 2025 14:12:00 +0000 Subject: [PATCH 26/45] Use task suffix in constants --- tasks/bump.js | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/tasks/bump.js b/tasks/bump.js index 62a8362..342e1c2 100644 --- a/tasks/bump.js +++ b/tasks/bump.js @@ -7,7 +7,7 @@ import sake from '../lib/sake.js' /** * Bumps the version in the main plugin file to match changelog.txt */ -const bump = (done) => { +const bumpTask = (done) => { let pluginFiles = [`${sake.config.paths.src}/${sake.config.plugin.mainFile}`] // also include the main Plugin class file @@ -20,11 +20,12 @@ const bump = (done) => { .pipe(replace(/const VERSION = '[0-9]*.[0-9]*.[0-9]*(-[a-z]+.[0-9]+)*';/, () => "const VERSION = '" + sake.getPluginVersion() + "';")) .pipe(gulp.dest(sake.config.paths.src)) } +bumpTask.displayName = 'bump' /** * Bumps the minimum requirements for the plugin. */ -const bumpMinReqs = (done) => { +const bumpMinReqsTask = (done) => { // helper to determine if a number is an integer let isInt = (n) => { return n % 1 === 0 @@ -49,20 +50,20 @@ const bumpMinReqs = (done) => { .pipe(gulpif(Boolean(sake.options.backwards_compatible && sake.config.framework === 'v4'), sakeReplace.replaceBackwardsCompatibleVersion())) .pipe(gulp.dest(sake.config.paths.src)) } -bumpMinReqs.displayName = 'bump:minreqs' +bumpMinReqsTask.displayName = 'bump:minreqs' /** * Bumps the v5 framework version in plugin files */ -const bumpFrameworkVersion = (done) => { +const bumpFrameworkVersionTask = (done) => { return gulp.src([`${sake.config.paths.src}/**/*.php`, `!${sake.config.paths.src}/${sake.config.paths.framework.base}`]) .pipe(gulpif(Boolean(sake.options.framework_version), sakeReplace.replaceFrameworkVersion())) .pipe(gulp.dest(sake.config.paths.src)) } -bumpFrameworkVersion.displayName = 'bump:framework_version' +bumpFrameworkVersionTask.displayName = 'bump:framework_version' export { - bump, - bumpMinReqs, - bumpFrameworkVersion + bumpTask, + bumpMinReqsTask, + bumpFrameworkVersionTask } From beafea5ddf19a297b78e82373a3e27d607771539 Mon Sep 17 00:00:00 2001 From: Ashley Gibson Date: Fri, 14 Mar 2025 14:14:34 +0000 Subject: [PATCH 27/45] Use task suffix --- tasks/build.js | 6 +++--- tasks/clean.js | 42 +++++++++++++++++++++--------------------- tasks/prompt.js | 18 +++++++++--------- 3 files changed, 33 insertions(+), 33 deletions(-) diff --git a/tasks/build.js b/tasks/build.js index 62570b0..db8dbc9 100644 --- a/tasks/build.js +++ b/tasks/build.js @@ -1,7 +1,7 @@ import _ from 'lodash'; import gulp from 'gulp' import sake from '../lib/sake.js' -import { cleanBuild, cleanComposer } from './clean.js' +import { cleanBuildTask, cleanComposerTask } from './clean.js' import { shellComposerInstall, shellComposerStatus } from './shell.js' import { compile } from './compile.js' import { copyBuild } from './copy.js' @@ -14,10 +14,10 @@ import { copyBuild } from './copy.js' * - Copies plugin files to the build directory */ const build = (done) => { - let tasks = [cleanBuild, shellComposerStatus, cleanComposer, shellComposerInstall, compile, 'bundle', copyBuild] // @TODO replace remaining + let tasks = [cleanBuildTask, shellComposerStatus, cleanComposerTask, shellComposerInstall, compile, 'bundle', copyBuild] // @TODO replace remaining if (sake.options['skip-composer']) { - tasks = _.without(tasks, shellComposerStatus, cleanComposer, shellComposerInstall) + tasks = _.without(tasks, shellComposerStatus, cleanComposerTask, shellComposerInstall) } return gulp.series(tasks) diff --git a/tasks/clean.js b/tasks/clean.js index 7e17b2c..84ddf08 100644 --- a/tasks/clean.js +++ b/tasks/clean.js @@ -5,82 +5,82 @@ import sake from '../lib/sake.js' /** * Clean dev directory from map files */ -const cleanDev = (done) => { +const cleanDevTask = (done) => { return del([ `${sake.config.paths.src}/${sake.config.paths.assets}/**/*.map` ]) } -cleanDev.displayName = 'clean:dev' +cleanDevTask.displayName = 'clean:dev' /** * Clean composer packages */ -const cleanComposer = (done) => { +const cleanComposerTask = (done) => { return del([ `${sake.config.paths.vendor}` ]) } -cleanComposer.displayName = 'clean:composer' +cleanComposerTask.displayName = 'clean:composer' /** * Clean/empty the build directory */ -const cleanBuild = (done) => { +const cleanBuildTask = (done) => { return del([ `${sake.config.paths.build}/${sake.config.plugin.id}`, `${sake.config.paths.build}/${sake.config.plugin.id}.*.zip` ]) } -cleanBuild.displayName = 'clean:build' +cleanBuildTask.displayName = 'clean:build' /** * Clean the WooCommerce repo directory * This will automatically exclude any dotfiles, such as the .git directory */ -const cleanWcRepo = (done) => { +const cleanWcRepoTask = (done) => { return del([ sake.getProductionRepoPath() + '**/*' ]) } -cleanWcRepo.displayName = 'clean:wc_repo' +cleanWcRepoTask.displayName = 'clean:wc_repo' /** * Delete prerelease */ -const cleanPrerelease = (done) => { +const cleanPrereleaseTask = (done) => { return del([ sake.getPrereleasesPath() + sake.config.plugin.id + '*.zip', sake.getPrereleasesPath() + sake.config.plugin.id + '*.txt' ]) } -cleanPrerelease.displayName = 'clean:prerelease' +cleanPrereleaseTask.displayName = 'clean:prerelease' /** * Clear WP repo trunk */ -const cleanWpTrunk = (done) => { +const cleanWpTrunkTask = (done) => { return del([ path.join(sake.getProductionRepoPath(), 'trunk') ]) } -cleanWpTrunk.displayName = 'clean:wp_trunk' +cleanWpTrunkTask.displayName = 'clean:wp_trunk' /** * Clear WP repo assets */ -const cleanWpAssets = (done) => { +const cleanWpAssetsTask = (done) => { return del([ path.join(sake.getProductionRepoPath(), 'assets') ]) } -cleanWpAssets.displayName = 'clean:wp_assets' +cleanWpAssetsTask.displayName = 'clean:wp_assets' export { - cleanDev, - cleanComposer, - cleanBuild, - cleanWcRepo, - cleanPrerelease, - cleanWpTrunk, - cleanWpAssets + cleanDevTask, + cleanComposerTask, + cleanBuildTask, + cleanWcRepoTask, + cleanPrereleaseTask, + cleanWpTrunkTask, + cleanWpAssetsTask } diff --git a/tasks/prompt.js b/tasks/prompt.js index 9de2bb2..dbea1eb 100644 --- a/tasks/prompt.js +++ b/tasks/prompt.js @@ -38,7 +38,7 @@ function getDefault () { /** * Internal task for prompting the deploy action */ -const promptDeploy = (done) => { +const promptDeployTask = (done) => { let currentVersion = sake.getPluginVersion() inquirer.prompt([ @@ -96,12 +96,12 @@ const promptDeploy = (done) => { done() }) } -promptDeploy.displayName = 'prompt:deploy' +promptDeployTask.displayName = 'prompt:deploy' /** * Internal task for prompting whether to upload the plugin to WooCommerce */ -const promptWcUpload = (done) => { +const promptWcUploadTask = (done) => { inquirer.prompt([{ type: 'confirm', name: 'upload_to_wc', @@ -115,12 +115,12 @@ const promptWcUpload = (done) => { } }) } -promptWcUpload.displayName = 'prompt:wc_upload' +promptWcUploadTask.displayName = 'prompt:wc_upload' /** * Internal task for prompting whether the release has been tested */ -const promptTestedReleaseZip = (done) => { +const promptTestedReleaseZipTask = (done) => { inquirer.prompt([{ type: 'confirm', name: 'tested_release_zip', @@ -133,10 +133,10 @@ const promptTestedReleaseZip = (done) => { } }) } -promptTestedReleaseZip.displayName = 'prompt:tested_release_zip' +promptTestedReleaseZipTask.displayName = 'prompt:tested_release_zip' export { - promptDeploy, - promptWcUpload, - promptTestedReleaseZip + promptDeployTask, + promptWcUploadTask, + promptTestedReleaseZipTask } From 5c517b0964a75d4970f68eab7cce430b803b9034 Mon Sep 17 00:00:00 2001 From: Ashley Gibson Date: Fri, 14 Mar 2025 14:20:09 +0000 Subject: [PATCH 28/45] Use task suffix --- tasks/github.js | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/tasks/github.js b/tasks/github.js index 510f828..ca6e7a5 100644 --- a/tasks/github.js +++ b/tasks/github.js @@ -23,7 +23,7 @@ let getGithub = (target = 'dev') => { return githubInstances[target] } -const gitHubGetReleaseIssue = (done) => { +const gitHubGetReleaseIssueTask = (done) => { let owner = sake.config.deploy.dev.owner let repo = sake.config.deploy.dev.name let github = getGithub('dev') @@ -77,9 +77,9 @@ const gitHubGetReleaseIssue = (done) => { done() }) } -gitHubGetReleaseIssue.displayName = 'github:get_rissue' +gitHubGetReleaseIssueTask.displayName = 'github:get_rissue' -const gitHubGetWcIssues = (done) => { +const gitHubGetWcIssuesTask = (done) => { if (!sake.config.deploy.production) { log.warn(chalk.yellow('No WC (production) repo configured for ' + sake.getPluginName() + ', skipping')) return done() @@ -125,12 +125,12 @@ const gitHubGetWcIssues = (done) => { done() }) } -gitHubGetWcIssues.displayName = 'github:get_wc_issues' +gitHubGetWcIssuesTask.displayName = 'github:get_wc_issues' /** * Creates a docs issue for the plugin */ -const gitHubCreateDocsIssue = (done) => { +const gitHubCreateDocsIssueTask = (done) => { if (! sake.config.deploy.docs) { log.warn(chalk.yellow('No docs repo configured for ' + sake.getPluginName() + ', skipping')) return done() @@ -178,12 +178,12 @@ const gitHubCreateDocsIssue = (done) => { } }) } -gitHubCreateDocsIssue.displayName = 'github:docs_issue' +gitHubCreateDocsIssueTask.displayName = 'github:docs_issue' /** * Creates a release for the plugin, attaching the build zip to it */ -const gitHubCreateRelease = (done) => { +const gitHubCreateReleaseTask = (done) => { let owner = sake.options.owner let repo = sake.options.repo || sake.config.plugin.id @@ -239,12 +239,12 @@ const gitHubCreateRelease = (done) => { gulp.series(tasks)(done) } -gitHubCreateRelease.displayName = 'github:create_release' +gitHubCreateReleaseTask.displayName = 'github:create_release' /** * Create release milestones for each Tuesday */ -const gitHubCreateReleaseMilestones = (done) => { +const gitHubCreateReleaseMilestonesTask = (done) => { let year = sake.options.year || new Date().getFullYear() let tuesdays = getTuesdays(year) @@ -270,12 +270,12 @@ const gitHubCreateReleaseMilestones = (done) => { return tuesdays } } -gitHubCreateReleaseMilestones.displayName = 'github:create_release_milestones' +gitHubCreateReleaseMilestonesTask.displayName = 'github:create_release_milestones' /** * Create monthly milestones */ -const gitHubCreateMonthMilestones = (done) => { +const gitHubCreateMonthMilestonesTask = (done) => { let year = sake.options.year || new Date().getFullYear() createMilestones(getMonthlyMilestones(year), done) @@ -295,7 +295,7 @@ const gitHubCreateMonthMilestones = (done) => { return months } } -gitHubCreateMonthMilestones.displayName = 'github:create_month_milestones' +gitHubCreateMonthMilestonesTask.displayName = 'github:create_month_milestones' // create a milestone for each date passed in const createMilestones = (milestones, done) => { @@ -333,10 +333,10 @@ const createMilestones = (milestones, done) => { } export { - gitHubGetReleaseIssue, - gitHubGetWcIssues, - gitHubCreateDocsIssue, - gitHubCreateRelease, - gitHubCreateReleaseMilestones, - gitHubCreateMonthMilestones + gitHubGetReleaseIssueTask, + gitHubGetWcIssuesTask, + gitHubCreateDocsIssueTask, + gitHubCreateReleaseTask, + gitHubCreateReleaseMilestonesTask, + gitHubCreateMonthMilestonesTask } From e1c28d622ee7250d9b6b0e50cceb0012fd44a506 Mon Sep 17 00:00:00 2001 From: Ashley Gibson Date: Fri, 14 Mar 2025 14:22:25 +0000 Subject: [PATCH 29/45] Use task suffix --- tasks/build.js | 11 +++--- tasks/shell.js | 96 +++++++++++++++++++++++++------------------------- 2 files changed, 54 insertions(+), 53 deletions(-) diff --git a/tasks/build.js b/tasks/build.js index db8dbc9..53b65b2 100644 --- a/tasks/build.js +++ b/tasks/build.js @@ -2,7 +2,7 @@ import _ from 'lodash'; import gulp from 'gulp' import sake from '../lib/sake.js' import { cleanBuildTask, cleanComposerTask } from './clean.js' -import { shellComposerInstall, shellComposerStatus } from './shell.js' +import { shellComposerInstallTask, shellComposerStatusTask } from './shell.js' import { compile } from './compile.js' import { copyBuild } from './copy.js' @@ -13,16 +13,17 @@ import { copyBuild } from './copy.js' * - Bundles any external dependencies to the plugin assets * - Copies plugin files to the build directory */ -const build = (done) => { - let tasks = [cleanBuildTask, shellComposerStatus, cleanComposerTask, shellComposerInstall, compile, 'bundle', copyBuild] // @TODO replace remaining +const buildTask = (done) => { + let tasks = [cleanBuildTask, shellComposerStatusTask, cleanComposerTask, shellComposerInstallTask, compile, 'bundle', copyBuild] // @TODO replace remaining if (sake.options['skip-composer']) { - tasks = _.without(tasks, shellComposerStatus, cleanComposerTask, shellComposerInstall) + tasks = _.without(tasks, shellComposerStatusTask, cleanComposerTask, shellComposerInstallTask) } return gulp.series(tasks) } +buildTask.displayName = 'build' export { - build + buildTask } diff --git a/tasks/shell.js b/tasks/shell.js index b295d74..0299b56 100644 --- a/tasks/shell.js +++ b/tasks/shell.js @@ -24,7 +24,7 @@ const exec = (command, opts, done) => { /** * Update framework subtree */ -const shellUpdateFramework = (done) => { +const shellUpdateFrameworkTask = (done) => { if (!sake.config.framework) { sake.throwError('Not a frameworked plugin, aborting') } @@ -57,12 +57,12 @@ const shellUpdateFramework = (done) => { exec(command, done) } -shellUpdateFramework.displayName = 'shell:update_framework' +shellUpdateFrameworkTask.displayName = 'shell:update_framework' /** * Commit framework update */ -const shellUpdateFrameworkCommit = (done) => { +const shellUpdateFrameworkCommitTask = (done) => { let frameworkPath = path.join(process.cwd(), sake.config.paths.src, sake.config.paths.framework.base) let command = '' @@ -81,12 +81,12 @@ const shellUpdateFrameworkCommit = (done) => { exec(command, done) } -shellUpdateFrameworkCommit.displayName = 'shell:update_framework_commit' +shellUpdateFrameworkCommitTask.displayName = 'shell:update_framework_commit' /** * Ensure the working copy (git tree) has no uncommitted changes */ -const shellGitEnsureCleanWorkingCopy = (done) => { +const shellGitEnsureCleanWorkingCopyTask = (done) => { let command = [ 'git diff-index --quiet HEAD' ].join(' && ') @@ -99,12 +99,12 @@ const shellGitEnsureCleanWorkingCopy = (done) => { }) }) } -shellGitEnsureCleanWorkingCopy.displayName = 'shell:git_ensure_clean_working_copy' +shellGitEnsureCleanWorkingCopyTask.displayName = 'shell:git_ensure_clean_working_copy' /** * Commit and push update */ -const shellGitPushUpdate = (done) => { +const shellGitPushUpdateTask = (done) => { const command = [ 'git add -A', 'git commit -m "' + sake.config.plugin.name + ': ' + sake.getPluginVersion() + ' Versioning"' + (sake.options.release_issue_to_close ? ' -m "Closes #' + sake.options.release_issue_to_close + '"' : ''), @@ -114,13 +114,13 @@ const shellGitPushUpdate = (done) => { exec(command, done) } -shellGitPushUpdate.displayName = 'shell:git_push_update' +shellGitPushUpdateTask.displayName = 'shell:git_push_update' /** * Pull updates from WC repo, or clone repo, if deploying for the first time * @deprecated We no longer use WC mirror repos */ -const shellGitPullWcRepo = (done) => { +const shellGitPullWcRepoTask = (done) => { let command = [] if (!fs.existsSync(sake.getProductionRepoPath())) { @@ -152,13 +152,13 @@ const shellGitPullWcRepo = (done) => { } }) } -shellGitPullWcRepo.displayName = 'shell:git_pull_wc_repo' +shellGitPullWcRepoTask.displayName = 'shell:git_pull_wc_repo' /** * Commit and push update to WC repo * @deprecated We no longer use WC mirror repos */ -const shellGitPushWcRepo = (done) => { +const shellGitPushWcRepoTask = (done) => { let closeIssues = '' if (sake.options.wc_issues_to_close) { @@ -179,13 +179,13 @@ const shellGitPushWcRepo = (done) => { exec(command, done) }) } -shellGitPushWcRepo.displayName = 'shell:git_push_wc_repo' +shellGitPushWcRepoTask.displayName = 'shell:git_push_wc_repo' /** * Commit and push update to WC repo, version 2 * @deprecated We no longer use WooCommerce mirror repos */ -const shellGitUpdateWcRepo = (done) => { +const shellGitUpdateWcRepoTask = (done) => { let command = [ 'cd ' + sake.getProductionRepoPath(), 'git pull', @@ -197,25 +197,25 @@ const shellGitUpdateWcRepo = (done) => { exec(command, done) } -shellGitUpdateWcRepo.displayName = 'shell:git_update_wc_repo' +shellGitUpdateWcRepoTask.displayName = 'shell:git_update_wc_repo' /** * Stash uncommitted changes */ -const shellGitStash = (done) => { +const shellGitStashTask = (done) => { exec('git stash', done) } -shellGitStash.displayName = 'shell:git_stash' +shellGitStashTask.displayName = 'shell:git_stash' /** * Apply latest stash */ -const shellGitStashApply = (done) => { +const shellGitStashApplyTask = (done) => { exec('git stash apply', done) } -shellGitStashApply.displayName = 'shell:git_stash_apply' +shellGitStashApplyTask.displayName = 'shell:git_stash_apply' -const shellComposerStatus = (done) => { +const shellComposerStatusTask = (done) => { if (fs.existsSync(path.join(process.cwd(), 'composer.json'))) { exec('composer status -v', done) } else { @@ -223,9 +223,9 @@ const shellComposerStatus = (done) => { done() } } -shellComposerStatus.displayName = 'shell:composer_status' +shellComposerStatusTask.displayName = 'shell:composer_status' -const shellComposerInstall = (done) => { +const shellComposerInstallTask = (done) => { if (fs.existsSync(path.join(process.cwd(), 'composer.json'))) { exec('composer install --no-dev', done) } else { @@ -233,9 +233,9 @@ const shellComposerInstall = (done) => { done() } } -shellComposerInstall.displayName = 'shell:composer_install' +shellComposerInstallTask.displayName = 'shell:composer_install' -const shellComposerUpdate = (done) => { +const shellComposerUpdateTask = (done) => { if (fs.existsSync(path.join(process.cwd(), 'composer.json'))) { exec('composer update --no-dev', done) } else { @@ -243,9 +243,9 @@ const shellComposerUpdate = (done) => { done() } } -shellComposerUpdate.displayName = 'shell:composer_update' +shellComposerUpdateTask.displayName = 'shell:composer_update' -const shellSvnCheckout = (done) => { +const shellSvnCheckoutTask = (done) => { // ensure that the tmp dir exists if (!fs.existsSync(sake.config.paths.tmp)) { shell.mkdir('-p', sake.config.paths.tmp) @@ -255,9 +255,9 @@ const shellSvnCheckout = (done) => { exec(command, done) } -shellSvnCheckout.displayName = 'shell:svn_checkout' +shellSvnCheckoutTask.displayName = 'shell:svn_checkout' -const shellSvnCommitTrunk = (done) => { +const shellSvnCommitTrunkTask = (done) => { const commitMsg = 'Committing ' + sake.getPluginVersion() + ' to trunk' let command = [ @@ -269,9 +269,9 @@ const shellSvnCommitTrunk = (done) => { exec(command, done) } -shellSvnCommitTrunk.displayName = 'shell:svn_commit_trunk' +shellSvnCommitTrunkTask.displayName = 'shell:svn_commit_trunk' -const shellSvnCommitTag = (done) => { +const shellSvnCommitTagTask = (done) => { const commitMsg = 'Tagging ' + sake.getPluginVersion() let command = [ @@ -282,9 +282,9 @@ const shellSvnCommitTag = (done) => { exec(command, done) } -shellSvnCommitTag.displayName = 'shell:svn_commit_tag' +shellSvnCommitTagTask.displayName = 'shell:svn_commit_tag' -const shellSvnCommitAssets = (done) => { +const shellSvnCommitAssetsTask = (done) => { const commitMsg = 'Committing assets for ' + sake.getPluginVersion() let command = [ @@ -296,23 +296,23 @@ const shellSvnCommitAssets = (done) => { exec(command, done) } -shellSvnCommitAssets.displayName = 'shell:svn_commit_assets' +shellSvnCommitAssetsTask.displayName = 'shell:svn_commit_assets' export { - shellUpdateFramework, - shellUpdateFrameworkCommit, - shellGitEnsureCleanWorkingCopy, - shellGitPushUpdate, - shellGitPullWcRepo, - shellGitPushWcRepo, - shellGitUpdateWcRepo, - shellGitStash, - shellGitStashApply, - shellComposerStatus, - shellComposerInstall, - shellComposerUpdate, - shellSvnCheckout, - shellSvnCommitTrunk, - shellSvnCommitTag, - shellSvnCommitAssets + shellUpdateFrameworkTask, + shellUpdateFrameworkCommitTask, + shellGitEnsureCleanWorkingCopyTask, + shellGitPushUpdateTask, + shellGitPullWcRepoTask, + shellGitPushWcRepoTask, + shellGitUpdateWcRepoTask, + shellGitStashTask, + shellGitStashApplyTask, + shellComposerStatusTask, + shellComposerInstallTask, + shellComposerUpdateTask, + shellSvnCheckoutTask, + shellSvnCommitTrunkTask, + shellSvnCommitTagTask, + shellSvnCommitAssetsTask } From a68bfe0d6a65e8e6ebaecc495c39fb134b67cd04 Mon Sep 17 00:00:00 2001 From: Ashley Gibson Date: Fri, 14 Mar 2025 14:26:51 +0000 Subject: [PATCH 30/45] Use task suffix --- tasks/compile.js | 4 ++-- tasks/lint.js | 41 +++++++++++++++++++++-------------------- tasks/scripts.js | 10 +++++----- tasks/styles.js | 6 +++--- tasks/validate.js | 6 +++--- tasks/zip.js | 8 +++++--- 6 files changed, 39 insertions(+), 36 deletions(-) diff --git a/tasks/compile.js b/tasks/compile.js index e8de547..590b704 100644 --- a/tasks/compile.js +++ b/tasks/compile.js @@ -14,7 +14,7 @@ import browserSync from 'browser-sync' import { scriptPipes } from '../pipes/scripts.js'; import sake from '../lib/sake.js' import rename from 'gulp-rename' -import { lintPhp } from './lint.js' +import { lintPhpTask } from './lint.js' import { minifyImages } from './imagemin.js' import { makepot } from './makepot.js' import { styles } from './styles.js' @@ -152,7 +152,7 @@ compileStyles.displayName = 'compile:styles' // Compile all plugin assets const compile = (done) => { // default compile tasks - let tasks = [lintPhp, 'scripts', styles, minifyImages] // NOTE: do not import the `scripts` constant here, otherwise it creates a circular dependency + let tasks = [lintPhpTask, 'scripts', styles, minifyImages] // NOTE: do not import the `scripts` constant here, otherwise it creates a circular dependency // unless exclusively told not to, generate the POT file as well if (!sake.options.skip_pot) { diff --git a/tasks/lint.js b/tasks/lint.js index 57a38d5..8b3ed08 100644 --- a/tasks/lint.js +++ b/tasks/lint.js @@ -11,7 +11,7 @@ import { fileURLToPath } from 'node:url' const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); -const lintPhp = (done) => { +const lintPhpTask = (done) => { let paths = [ `${sake.config.paths.src}/**/*.php`, `!${sake.config.paths.vendor}/**/*.php`, @@ -39,9 +39,9 @@ const lintPhp = (done) => { } })) } -lintPhp.displayName = 'lint:php' +lintPhpTask.displayName = 'lint:php' -const lintCoffee = (done) => { +const lintCoffeeTask = (done) => { if (! fs.existsSync(sake.config.paths.assetPaths.js)) { return Promise.resolve() } @@ -55,9 +55,9 @@ const lintCoffee = (done) => { .on('end', done) .on('error', done) } -lintCoffee.displayName = 'lint:coffee' +lintCoffeeTask.displayName = 'lint:coffee' -const lintJs = (done) => { +const lintJsTask = (done) => { if (! fs.existsSync(sake.config.paths.assetPaths.js)) { return Promise.resolve() } @@ -74,9 +74,9 @@ const lintJs = (done) => { .pipe(eslint(esLintOptions)) .pipe(eslint.format('table')) } -lintJs.displayName = 'lint:js' +lintJsTask.displayName = 'lint:js' -const lintScss = (done) => { +const lintScssTask = (done) => { if (! fs.existsSync(sake.config.paths.assetPaths.css)) { return Promise.resolve() } @@ -88,24 +88,25 @@ const lintScss = (done) => { .on('end', done) .on('error', done) } -lintScss.displayName = 'lint:scss' +lintScssTask.displayName = 'lint:scss' // the main task to lint scripts -const lintScripts = gulp.parallel(lintCoffee, lintJs) -lintScripts.displayName = 'lint:scripts' +const lintScriptsTask = gulp.parallel(lintCoffeeTask, lintJsTask) +lintScriptsTask.displayName = 'lint:scripts' // the main task to lint styles -const lintStyles = gulp.parallel(lintScss) -lintStyles.displayName = 'lint:styles' +const lintStylesTask = gulp.parallel(lintScssTask) +lintStylesTask.displayName = 'lint:styles' -const lint = gulp.parallel(lintPhp, lintScripts, lintStyles) +const lintTask = gulp.parallel(lintPhpTask, lintScriptsTask, lintStylesTask) +lintTask.displayName = 'lint' export { - lint, - lintScripts, - lintPhp, - lintCoffee, - lintJs, - lintScss, - lintStyles + lintTask, + lintScriptsTask, + lintPhpTask, + lintCoffeeTask, + lintJsTask, + lintScssTask, + lintStylesTask } diff --git a/tasks/scripts.js b/tasks/scripts.js index d6f0f23..54e7689 100644 --- a/tasks/scripts.js +++ b/tasks/scripts.js @@ -1,5 +1,5 @@ import gulp from 'gulp' -import { lintCoffee, lintJs, lintScripts } from './lint.js' +import { lintCoffeeTask, lintJsTask, lintScriptsTask } from './lint.js' import { compileBlocks, compileCoffee, compileJs, compileScripts } from './compile.js' import sake from '../lib/sake.js' @@ -7,10 +7,10 @@ import sake from '../lib/sake.js' * The main task */ const scripts = (done) => { - let tasks = [lintScripts, compileScripts] + let tasks = [lintScriptsTask, compileScripts] // don't lint styles if they have already been linted, unless we're watching - if (! sake.isWatching && gulp.lastRun(lintScripts)) { + if (! sake.isWatching && gulp.lastRun(lintScriptsTask)) { tasks.shift() } @@ -19,10 +19,10 @@ const scripts = (done) => { /** type-specific script tasks - lints and then compiles */ -const scriptsCoffee = gulp.series(lintCoffee, compileCoffee) +const scriptsCoffee = gulp.series(lintCoffeeTask, compileCoffee) scriptsCoffee.displayName = 'scripts:coffee' -const scriptsJs = gulp.series(lintJs, compileJs) +const scriptsJs = gulp.series(lintJsTask, compileJs) scriptsJs.displayName = 'scripts:js' const scriptsBlocks = gulp.series(compileBlocks) diff --git a/tasks/styles.js b/tasks/styles.js index 79751cf..7852b00 100644 --- a/tasks/styles.js +++ b/tasks/styles.js @@ -1,13 +1,13 @@ import gulp from 'gulp' import sake from '../lib/sake.js' -import { lintStyles } from './lint.js' +import { lintStylesTask } from './lint.js' import { compileStyles } from './compile.js' const styles = (done) => { - let tasks = [lintStyles, compileStyles] + let tasks = [lintStylesTask, compileStyles] // don't lint styles if they have already been linted, unless we're watching - if (!sake.isWatching && gulp.lastRun(lintStyles)) { + if (!sake.isWatching && gulp.lastRun(lintStylesTask)) { tasks.shift() } diff --git a/tasks/validate.js b/tasks/validate.js index fb01bb7..7826419 100644 --- a/tasks/validate.js +++ b/tasks/validate.js @@ -2,7 +2,7 @@ import fs from 'node:fs' import log from 'fancy-log' import sake from '../lib/sake.js' -const validateReadmeHeaders = (done) => { +const validateReadmeHeadersTask = (done) => { fs.readFile(`${sake.config.paths.src}/readme.txt`, 'utf8', (err, data) => { if (err) sake.throwError(err) @@ -29,8 +29,8 @@ const validateReadmeHeaders = (done) => { }) } -validateReadmeHeaders.displayName = 'validate:readme_headers' +validateReadmeHeadersTask.displayName = 'validate:readme_headers' export { - validateReadmeHeaders + validateReadmeHeadersTask } diff --git a/tasks/zip.js b/tasks/zip.js index eaee109..0eb1804 100644 --- a/tasks/zip.js +++ b/tasks/zip.js @@ -1,8 +1,9 @@ import sake from '../lib/sake.js' import gulp from 'gulp' import zip from 'gulp-zip' +import { buildTask } from './build.js' -const compress = (done) => { +const compressTask = (done) => { let zipDest = sake.options.zipDest || sake.config.paths.build let zipFileName = sake.config.plugin.id + '.' + sake.getPluginVersion() + '.zip' @@ -15,11 +16,12 @@ const compress = (done) => { .pipe(zip(zipFileName)) .pipe(gulp.dest(sake.config.paths.zipDest)) } +compressTask.displayName = 'compress' -const buildAndZip = gulp.series('build', compress) // @TODO replace "build" +const buildAndZip = gulp.series(buildTask, compressTask) buildAndZip.displayName = 'zip' export { - compress, + compressTask, buildAndZip } From 03707159b5edf25858b54b28c426d4d00164be06 Mon Sep 17 00:00:00 2001 From: Ashley Gibson Date: Fri, 14 Mar 2025 16:20:54 +0000 Subject: [PATCH 31/45] Start reworking deploy --- tasks/deploy.js | 255 +++++++++++++++++++++++++++--------------------- 1 file changed, 143 insertions(+), 112 deletions(-) diff --git a/tasks/deploy.js b/tasks/deploy.js index fd6f92a..1522dd3 100644 --- a/tasks/deploy.js +++ b/tasks/deploy.js @@ -4,138 +4,169 @@ import _ from 'lodash'; import axios from 'axios'; import log from 'fancy-log'; import chalk from 'chalk'; - -module.exports = (gulp, plugins, sake) => { - let validatedEnvVariables = false - - // TODO: consider setting these variables in the sake.config on load instead, and validating sake.config vars instead - // validate env variables before deploy - function validateEnvVariables () { - if (validatedEnvVariables) return - - let variables = ['GITHUB_API_KEY', 'GITHUB_USERNAME', 'SAKE_PRE_RELEASE_PATH'] - - if (sake.config.deploy.type === 'wc') { - variables = variables.concat(['WC_CONSUMER_KEY', 'WC_CONSUMER_SECRET']) - } - - if (sake.config.deploy.type === 'wp') { - variables = variables.concat(['WP_SVN_USER']) - } - - sake.validateEnvironmentVariables(variables) +import sake from '../lib/sake.js' +import gulp from 'gulp' +import { promptDeployTask, promptTestedReleaseZipTask, promptWcUploadTask } from './prompt.js' +import { bumpMinReqsTask, bumpTask } from './bump.js' +import { cleanPrereleaseTask } from './clean.js' +import { buildTask } from './build.js' +import { gitHubCreateDocsIssueTask, gitHubGetReleaseIssueTask } from './github.js' +import { shellGitEnsureCleanWorkingCopyTask, shellGitPushUpdateTask } from './shell.js' +import { compressTask } from './zip.js' +import { validateReadmeHeadersTask } from './validate.js' +import { lintScriptsTask, lintStylesTask } from './lint.js' + +let validatedEnvVariables = false + +// TODO: consider setting these variables in the sake.config on load instead, and validating sake.config vars instead +// validate env variables before deploy +function validateEnvVariables () { + if (validatedEnvVariables) return + + let variables = ['GITHUB_API_KEY', 'GITHUB_USERNAME', 'SAKE_PRE_RELEASE_PATH'] + + if (sake.config.deploy.type === 'wc') { + variables = variables.concat(['WC_CONSUMER_KEY', 'WC_CONSUMER_SECRET']) } - // deploy the plugin - gulp.task('deploy', (done) => { - validateEnvVariables() - - if (!sake.isDeployable()) { - sake.throwError('Plugin is not deployable: \n * ' + sake.getChangelogErrors().join('\n * ')) - } + if (sake.config.deploy.type === 'wp') { + variables = variables.concat(['WP_SVN_USER']) + } - // indicate that we are deploying - sake.options.deploy = true - // ensure scripts and styles are minified - sake.options.minify = true + sake.validateEnvironmentVariables(variables) +} - let tasks = [ - // preflight checks, will fail the deploy on errors - 'prompt:tested_release_zip', - 'deploy:preflight', - // ensure version is bumped - 'bump', - // fetch the latest WP/WC versions & bump the "tested up to" values - 'fetch_latest_wp_wc_versions', - 'bump:minreqs', - // prompt for the version to deploy as - 'prompt:deploy', - function (cb) { - if (sake.options.version === 'skip') { - log.error(chalk.red('Deploy skipped!')) - return done() - } - cb() - }, - // replace version number & date - 'replace:version', - // delete prerelease, if any - 'clean:prerelease', - // build the plugin - compiles and copies to build dir - 'build', - // ensure the required framework version is installed - 'deploy:validate_framework_version', - // grab issues to close with commit - 'github:get_rissue', - // rebuild plugin configuration (version number, etc) - function rebuildPluginConfig (cb) { - sake.buildPluginConfig() - cb() - }, - // git commit & push - 'shell:git_push_update', - // create the zip, which will be attached to the releases - 'compress', - // create releases, attaching the zip - 'deploy_create_releases' - ] +/** + * Deploy the plugin + */ +const deployTask = (done) => { + validateEnvVariables() - if (sake.config.deploy.wooId && sake.config.deploy.type === 'wc') { - tasks.push('prompt:wc_upload') - } + if (!sake.isDeployable()) { + sake.throwError('Plugin is not deployable: \n * ' + sake.getChangelogErrors().join('\n * ')) + } - if (sake.config.deploy.type === 'wp') { - tasks.push('deploy_to_wp_repo') - } + // indicate that we are deploying + sake.options.deploy = true + // ensure scripts and styles are minified + sake.options.minify = true + + let tasks = [ + // preflight checks, will fail the deploy on errors + promptTestedReleaseZipTask, + 'deploy:preflight', + // ensure version is bumped + bumpTask, + // fetch the latest WP/WC versions & bump the "tested up to" values + 'fetch_latest_wp_wc_versions', + bumpMinReqsTask, + // prompt for the version to deploy as + promptDeployTask, + function (cb) { + if (sake.options.version === 'skip') { + log.error(chalk.red('Deploy skipped!')) + return done() + } + cb() + }, + // replace version number & date + 'replace:version', + // delete prerelease, if any + cleanPrereleaseTask, + // build the plugin - compiles and copies to build dir + buildTask, + // ensure the required framework version is installed + deployValidateFrameworkVersionTask, + // grab issues to close with commit + gitHubGetReleaseIssueTask, + // rebuild plugin configuration (version number, etc) + function rebuildPluginConfig (cb) { + sake.buildPluginConfig() + cb() + }, + // git commit & push + shellGitPushUpdateTask, + // create the zip, which will be attached to the releases + compressTask, + // create releases, attaching the zip + 'deploy_create_releases' + ] + + if (sake.config.deploy.wooId && sake.config.deploy.type === 'wc') { + tasks.push(promptWcUploadTask) + } - // finally, create a docs issue, if necessary - tasks.push('github:docs_issue') + if (sake.config.deploy.type === 'wp') { + tasks.push('deploy_to_wp_repo') + } - return gulp.series(tasks)(done) - }) + // finally, create a docs issue, if necessary + tasks.push(gitHubCreateDocsIssueTask) - // run deploy preflight checks - gulp.task('deploy:preflight', (done) => { - let tasks = [ - 'shell:git_ensure_clean_working_copy', - 'validate:readme_headers', - 'lint:scripts', - 'lint:styles' - ] + return gulp.series(tasks)(done) +} +deployTask.displayName = 'deploy' + +/** + * Run deploy preflight checks + */ +const deployPreflightTask = (done) => { + let tasks = [ + shellGitEnsureCleanWorkingCopyTask, + validateReadmeHeadersTask, + lintScriptsTask, + lintStylesTask + ] + + if (sake.config.deploy.type === 'wc') { + tasks.unshift(searchWtUpdateKeyTask) + } - if (sake.config.deploy.type === 'wc') { - tasks.unshift('search:wt_update_key') - } + gulp.parallel(tasks)(done) +} +deployPreflightTask.displayName = 'deploy:preflight' - gulp.parallel(tasks)(done) - }) +const deployValidateFrameworkVersionTask = (done) => { + if (sake.config.framework === 'v5' && sake.getFrameworkVersion() !== sake.getRequiredFrameworkVersion()) { + sake.throwError('Required framework version in composer.json (' + sake.getRequiredFrameworkVersion() + ') and installed framework version (' + sake.getFrameworkVersion() + ') do not match. Halting deploy.') + } - gulp.task('deploy:validate_framework_version', (done) => { - if (sake.config.framework === 'v5' && sake.getFrameworkVersion() !== sake.getRequiredFrameworkVersion()) { - sake.throwError('Required framework version in composer.json (' + sake.getRequiredFrameworkVersion() + ') and installed framework version (' + sake.getFrameworkVersion() + ') do not match. Halting deploy.') + done() +} +deployValidateFrameworkVersionTask.displayName = 'deploy:validate_framework_version' + +/** + * Internal task for making sure the WT updater keys have been set + */ +const searchWtUpdateKeyTask = (done) => { + fs.readFile(`${sake.config.paths.src}/${sake.config.plugin.mainFile}`, 'utf8', (err, data) => { + if (err) sake.throwError(err) + + // matches " * Woo: ProductId:ProductKey" in the main plugin file PHPDoc + const phpDocMatch = data.match(/\s*\*\s*Woo:\s*\d*:(.+)/ig) + // matches legacy woothemes_queue_update() usage in the main plugin file + const phpFuncMatch = data.match(/woothemes_queue_update\s*\(\s*plugin_basename\s*\(\s*__FILE__\s*\)\s*,\s*'(.+)'\s*,\s*'(\d+)'\s*\);/ig) + + // throw an error if no WT keys have been found with either method + if (!phpDocMatch && !phpFuncMatch) { + sake.throwError('WooThemes updater keys for the plugin have not been properly set ;(') } done() }) +} +searchWtUpdateKeyTask.displayName = 'search:wt_update_key' - // internal task for making sure the WT updater keys have been set - gulp.task('search:wt_update_key', (done) => { - fs.readFile(`${sake.config.paths.src}/${sake.config.plugin.mainFile}`, 'utf8', (err, data) => { - if (err) sake.throwError(err) +export { + deployTask, + deployPreflightTask, + deployValidateFrameworkVersionTask, + searchWtUpdateKeyTask +} - // matches " * Woo: ProductId:ProductKey" in the main plugin file PHPDoc - let phpDocMatch = data.match(/\s*\*\s*Woo:\s*\d*:(.+)/ig) - // matches legacy woothemes_queue_update() usage in the main plugin file - let phpFuncMatch = data.match(/woothemes_queue_update\s*\(\s*plugin_basename\s*\(\s*__FILE__\s*\)\s*,\s*'(.+)'\s*,\s*'(\d+)'\s*\);/ig) +module.exports = (gulp, plugins, sake) => { - // throw an error if no WT keys have been found with either method - if (!phpDocMatch && !phpFuncMatch) { - sake.throwError('WooThemes updater keys for the plugin have not been properly set ;(') - } - done() - }) - }) // internal task for replacing version and date when deploying gulp.task('replace:version', () => { From 59a5cca5de4899b9ae2db1eaf94057dfd668dc37 Mon Sep 17 00:00:00 2001 From: Ashley Gibson Date: Mon, 17 Mar 2025 10:56:49 +0000 Subject: [PATCH 32/45] Rework deploy tasks --- tasks/build.js | 4 +- tasks/copy.js | 36 ++-- tasks/deploy.js | 500 ++++++++++++++++++++++++++---------------------- tasks/prompt.js | 4 +- tasks/wc.js | 18 +- 5 files changed, 303 insertions(+), 259 deletions(-) diff --git a/tasks/build.js b/tasks/build.js index 53b65b2..9825557 100644 --- a/tasks/build.js +++ b/tasks/build.js @@ -4,7 +4,7 @@ import sake from '../lib/sake.js' import { cleanBuildTask, cleanComposerTask } from './clean.js' import { shellComposerInstallTask, shellComposerStatusTask } from './shell.js' import { compile } from './compile.js' -import { copyBuild } from './copy.js' +import { copyBuildTask } from './copy.js' /** * The main task for building the plugin: @@ -14,7 +14,7 @@ import { copyBuild } from './copy.js' * - Copies plugin files to the build directory */ const buildTask = (done) => { - let tasks = [cleanBuildTask, shellComposerStatusTask, cleanComposerTask, shellComposerInstallTask, compile, 'bundle', copyBuild] // @TODO replace remaining + let tasks = [cleanBuildTask, shellComposerStatusTask, cleanComposerTask, shellComposerInstallTask, compile, 'bundle', copyBuildTask] // @TODO replace remaining if (sake.options['skip-composer']) { tasks = _.without(tasks, shellComposerStatusTask, cleanComposerTask, shellComposerInstallTask) diff --git a/tasks/copy.js b/tasks/copy.js index 5c668d4..6f99f5c 100644 --- a/tasks/copy.js +++ b/tasks/copy.js @@ -8,7 +8,7 @@ import gulpFilter from 'gulp-filter' /** * Copy files from source to build */ -const copyBuild = (done) => { +const copyBuildTask = (done) => { const filter = gulpFilter(['**/*.min.css', '**/*.min.js'], { restore: true }) let paths = [ @@ -164,12 +164,12 @@ const copyBuild = (done) => { .pipe(filter.restore) .pipe(gulp.dest(`${sake.config.paths.build}/${sake.config.plugin.id}`)) } -copyBuild.displayName = 'copy:build' +copyBuildTask.displayName = 'copy:build' /** * Copy plugin zip and changelog to prereleases folder */ -const copyPrerelease = (done) => { +const copyPrereleaseTask = (done) => { let filename = sake.config.deploy.type === 'wp' ? 'readme' : 'changelog' const filter = gulpFilter([`**/${filename}.txt`], { restore: true }) @@ -182,45 +182,45 @@ const copyPrerelease = (done) => { .pipe(filter.restore) .pipe(gulp.dest(sake.getPrereleasesPath())) } -copyPrerelease.displayName = 'copy:prerelease' +copyPrereleaseTask.displayName = 'copy:prerelease' /** * Copy files from build to WC repo folder */ -const copyWcRepo = (done) => { +const copyWcRepoTask = (done) => { return gulp.src(`${sake.config.paths.build}/${sake.config.plugin.id}/**/*`).pipe(gulp.dest(sake.getProductionRepoPath())) } -copyWcRepo.displayName = 'copy:wc_repo' +copyWcRepoTask.displayName = 'copy:wc_repo' /** * Copy files from build to WP trunk folder */ -const copyWpTrunk = (done) => { +const copyWpTrunkTask = (done) => { return gulp.src(`${sake.config.paths.build}/${sake.config.plugin.id}/**/*`).pipe(gulp.dest(path.join(sake.getProductionRepoPath(), 'trunk'))) } -copyWpTrunk.displayName = 'copy:wp_trunk' +copyWpTrunkTask.displayName = 'copy:wp_trunk' /** * Copy files from build to WP assets folder */ -const copyWpAssets = (done) => { +const copyWpAssetsTask = (done) => { return gulp.src(`${sake.config.paths.wpAssets}/**/*`).pipe(gulp.dest(path.join(sake.getProductionRepoPath(), 'assets'))) } -copyWpAssets.displayName = 'copy:wp_assets' +copyWpAssetsTask.displayName = 'copy:wp_assets' /** * Copy files from WP trunk to tag */ -const copyWpTag = (done) => { +const copyWpTagTask = (done) => { return gulp.src(path.join(sake.getProductionRepoPath(), 'trunk/**/*')).pipe(gulp.dest(path.join(sake.getProductionRepoPath(), 'tags', sake.getPluginVersion()))) } -copyWpTag.displayName = 'copy:wp_tag' +copyWpTagTask.displayName = 'copy:wp_tag' export { - copyBuild, - copyPrerelease, - copyWcRepo, - copyWpTrunk, - copyWpAssets, - copyWpTag + copyBuildTask, + copyPrereleaseTask, + copyWcRepoTask, + copyWpTrunkTask, + copyWpAssetsTask, + copyWpTagTask } diff --git a/tasks/deploy.js b/tasks/deploy.js index 1522dd3..200f6f1 100644 --- a/tasks/deploy.js +++ b/tasks/deploy.js @@ -6,15 +6,33 @@ import log from 'fancy-log'; import chalk from 'chalk'; import sake from '../lib/sake.js' import gulp from 'gulp' +import filter from 'gulp-filter' +import replace from 'gulp-replace' +import replaceTask from 'gulp-replace-task' import { promptDeployTask, promptTestedReleaseZipTask, promptWcUploadTask } from './prompt.js' import { bumpMinReqsTask, bumpTask } from './bump.js' -import { cleanPrereleaseTask } from './clean.js' +import { cleanPrereleaseTask, cleanWcRepoTask, cleanWpAssetsTask, cleanWpTrunkTask } from './clean.js' import { buildTask } from './build.js' -import { gitHubCreateDocsIssueTask, gitHubGetReleaseIssueTask } from './github.js' -import { shellGitEnsureCleanWorkingCopyTask, shellGitPushUpdateTask } from './shell.js' +import { + gitHubCreateDocsIssueTask, + gitHubCreateReleaseTask, + gitHubGetReleaseIssueTask, + gitHubGetWcIssuesTask +} from './github.js' +import { + shellGitEnsureCleanWorkingCopyTask, + shellGitPullWcRepoTask, + shellGitPushUpdateTask, + shellGitPushWcRepoTask, + shellGitUpdateWcRepoTask, shellSvnCheckoutTask, + shellSvnCommitAssetsTask, + shellSvnCommitTagTask, + shellSvnCommitTrunkTask +} from './shell.js' import { compressTask } from './zip.js' import { validateReadmeHeadersTask } from './validate.js' import { lintScriptsTask, lintStylesTask } from './lint.js' +import { copyWcRepoTask, copyWpAssetsTask, copyWpTagTask, copyWpTrunkTask } from './copy.js' let validatedEnvVariables = false @@ -54,11 +72,11 @@ const deployTask = (done) => { let tasks = [ // preflight checks, will fail the deploy on errors promptTestedReleaseZipTask, - 'deploy:preflight', + deployPreflightTask, // ensure version is bumped bumpTask, // fetch the latest WP/WC versions & bump the "tested up to" values - 'fetch_latest_wp_wc_versions', + fetchLatestWpWcVersionsTask, bumpMinReqsTask, // prompt for the version to deploy as promptDeployTask, @@ -70,7 +88,7 @@ const deployTask = (done) => { cb() }, // replace version number & date - 'replace:version', + replaceVersionTask, // delete prerelease, if any cleanPrereleaseTask, // build the plugin - compiles and copies to build dir @@ -89,7 +107,7 @@ const deployTask = (done) => { // create the zip, which will be attached to the releases compressTask, // create releases, attaching the zip - 'deploy_create_releases' + deployCreateReleasesTask, ] if (sake.config.deploy.wooId && sake.config.deploy.type === 'wc') { @@ -97,7 +115,7 @@ const deployTask = (done) => { } if (sake.config.deploy.type === 'wp') { - tasks.push('deploy_to_wp_repo') + tasks.push(deployToWpRepoTask) } // finally, create a docs issue, if necessary @@ -157,260 +175,286 @@ const searchWtUpdateKeyTask = (done) => { } searchWtUpdateKeyTask.displayName = 'search:wt_update_key' -export { - deployTask, - deployPreflightTask, - deployValidateFrameworkVersionTask, - searchWtUpdateKeyTask -} +/** + * Internal task for replacing the version and date when deploying + */ +const replaceVersionTask = (done) => { + if (!sake.getVersionBump()) { + sake.throwError('No version replacement specified') + } -module.exports = (gulp, plugins, sake) => { + const versions = sake.getPrereleaseVersions(sake.getPluginVersion()) + const versionReplacements = versions.map(version => { + return { match: version, replacement: () => sake.getVersionBump() } + }) + const filterChangelog = filter('**/{readme.md,readme.txt,changelog.txt}', { restore: true }) + const date = dateFormat(new Date(), 'yyyy.mm.dd') + + let paths = [ + `${sake.config.paths.src}/**/*.php`, + `${sake.config.paths.src}/readme.md`, + `${sake.config.paths.src}/readme.txt`, + `${sake.config.paths.src}/changelog.txt`, + `!${sake.config.paths.src}/*.json`, + `!${sake.config.paths.src}/*.xml`, + `!${sake.config.paths.src}/*.yml` + ] + if (fs.existsSync(sake.config.paths.assetPaths.js)) { + paths.concat([ + `${sake.config.paths.assetPaths.js}/**/*.{coffee,js}`, + `!${sake.config.paths.assetPaths.js}/**/*.min.js`, + ]) + } - // internal task for replacing version and date when deploying - gulp.task('replace:version', () => { - if (!sake.getVersionBump()) { - sake.throwError('No version replacement specified') - } + if (fs.existsSync(sake.config.paths.assetPaths.css)) { + paths.concat([ + `${sake.config.paths.assetPaths.css}/**/*.scss`, + `${sake.config.paths.assetPaths.css}/**/*.css`, + ]) + } - const versions = sake.getPrereleaseVersions(sake.getPluginVersion()) - const versionReplacements = versions.map(version => { - return { match: version, replacement: () => sake.getVersionBump() } - }) - - const filterChangelog = plugins.filter('**/{readme.md,readme.txt,changelog.txt}', { restore: true }) - const date = dateFormat(new Date(), 'yyyy.mm.dd') - - let paths = [ - `${sake.config.paths.src}/**/*.php`, - `${sake.config.paths.src}/readme.md`, - `${sake.config.paths.src}/readme.txt`, - `${sake.config.paths.src}/changelog.txt`, - `!${sake.config.paths.src}/*.json`, - `!${sake.config.paths.src}/*.xml`, - `!${sake.config.paths.src}/*.yml` - ] - - if (fs.existsSync(sake.config.paths.assetPaths.js)) { - paths.concat([ - `${sake.config.paths.assetPaths.js}/**/*.{coffee,js}`, - `!${sake.config.paths.assetPaths.js}/**/*.min.js`, - ]) - } + if (fs.existsSync(`!${sake.config.paths.src}/lib`)) { + paths.push(`!${sake.config.paths.src}/lib/**`) + } - if (fs.existsSync(sake.config.paths.assetPaths.css)) { - paths.concat([ - `${sake.config.paths.assetPaths.css}/**/*.scss`, - `${sake.config.paths.assetPaths.css}/**/*.css`, - ]) - } + if (fs.existsSync(`!${sake.config.paths.src}/vendor`)) { + paths.push(`!${sake.config.paths.src}/vendor/**`) + } - if (fs.existsSync(`!${sake.config.paths.src}/lib`)) { - paths.push(`!${sake.config.paths.src}/lib/**`) - } + if (fs.existsSync(`!${sake.config.paths.src}/tests`)) { + paths.push(`!${sake.config.paths.src}/tests/**`) + } - if (fs.existsSync(`!${sake.config.paths.src}/vendor`)) { - paths.push(`!${sake.config.paths.src}/vendor/**`) - } + if (fs.existsSync(`!${sake.config.paths.src}/node_modules`)) { + paths.push(`!${sake.config.paths.src}/node_modules/**`) + } - if (fs.existsSync(`!${sake.config.paths.src}/tests`)) { - paths.push(`!${sake.config.paths.src}/tests/**`) - } + return gulp.src(paths, { base: './', allowEmpty: true }) + // unlike gulp-replace, gulp-replace-task supports multiple replacements + .pipe(replaceTask({ patterns: versionReplacements, usePrefix: false })) + .pipe(filterChangelog) + .pipe(replace(/[0-9]+\.nn\.nn/, date)) + .pipe(filterChangelog.restore) + .pipe(gulp.dest('./')) +} +replaceVersionTask.displayName = 'replace:version' - if (fs.existsSync(`!${sake.config.paths.src}/node_modules`)) { - paths.push(`!${sake.config.paths.src}/node_modules/**`) - } +/** + * Grab any issues to close with the deploy + */ +const getIssuesToCloseTask = (done) => { + let tasks = [gitHubGetReleaseIssueTask] - return gulp.src(paths, { base: './', allowEmpty: true }) - // unlike gulp-replace, gulp-replace-task supports multiple replacements - .pipe(plugins.replaceTask({ patterns: versionReplacements, usePrefix: false })) - .pipe(filterChangelog) - .pipe(plugins.replace(/[0-9]+\.nn\.nn/, date)) - .pipe(filterChangelog.restore) - .pipe(gulp.dest('./')) - }) + if (sake.config.deploy.type === 'wc') { + tasks.push(gitHubGetWcIssuesTask) + } - /** - * Grab any issues to close with the deploy - */ - gulp.task('get_issues_to_close', (done) => { - let tasks = ['github:get_rissue'] + gulp.series(tasks)(done) +} +getIssuesToCloseTask.displayName = 'get_issues_to_close' - if (sake.config.deploy.type === 'wc') { - tasks.push('github:get_wc_issues') - } +/** + * Create releases for a deploy + * + * This task is especially useful if your deploy failed before the release + * creating step or you need to re-create the releases for some reason + */ +const deployCreateReleasesTask = (done) => { + // TODO: consider using async or similar to hide the anonymous tasks from gulp, see: https://github.com/gulpjs/gulp/issues/1143 - gulp.series(tasks)(done) - }) + let tasks = [ + function (cb) { + sake.options.owner = sake.config.deploy.dev.owner + sake.options.repo = sake.config.deploy.dev.name + sake.options.prefix_release_tag = sake.config.multiPluginRepo + cb() + }, + gitHubCreateReleaseTask + ] - /** - * Create releases for a deploy - * - * This task is especially useful if your deploy failed before the release - * creating step or you need to re-create the releases for some reason - */ - gulp.task('deploy_create_releases', (done) => { - // TODO: consider using async or similar to hide the anonymous tasks from gulp, see: https://github.com/gulpjs/gulp/issues/1143 - - let tasks = [ - function (cb) { - sake.options.owner = sake.config.deploy.dev.owner - sake.options.repo = sake.config.deploy.dev.name - sake.options.prefix_release_tag = sake.config.multiPluginRepo - cb() - }, - 'github:create_release' - ] - - return gulp.series(tasks)(done) - }) + return gulp.series(tasks)(done) +} +deployCreateReleasesTask.displayName = 'deploy_create_releases' - // main task for deploying the plugin after build to the production repo - gulp.task('deploy_to_production_repo', (done) => { - let tasks = [] - - if (sake.config.deploy.type === 'wc') { - tasks.push('deploy_to_wc_repo') - } else if (sake.config.deploy.type === 'wp') { - tasks.push('deploy_to_wp_repo') - } else { - log.warn(chalk.yellow('No deploy type set, skipping deploy to remote repo')) - return done() - } +/** + * Main task for deploying the plugin after build to the production repo + * @deprecated + */ +const deployToProductionRepoTask = (done) => { + let tasks = [] - gulp.series(tasks)(done) - }) + if (sake.config.deploy.type === 'wc') { + tasks.push(deployToWcRepoTask) + } else if (sake.config.deploy.type === 'wp') { + tasks.push(deployToWpRepoTask) + } else { + log.warn(chalk.yellow('No deploy type set, skipping deploy to remote repo')) + return done() + } - /** WooCommerce repo related tasks ****************************************/ + gulp.series(tasks)(done) +} +deployToProductionRepoTask.displayName = 'deploy_to_production_repo' - // deploy to WC repo - gulp.task('deploy_to_wc_repo', (done) => { - validateEnvVariables() +/** WooCommerce repo related tasks ****************************************/ - gulp.series('copy_to_wc_repo', 'shell:git_push_wc_repo')(done) - }) +/** + * Deploy to WC repo + * @deprecated + */ +const deployToWcRepoTask = (done) => { + validateEnvVariables() - /** - * Copy to WC repo - * - * Helper task which copies files to WC repo (used by update_wc_repo) - * - * Builds the plugin, pulls chances from the WC repo, cleans the local WC - * repo clone, and then copies built plugin to clone - */ - gulp.task('copy_to_wc_repo', (done) => { - validateEnvVariables() - - let tasks = [ - // copy files to build directory - 'build', - // ensure WC repo is up to date - 'shell:git_pull_wc_repo', - // clean the WC plugin dir - 'clean:wc_repo', - // copy files from build to WC repo directory - 'copy:wc_repo' - ] - - // no need to build when part of deploy process - if (sake.options.deploy) { - tasks.shift() - } + gulp.series(copyToWcRepoTask, shellGitPushWcRepoTask)(done) +} +deployToWcRepoTask.displayName = 'deploy_to_wc_repo' - gulp.series(tasks)(done) - }) +/** + * Copy to WC repo + * + * Helper task which copies files to WC repo (used by {@see updateWcRepoTask()}) + * + * Builds the plugin, pulls chances from the WC repo, cleans the local WC + * repo clone, and then copies built plugin to clone + * @deprecated + */ +const copyToWcRepoTask = (done) => { + validateEnvVariables() - // TODO: do we need this anymore? - /** - * Update WC repo - * - * Builds and copies plugin to WC repo then pushes a general "Updating {plugin name}" - * commit. This is not a very useful task as it was created many moons ago to allow - * us to quickly fix issues with the deploy (such as extra files, etc). The - * task remains for posterity - */ - gulp.task('update_wc_repo', (done) => { - validateEnvVariables() - - gulp.series('copy_to_wc_repo', 'shell:git_update_wc_repo')(done) - }) + let tasks = [ + // copy files to build directory + buildTask, + // ensure WC repo is up to date + shellGitPullWcRepoTask, + // clean the WC plugin dir + cleanWcRepoTask, + // copy files from build to WC repo directory + copyWcRepoTask, + ] - /** WP.org deploy related tasks ****************************************/ + // no need to build when part of deploy process + if (sake.options.deploy) { + tasks.shift() + } - gulp.task('deploy_to_wp_repo', (done) => { - let tasks = ['copy_to_wp_repo', 'shell:svn_commit_trunk'] + gulp.series(tasks)(done) +} +copyToWcRepoTask.displayName = 'copy_to_wc_repo' - sake.options = _.merge({ - deployTag: true, - deployAssets: true - }, sake.options) +/** + * @TODO: do we need this anymore? + * + * Update WC repo + * + * Builds and copies plugin to WC repo then pushes a general "Updating {plugin name}" + * commit. This is not a very useful task as it was created many moons ago to allow + * us to quickly fix issues with the deploy (such as extra files, etc). The + * task remains for posterity + * @deprecated + */ +const updateWcRepoTask = (done) => { + validateEnvVariables() - if (sake.options.deployTag) { - tasks.push('copy:wp_tag') - tasks.push('shell:svn_commit_tag') - } + gulp.series(copyToWcRepoTask, shellGitUpdateWcRepoTask)(done) +} +updateWcRepoTask.displayName = 'update_wc_repo' - if (sake.options.deployAssets) { - tasks.push('clean:wp_assets') - tasks.push('copy:wp_assets') - tasks.push('shell:svn_commit_assets') - } +/** WP.org deploy related tasks ****************************************/ - gulp.series(tasks)(done) - }) +const deployToWpRepoTask = (done) => { + let tasks = [copyToWpRepoTask, shellSvnCommitTrunkTask] - gulp.task('copy_to_wp_repo', (done) => { - let tasks = [ - // copy files to build directory - 'build', - // ensure WP repo is up to date - 'shell:svn_checkout', - // clean the WC plugin dir - 'clean:wp_trunk', - // copy files from build to WP repo directory - 'copy:wp_trunk' - ] - - // no need to build when part of deploy process - if (sake.options.deploy) { - tasks.shift() - } + sake.options = _.merge({ + deployTag: true, + deployAssets: true + }, sake.options) - gulp.series(tasks)(done) - }) + if (sake.options.deployTag) { + tasks.push(copyWpTagTask) + tasks.push(shellSvnCommitTagTask) + } - gulp.task('fetch_latest_wp_wc_versions', (done) => { - log.info('Fetching latest WP and WC versions') + if (sake.options.deployAssets) { + tasks.push(cleanWpAssetsTask) + tasks.push(copyWpAssetsTask) + tasks.push(shellSvnCommitAssetsTask) + } - let requests = [] + gulp.series(tasks)(done) +} +deployToWpRepoTask.displayName = 'deploy_to_wp_repo' - // only fetch the latest if a version is specified - // this allows us to set to a version that isn't yet released - if (!sake.options.tested_up_to_wp_version) { - requests.push( - axios.get('https://api.wordpress.org/core/version-check/1.7/') - .then(res => { - sake.options.tested_up_to_wp_version = res.data.offers[0].version - }) - ) - } +const copyToWpRepoTask = (done) => { + let tasks = [ + // copy files to build directory + buildTask, + // ensure WP repo is up to date + shellSvnCheckoutTask, + // clean the WC plugin dir + cleanWpTrunkTask, + // copy files from build to WP repo directory + copyWpTrunkTask + ] - if (sake.config.platform === 'wc' && !sake.options.tested_up_to_wc_version) { - requests.push( - axios.get('https://api.wordpress.org/plugins/info/1.0/woocommerce.json') - .then(res => { - if (res.data.error) { - throw res.data.error - } - - sake.options.tested_up_to_wc_version = res.data.version - }) - ) - } + // no need to build when part of deploy process + if (sake.options.deploy) { + tasks.shift() + } - axios.all(requests) - .then(() => done()) - .catch(err => sake.throwDeferredError('An error occurred when fetching latest WP / WC versions: ' + err.toString())) - }) + gulp.series(tasks)(done) +} +copyToWpRepoTask.displayName = 'copy_to_wp_repo' + +const fetchLatestWpWcVersionsTask = (done) => { + log.info('Fetching latest WP and WC versions') + + let requests = [] + + // only fetch the latest if a version is specified + // this allows us to set to a version that isn't yet released + if (!sake.options.tested_up_to_wp_version) { + requests.push( + axios.get('https://api.wordpress.org/core/version-check/1.7/') + .then(res => { + sake.options.tested_up_to_wp_version = res.data.offers[0].version + }) + ) + } + + if (sake.config.platform === 'wc' && !sake.options.tested_up_to_wc_version) { + requests.push( + axios.get('https://api.wordpress.org/plugins/info/1.0/woocommerce.json') + .then(res => { + if (res.data.error) { + throw res.data.error + } + + sake.options.tested_up_to_wc_version = res.data.version + }) + ) + } + + axios.all(requests) + .then(() => done()) + .catch(err => sake.throwDeferredError('An error occurred when fetching latest WP / WC versions: ' + err.toString())) +} +fetchLatestWpWcVersionsTask.displayName = 'fetch_latest_wp_wc_versions' + +export { + deployTask, + deployPreflightTask, + deployValidateFrameworkVersionTask, + searchWtUpdateKeyTask, + replaceVersionTask, + getIssuesToCloseTask, + deployCreateReleasesTask, + deployToProductionRepoTask, + deployToWcRepoTask, + copyToWcRepoTask, + updateWcRepoTask, + deployToWpRepoTask, + copyToWpRepoTask, + fetchLatestWpWcVersionsTask } diff --git a/tasks/prompt.js b/tasks/prompt.js index dbea1eb..94f4392 100644 --- a/tasks/prompt.js +++ b/tasks/prompt.js @@ -5,7 +5,7 @@ import chalk from 'chalk' import _ from 'lodash' import sake from '../lib/sake.js' import gulp from 'gulp' -import { wcDeploy } from './wc.js' +import { wcDeployTask } from './wc.js' function filterIncrement (value) { if (value[1] === 'custom') { @@ -108,7 +108,7 @@ const promptWcUploadTask = (done) => { message: 'Upload plugin to WooCommerce.com?' }]).then((answers) => { if (answers.upload_to_wc) { - gulp.series(wcDeploy)(done) + gulp.series(wcDeployTask)(done) } else { log.error(chalk.red('Skipped uploading to WooCommerce.com')) done() diff --git a/tasks/wc.js b/tasks/wc.js index c681113..c7345fb 100644 --- a/tasks/wc.js +++ b/tasks/wc.js @@ -26,7 +26,7 @@ let formatError = (err) => { /** * Internal task to validate whether the plugin can be deployed to WooCommerce.com */ -const wcValidate = (done) => { +const wcValidateTask = (done) => { log.info('Making sure plugin is deployable...') let url = getApiURL('deploy/status') @@ -81,12 +81,12 @@ const wcValidate = (done) => { }) } -wcValidate.displayName = 'wc:validate' +wcValidateTask.displayName = 'wc:validate' /** * Internal task the handles the zip file upload */ -const wcUpload = (done) => { +const wcUploadTask = (done) => { let version = sake.getPluginVersion() let zipPath = path.join(process.cwd(), sake.config.paths.build, `${sake.config.plugin.id}.${version}.zip`) @@ -141,16 +141,16 @@ const wcUpload = (done) => { }) } -wcUpload.displayName = 'wc:upload' +wcUploadTask.displayName = 'wc:upload' /** * The main task to deploy woocommerce.com plugins */ -const wcDeploy = gulpSeries(wcValidate, wcUpload) -wcDeploy.displayName = 'wc:deploy' +const wcDeployTask = gulpSeries(wcValidateTask, wcUploadTask) +wcDeployTask.displayName = 'wc:deploy' export { - wcValidate, - wcUpload, - wcDeploy + wcValidateTask, + wcUploadTask, + wcDeployTask } From d0bae0fc211c441e8e59029d018acf5d3ac34337 Mon Sep 17 00:00:00 2001 From: Ashley Gibson Date: Mon, 17 Mar 2025 11:00:04 +0000 Subject: [PATCH 33/45] Update prerelease tasks --- tasks/deploy.js | 4 +-- tasks/prerelease.js | 69 +++++++++++++++++++++++++++------------------ tasks/zip.js | 8 +++--- 3 files changed, 47 insertions(+), 34 deletions(-) diff --git a/tasks/deploy.js b/tasks/deploy.js index 200f6f1..a7d8fd4 100644 --- a/tasks/deploy.js +++ b/tasks/deploy.js @@ -29,7 +29,7 @@ import { shellSvnCommitTagTask, shellSvnCommitTrunkTask } from './shell.js' -import { compressTask } from './zip.js' +import { zipTask } from './zip.js' import { validateReadmeHeadersTask } from './validate.js' import { lintScriptsTask, lintStylesTask } from './lint.js' import { copyWcRepoTask, copyWpAssetsTask, copyWpTagTask, copyWpTrunkTask } from './copy.js' @@ -105,7 +105,7 @@ const deployTask = (done) => { // git commit & push shellGitPushUpdateTask, // create the zip, which will be attached to the releases - compressTask, + zipTask, // create releases, attaching the zip deployCreateReleasesTask, ] diff --git a/tasks/prerelease.js b/tasks/prerelease.js index 60c56ed..4421adb 100644 --- a/tasks/prerelease.js +++ b/tasks/prerelease.js @@ -1,36 +1,49 @@ import fs from 'node:fs' +import sake from '../lib/sake.js' +import gulp from 'gulp' +import { bumpTask } from './bump.js' +import { zipTask } from './zip.js' +import { cleanBuildTask, cleanPrereleaseTask } from './clean.js' +import { copyPrereleaseTask } from './copy.js' + +// validate env variables before deploying a prerelease +function validateEnvVariables () { + let errors = [] + let prereleasePath = '' + + if (process.env.SAKE_PRE_RELEASE_PATH) { + prereleasePath = sake.resolvePath(process.env.SAKE_PRE_RELEASE_PATH) + } else { + errors.push('SAKE_PRE_RELEASE_PATH not set') + } + + if (prereleasePath && !fs.existsSync(prereleasePath)) { + errors.push(`SAKE_PRE_RELEASE_PATH is invalid - the path '${prereleasePath}' does not exist`) + } -module.exports = (gulp, plugins, sake) => { - // validate env variables before deploying a prerelease - function validateEnvVariables () { - let errors = [] - let prereleasePath = '' - - if (process.env.SAKE_PRE_RELEASE_PATH) { - prereleasePath = sake.resolvePath(process.env.SAKE_PRE_RELEASE_PATH) - } else { - errors.push('SAKE_PRE_RELEASE_PATH not set') - } - - if (prereleasePath && !fs.existsSync(prereleasePath)) { - errors.push(`SAKE_PRE_RELEASE_PATH is invalid - the path '${prereleasePath}' does not exist`) - } - - if (errors.length) { - sake.throwError('Environment variables missing or invalid: \n * ' + errors.join('\n * ')) - } + if (errors.length) { + sake.throwError('Environment variables missing or invalid: \n * ' + errors.join('\n * ')) } +} - // bumps the version in the main plugin file to match changelog.txt - gulp.task('prerelease', (done) => { - validateEnvVariables() +/** + * Bumps the version in the main plugin file to match changelog.txt + */ +const prereleaseTask = (done) => { + validateEnvVariables() - if (!sake.isDeployable()) { - sake.throwError('Plugin is not deployable: \n * ' + sake.getChangelogErrors().join('\n * ')) - } + if (!sake.isDeployable()) { + sake.throwError('Plugin is not deployable: \n * ' + sake.getChangelogErrors().join('\n * ')) + } + + gulp.series(bumpTask, zipTask, cleanPrereleaseTask, copyPrereleaseTask, cleanBuildTask)(done) +} +prereleaseTask.displayName = 'prerelease' - gulp.series('bump', 'zip', 'clean:prerelease', 'copy:prerelease', 'clean:build')(done) - }) +const preTask = gulp.parallel(prereleaseTask) +preTask.displayName = 'pre' - gulp.task('pre', gulp.parallel('prerelease')) +export { + prereleaseTask, + preTask } diff --git a/tasks/zip.js b/tasks/zip.js index 0eb1804..7931949 100644 --- a/tasks/zip.js +++ b/tasks/zip.js @@ -3,7 +3,7 @@ import gulp from 'gulp' import zip from 'gulp-zip' import { buildTask } from './build.js' -const compressTask = (done) => { +const zipTask = (done) => { let zipDest = sake.options.zipDest || sake.config.paths.build let zipFileName = sake.config.plugin.id + '.' + sake.getPluginVersion() + '.zip' @@ -16,12 +16,12 @@ const compressTask = (done) => { .pipe(zip(zipFileName)) .pipe(gulp.dest(sake.config.paths.zipDest)) } -compressTask.displayName = 'compress' +zipTask.displayName = 'compress' -const buildAndZip = gulp.series(buildTask, compressTask) +const buildAndZip = gulp.series(buildTask, zipTask) buildAndZip.displayName = 'zip' export { - compressTask, + zipTask, buildAndZip } From c0a821b67f595eb50e743b60d0ff42309a1a63e4 Mon Sep 17 00:00:00 2001 From: Ashley Gibson Date: Mon, 17 Mar 2025 12:46:11 +0000 Subject: [PATCH 34/45] Update upfw tasks --- gulpfile.js | 5 ++- tasks/upfw.js | 89 +++++++++++++++++++++++++++++---------------------- 2 files changed, 55 insertions(+), 39 deletions(-) diff --git a/gulpfile.js b/gulpfile.js index 2ae1e91..ec5dfe9 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -70,15 +70,18 @@ export * from './tasks/clean.js' export * from './tasks/compile.js' export * from './tasks/config.js' export * from './tasks/copy.js' -export * from './tasks/imagemin.js' export * from './tasks/decaffeinate.js' +export * from './tasks/deploy.js' export * from './tasks/github.js' +export * from './tasks/imagemin.js' export * from './tasks/lint.js' export * from './tasks/makepot.js' +export * from './tasks/prerelease.js' export * from './tasks/prompt.js' export * from './tasks/scripts.js' export * from './tasks/shell.js' export * from './tasks/styles.js' +export * from './tasks/upfw.js' export * from './tasks/validate.js' export * from './tasks/watch.js' export * from './tasks/wc.js' diff --git a/tasks/upfw.js b/tasks/upfw.js index 8cd306e..e213bd3 100644 --- a/tasks/upfw.js +++ b/tasks/upfw.js @@ -1,48 +1,61 @@ import fs from 'node:fs' import path from 'node:path' import dottie from 'dottie' - -module.exports = (gulp, plugins, sake) => { - // reload the framework version after updating the framework - gulp.task('set_framework_version', (done) => { - sake.config.plugin.frameworkVersion = sake.getFrameworkVersion() - done() - }) - - // update framework to a specific version or branch - // example use: `sake upfw` or `sake upfw --backwards_compatible=4.4 --minimum_wc_version=2.5.5 --tested_up_to_wc_version=2.7.0 --minimum_wp_version=4.1 --tested_up_to_wp_version=4.6` - gulp.task('upfw', (done) => { - let tasks = [ - 'set_framework_version', - 'bump:minreqs', - 'shell:update_framework_commit' - ] - - if (sake.config.framework === 'v4' && !dottie.get(sake.config.composer, 'require.skyverge/wc-plugin-framework')) { - tasks.unshift('shell:update_framework') - } - - if (sake.config.framework === 'v5') { - tasks.unshift('bump:framework_version') +import sake from '../lib/sake' +import gulp from 'gulp' +import { bumpFrameworkVersionTask, bumpMinReqsTask } from './bump.js' +import { shellComposerUpdateTask, shellUpdateFrameworkCommitTask, shellUpdateFrameworkTask } from './shell.js' + +/** + * Reload the framework version after updating the framework + */ +const setFrameworkVersionTask = (done) => { + sake.config.plugin.frameworkVersion = sake.getFrameworkVersion() + done() +} +setFrameworkVersionTask.displayName = 'set_framework_version' + +/** + * Update the framework to a specific version or branch + * example use: `sake upfw` or `sake upfw --backwards_compatible=4.4 --minimum_wc_version=2.5.5 --tested_up_to_wc_version=2.7.0 --minimum_wp_version=4.1 --tested_up_to_wp_version=4.6` + */ +const updateFrameworkTask = (done) => { + let tasks = [ + setFrameworkVersionTask, + bumpMinReqsTask, + shellUpdateFrameworkCommitTask + ] + + if (sake.config.framework === 'v4' && !dottie.get(sake.config.composer, 'require.skyverge/wc-plugin-framework')) { + tasks.unshift(shellUpdateFrameworkTask) + } + + if (sake.config.framework === 'v5') { + tasks.unshift(bumpFrameworkVersionTask) + } + + // update composer + if (!sake.options['skip-composer-update']) { + // ensure FW version to update to is specified + if (!sake.options.framework_version) { + sake.throwError('Framework version not specified') } - // update composer - if (!sake.options['skip-composer-update']) { - // ensure FW version to update to is specified - if (!sake.options.framework_version) { - sake.throwError('Framework version not specified') - } + dottie.set(sake.config.composer, 'require.skyverge/wc-plugin-framework', sake.options.framework_version) - dottie.set(sake.config.composer, 'require.skyverge/wc-plugin-framework', sake.options.framework_version) + // update composer.json + fs.writeFileSync(path.join(process.cwd(), 'composer.json'), JSON.stringify(sake.config.composer, null, ' ')) - // update composer.json - fs.writeFileSync(path.join(process.cwd(), 'composer.json'), JSON.stringify(sake.config.composer, null, ' ')) + tasks.unshift(shellComposerUpdateTask) + } else { + sake.options.framework_version = sake.config.plugin.frameworkVersion + } - tasks.unshift('shell:composer_update') - } else { - sake.options.framework_version = sake.config.plugin.frameworkVersion - } + gulp.series(tasks)(done) +} +updateFrameworkTask.displayName = 'upfw' - gulp.series(tasks)(done) - }) +export { + setFrameworkVersionTask, + updateFrameworkTask } From 1291ccdec7ad3f5b5ebf386cdb7e4339a75c230a Mon Sep 17 00:00:00 2001 From: Ashley Gibson Date: Mon, 17 Mar 2025 12:52:43 +0000 Subject: [PATCH 35/45] Update naming --- tasks/build.js | 3 ++- tasks/compile.js | 36 ++++++++++++++++++------------------ tasks/config.js | 7 ++++++- tasks/decaffeinate.js | 5 +++-- tasks/imagemin.js | 6 +++--- tasks/makepot.js | 5 +++-- tasks/scripts.js | 9 +++++---- 7 files changed, 40 insertions(+), 31 deletions(-) diff --git a/tasks/build.js b/tasks/build.js index 9825557..65f60dc 100644 --- a/tasks/build.js +++ b/tasks/build.js @@ -5,6 +5,7 @@ import { cleanBuildTask, cleanComposerTask } from './clean.js' import { shellComposerInstallTask, shellComposerStatusTask } from './shell.js' import { compile } from './compile.js' import { copyBuildTask } from './copy.js' +import { bundleTask } from './bundle.js' /** * The main task for building the plugin: @@ -14,7 +15,7 @@ import { copyBuildTask } from './copy.js' * - Copies plugin files to the build directory */ const buildTask = (done) => { - let tasks = [cleanBuildTask, shellComposerStatusTask, cleanComposerTask, shellComposerInstallTask, compile, 'bundle', copyBuildTask] // @TODO replace remaining + let tasks = [cleanBuildTask, shellComposerStatusTask, cleanComposerTask, shellComposerInstallTask, compile, bundleTask, copyBuildTask] if (sake.options['skip-composer']) { tasks = _.without(tasks, shellComposerStatusTask, cleanComposerTask, shellComposerInstallTask) diff --git a/tasks/compile.js b/tasks/compile.js index 590b704..14c3c7a 100644 --- a/tasks/compile.js +++ b/tasks/compile.js @@ -15,8 +15,8 @@ import { scriptPipes } from '../pipes/scripts.js'; import sake from '../lib/sake.js' import rename from 'gulp-rename' import { lintPhpTask } from './lint.js' -import { minifyImages } from './imagemin.js' -import { makepot } from './makepot.js' +import { minifyImagesTask } from './imagemin.js' +import { makepotTask } from './makepot.js' import { styles } from './styles.js' const sass = gulpSaas(dartSaas); @@ -25,7 +25,7 @@ const sass = gulpSaas(dartSaas); /** * Compile, transpile, and minify coffee scripts */ -const compileCoffee = (done) => { +const compileCoffeeTask = (done) => { if (! fs.existsSync(sake.config.paths.assetPaths.js)) { return Promise.resolve() } @@ -39,12 +39,12 @@ const compileCoffee = (done) => { .pipe(gulp.dest(sake.config.paths.assetPaths.js)) .pipe(gulpif(() => sake.isWatching && sake.config.tasks.watch.useBrowserSync, browserSync.stream.apply({ match: '**/*.js' }))) } -compileCoffee.displayName = 'compile:coffee' +compileCoffeeTask.displayName = 'compile:coffee' /** * Transpile and minify JS files */ -const compileJs = (done) => { +const compileJsTask = (done) => { if (! fs.existsSync(sake.config.paths.assetPaths.js)) { return Promise.resolve() } @@ -57,12 +57,12 @@ const compileJs = (done) => { .pipe(gulp.dest(sake.config.paths.assetPaths.js)) .pipe(gulpif(() => sake.isWatching && sake.config.tasks.watch.useBrowserSync, browserSync.stream.apply({ match: '**/*.js' }))) } -compileJs.displayName = 'compile:js' +compileJsTask.displayName = 'compile:js' /** * This task is specific for plugins that add one or more self-contained Gutenberg blocks in their assets to be transpiled from ES6 */ -const compileBlocks = (done) => { +const compileBlocksTask = (done) => { const i18nPath = `${process.cwd()}/i18n/languages/blocks/` const blockPath = `${sake.config.paths.assetPaths.js}/blocks/src/` const blockSrc = fs.existsSync(blockPath) ? fs.readdirSync(blockPath).filter(function (file) { @@ -104,14 +104,14 @@ const compileBlocks = (done) => { .pipe(gulpif(() => sake.isWatching && sake.config.tasks.watch.useBrowserSync, browserSync.stream.apply({ match: '**/*.js' }))) } } -compileBlocks.displayName = 'compile:blocks' +compileBlocksTask.displayName = 'compile:blocks' /************************** Styles */ /** * Compile SCSS to CSS */ -const compileScss = (done) => { +const compileScssTask = (done) => { if (! fs.existsSync(sake.config.paths.assetPaths.css)) { return Promise.resolve() } @@ -137,36 +137,36 @@ const compileScss = (done) => { .pipe(gulp.dest(`${sake.config.paths.src}/${sake.config.paths.css}`)) .pipe(gulpif(() => sake.isWatching && sake.config.tasks.watch.useBrowserSync, browserSync.stream({match: '**/*.css'}))) } -compileScss.displayName = 'compile:scss' +compileScssTask.displayName = 'compile:scss' /************************** Parallels */ // The main task to compile scripts -const compileScripts = gulp.parallel(compileCoffee, compileJs, compileBlocks) +const compileScripts = gulp.parallel(compileCoffeeTask, compileJsTask, compileBlocksTask) compileScripts.displayName = 'compile:scripts' // The main task to compile styles -const compileStyles = gulp.parallel(compileScss) +const compileStyles = gulp.parallel(compileScssTask) compileStyles.displayName = 'compile:styles' // Compile all plugin assets const compile = (done) => { // default compile tasks - let tasks = [lintPhpTask, 'scripts', styles, minifyImages] // NOTE: do not import the `scripts` constant here, otherwise it creates a circular dependency + let tasks = [lintPhpTask, 'scripts', styles, minifyImagesTask] // NOTE: do not import the `scripts` constant here, otherwise it creates a circular dependency // unless exclusively told not to, generate the POT file as well if (!sake.options.skip_pot) { - tasks.push(makepot) + tasks.push(makepotTask) } gulp.parallel(tasks)(done) } export { - compileCoffee, - compileJs, - compileBlocks, - compileScss, + compileCoffeeTask, + compileJsTask, + compileBlocksTask, + compileScssTask, compileScripts, compileStyles, compile diff --git a/tasks/config.js b/tasks/config.js index ebd9f67..ef1a323 100644 --- a/tasks/config.js +++ b/tasks/config.js @@ -1,7 +1,7 @@ import dottie from 'dottie'; import sake from '../lib/sake.js' -export const config = (done) => { +const configTask = (done) => { // pass --property=deploy.production to only see sake.config values for that property if (sake.options.property) { console.log(dottie.get(sake.config, sake.options.property)) @@ -11,3 +11,8 @@ export const config = (done) => { done() } +configTask.displayName = 'config' + +export { + configTask +} diff --git a/tasks/decaffeinate.js b/tasks/decaffeinate.js index 9b854f9..e892572 100644 --- a/tasks/decaffeinate.js +++ b/tasks/decaffeinate.js @@ -13,7 +13,7 @@ const __dirname = path.dirname(__filename); * Converts CoffeeScripts to ES6 JavaScript without minification or further handling. * This command should only be run once when converting an existing plugin CoffeeScript codebase to plain SE6. */ -const decaffeinate = (done) => { +const decaffeinateTask = (done) => { // use WordPress standards - overrideable by individual plugins that provide a .eslintrc file // see https://github.com/WordPress-Coding-Standards/eslint-config-wordpress/blob/master/index.js let esLintFile = sake.options['eslint-configFile'] ? path.join(process.cwd(), sake.options['eslint-configFile']) : path.join(__dirname, '../lib/lintfiles/.eslintrc') @@ -31,7 +31,8 @@ const decaffeinate = (done) => { .pipe(gulp.dest(sake.config.paths.assetPaths.js)) .pipe(gulpif(() => sake.isWatching && sake.config.tasks.watch.useBrowserSync, browserSync.stream.apply({ match: '**/*.js' }))) } +decaffeinateTask.displayName = 'decaffeinate' export { - decaffeinate + decaffeinateTask } diff --git a/tasks/imagemin.js b/tasks/imagemin.js index 2fb6b65..019d909 100644 --- a/tasks/imagemin.js +++ b/tasks/imagemin.js @@ -6,7 +6,7 @@ import gulpif from 'gulp-if' import sake from '../lib/sake.js' import browserSync from 'browser-sync' -const minifyImages = (done) => { +const minifyImagesTask = (done) => { if (! fs.existsSync(sake.config.paths.assetPaths.images)) { log.info(`The directory ${sake.config.paths.assetPaths.images} does not exist.`) return Promise.resolve() @@ -18,8 +18,8 @@ const minifyImages = (done) => { .pipe(gulpif(() => sake.isWatching && sake.config.tasks.watch.useBrowserSync, browserSync.stream())) } -minifyImages.displayName = 'imagemin' +minifyImagesTask.displayName = 'imagemin' export { - minifyImages + minifyImagesTask } diff --git a/tasks/makepot.js b/tasks/makepot.js index db8aa3c..bc7330e 100644 --- a/tasks/makepot.js +++ b/tasks/makepot.js @@ -2,7 +2,7 @@ import log from 'fancy-log' import shell from 'shelljs' import sake from '../lib/sake.js' -const makepot = (done) => { +const makepotTask = (done) => { const options = sake.config.tasks.makepot const domainPath = ( options.domainPath || 'i18n/languages' ) + '/' + sake.config.plugin.id + '.pot' const excludedPaths = ['.github/.*', 'lib/.*', 'vendor/.*', 'tests/.*', 'node_modules/.*'] @@ -22,7 +22,8 @@ const makepot = (done) => { done() } } +makepotTask.displayName = 'makepot' export { - makepot + makepotTask } diff --git a/tasks/scripts.js b/tasks/scripts.js index 54e7689..74a3ab8 100644 --- a/tasks/scripts.js +++ b/tasks/scripts.js @@ -1,6 +1,6 @@ import gulp from 'gulp' import { lintCoffeeTask, lintJsTask, lintScriptsTask } from './lint.js' -import { compileBlocks, compileCoffee, compileJs, compileScripts } from './compile.js' +import { compileBlocksTask, compileCoffeeTask, compileJsTask, compileScripts } from './compile.js' import sake from '../lib/sake.js' /** @@ -16,16 +16,17 @@ const scripts = (done) => { gulp.series(tasks)(done) } +scripts.displayName = 'scripts' /** type-specific script tasks - lints and then compiles */ -const scriptsCoffee = gulp.series(lintCoffeeTask, compileCoffee) +const scriptsCoffee = gulp.series(lintCoffeeTask, compileCoffeeTask) scriptsCoffee.displayName = 'scripts:coffee' -const scriptsJs = gulp.series(lintJsTask, compileJs) +const scriptsJs = gulp.series(lintJsTask, compileJsTask) scriptsJs.displayName = 'scripts:js' -const scriptsBlocks = gulp.series(compileBlocks) +const scriptsBlocks = gulp.series(compileBlocksTask) scriptsBlocks.displayName = 'compile:blocks' export { From 021286763d96bfc08cd4eb9b8b639dd1e6af0192 Mon Sep 17 00:00:00 2001 From: Ashley Gibson Date: Mon, 17 Mar 2025 12:55:35 +0000 Subject: [PATCH 36/45] Update naming --- tasks/compile.js | 4 ++-- tasks/scripts.js | 6 +++--- tasks/styles.js | 5 +++-- tasks/watch.js | 5 +++-- 4 files changed, 11 insertions(+), 9 deletions(-) diff --git a/tasks/compile.js b/tasks/compile.js index 14c3c7a..7baef41 100644 --- a/tasks/compile.js +++ b/tasks/compile.js @@ -17,7 +17,7 @@ import rename from 'gulp-rename' import { lintPhpTask } from './lint.js' import { minifyImagesTask } from './imagemin.js' import { makepotTask } from './makepot.js' -import { styles } from './styles.js' +import { stylesTask } from './styles.js' const sass = gulpSaas(dartSaas); /************************** Scripts */ @@ -152,7 +152,7 @@ compileStyles.displayName = 'compile:styles' // Compile all plugin assets const compile = (done) => { // default compile tasks - let tasks = [lintPhpTask, 'scripts', styles, minifyImagesTask] // NOTE: do not import the `scripts` constant here, otherwise it creates a circular dependency + let tasks = [lintPhpTask, 'scripts', stylesTask, minifyImagesTask] // NOTE: do not import the `scripts` constant here, otherwise it creates a circular dependency // unless exclusively told not to, generate the POT file as well if (!sake.options.skip_pot) { diff --git a/tasks/scripts.js b/tasks/scripts.js index 74a3ab8..dab4199 100644 --- a/tasks/scripts.js +++ b/tasks/scripts.js @@ -6,7 +6,7 @@ import sake from '../lib/sake.js' /** * The main task */ -const scripts = (done) => { +const scriptsTask = (done) => { let tasks = [lintScriptsTask, compileScripts] // don't lint styles if they have already been linted, unless we're watching @@ -16,7 +16,7 @@ const scripts = (done) => { gulp.series(tasks)(done) } -scripts.displayName = 'scripts' +scriptsTask.displayName = 'scripts' /** type-specific script tasks - lints and then compiles */ @@ -30,7 +30,7 @@ const scriptsBlocks = gulp.series(compileBlocksTask) scriptsBlocks.displayName = 'compile:blocks' export { - scripts, + scriptsTask, scriptsCoffee, scriptsJs, scriptsBlocks diff --git a/tasks/styles.js b/tasks/styles.js index 7852b00..14a3af3 100644 --- a/tasks/styles.js +++ b/tasks/styles.js @@ -3,7 +3,7 @@ import sake from '../lib/sake.js' import { lintStylesTask } from './lint.js' import { compileStyles } from './compile.js' -const styles = (done) => { +const stylesTask = (done) => { let tasks = [lintStylesTask, compileStyles] // don't lint styles if they have already been linted, unless we're watching @@ -13,7 +13,8 @@ const styles = (done) => { gulp.series(tasks)(done) } +stylesTask.displayName = 'styles' export { - styles + stylesTask } diff --git a/tasks/watch.js b/tasks/watch.js index 25775aa..a90d975 100644 --- a/tasks/watch.js +++ b/tasks/watch.js @@ -3,7 +3,7 @@ import browserSync from 'browser-sync' import sake from '../lib/sake.js' import gulp from 'gulp' -const watch = (done) => { +const watchTask = (done) => { // start browsersync if enabled if (sake.config.tasks.watch.useBrowserSync) { let port = null @@ -41,7 +41,8 @@ const watch = (done) => { // gulp.watch(`${sake.config.paths.assetPaths.images}/**.*{png,jpg,gif,svg}`, gulp.parallel('imagemin')) // TODO: should we also watch for changes in PHP files and regenerate POT files and reload the browser? } +watchTask.displayName = 'watch' export { - watch + watchTask } From c79a6e0aabd9431f15f3f0c7369d3b58e08b0a1a Mon Sep 17 00:00:00 2001 From: Ashley Gibson Date: Mon, 17 Mar 2025 12:57:21 +0000 Subject: [PATCH 37/45] Fix import --- tasks/upfw.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasks/upfw.js b/tasks/upfw.js index e213bd3..0597b63 100644 --- a/tasks/upfw.js +++ b/tasks/upfw.js @@ -1,7 +1,7 @@ import fs from 'node:fs' import path from 'node:path' import dottie from 'dottie' -import sake from '../lib/sake' +import sake from '../lib/sake.js' import gulp from 'gulp' import { bumpFrameworkVersionTask, bumpMinReqsTask } from './bump.js' import { shellComposerUpdateTask, shellUpdateFrameworkCommitTask, shellUpdateFrameworkTask } from './shell.js' From c1ccfcfbe84c63b64ab0349b10239ae51febbc62 Mon Sep 17 00:00:00 2001 From: Ashley Gibson Date: Mon, 17 Mar 2025 12:57:27 +0000 Subject: [PATCH 38/45] Update deprecated sass import --- tasks/compile.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasks/compile.js b/tasks/compile.js index 7baef41..1fb1de0 100644 --- a/tasks/compile.js +++ b/tasks/compile.js @@ -1,7 +1,7 @@ import webpack from 'webpack-stream'; import fs from 'node:fs'; import path from 'node:path'; -import dartSaas from 'sass'; +import * as dartSaas from 'sass'; import gulpSaas from 'gulp-sass'; import autoprefixer from 'autoprefixer'; import gulp from 'gulp' From 2b08904d5a2ea722abaad17daca0b275fb166cce Mon Sep 17 00:00:00 2001 From: Ashley Gibson Date: Wed, 19 Mar 2025 13:15:55 +0000 Subject: [PATCH 39/45] Remove console log --- lib/sake.js | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/sake.js b/lib/sake.js index 8966fab..bf774b9 100644 --- a/lib/sake.js +++ b/lib/sake.js @@ -29,7 +29,6 @@ sake.initConfig(); export default sake; function initializeSake(config, options) { - console.log('initializing sake'); const exports = {} // current task(s) from CLI, ie for `npx sake clean build` this will result in ['clean', 'build'] const cliTasks = process.argv.slice(2, -4) From df04967456d966772dd9e2702d4d1c00e66c30e0 Mon Sep 17 00:00:00 2001 From: Ashley Gibson Date: Wed, 19 Mar 2025 13:16:43 +0000 Subject: [PATCH 40/45] Rework how series is created --- tasks/build.js | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/tasks/build.js b/tasks/build.js index 65f60dc..81de017 100644 --- a/tasks/build.js +++ b/tasks/build.js @@ -14,15 +14,14 @@ import { bundleTask } from './bundle.js' * - Bundles any external dependencies to the plugin assets * - Copies plugin files to the build directory */ -const buildTask = (done) => { - let tasks = [cleanBuildTask, shellComposerStatusTask, cleanComposerTask, shellComposerInstallTask, compile, bundleTask, copyBuildTask] - if (sake.options['skip-composer']) { - tasks = _.without(tasks, shellComposerStatusTask, cleanComposerTask, shellComposerInstallTask) - } +let tasks = [cleanBuildTask, shellComposerStatusTask, cleanComposerTask, shellComposerInstallTask, compile, bundleTask, copyBuildTask] - return gulp.series(tasks) +if (sake.options['skip-composer']) { + tasks = _.without(tasks, shellComposerStatusTask, cleanComposerTask, shellComposerInstallTask) } + +const buildTask = gulp.series(tasks) buildTask.displayName = 'build' export { From d72c2bac9829d657c42b475fc11de7c46b9771b1 Mon Sep 17 00:00:00 2001 From: Ashley Gibson Date: Tue, 25 Mar 2025 10:45:38 +0000 Subject: [PATCH 41/45] Add force option --- tasks/clean.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tasks/clean.js b/tasks/clean.js index 84ddf08..8988120 100644 --- a/tasks/clean.js +++ b/tasks/clean.js @@ -61,7 +61,9 @@ cleanPrereleaseTask.displayName = 'clean:prerelease' const cleanWpTrunkTask = (done) => { return del([ path.join(sake.getProductionRepoPath(), 'trunk') - ]) + ], { + force: true // required to allow deleting outside of current working directory + }) } cleanWpTrunkTask.displayName = 'clean:wp_trunk' @@ -71,7 +73,9 @@ cleanWpTrunkTask.displayName = 'clean:wp_trunk' const cleanWpAssetsTask = (done) => { return del([ path.join(sake.getProductionRepoPath(), 'assets') - ]) + ], { + force: true // required to allow deleting outside of current working directory + }) } cleanWpAssetsTask.displayName = 'clean:wp_assets' From bc3f35ddfe8cc1a1cd29c0800638095c61ed5ffc Mon Sep 17 00:00:00 2001 From: Ashley Gibson Date: Fri, 22 Aug 2025 09:23:45 +0100 Subject: [PATCH 42/45] Apply changes from master --- tasks/clean.js | 8 ++++++-- tasks/copy.js | 4 +++- tasks/zip.js | 2 +- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/tasks/clean.js b/tasks/clean.js index 8988120..8ff23a8 100644 --- a/tasks/clean.js +++ b/tasks/clean.js @@ -40,7 +40,9 @@ cleanBuildTask.displayName = 'clean:build' const cleanWcRepoTask = (done) => { return del([ sake.getProductionRepoPath() + '**/*' - ]) + ], { + force: true // required to allow deleting outside of current working directory + }) } cleanWcRepoTask.displayName = 'clean:wc_repo' @@ -51,7 +53,9 @@ const cleanPrereleaseTask = (done) => { return del([ sake.getPrereleasesPath() + sake.config.plugin.id + '*.zip', sake.getPrereleasesPath() + sake.config.plugin.id + '*.txt' - ]) + ], { + force: true // required to allow deleting outside of current working directory + }) } cleanPrereleaseTask.displayName = 'clean:prerelease' diff --git a/tasks/copy.js b/tasks/copy.js index 6f99f5c..1e068ef 100644 --- a/tasks/copy.js +++ b/tasks/copy.js @@ -157,7 +157,9 @@ const copyBuildTask = (done) => { }) } - return gulp.src(paths, { base: sake.config.paths.src, allowEmpty: true }) + // encoding: false is required because otherwise images will become corrupted + // @link https://github.com/gulpjs/gulp/issues/2790 + return gulp.src(paths, { base: sake.config.paths.src, allowEmpty: true, encoding: false }) .pipe(filter) .pipe(replace(/\/\*# sourceMappingURL=.*?\*\/$/mg, '')) // remove source mapping references - TODO: consider skipping sourcemaps in compilers instead when running build/deploy tasks .pipe(replace('\n', '')) // remove an extra line added by libsass/node-sass diff --git a/tasks/zip.js b/tasks/zip.js index 7931949..6133f70 100644 --- a/tasks/zip.js +++ b/tasks/zip.js @@ -12,7 +12,7 @@ const zipTask = (done) => { return gulp.src([ `${sake.config.paths.build}/${sake.config.plugin.id}/**`, `!${sake.config.paths.build}/${sake.config.plugin.id}/**/*.zip` - ], { nodir: true, base: sake.config.paths.build }) // exclude empty directories, include plugin dir in zip + ], { nodir: true, base: sake.config.paths.build, encoding: false }) // exclude empty directories, include plugin dir in zip, no encoding because it breaks images .pipe(zip(zipFileName)) .pipe(gulp.dest(sake.config.paths.zipDest)) } From 4828df179c48588cee00fedae03e0279b3ee4d9c Mon Sep 17 00:00:00 2001 From: Ashley Gibson <99189195+agibson-godaddy@users.noreply.github.com> Date: Fri, 22 Aug 2025 12:32:28 +0100 Subject: [PATCH 43/45] Apply suggestions from code review Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- tasks/decaffeinate.js | 2 +- tasks/github.js | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/tasks/decaffeinate.js b/tasks/decaffeinate.js index e892572..5b9d52b 100644 --- a/tasks/decaffeinate.js +++ b/tasks/decaffeinate.js @@ -11,7 +11,7 @@ const __dirname = path.dirname(__filename); /** * Converts CoffeeScripts to ES6 JavaScript without minification or further handling. - * This command should only be run once when converting an existing plugin CoffeeScript codebase to plain SE6. + * This command should only be run once when converting an existing plugin CoffeeScript codebase to plain ES6. */ const decaffeinateTask = (done) => { // use WordPress standards - overrideable by individual plugins that provide a .eslintrc file diff --git a/tasks/github.js b/tasks/github.js index ca6e7a5..363307a 100644 --- a/tasks/github.js +++ b/tasks/github.js @@ -41,7 +41,6 @@ const gitHubGetReleaseIssueTask = (done) => { labels: labels.join(',') }).then((result) => { if (! result.data.length) { - log.info('No labels found') done() } else { inquirer.prompt([{ From b7ba4da155eae862bba48a4184601c6e1d85f8f0 Mon Sep 17 00:00:00 2001 From: Ashley Gibson Date: Fri, 22 Aug 2025 12:39:05 +0100 Subject: [PATCH 44/45] Execute codename as a function --- tasks/github.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tasks/github.js b/tasks/github.js index 363307a..c26d0a0 100644 --- a/tasks/github.js +++ b/tasks/github.js @@ -4,7 +4,7 @@ import fs from 'node:fs' import path from 'node:path' import async from 'async' import chalk from 'chalk' -import codename from 'codename' // @TODO check this? old was: const codename = require('codename')() +import codename from 'codename' import dateFormat from 'dateformat' import log from 'fancy-log' import sake from '../lib/sake.js' @@ -303,7 +303,7 @@ const createMilestones = (milestones, done) => { let github = getGithub(sake.options.owner === sake.config.deploy.production.owner ? 'production' : 'dev') async.eachLimit(milestones, 5, function (milestone, cb) { - let description = codename.generate(['unique', 'alliterative', 'random'], ['adjectives', 'animals']).join(' ') + let description = codename().generate(['unique', 'alliterative', 'random'], ['adjectives', 'animals']).join(' ') let formattedDate = dateFormat(milestone.date, 'yyyy-mm-dd') github.issues.createMilestone({ From 2bb4f13092a46fff1109a4656a145df42e7870b8 Mon Sep 17 00:00:00 2001 From: Ashley Gibson <99189195+agibson-godaddy@users.noreply.github.com> Date: Fri, 22 Aug 2025 12:48:06 +0100 Subject: [PATCH 45/45] Fix typo Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- tasks/wc.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasks/wc.js b/tasks/wc.js index c7345fb..62753dd 100644 --- a/tasks/wc.js +++ b/tasks/wc.js @@ -84,7 +84,7 @@ const wcValidateTask = (done) => { wcValidateTask.displayName = 'wc:validate' /** - * Internal task the handles the zip file upload + * Internal task that handles the zip file upload */ const wcUploadTask = (done) => { let version = sake.getPluginVersion()