diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 2d4c8e377..36a1b157d 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -52,6 +52,10 @@ jobs:
- name: Test
run: npm run test
+ - name: Test (Publish)
+ if: matrix.node-version != '20'
+ run: npx vitest run --project publish
+
- name: Test (Integration)
if: matrix.operating-system == 'ubuntu-latest'
run: npm run test:integration
diff --git a/Gruntfile.js b/Gruntfile.js
deleted file mode 100644
index 7c7d10e2b..000000000
--- a/Gruntfile.js
+++ /dev/null
@@ -1,9 +0,0 @@
-// Legacy Gruntfile — kept only for the 'metrics' and 'version' tasks.
-// The main build pipeline uses rspack + swc (see rspack.config.js and .swcrc).
-module.exports = function (grunt) {
- grunt.initConfig({
- pkg: grunt.file.readJSON('package.json'),
- });
-
- grunt.task.loadTasks('tasks');
-};
diff --git a/package-lock.json b/package-lock.json
index db79d4120..383276b77 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -15,7 +15,7 @@
"yargs": "^18.0.0"
},
"bin": {
- "handlebars": "bin/handlebars.js"
+ "handlebars": "bin/handlebars.mjs"
},
"devDependencies": {
"@aws-sdk/client-s3": "^3.1011.0",
@@ -393,20 +393,20 @@
"license": "0BSD"
},
"node_modules/@aws-sdk/core": {
- "version": "3.973.20",
- "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.973.20.tgz",
- "integrity": "sha512-i3GuX+lowD892F3IuJf8o6AbyDupMTdyTxQrCJGcn71ni5hTZ82L4nQhcdumxZ7XPJRJJVHS/CR3uYOIIs0PVA==",
+ "version": "3.973.22",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.973.22.tgz",
+ "integrity": "sha512-lY6g5L95jBNgOUitUhfV2N/W+i08jHEl3xuLODYSQH5Sf50V+LkVYBSyZRLtv2RyuXZXiV7yQ+acpswK1tlrOA==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@aws-sdk/types": "^3.973.6",
- "@aws-sdk/xml-builder": "^3.972.11",
- "@smithy/core": "^3.23.11",
+ "@aws-sdk/xml-builder": "^3.972.14",
+ "@smithy/core": "^3.23.12",
"@smithy/node-config-provider": "^4.3.12",
"@smithy/property-provider": "^4.2.12",
"@smithy/protocol-http": "^5.3.12",
"@smithy/signature-v4": "^5.3.12",
- "@smithy/smithy-client": "^4.12.5",
+ "@smithy/smithy-client": "^4.12.6",
"@smithy/types": "^4.13.1",
"@smithy/util-base64": "^4.3.2",
"@smithy/util-middleware": "^4.2.12",
@@ -446,13 +446,13 @@
"license": "0BSD"
},
"node_modules/@aws-sdk/credential-provider-env": {
- "version": "3.972.18",
- "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.972.18.tgz",
- "integrity": "sha512-X0B8AlQY507i5DwjLByeU2Af4ARsl9Vr84koDcXCbAkplmU+1xBFWxEPrWRAoh56waBne/yJqEloSwvRf4x6XA==",
+ "version": "3.972.20",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.972.20.tgz",
+ "integrity": "sha512-vI0QN96DFx3g9AunfOWF3CS4cMkqFiR/WM/FyP9QHr5rZ2dKPkYwP3tCgAOvGuu9CXI7dC1vU2FVUuZ+tfpNvQ==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/core": "^3.973.20",
+ "@aws-sdk/core": "^3.973.22",
"@aws-sdk/types": "^3.973.6",
"@smithy/property-provider": "^4.2.12",
"@smithy/types": "^4.13.1",
@@ -470,21 +470,21 @@
"license": "0BSD"
},
"node_modules/@aws-sdk/credential-provider-http": {
- "version": "3.972.20",
- "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.972.20.tgz",
- "integrity": "sha512-ey9Lelj001+oOfrbKmS6R2CJAiXX7QKY4Vj9VJv6L2eE6/VjD8DocHIoYqztTm70xDLR4E1jYPTKfIui+eRNDA==",
+ "version": "3.972.22",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.972.22.tgz",
+ "integrity": "sha512-aS/81smalpe7XDnuQfOq4LIPuaV2PRKU2aMTrHcqO5BD4HwO5kESOHNcec2AYfBtLtIDqgF6RXisgBnfK/jt0w==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/core": "^3.973.20",
+ "@aws-sdk/core": "^3.973.22",
"@aws-sdk/types": "^3.973.6",
"@smithy/fetch-http-handler": "^5.3.15",
- "@smithy/node-http-handler": "^4.4.16",
+ "@smithy/node-http-handler": "^4.5.0",
"@smithy/property-provider": "^4.2.12",
"@smithy/protocol-http": "^5.3.12",
- "@smithy/smithy-client": "^4.12.5",
+ "@smithy/smithy-client": "^4.12.6",
"@smithy/types": "^4.13.1",
- "@smithy/util-stream": "^4.5.19",
+ "@smithy/util-stream": "^4.5.20",
"tslib": "^2.6.2"
},
"engines": {
@@ -499,20 +499,20 @@
"license": "0BSD"
},
"node_modules/@aws-sdk/credential-provider-ini": {
- "version": "3.972.20",
- "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.972.20.tgz",
- "integrity": "sha512-5flXSnKHMloObNF+9N0cupKegnH1Z37cdVlpETVgx8/rAhCe+VNlkcZH3HDg2SDn9bI765S+rhNPXGDJJPfbtA==",
+ "version": "3.972.22",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.972.22.tgz",
+ "integrity": "sha512-rpF8fBT0LllMDp78s62aL2A/8MaccjyJ0ORzqu+ZADeECLSrrCWIeeXsuRam+pxiAMkI1uIyDZJmgLGdadkPXw==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/core": "^3.973.20",
- "@aws-sdk/credential-provider-env": "^3.972.18",
- "@aws-sdk/credential-provider-http": "^3.972.20",
- "@aws-sdk/credential-provider-login": "^3.972.20",
- "@aws-sdk/credential-provider-process": "^3.972.18",
- "@aws-sdk/credential-provider-sso": "^3.972.20",
- "@aws-sdk/credential-provider-web-identity": "^3.972.20",
- "@aws-sdk/nested-clients": "^3.996.10",
+ "@aws-sdk/core": "^3.973.22",
+ "@aws-sdk/credential-provider-env": "^3.972.20",
+ "@aws-sdk/credential-provider-http": "^3.972.22",
+ "@aws-sdk/credential-provider-login": "^3.972.22",
+ "@aws-sdk/credential-provider-process": "^3.972.20",
+ "@aws-sdk/credential-provider-sso": "^3.972.22",
+ "@aws-sdk/credential-provider-web-identity": "^3.972.22",
+ "@aws-sdk/nested-clients": "^3.996.12",
"@aws-sdk/types": "^3.973.6",
"@smithy/credential-provider-imds": "^4.2.12",
"@smithy/property-provider": "^4.2.12",
@@ -532,14 +532,14 @@
"license": "0BSD"
},
"node_modules/@aws-sdk/credential-provider-login": {
- "version": "3.972.20",
- "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-login/-/credential-provider-login-3.972.20.tgz",
- "integrity": "sha512-gEWo54nfqp2jABMu6HNsjVC4hDLpg9HC8IKSJnp0kqWtxIJYHTmiLSsIfI4ScQjxEwpB+jOOH8dOLax1+hy/Hw==",
+ "version": "3.972.22",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-login/-/credential-provider-login-3.972.22.tgz",
+ "integrity": "sha512-u33CO9zeNznlVSg9tWTCRYxaGkqr1ufU6qeClpmzAabXZa8RZxQoVXxL5T53oZJFzQYj+FImORCSsi7H7B77gQ==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/core": "^3.973.20",
- "@aws-sdk/nested-clients": "^3.996.10",
+ "@aws-sdk/core": "^3.973.22",
+ "@aws-sdk/nested-clients": "^3.996.12",
"@aws-sdk/types": "^3.973.6",
"@smithy/property-provider": "^4.2.12",
"@smithy/protocol-http": "^5.3.12",
@@ -559,18 +559,18 @@
"license": "0BSD"
},
"node_modules/@aws-sdk/credential-provider-node": {
- "version": "3.972.21",
- "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.972.21.tgz",
- "integrity": "sha512-hah8if3/B/Q+LBYN5FukyQ1Mym6PLPDsBOBsIgNEYD6wLyZg0UmUF/OKIVC3nX9XH8TfTPuITK+7N/jenVACWA==",
+ "version": "3.972.23",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.972.23.tgz",
+ "integrity": "sha512-U8tyLbLOZItuVWTH0ay9gWo4xMqZwqQbg1oMzdU4FQSkTpqXemm4X0uoKBR6llqAStgBp30ziKFJHTA43l4qMw==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/credential-provider-env": "^3.972.18",
- "@aws-sdk/credential-provider-http": "^3.972.20",
- "@aws-sdk/credential-provider-ini": "^3.972.20",
- "@aws-sdk/credential-provider-process": "^3.972.18",
- "@aws-sdk/credential-provider-sso": "^3.972.20",
- "@aws-sdk/credential-provider-web-identity": "^3.972.20",
+ "@aws-sdk/credential-provider-env": "^3.972.20",
+ "@aws-sdk/credential-provider-http": "^3.972.22",
+ "@aws-sdk/credential-provider-ini": "^3.972.22",
+ "@aws-sdk/credential-provider-process": "^3.972.20",
+ "@aws-sdk/credential-provider-sso": "^3.972.22",
+ "@aws-sdk/credential-provider-web-identity": "^3.972.22",
"@aws-sdk/types": "^3.973.6",
"@smithy/credential-provider-imds": "^4.2.12",
"@smithy/property-provider": "^4.2.12",
@@ -590,13 +590,13 @@
"license": "0BSD"
},
"node_modules/@aws-sdk/credential-provider-process": {
- "version": "3.972.18",
- "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.972.18.tgz",
- "integrity": "sha512-Tpl7SRaPoOLT32jbTWchPsn52hYYgJ0kpiFgnwk8pxTANQdUymVSZkzFvv1+oOgZm1CrbQUP9MBeoMZ9IzLZjA==",
+ "version": "3.972.20",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.972.20.tgz",
+ "integrity": "sha512-QRfk7GbA4/HDRjhP3QYR6QBr/QKreVoOzvvlRHnOuGgYJkeoPgPY3LAI1kK1ZMgZ4hH9KiGp757/ntol+INAig==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/core": "^3.973.20",
+ "@aws-sdk/core": "^3.973.22",
"@aws-sdk/types": "^3.973.6",
"@smithy/property-provider": "^4.2.12",
"@smithy/shared-ini-file-loader": "^4.4.7",
@@ -615,15 +615,15 @@
"license": "0BSD"
},
"node_modules/@aws-sdk/credential-provider-sso": {
- "version": "3.972.20",
- "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.972.20.tgz",
- "integrity": "sha512-p+R+PYR5Z7Gjqf/6pvbCnzEHcqPCpLzR7Yf127HjJ6EAb4hUcD+qsNRnuww1sB/RmSeCLxyay8FMyqREw4p1RA==",
+ "version": "3.972.22",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.972.22.tgz",
+ "integrity": "sha512-4vqlSaUbBj4aNPVKfB6yXuIQ2Z2mvLfIGba2OzzF6zUkN437/PGWsxBU2F8QPSFHti6seckvyCXidU3H+R8NvQ==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/core": "^3.973.20",
- "@aws-sdk/nested-clients": "^3.996.10",
- "@aws-sdk/token-providers": "3.1009.0",
+ "@aws-sdk/core": "^3.973.22",
+ "@aws-sdk/nested-clients": "^3.996.12",
+ "@aws-sdk/token-providers": "3.1013.0",
"@aws-sdk/types": "^3.973.6",
"@smithy/property-provider": "^4.2.12",
"@smithy/shared-ini-file-loader": "^4.4.7",
@@ -642,14 +642,14 @@
"license": "0BSD"
},
"node_modules/@aws-sdk/credential-provider-web-identity": {
- "version": "3.972.20",
- "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.972.20.tgz",
- "integrity": "sha512-rWCmh8o7QY4CsUj63qopzMzkDq/yPpkrpb+CnjBEFSOg/02T/we7sSTVg4QsDiVS9uwZ8VyONhq98qt+pIh3KA==",
+ "version": "3.972.22",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.972.22.tgz",
+ "integrity": "sha512-/wN1CYg2rVLhW8/jLxMWacQrkpaynnL+4j/Z+e6X1PfoE6NiC0BeOw3i0JmtZrKun85wNV5GmspvuWJihfeeUw==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/core": "^3.973.20",
- "@aws-sdk/nested-clients": "^3.996.10",
+ "@aws-sdk/core": "^3.973.22",
+ "@aws-sdk/nested-clients": "^3.996.12",
"@aws-sdk/types": "^3.973.6",
"@smithy/property-provider": "^4.2.12",
"@smithy/shared-ini-file-loader": "^4.4.7",
@@ -896,16 +896,16 @@
"license": "0BSD"
},
"node_modules/@aws-sdk/middleware-user-agent": {
- "version": "3.972.21",
- "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.972.21.tgz",
- "integrity": "sha512-62XRl1GDYPpkt7cx1AX1SPy9wgNE9Iw/NPuurJu4lmhCWS7sGKO+kS53TQ8eRmIxy3skmvNInnk0ZbWrU5Dpyg==",
+ "version": "3.972.23",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.972.23.tgz",
+ "integrity": "sha512-HQu8QoqGZZTvg0Spl9H39QTsSMFwgu+8yz/QGKndXFLk9FZMiCiIgBCVlTVKMDvVbgqIzD9ig+/HmXsIL2Rb+g==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/core": "^3.973.20",
+ "@aws-sdk/core": "^3.973.22",
"@aws-sdk/types": "^3.973.6",
"@aws-sdk/util-endpoints": "^3.996.5",
- "@smithy/core": "^3.23.11",
+ "@smithy/core": "^3.23.12",
"@smithy/protocol-http": "^5.3.12",
"@smithy/types": "^4.13.1",
"@smithy/util-retry": "^4.2.12",
@@ -923,45 +923,45 @@
"license": "0BSD"
},
"node_modules/@aws-sdk/nested-clients": {
- "version": "3.996.10",
- "resolved": "https://registry.npmjs.org/@aws-sdk/nested-clients/-/nested-clients-3.996.10.tgz",
- "integrity": "sha512-SlDol5Z+C7Ivnc2rKGqiqfSUmUZzY1qHfVs9myt/nxVwswgfpjdKahyTzLTx802Zfq0NFRs7AejwKzzzl5Co2w==",
+ "version": "3.996.12",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/nested-clients/-/nested-clients-3.996.12.tgz",
+ "integrity": "sha512-KLdQGJPSm98uLINolQ0Tol8OAbk7g0Y7zplHJ1K83vbMIH13aoCvR6Tho66xueW4l4aZlEgVGLWBnD8ifUMsGQ==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@aws-crypto/sha256-browser": "5.2.0",
"@aws-crypto/sha256-js": "5.2.0",
- "@aws-sdk/core": "^3.973.20",
+ "@aws-sdk/core": "^3.973.22",
"@aws-sdk/middleware-host-header": "^3.972.8",
"@aws-sdk/middleware-logger": "^3.972.8",
"@aws-sdk/middleware-recursion-detection": "^3.972.8",
- "@aws-sdk/middleware-user-agent": "^3.972.21",
+ "@aws-sdk/middleware-user-agent": "^3.972.23",
"@aws-sdk/region-config-resolver": "^3.972.8",
"@aws-sdk/types": "^3.973.6",
"@aws-sdk/util-endpoints": "^3.996.5",
"@aws-sdk/util-user-agent-browser": "^3.972.8",
- "@aws-sdk/util-user-agent-node": "^3.973.7",
+ "@aws-sdk/util-user-agent-node": "^3.973.9",
"@smithy/config-resolver": "^4.4.11",
- "@smithy/core": "^3.23.11",
+ "@smithy/core": "^3.23.12",
"@smithy/fetch-http-handler": "^5.3.15",
"@smithy/hash-node": "^4.2.12",
"@smithy/invalid-dependency": "^4.2.12",
"@smithy/middleware-content-length": "^4.2.12",
- "@smithy/middleware-endpoint": "^4.4.25",
- "@smithy/middleware-retry": "^4.4.42",
- "@smithy/middleware-serde": "^4.2.14",
+ "@smithy/middleware-endpoint": "^4.4.26",
+ "@smithy/middleware-retry": "^4.4.43",
+ "@smithy/middleware-serde": "^4.2.15",
"@smithy/middleware-stack": "^4.2.12",
"@smithy/node-config-provider": "^4.3.12",
- "@smithy/node-http-handler": "^4.4.16",
+ "@smithy/node-http-handler": "^4.5.0",
"@smithy/protocol-http": "^5.3.12",
- "@smithy/smithy-client": "^4.12.5",
+ "@smithy/smithy-client": "^4.12.6",
"@smithy/types": "^4.13.1",
"@smithy/url-parser": "^4.2.12",
"@smithy/util-base64": "^4.3.2",
"@smithy/util-body-length-browser": "^4.2.2",
"@smithy/util-body-length-node": "^4.2.3",
- "@smithy/util-defaults-mode-browser": "^4.3.41",
- "@smithy/util-defaults-mode-node": "^4.2.44",
+ "@smithy/util-defaults-mode-browser": "^4.3.42",
+ "@smithy/util-defaults-mode-node": "^4.2.45",
"@smithy/util-endpoints": "^3.3.3",
"@smithy/util-middleware": "^4.2.12",
"@smithy/util-retry": "^4.2.12",
@@ -1029,14 +1029,14 @@
"license": "0BSD"
},
"node_modules/@aws-sdk/token-providers": {
- "version": "3.1009.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.1009.0.tgz",
- "integrity": "sha512-KCPLuTqN9u0Rr38Arln78fRG9KXpzsPWmof+PZzfAHMMQq2QED6YjQrkrfiH7PDefLWEposY1o4/eGwrmKA4JA==",
+ "version": "3.1013.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.1013.0.tgz",
+ "integrity": "sha512-IL1c54UvbuERrs9oLm5rvkzMciwhhpn1FL0SlC3XUMoLlFhdBsWJgQKK8O5fsQLxbFVqjbjFx9OBkrn44X9PHw==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/core": "^3.973.20",
- "@aws-sdk/nested-clients": "^3.996.10",
+ "@aws-sdk/core": "^3.973.22",
+ "@aws-sdk/nested-clients": "^3.996.12",
"@aws-sdk/types": "^3.973.6",
"@smithy/property-provider": "^4.2.12",
"@smithy/shared-ini-file-loader": "^4.4.7",
@@ -1160,13 +1160,13 @@
"license": "0BSD"
},
"node_modules/@aws-sdk/util-user-agent-node": {
- "version": "3.973.7",
- "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.973.7.tgz",
- "integrity": "sha512-Hz6EZMUAEzqUd7e+vZ9LE7mn+5gMbxltXy18v+YSFY+9LBJz15wkNZvw5JqfX3z0FS9n3bgUtz3L5rAsfh4YlA==",
+ "version": "3.973.9",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.973.9.tgz",
+ "integrity": "sha512-jeFqqp8KD/P5O+qeKxyGeu7WEVIZFNprnkaDjGmBOjwxYwafCBhpxTgV1TlW6L8e76Vh/siNylNmN/OmSIFBUQ==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/middleware-user-agent": "^3.972.21",
+ "@aws-sdk/middleware-user-agent": "^3.972.23",
"@aws-sdk/types": "^3.973.6",
"@smithy/node-config-provider": "^4.3.12",
"@smithy/types": "^4.13.1",
@@ -1193,14 +1193,14 @@
"license": "0BSD"
},
"node_modules/@aws-sdk/xml-builder": {
- "version": "3.972.11",
- "resolved": "https://registry.npmjs.org/@aws-sdk/xml-builder/-/xml-builder-3.972.11.tgz",
- "integrity": "sha512-iitV/gZKQMvY9d7ovmyFnFuTHbBAtrmLnvaSb/3X8vOKyevwtpmEtyc8AdhVWZe0pI/1GsHxlEvQeOePFzy7KQ==",
+ "version": "3.972.14",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/xml-builder/-/xml-builder-3.972.14.tgz",
+ "integrity": "sha512-G/Yd8Bnnyh8QrqLf8jWJbixEnScUFW24e/wOBGYdw1Cl4r80KX/DvHyM2GVZ2vTp7J4gTEr8IXJlTadA8+UfuQ==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@smithy/types": "^4.13.1",
- "fast-xml-parser": "5.4.1",
+ "fast-xml-parser": "5.5.6",
"tslib": "^2.6.2"
},
"engines": {
@@ -9187,9 +9187,9 @@
}
},
"node_modules/fast-xml-parser": {
- "version": "5.4.1",
- "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.4.1.tgz",
- "integrity": "sha512-BQ30U1mKkvXQXXkAGcuyUA/GA26oEB7NzOtsxCDtyu62sjGw5QraKFhx2Em3WQNjPw9PG6MQ9yuIIgkSDfGu5A==",
+ "version": "5.5.6",
+ "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.5.6.tgz",
+ "integrity": "sha512-3+fdZyBRVg29n4rXP0joHthhcHdPUHaIC16cuyyd1iLsuaO6Vea36MPrxgAzbZna8lhvZeRL8Bc9GP56/J9xEw==",
"dev": true,
"funding": [
{
@@ -9199,7 +9199,8 @@
],
"license": "MIT",
"dependencies": {
- "fast-xml-builder": "^1.0.0",
+ "fast-xml-builder": "^1.1.4",
+ "path-expression-matcher": "^1.1.3",
"strnum": "^2.1.2"
},
"bin": {
@@ -12883,9 +12884,9 @@
}
},
"node_modules/strnum": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/strnum/-/strnum-2.2.0.tgz",
- "integrity": "sha512-Y7Bj8XyJxnPAORMZj/xltsfo55uOiyHcU2tnAVzHUnSJR/KsEX+9RoDeXEnsXtl/CX4fAcrt64gZ13aGaWPeBg==",
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/strnum/-/strnum-2.2.1.tgz",
+ "integrity": "sha512-BwRvNd5/QoAtyW1na1y1LsJGQNvRlkde6Q/ipqqEaivoMdV+B1OMOTVdwR+N/cwVUcIt9PYyHmV8HyexCZSupg==",
"dev": true,
"funding": [
{
@@ -14303,19 +14304,19 @@
}
},
"@aws-sdk/core": {
- "version": "3.973.20",
- "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.973.20.tgz",
- "integrity": "sha512-i3GuX+lowD892F3IuJf8o6AbyDupMTdyTxQrCJGcn71ni5hTZ82L4nQhcdumxZ7XPJRJJVHS/CR3uYOIIs0PVA==",
+ "version": "3.973.22",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.973.22.tgz",
+ "integrity": "sha512-lY6g5L95jBNgOUitUhfV2N/W+i08jHEl3xuLODYSQH5Sf50V+LkVYBSyZRLtv2RyuXZXiV7yQ+acpswK1tlrOA==",
"dev": true,
"requires": {
"@aws-sdk/types": "^3.973.6",
- "@aws-sdk/xml-builder": "^3.972.11",
- "@smithy/core": "^3.23.11",
+ "@aws-sdk/xml-builder": "^3.972.14",
+ "@smithy/core": "^3.23.12",
"@smithy/node-config-provider": "^4.3.12",
"@smithy/property-provider": "^4.2.12",
"@smithy/protocol-http": "^5.3.12",
"@smithy/signature-v4": "^5.3.12",
- "@smithy/smithy-client": "^4.12.5",
+ "@smithy/smithy-client": "^4.12.6",
"@smithy/types": "^4.13.1",
"@smithy/util-base64": "^4.3.2",
"@smithy/util-middleware": "^4.2.12",
@@ -14350,12 +14351,12 @@
}
},
"@aws-sdk/credential-provider-env": {
- "version": "3.972.18",
- "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.972.18.tgz",
- "integrity": "sha512-X0B8AlQY507i5DwjLByeU2Af4ARsl9Vr84koDcXCbAkplmU+1xBFWxEPrWRAoh56waBne/yJqEloSwvRf4x6XA==",
+ "version": "3.972.20",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.972.20.tgz",
+ "integrity": "sha512-vI0QN96DFx3g9AunfOWF3CS4cMkqFiR/WM/FyP9QHr5rZ2dKPkYwP3tCgAOvGuu9CXI7dC1vU2FVUuZ+tfpNvQ==",
"dev": true,
"requires": {
- "@aws-sdk/core": "^3.973.20",
+ "@aws-sdk/core": "^3.973.22",
"@aws-sdk/types": "^3.973.6",
"@smithy/property-provider": "^4.2.12",
"@smithy/types": "^4.13.1",
@@ -14371,20 +14372,20 @@
}
},
"@aws-sdk/credential-provider-http": {
- "version": "3.972.20",
- "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.972.20.tgz",
- "integrity": "sha512-ey9Lelj001+oOfrbKmS6R2CJAiXX7QKY4Vj9VJv6L2eE6/VjD8DocHIoYqztTm70xDLR4E1jYPTKfIui+eRNDA==",
+ "version": "3.972.22",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.972.22.tgz",
+ "integrity": "sha512-aS/81smalpe7XDnuQfOq4LIPuaV2PRKU2aMTrHcqO5BD4HwO5kESOHNcec2AYfBtLtIDqgF6RXisgBnfK/jt0w==",
"dev": true,
"requires": {
- "@aws-sdk/core": "^3.973.20",
+ "@aws-sdk/core": "^3.973.22",
"@aws-sdk/types": "^3.973.6",
"@smithy/fetch-http-handler": "^5.3.15",
- "@smithy/node-http-handler": "^4.4.16",
+ "@smithy/node-http-handler": "^4.5.0",
"@smithy/property-provider": "^4.2.12",
"@smithy/protocol-http": "^5.3.12",
- "@smithy/smithy-client": "^4.12.5",
+ "@smithy/smithy-client": "^4.12.6",
"@smithy/types": "^4.13.1",
- "@smithy/util-stream": "^4.5.19",
+ "@smithy/util-stream": "^4.5.20",
"tslib": "^2.6.2"
},
"dependencies": {
@@ -14397,19 +14398,19 @@
}
},
"@aws-sdk/credential-provider-ini": {
- "version": "3.972.20",
- "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.972.20.tgz",
- "integrity": "sha512-5flXSnKHMloObNF+9N0cupKegnH1Z37cdVlpETVgx8/rAhCe+VNlkcZH3HDg2SDn9bI765S+rhNPXGDJJPfbtA==",
- "dev": true,
- "requires": {
- "@aws-sdk/core": "^3.973.20",
- "@aws-sdk/credential-provider-env": "^3.972.18",
- "@aws-sdk/credential-provider-http": "^3.972.20",
- "@aws-sdk/credential-provider-login": "^3.972.20",
- "@aws-sdk/credential-provider-process": "^3.972.18",
- "@aws-sdk/credential-provider-sso": "^3.972.20",
- "@aws-sdk/credential-provider-web-identity": "^3.972.20",
- "@aws-sdk/nested-clients": "^3.996.10",
+ "version": "3.972.22",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.972.22.tgz",
+ "integrity": "sha512-rpF8fBT0LllMDp78s62aL2A/8MaccjyJ0ORzqu+ZADeECLSrrCWIeeXsuRam+pxiAMkI1uIyDZJmgLGdadkPXw==",
+ "dev": true,
+ "requires": {
+ "@aws-sdk/core": "^3.973.22",
+ "@aws-sdk/credential-provider-env": "^3.972.20",
+ "@aws-sdk/credential-provider-http": "^3.972.22",
+ "@aws-sdk/credential-provider-login": "^3.972.22",
+ "@aws-sdk/credential-provider-process": "^3.972.20",
+ "@aws-sdk/credential-provider-sso": "^3.972.22",
+ "@aws-sdk/credential-provider-web-identity": "^3.972.22",
+ "@aws-sdk/nested-clients": "^3.996.12",
"@aws-sdk/types": "^3.973.6",
"@smithy/credential-provider-imds": "^4.2.12",
"@smithy/property-provider": "^4.2.12",
@@ -14427,13 +14428,13 @@
}
},
"@aws-sdk/credential-provider-login": {
- "version": "3.972.20",
- "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-login/-/credential-provider-login-3.972.20.tgz",
- "integrity": "sha512-gEWo54nfqp2jABMu6HNsjVC4hDLpg9HC8IKSJnp0kqWtxIJYHTmiLSsIfI4ScQjxEwpB+jOOH8dOLax1+hy/Hw==",
+ "version": "3.972.22",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-login/-/credential-provider-login-3.972.22.tgz",
+ "integrity": "sha512-u33CO9zeNznlVSg9tWTCRYxaGkqr1ufU6qeClpmzAabXZa8RZxQoVXxL5T53oZJFzQYj+FImORCSsi7H7B77gQ==",
"dev": true,
"requires": {
- "@aws-sdk/core": "^3.973.20",
- "@aws-sdk/nested-clients": "^3.996.10",
+ "@aws-sdk/core": "^3.973.22",
+ "@aws-sdk/nested-clients": "^3.996.12",
"@aws-sdk/types": "^3.973.6",
"@smithy/property-provider": "^4.2.12",
"@smithy/protocol-http": "^5.3.12",
@@ -14451,17 +14452,17 @@
}
},
"@aws-sdk/credential-provider-node": {
- "version": "3.972.21",
- "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.972.21.tgz",
- "integrity": "sha512-hah8if3/B/Q+LBYN5FukyQ1Mym6PLPDsBOBsIgNEYD6wLyZg0UmUF/OKIVC3nX9XH8TfTPuITK+7N/jenVACWA==",
+ "version": "3.972.23",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.972.23.tgz",
+ "integrity": "sha512-U8tyLbLOZItuVWTH0ay9gWo4xMqZwqQbg1oMzdU4FQSkTpqXemm4X0uoKBR6llqAStgBp30ziKFJHTA43l4qMw==",
"dev": true,
"requires": {
- "@aws-sdk/credential-provider-env": "^3.972.18",
- "@aws-sdk/credential-provider-http": "^3.972.20",
- "@aws-sdk/credential-provider-ini": "^3.972.20",
- "@aws-sdk/credential-provider-process": "^3.972.18",
- "@aws-sdk/credential-provider-sso": "^3.972.20",
- "@aws-sdk/credential-provider-web-identity": "^3.972.20",
+ "@aws-sdk/credential-provider-env": "^3.972.20",
+ "@aws-sdk/credential-provider-http": "^3.972.22",
+ "@aws-sdk/credential-provider-ini": "^3.972.22",
+ "@aws-sdk/credential-provider-process": "^3.972.20",
+ "@aws-sdk/credential-provider-sso": "^3.972.22",
+ "@aws-sdk/credential-provider-web-identity": "^3.972.22",
"@aws-sdk/types": "^3.973.6",
"@smithy/credential-provider-imds": "^4.2.12",
"@smithy/property-provider": "^4.2.12",
@@ -14479,12 +14480,12 @@
}
},
"@aws-sdk/credential-provider-process": {
- "version": "3.972.18",
- "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.972.18.tgz",
- "integrity": "sha512-Tpl7SRaPoOLT32jbTWchPsn52hYYgJ0kpiFgnwk8pxTANQdUymVSZkzFvv1+oOgZm1CrbQUP9MBeoMZ9IzLZjA==",
+ "version": "3.972.20",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.972.20.tgz",
+ "integrity": "sha512-QRfk7GbA4/HDRjhP3QYR6QBr/QKreVoOzvvlRHnOuGgYJkeoPgPY3LAI1kK1ZMgZ4hH9KiGp757/ntol+INAig==",
"dev": true,
"requires": {
- "@aws-sdk/core": "^3.973.20",
+ "@aws-sdk/core": "^3.973.22",
"@aws-sdk/types": "^3.973.6",
"@smithy/property-provider": "^4.2.12",
"@smithy/shared-ini-file-loader": "^4.4.7",
@@ -14501,14 +14502,14 @@
}
},
"@aws-sdk/credential-provider-sso": {
- "version": "3.972.20",
- "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.972.20.tgz",
- "integrity": "sha512-p+R+PYR5Z7Gjqf/6pvbCnzEHcqPCpLzR7Yf127HjJ6EAb4hUcD+qsNRnuww1sB/RmSeCLxyay8FMyqREw4p1RA==",
+ "version": "3.972.22",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.972.22.tgz",
+ "integrity": "sha512-4vqlSaUbBj4aNPVKfB6yXuIQ2Z2mvLfIGba2OzzF6zUkN437/PGWsxBU2F8QPSFHti6seckvyCXidU3H+R8NvQ==",
"dev": true,
"requires": {
- "@aws-sdk/core": "^3.973.20",
- "@aws-sdk/nested-clients": "^3.996.10",
- "@aws-sdk/token-providers": "3.1009.0",
+ "@aws-sdk/core": "^3.973.22",
+ "@aws-sdk/nested-clients": "^3.996.12",
+ "@aws-sdk/token-providers": "3.1013.0",
"@aws-sdk/types": "^3.973.6",
"@smithy/property-provider": "^4.2.12",
"@smithy/shared-ini-file-loader": "^4.4.7",
@@ -14525,13 +14526,13 @@
}
},
"@aws-sdk/credential-provider-web-identity": {
- "version": "3.972.20",
- "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.972.20.tgz",
- "integrity": "sha512-rWCmh8o7QY4CsUj63qopzMzkDq/yPpkrpb+CnjBEFSOg/02T/we7sSTVg4QsDiVS9uwZ8VyONhq98qt+pIh3KA==",
+ "version": "3.972.22",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.972.22.tgz",
+ "integrity": "sha512-/wN1CYg2rVLhW8/jLxMWacQrkpaynnL+4j/Z+e6X1PfoE6NiC0BeOw3i0JmtZrKun85wNV5GmspvuWJihfeeUw==",
"dev": true,
"requires": {
- "@aws-sdk/core": "^3.973.20",
- "@aws-sdk/nested-clients": "^3.996.10",
+ "@aws-sdk/core": "^3.973.22",
+ "@aws-sdk/nested-clients": "^3.996.12",
"@aws-sdk/types": "^3.973.6",
"@smithy/property-provider": "^4.2.12",
"@smithy/shared-ini-file-loader": "^4.4.7",
@@ -14749,15 +14750,15 @@
}
},
"@aws-sdk/middleware-user-agent": {
- "version": "3.972.21",
- "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.972.21.tgz",
- "integrity": "sha512-62XRl1GDYPpkt7cx1AX1SPy9wgNE9Iw/NPuurJu4lmhCWS7sGKO+kS53TQ8eRmIxy3skmvNInnk0ZbWrU5Dpyg==",
+ "version": "3.972.23",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.972.23.tgz",
+ "integrity": "sha512-HQu8QoqGZZTvg0Spl9H39QTsSMFwgu+8yz/QGKndXFLk9FZMiCiIgBCVlTVKMDvVbgqIzD9ig+/HmXsIL2Rb+g==",
"dev": true,
"requires": {
- "@aws-sdk/core": "^3.973.20",
+ "@aws-sdk/core": "^3.973.22",
"@aws-sdk/types": "^3.973.6",
"@aws-sdk/util-endpoints": "^3.996.5",
- "@smithy/core": "^3.23.11",
+ "@smithy/core": "^3.23.12",
"@smithy/protocol-http": "^5.3.12",
"@smithy/types": "^4.13.1",
"@smithy/util-retry": "^4.2.12",
@@ -14773,44 +14774,44 @@
}
},
"@aws-sdk/nested-clients": {
- "version": "3.996.10",
- "resolved": "https://registry.npmjs.org/@aws-sdk/nested-clients/-/nested-clients-3.996.10.tgz",
- "integrity": "sha512-SlDol5Z+C7Ivnc2rKGqiqfSUmUZzY1qHfVs9myt/nxVwswgfpjdKahyTzLTx802Zfq0NFRs7AejwKzzzl5Co2w==",
+ "version": "3.996.12",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/nested-clients/-/nested-clients-3.996.12.tgz",
+ "integrity": "sha512-KLdQGJPSm98uLINolQ0Tol8OAbk7g0Y7zplHJ1K83vbMIH13aoCvR6Tho66xueW4l4aZlEgVGLWBnD8ifUMsGQ==",
"dev": true,
"requires": {
"@aws-crypto/sha256-browser": "5.2.0",
"@aws-crypto/sha256-js": "5.2.0",
- "@aws-sdk/core": "^3.973.20",
+ "@aws-sdk/core": "^3.973.22",
"@aws-sdk/middleware-host-header": "^3.972.8",
"@aws-sdk/middleware-logger": "^3.972.8",
"@aws-sdk/middleware-recursion-detection": "^3.972.8",
- "@aws-sdk/middleware-user-agent": "^3.972.21",
+ "@aws-sdk/middleware-user-agent": "^3.972.23",
"@aws-sdk/region-config-resolver": "^3.972.8",
"@aws-sdk/types": "^3.973.6",
"@aws-sdk/util-endpoints": "^3.996.5",
"@aws-sdk/util-user-agent-browser": "^3.972.8",
- "@aws-sdk/util-user-agent-node": "^3.973.7",
+ "@aws-sdk/util-user-agent-node": "^3.973.9",
"@smithy/config-resolver": "^4.4.11",
- "@smithy/core": "^3.23.11",
+ "@smithy/core": "^3.23.12",
"@smithy/fetch-http-handler": "^5.3.15",
"@smithy/hash-node": "^4.2.12",
"@smithy/invalid-dependency": "^4.2.12",
"@smithy/middleware-content-length": "^4.2.12",
- "@smithy/middleware-endpoint": "^4.4.25",
- "@smithy/middleware-retry": "^4.4.42",
- "@smithy/middleware-serde": "^4.2.14",
+ "@smithy/middleware-endpoint": "^4.4.26",
+ "@smithy/middleware-retry": "^4.4.43",
+ "@smithy/middleware-serde": "^4.2.15",
"@smithy/middleware-stack": "^4.2.12",
"@smithy/node-config-provider": "^4.3.12",
- "@smithy/node-http-handler": "^4.4.16",
+ "@smithy/node-http-handler": "^4.5.0",
"@smithy/protocol-http": "^5.3.12",
- "@smithy/smithy-client": "^4.12.5",
+ "@smithy/smithy-client": "^4.12.6",
"@smithy/types": "^4.13.1",
"@smithy/url-parser": "^4.2.12",
"@smithy/util-base64": "^4.3.2",
"@smithy/util-body-length-browser": "^4.2.2",
"@smithy/util-body-length-node": "^4.2.3",
- "@smithy/util-defaults-mode-browser": "^4.3.41",
- "@smithy/util-defaults-mode-node": "^4.2.44",
+ "@smithy/util-defaults-mode-browser": "^4.3.42",
+ "@smithy/util-defaults-mode-node": "^4.2.45",
"@smithy/util-endpoints": "^3.3.3",
"@smithy/util-middleware": "^4.2.12",
"@smithy/util-retry": "^4.2.12",
@@ -14870,13 +14871,13 @@
}
},
"@aws-sdk/token-providers": {
- "version": "3.1009.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.1009.0.tgz",
- "integrity": "sha512-KCPLuTqN9u0Rr38Arln78fRG9KXpzsPWmof+PZzfAHMMQq2QED6YjQrkrfiH7PDefLWEposY1o4/eGwrmKA4JA==",
+ "version": "3.1013.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.1013.0.tgz",
+ "integrity": "sha512-IL1c54UvbuERrs9oLm5rvkzMciwhhpn1FL0SlC3XUMoLlFhdBsWJgQKK8O5fsQLxbFVqjbjFx9OBkrn44X9PHw==",
"dev": true,
"requires": {
- "@aws-sdk/core": "^3.973.20",
- "@aws-sdk/nested-clients": "^3.996.10",
+ "@aws-sdk/core": "^3.973.22",
+ "@aws-sdk/nested-clients": "^3.996.12",
"@aws-sdk/types": "^3.973.6",
"@smithy/property-provider": "^4.2.12",
"@smithy/shared-ini-file-loader": "^4.4.7",
@@ -14986,12 +14987,12 @@
}
},
"@aws-sdk/util-user-agent-node": {
- "version": "3.973.7",
- "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.973.7.tgz",
- "integrity": "sha512-Hz6EZMUAEzqUd7e+vZ9LE7mn+5gMbxltXy18v+YSFY+9LBJz15wkNZvw5JqfX3z0FS9n3bgUtz3L5rAsfh4YlA==",
+ "version": "3.973.9",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.973.9.tgz",
+ "integrity": "sha512-jeFqqp8KD/P5O+qeKxyGeu7WEVIZFNprnkaDjGmBOjwxYwafCBhpxTgV1TlW6L8e76Vh/siNylNmN/OmSIFBUQ==",
"dev": true,
"requires": {
- "@aws-sdk/middleware-user-agent": "^3.972.21",
+ "@aws-sdk/middleware-user-agent": "^3.972.23",
"@aws-sdk/types": "^3.973.6",
"@smithy/node-config-provider": "^4.3.12",
"@smithy/types": "^4.13.1",
@@ -15008,13 +15009,13 @@
}
},
"@aws-sdk/xml-builder": {
- "version": "3.972.11",
- "resolved": "https://registry.npmjs.org/@aws-sdk/xml-builder/-/xml-builder-3.972.11.tgz",
- "integrity": "sha512-iitV/gZKQMvY9d7ovmyFnFuTHbBAtrmLnvaSb/3X8vOKyevwtpmEtyc8AdhVWZe0pI/1GsHxlEvQeOePFzy7KQ==",
+ "version": "3.972.14",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/xml-builder/-/xml-builder-3.972.14.tgz",
+ "integrity": "sha512-G/Yd8Bnnyh8QrqLf8jWJbixEnScUFW24e/wOBGYdw1Cl4r80KX/DvHyM2GVZ2vTp7J4gTEr8IXJlTadA8+UfuQ==",
"dev": true,
"requires": {
"@smithy/types": "^4.13.1",
- "fast-xml-parser": "5.4.1",
+ "fast-xml-parser": "5.5.6",
"tslib": "^2.6.2"
},
"dependencies": {
@@ -20216,12 +20217,13 @@
}
},
"fast-xml-parser": {
- "version": "5.4.1",
- "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.4.1.tgz",
- "integrity": "sha512-BQ30U1mKkvXQXXkAGcuyUA/GA26oEB7NzOtsxCDtyu62sjGw5QraKFhx2Em3WQNjPw9PG6MQ9yuIIgkSDfGu5A==",
+ "version": "5.5.6",
+ "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.5.6.tgz",
+ "integrity": "sha512-3+fdZyBRVg29n4rXP0joHthhcHdPUHaIC16cuyyd1iLsuaO6Vea36MPrxgAzbZna8lhvZeRL8Bc9GP56/J9xEw==",
"dev": true,
"requires": {
- "fast-xml-builder": "^1.0.0",
+ "fast-xml-builder": "^1.1.4",
+ "path-expression-matcher": "^1.1.3",
"strnum": "^2.1.2"
}
},
@@ -22688,9 +22690,9 @@
"dev": true
},
"strnum": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/strnum/-/strnum-2.2.0.tgz",
- "integrity": "sha512-Y7Bj8XyJxnPAORMZj/xltsfo55uOiyHcU2tnAVzHUnSJR/KsEX+9RoDeXEnsXtl/CX4fAcrt64gZ13aGaWPeBg==",
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/strnum/-/strnum-2.2.1.tgz",
+ "integrity": "sha512-BwRvNd5/QoAtyW1na1y1LsJGQNvRlkde6Q/ipqqEaivoMdV+B1OMOTVdwR+N/cwVUcIt9PYyHmV8HyexCZSupg==",
"dev": true
},
"strtok3": {
diff --git a/package.json b/package.json
index 856466cb8..d089b5792 100644
--- a/package.json
+++ b/package.json
@@ -48,6 +48,7 @@
"test:browser": "vitest run --project browser",
"test:unit": "vitest run --project node",
"test:tasks": "vitest run --project tasks",
+ "test:publish": "npm run build && vitest run --project publish",
"test:browser-smoke": "playwright test --config tests/browser/playwright.config.js",
"test:serve": "npx serve -l 9999 .",
"test:integration": "npm run build && ./tests/integration/run-integration-tests.sh",
diff --git a/tasks/publish-to-aws.js b/tasks/publish-to-aws.js
index 00cb9f693..80b2b5120 100644
--- a/tasks/publish-to-aws.js
+++ b/tasks/publish-to-aws.js
@@ -4,6 +4,13 @@ const { S3, PutObjectCommand } = require('@aws-sdk/client-s3');
const git = require('./util/git');
const semver = require('semver');
+const PUBLISHED_FILES = [
+ 'handlebars.js',
+ 'handlebars.min.js',
+ 'handlebars.runtime.js',
+ 'handlebars.runtime.min.js',
+];
+
let s3Client;
async function main() {
@@ -13,24 +20,28 @@ async function main() {
const commitInfo = await git.commitInfo();
console.log('tag: ', commitInfo.tagName);
+ const suffixes = buildSuffixes(commitInfo);
+
+ if (suffixes.length > 0) {
+ validateS3Env();
+ console.log('publishing file-suffixes: ' + JSON.stringify(suffixes));
+ await publish(suffixes);
+ }
+}
+
+function buildSuffixes(commitInfo) {
const suffixes = [];
- // Publish the master as "latest" and with the commit-id
if (commitInfo.isMaster) {
suffixes.push('-latest');
suffixes.push('-' + commitInfo.headSha);
}
- // Publish tags by their tag-name
if (commitInfo.tagName != null && semver.valid(commitInfo.tagName)) {
suffixes.push('-' + commitInfo.tagName);
}
- if (suffixes.length > 0) {
- validateS3Env();
- console.log('publishing file-suffixes: ' + JSON.stringify(suffixes));
- await publish(suffixes);
- }
+ return suffixes;
}
function validateS3Env() {
@@ -44,33 +55,30 @@ function validateS3Env() {
}
}
-async function publish(suffixes) {
- const publishPromises = suffixes.map((suffix) => publishSuffix(suffix));
+async function publish(suffixes, overrides) {
+ const publishPromises = suffixes.map((suffix) =>
+ publishSuffix(suffix, overrides)
+ );
return Promise.all(publishPromises);
}
-async function publishSuffix(suffix) {
- const filenames = [
- 'handlebars.js',
- 'handlebars.min.js',
- 'handlebars.runtime.js',
- 'handlebars.runtime.min.js',
- ];
- const publishPromises = filenames.map(async (filename) => {
+async function publishSuffix(suffix, overrides) {
+ const publishPromises = PUBLISHED_FILES.map(async (filename) => {
const nameInBucket = getNameInBucket(filename, suffix);
const localFile = getLocalFile(filename);
- await uploadToBucket(localFile, nameInBucket);
+ await uploadToBucket(localFile, nameInBucket, overrides);
console.log(`Published ${localFile} to build server (${nameInBucket})`);
});
return Promise.all(publishPromises);
}
-async function uploadToBucket(localFile, nameInBucket) {
- const s3 = getS3Client();
+async function uploadToBucket(localFile, nameInBucket, overrides) {
+ const s3 = overrides?.s3Client ?? getS3Client();
+ const bucket = overrides?.bucket ?? process.env.S3_BUCKET_NAME;
return s3.send(
new PutObjectCommand({
- Bucket: process.env.S3_BUCKET_NAME,
+ Bucket: bucket,
Key: nameInBucket,
Body: fs.readFileSync(localFile, 'utf8'),
})
@@ -98,6 +106,15 @@ function getLocalFile(filename) {
return 'dist/' + filename;
}
+module.exports = {
+ PUBLISHED_FILES,
+ buildSuffixes,
+ validateS3Env,
+ publish,
+ getNameInBucket,
+ getLocalFile,
+};
+
if (require.main === module) {
main().catch((err) => {
console.error(err);
diff --git a/tasks/tests/fake-s3.js b/tasks/tests/fake-s3.js
new file mode 100644
index 000000000..a12cc26e6
--- /dev/null
+++ b/tasks/tests/fake-s3.js
@@ -0,0 +1,81 @@
+const http = require('http');
+
+/**
+ * Minimal in-memory S3-compatible server for testing.
+ * Supports PutObject and GetObject via path-style requests.
+ */
+function createFakeS3() {
+ const buckets = new Map();
+
+ const server = http.createServer((req, res) => {
+ const { bucket, key } = parsePath(req.url);
+
+ if (!bucket || !buckets.has(bucket)) {
+ res.writeHead(404, { 'Content-Type': 'application/xml' });
+ res.end('NoSuchBucket');
+ return;
+ }
+
+ const store = buckets.get(bucket);
+
+ if (req.method === 'PUT' && key) {
+ const chunks = [];
+ req.on('data', (chunk) => chunks.push(chunk));
+ req.on('end', () => {
+ store.set(key, Buffer.concat(chunks));
+ res.writeHead(200);
+ res.end();
+ });
+ } else if ((req.method === 'GET' || req.method === 'HEAD') && key) {
+ if (!store.has(key)) {
+ res.writeHead(404, { 'Content-Type': 'application/xml' });
+ res.end('NoSuchKey');
+ return;
+ }
+ const body = store.get(key);
+ res.writeHead(200, {
+ 'Content-Length': body.length,
+ 'Content-Type': 'application/octet-stream',
+ });
+ res.end(req.method === 'HEAD' ? undefined : body);
+ } else {
+ res.writeHead(405);
+ res.end();
+ }
+ });
+
+ return {
+ start() {
+ return new Promise((resolve) => {
+ server.listen(0, '127.0.0.1', () => {
+ const { port } = server.address();
+ resolve({
+ address: `http://127.0.0.1:${port}`,
+ createBucket(name) {
+ if (!buckets.has(name)) buckets.set(name, new Map());
+ },
+ reset() {
+ for (const store of buckets.values()) store.clear();
+ },
+ stop() {
+ return new Promise((r) => server.close(r));
+ },
+ });
+ });
+ });
+ },
+ };
+}
+
+function parsePath(url) {
+ // Path-style: //
+ const parts = new URL(url, 'http://localhost').pathname
+ .replace(/^\//, '')
+ .split('/');
+ return {
+ bucket: parts[0] || null,
+ key: parts.slice(1).join('/') || null,
+ };
+}
+
+module.exports = { createFakeS3 };
diff --git a/tasks/tests/publish-to-aws.test.js b/tasks/tests/publish-to-aws.test.js
new file mode 100644
index 000000000..70b5ce8fa
--- /dev/null
+++ b/tasks/tests/publish-to-aws.test.js
@@ -0,0 +1,221 @@
+const fs = require('fs');
+const { S3, GetObjectCommand } = require('@aws-sdk/client-s3');
+const { createFakeS3 } = require('./fake-s3');
+
+const BUCKET = 'test-bucket';
+
+const {
+ PUBLISHED_FILES,
+ buildSuffixes,
+ validateS3Env,
+ publish,
+ getNameInBucket,
+ getLocalFile,
+} = require('../publish-to-aws');
+
+let server;
+let s3Client;
+
+beforeAll(async () => {
+ server = await createFakeS3().start();
+ server.createBucket(BUCKET);
+
+ s3Client = new S3({
+ endpoint: server.address,
+ region: 'us-east-1',
+ credentials: { accessKeyId: 'test', secretAccessKey: 'test' },
+ forcePathStyle: true,
+ });
+});
+
+afterAll(async () => {
+ await server?.stop();
+});
+
+beforeEach(() => {
+ server.reset();
+});
+
+async function getObjectBody(key) {
+ const response = await s3Client.send(
+ new GetObjectCommand({ Bucket: BUCKET, Key: key })
+ );
+ return response.Body.transformToString();
+}
+
+describe('buildSuffixes', () => {
+ it('should add -latest and commit sha for master', () => {
+ const result = buildSuffixes({
+ isMaster: true,
+ headSha: 'abc123',
+ tagName: null,
+ });
+ expect(result).toEqual(['-latest', '-abc123']);
+ });
+
+ it('should add tag suffix for valid semver tag', () => {
+ const result = buildSuffixes({
+ isMaster: false,
+ headSha: 'abc123',
+ tagName: '4.7.0',
+ });
+ expect(result).toEqual(['-4.7.0']);
+ });
+
+ it('should add both master and tag suffixes when on master with a tag', () => {
+ const result = buildSuffixes({
+ isMaster: true,
+ headSha: 'abc123',
+ tagName: '4.7.0',
+ });
+ expect(result).toEqual(['-latest', '-abc123', '-4.7.0']);
+ });
+
+ it('should return empty array for non-master with no valid tag', () => {
+ const result = buildSuffixes({
+ isMaster: false,
+ headSha: 'abc123',
+ tagName: null,
+ });
+ expect(result).toEqual([]);
+ });
+
+ it('should ignore invalid semver tags', () => {
+ const result = buildSuffixes({
+ isMaster: false,
+ headSha: 'abc123',
+ tagName: 'not-semver',
+ });
+ expect(result).toEqual([]);
+ });
+});
+
+describe('getNameInBucket', () => {
+ it('should insert suffix before .js extension', () => {
+ expect(getNameInBucket('handlebars.js', '-latest')).toBe(
+ 'handlebars-latest.js'
+ );
+ });
+
+ it('should handle .min.js files', () => {
+ expect(getNameInBucket('handlebars.min.js', '-4.7.0')).toBe(
+ 'handlebars.min-4.7.0.js'
+ );
+ });
+
+ it('should handle runtime files', () => {
+ expect(getNameInBucket('handlebars.runtime.js', '-abc123')).toBe(
+ 'handlebars.runtime-abc123.js'
+ );
+ });
+});
+
+describe('getLocalFile', () => {
+ it('should prefix with dist/', () => {
+ expect(getLocalFile('handlebars.js')).toBe('dist/handlebars.js');
+ });
+});
+
+describe('validateS3Env', () => {
+ const S3_KEYS = [
+ 'S3_BUCKET_NAME',
+ 'S3_REGION',
+ 'S3_ACCESS_KEY_ID',
+ 'S3_SECRET_ACCESS_KEY',
+ ];
+ const saved = {};
+
+ beforeEach(() => {
+ for (const key of S3_KEYS) {
+ saved[key] = process.env[key];
+ }
+ });
+
+ afterEach(() => {
+ for (const key of S3_KEYS) {
+ if (saved[key] === undefined) {
+ delete process.env[key];
+ } else {
+ process.env[key] = saved[key];
+ }
+ }
+ });
+
+ it('should throw when S3 env vars are missing', () => {
+ for (const key of S3_KEYS) {
+ delete process.env[key];
+ }
+
+ expect(() => validateS3Env()).toThrow('Missing S3 config values');
+ });
+
+ it('should not throw when all S3 env vars are set', () => {
+ process.env.S3_BUCKET_NAME = 'test-bucket';
+ process.env.S3_REGION = 'us-east-1';
+ process.env.S3_ACCESS_KEY_ID = 'key';
+ process.env.S3_SECRET_ACCESS_KEY = 'secret';
+
+ expect(() => validateS3Env()).not.toThrow();
+ });
+});
+
+describe('publish to S3', () => {
+ const overrides = {};
+
+ beforeAll(() => {
+ overrides.s3Client = s3Client;
+ overrides.bucket = BUCKET;
+ });
+
+ it('should upload all 4 files for a single suffix', async () => {
+ await publish(['-latest'], overrides);
+
+ for (const filename of PUBLISHED_FILES) {
+ const key = getNameInBucket(filename, '-latest');
+ const body = await getObjectBody(key);
+ const localContent = fs.readFileSync(getLocalFile(filename), 'utf8');
+ expect(body).toBe(localContent);
+ }
+ });
+
+ it('should upload files for multiple suffixes', async () => {
+ await publish(['-latest', '-abc123'], overrides);
+
+ for (const suffix of ['-latest', '-abc123']) {
+ for (const filename of PUBLISHED_FILES) {
+ const key = getNameInBucket(filename, suffix);
+ const body = await getObjectBody(key);
+ expect(body).toBeTruthy();
+ }
+ }
+ });
+
+ it('should upload correct content from dist/', async () => {
+ await publish(['-v1.0.0'], overrides);
+
+ const key = getNameInBucket('handlebars.js', '-v1.0.0');
+ const uploaded = await getObjectBody(key);
+ const local = fs.readFileSync('dist/handlebars.js', 'utf8');
+ expect(uploaded).toBe(local);
+ });
+
+ it('should produce correct keys for a version tag', async () => {
+ await publish(['-4.7.0'], overrides);
+
+ const expectedKeys = PUBLISHED_FILES.map((f) =>
+ getNameInBucket(f, '-4.7.0')
+ );
+
+ for (const key of expectedKeys) {
+ const body = await getObjectBody(key);
+ expect(body).toBeTruthy();
+ }
+
+ expect(expectedKeys).toEqual([
+ 'handlebars-4.7.0.js',
+ 'handlebars.min-4.7.0.js',
+ 'handlebars.runtime-4.7.0.js',
+ 'handlebars.runtime.min-4.7.0.js',
+ ]);
+ });
+});
diff --git a/tasks/util/async-grunt-task.js b/tasks/util/async-grunt-task.js
deleted file mode 100644
index 432d68afd..000000000
--- a/tasks/util/async-grunt-task.js
+++ /dev/null
@@ -1,13 +0,0 @@
-module.exports = { createRegisterAsyncTaskFn };
-
-function createRegisterAsyncTaskFn(grunt) {
- return function registerAsyncTask(name, asyncFunction) {
- grunt.registerTask(name, function () {
- asyncFunction()
- .catch((error) => {
- grunt.fatal(error);
- })
- .finally(this.async());
- });
- };
-}
diff --git a/tasks/version.js b/tasks/version.js
index 4c7749873..39bf11da6 100644
--- a/tasks/version.js
+++ b/tasks/version.js
@@ -1,63 +1,68 @@
+const fs = require('fs');
const { execSync } = require('child_process');
const git = require('./util/git');
const semver = require('semver');
-const { createRegisterAsyncTaskFn } = require('./util/async-grunt-task');
-
-module.exports = function (grunt) {
- const registerAsyncTask = createRegisterAsyncTaskFn(grunt);
-
- registerAsyncTask('version', async () => {
- const pkg = grunt.config('pkg');
- const version = grunt.option('ver');
- if (!semver.valid(version)) {
- throw new Error(
- 'Must provide a version number (Ex: --ver=1.0.0):\n\t' +
- version +
- '\n\n'
- );
- }
- pkg.version = version;
- grunt.config('pkg', pkg);
-
- const replaceSpec = [
- {
- path: 'lib/handlebars/base.js',
- regex: /const VERSION = ['"](.*)['"];/,
- replacement: `const VERSION = '${version}';`,
- },
- {
- path: 'components/bower.json',
- regex: /"version":.*/,
- replacement: `"version": "${version}",`,
- },
- {
- path: 'components/package.json',
- regex: /"version":.*/,
- replacement: `"version": "${version}",`,
- },
- {
- path: 'components/handlebars.js.nuspec',
- regex: /.*<\/version>/,
- replacement: `${version}`,
- },
- ];
-
- await Promise.all(
- replaceSpec.map((replaceSpec) =>
- replaceAndAdd(
- replaceSpec.path,
- replaceSpec.regex,
- replaceSpec.replacement
- )
- )
- );
- execSync('npm run build', { stdio: 'inherit' });
- });
- async function replaceAndAdd(path, regex, value) {
- let content = grunt.file.read(path);
- content = content.replace(regex, value);
- grunt.file.write(path, content);
- await git.add(path);
+async function main() {
+ const version = process.argv[2];
+ if (!semver.valid(version)) {
+ throw new Error(
+ 'Must provide a valid semver version as first argument (e.g.: node tasks/version.js 1.0.0):\n\t' +
+ version +
+ '\n\n'
+ );
}
-};
+
+ const pkg = JSON.parse(fs.readFileSync('package.json', 'utf8'));
+ pkg.version = version;
+ fs.writeFileSync('package.json', JSON.stringify(pkg, null, 2) + '\n');
+ await git.add('package.json');
+
+ const replaceSpec = [
+ {
+ path: 'lib/handlebars/base.js',
+ regex: /const VERSION = ['"](.*)['"];/,
+ replacement: `const VERSION = '${version}';`,
+ },
+ {
+ path: 'components/bower.json',
+ regex: /"version":.*/,
+ replacement: `"version": "${version}",`,
+ },
+ {
+ path: 'components/package.json',
+ regex: /"version":.*/,
+ replacement: `"version": "${version}",`,
+ },
+ {
+ path: 'components/handlebars.js.nuspec',
+ regex: /.*<\/version>/,
+ replacement: `${version}`,
+ },
+ ];
+
+ await Promise.all(
+ replaceSpec.map((spec) =>
+ replaceAndAdd(spec.path, spec.regex, spec.replacement)
+ )
+ );
+
+ execSync('npm run build', { stdio: 'inherit' });
+}
+
+async function replaceAndAdd(filePath, regex, value) {
+ let content = fs.readFileSync(filePath, 'utf8');
+ content = content.replace(regex, value);
+ fs.writeFileSync(filePath, content);
+ await git.add(filePath);
+}
+
+module.exports = { replaceAndAdd };
+
+if (require.main === module) {
+ main().catch((err) => {
+ // eslint-disable-next-line no-console
+ console.error(err);
+ process.exit(1);
+ });
+}
diff --git a/tests/browser/README.md b/tests/browser/README.md
index 74d3d3c71..b04bc0ff7 100644
--- a/tests/browser/README.md
+++ b/tests/browser/README.md
@@ -8,7 +8,7 @@ Execute the following commands in the project root:
```bash
npm install
-npx grunt prepare
+npm run build
docker pull mcr.microsoft.com/playwright:focal
docker run -it --rm --volume $(pwd):/srv/app --workdir /srv/app --ipc=host mcr.microsoft.com/playwright:focal npm run test:browser
```
diff --git a/vitest.config.js b/vitest.config.js
index b475d4992..6cf88605b 100644
--- a/vitest.config.js
+++ b/vitest.config.js
@@ -17,6 +17,7 @@ export default defineConfig({
test: {
name: 'tasks',
include: ['tasks/tests/*.test.js'],
+ exclude: ['tasks/tests/publish-to-aws.test.js'],
globals: true,
pool: 'forks',
},
@@ -28,6 +29,14 @@ export default defineConfig({
globals: true,
},
},
+ {
+ test: {
+ name: 'publish',
+ include: ['tasks/tests/publish-to-aws.test.js'],
+ globals: true,
+ pool: 'forks',
+ },
+ },
{
test: {
name: 'browser',