mirror of
https://github.com/discordjs/discord.js.git
synced 2026-03-09 16:13:31 +01:00
ci: better release workflow (#10325)
* ci: better release workflow * ci: simplify + use changelog * ci(release): better parsing and exclusions * ci(release): remove tree log * ci(release): improve logs * ci(release): properly check inputs * ci(release): better promise handling Co-authored-by: Aura <kyradiscord@gmail.com> * ci: refactor release to use bun * ci(release): whitespace Co-authored-by: Vlad Frangu <kingdgrizzle@gmail.com> * ci(release): add dev release handling * ci(release): fixes from testing * ci(release): make the promise run * ci(release): when specifying package, skip exclusions * ci(dev): create-discord-bot dev release * ci(release): improve changelog detection * ci: fix typo and allow releasing branches * ci(release): set make_latest for gh releases * ci(release): add ssh_key so pushed tags run workflow --------- Co-authored-by: Aura <kyradiscord@gmail.com> Co-authored-by: Vlad Frangu <kingdgrizzle@gmail.com> Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
This commit is contained in:
32
.github/workflows/publish-dev.yml
vendored
32
.github/workflows/publish-dev.yml
vendored
@@ -3,6 +3,10 @@ on:
|
||||
schedule:
|
||||
- cron: '0 */12 * * *'
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
dry_run:
|
||||
type: boolean
|
||||
default: false
|
||||
jobs:
|
||||
npm-publish:
|
||||
name: npm publish
|
||||
@@ -55,32 +59,18 @@ jobs:
|
||||
node-version: 22
|
||||
registry-url: https://registry.npmjs.org/
|
||||
|
||||
- name: Check the current development version
|
||||
id: release-check
|
||||
run: |
|
||||
if [[ $(npm view ${{ matrix.package }}@dev version | grep -e "$(git rev-parse --short HEAD)") ]]; \
|
||||
then echo "RELEASE=0" >> "$GITHUB_OUTPUT"; \
|
||||
else echo "RELEASE=1" >> "$GITHUB_OUTPUT"; \
|
||||
fi
|
||||
|
||||
- name: Install dependencies
|
||||
if: steps.release-check.outputs.release == '1'
|
||||
uses: ./packages/actions/src/pnpmCache
|
||||
|
||||
- name: Build dependencies
|
||||
if: steps.release-check.outputs.release == '1'
|
||||
run: pnpm run build
|
||||
|
||||
- name: Publish package
|
||||
if: steps.release-check.outputs.release == '1'
|
||||
run: |
|
||||
pnpm --filter=${{ matrix.package }} run release --preid "dev.$(date +%s)-$(git rev-parse --short HEAD)" --skip-changelog
|
||||
pnpm --filter=${{ matrix.package }} publish --provenance --no-git-checks --tag dev || true
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{ secrets.NPM_PUBLISH_TOKEN }}
|
||||
|
||||
- name: Deprecate prior development releases
|
||||
if: steps.release-check.outputs.release == '1'
|
||||
run: pnpm exec npm-deprecate --name "*dev*" --message "This version is deprecated. Please use a newer version." --package ${{ matrix.package }}
|
||||
- name: Publish packages
|
||||
uses: ./packages/actions/src/releasePackages
|
||||
with:
|
||||
exclude: '@discordjs/docgen'
|
||||
dry: ${{ inputs.dry_run }}
|
||||
dev: true
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{ secrets.NPM_PUBLISH_TOKEN }}
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
75
.github/workflows/release.yml
vendored
Normal file
75
.github/workflows/release.yml
vendored
Normal file
@@ -0,0 +1,75 @@
|
||||
name: Release
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
ref:
|
||||
description: 'The branch, tag or SHA to checkout'
|
||||
required: true
|
||||
default: 'main'
|
||||
package:
|
||||
description: 'The published name of a single package to release'
|
||||
type: choice
|
||||
required: false
|
||||
options:
|
||||
- all
|
||||
- discord.js
|
||||
- '@discordjs/brokers'
|
||||
- '@discordjs/builders'
|
||||
- '@discordjs/collection'
|
||||
- '@discordjs/core'
|
||||
- 'create-discord-bot'
|
||||
- '@discordjs/docgen'
|
||||
- '@discordjs/formatters'
|
||||
- '@discordjs/next'
|
||||
- '@discordjs/proxy'
|
||||
- '@discordjs/rest'
|
||||
- '@discordjs/util'
|
||||
- '@discordjs/voice'
|
||||
- '@discordjs/ws'
|
||||
exclude:
|
||||
description: 'Comma separated list of packages to exclude from release (if not depended upon)'
|
||||
required: false
|
||||
type: string
|
||||
default: '@discordjs/docgen,@discordjs/next'
|
||||
dry_run:
|
||||
type: boolean
|
||||
default: false
|
||||
jobs:
|
||||
npm-publish:
|
||||
name: npm publish
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
id-token: write
|
||||
contents: write
|
||||
env:
|
||||
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
|
||||
TURBO_TEAM: ${{ secrets.TURBO_TEAM }}
|
||||
if: github.repository_owner == 'discordjs'
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ inputs.ref || '' }}
|
||||
ssh_key: ${{ secrets.DEPLOY_KEY_CI_RELEASE_TAGS }}
|
||||
|
||||
- name: Install Node.js v20
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 20
|
||||
registry-url: https://registry.npmjs.org/
|
||||
|
||||
- name: Install dependencies
|
||||
uses: ./packages/actions/src/pnpmCache
|
||||
|
||||
- name: Build dependencies
|
||||
run: pnpm run build
|
||||
|
||||
- name: Release packages
|
||||
uses: ./packages/actions/src/releasePackages
|
||||
with:
|
||||
package: ${{ inputs.package }}
|
||||
exclude: ${{ inputs.exclude }}
|
||||
dry: ${{ inputs.dry_run }}
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{ secrets.NPM_PUBLISH_TOKEN }}
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
@@ -22,7 +22,8 @@
|
||||
"prepare": "is-ci || husky",
|
||||
"update": "pnpm --recursive update --interactive",
|
||||
"update:latest": "pnpm --recursive update --interactive --latest",
|
||||
"create-package": "turbo gen create-package --args"
|
||||
"create-package": "turbo gen create-package --args",
|
||||
"release": "bun ./packages/actions/src/releasePackages/index.ts"
|
||||
},
|
||||
"type": "module",
|
||||
"contributors": [
|
||||
|
||||
@@ -42,12 +42,14 @@
|
||||
"funding": "https://github.com/discordjs/discord.js?sponsor",
|
||||
"dependencies": {
|
||||
"@actions/core": "^1.11.1",
|
||||
"@actions/github": "^6.0.1",
|
||||
"@actions/glob": "^0.5.0",
|
||||
"@aws-sdk/client-s3": "^3.844.0",
|
||||
"@discordjs/scripts": "workspace:^",
|
||||
"@vercel/blob": "^1.1.1",
|
||||
"@vercel/postgres": "^0.10.0",
|
||||
"cloudflare": "^4.4.1",
|
||||
"commander": "^14.0.0",
|
||||
"meilisearch": "^0.38.0",
|
||||
"p-limit": "^6.2.0",
|
||||
"p-queue": "^8.1.0",
|
||||
@@ -55,6 +57,8 @@
|
||||
"undici": "7.11.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@npm/types": "^2.1.0",
|
||||
"@types/bun": "^1.2.19",
|
||||
"@types/node": "^22.16.3",
|
||||
"@vitest/coverage-v8": "^3.2.4",
|
||||
"cross-env": "^7.0.3",
|
||||
|
||||
24
packages/actions/src/releasePackages/action.yml
Normal file
24
packages/actions/src/releasePackages/action.yml
Normal file
@@ -0,0 +1,24 @@
|
||||
name: 'Release Packages'
|
||||
description: 'Tags and releases any unreleased packages'
|
||||
inputs:
|
||||
dev:
|
||||
description: 'Releases development versions of packages (skips tagging and github releases)'
|
||||
default: false
|
||||
dry:
|
||||
descrption: 'Perform a dry run that skips publishing and outputs logs indicating what would have happened'
|
||||
default: false
|
||||
package:
|
||||
description: 'The published name of a single package to release'
|
||||
exclude:
|
||||
description: 'Comma separated list of packages to exclude from release (if not depended upon)'
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
- uses: oven-sh/setup-bun@v1
|
||||
- run: bun packages/actions/src/releasePackages/index.ts
|
||||
shell: bash
|
||||
env:
|
||||
INPUT_DEV: ${{ inputs.dev }}
|
||||
INPUT_DRY: ${{ inputs.dry }}
|
||||
INPUT_PACKAGE: ${{ inputs.package }}
|
||||
INPUT_EXCLUDE: ${{ inputs.exclude }}
|
||||
230
packages/actions/src/releasePackages/generateReleaseTree.ts
Normal file
230
packages/actions/src/releasePackages/generateReleaseTree.ts
Normal file
@@ -0,0 +1,230 @@
|
||||
import { info, warning } from '@actions/core';
|
||||
import type { PackageJSON, PackumentVersion } from '@npm/types';
|
||||
import { $, file, write } from 'bun';
|
||||
|
||||
const nonNodePackages = new Set(['@discordjs/proxy-container']);
|
||||
|
||||
interface pnpmTreeDependency {
|
||||
from: string;
|
||||
path: string;
|
||||
version: string;
|
||||
}
|
||||
|
||||
interface pnpmTree {
|
||||
dependencies?: Record<string, pnpmTreeDependency>;
|
||||
name?: string;
|
||||
path: string;
|
||||
private?: boolean;
|
||||
unsavedDependencies?: Record<string, pnpmTreeDependency>;
|
||||
version?: string;
|
||||
}
|
||||
|
||||
export interface ReleaseEntry {
|
||||
changelog?: string;
|
||||
dependsOn?: string[];
|
||||
name: string;
|
||||
version: string;
|
||||
}
|
||||
|
||||
async function fetchDevVersion(pkg: string) {
|
||||
try {
|
||||
const res = await fetch(`https://registry.npmjs.org/${pkg}/dev`);
|
||||
if (!res.ok) return null;
|
||||
const packument = (await res.json()) as PackumentVersion;
|
||||
return packument.version;
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async function getReleaseEntries(dev: boolean, dry: boolean) {
|
||||
const releaseEntries: ReleaseEntry[] = [];
|
||||
const packageList: pnpmTree[] =
|
||||
await $`pnpm list --recursive --only-projects --filter {packages/\*} --prod --json`.json();
|
||||
|
||||
const commitHash = (await $`git rev-parse --short HEAD`.text()).trim();
|
||||
|
||||
for (const pkg of packageList) {
|
||||
// Don't release private packages ever (npm will error anyways)
|
||||
if (pkg.private) continue;
|
||||
// Just in case
|
||||
if (!pkg.version || !pkg.name) continue;
|
||||
if (nonNodePackages.has(pkg.name)) continue;
|
||||
|
||||
const release: ReleaseEntry = {
|
||||
name: pkg.name,
|
||||
version: pkg.version,
|
||||
};
|
||||
|
||||
if (dev) {
|
||||
const devVersion = await fetchDevVersion(pkg.name);
|
||||
if (devVersion?.endsWith(commitHash)) {
|
||||
// Write the currently released dev version so when pnpm publish runs on dependents they depend on the dev versions
|
||||
if (dry) {
|
||||
info(`[DRY] ${pkg.name}@${devVersion} already released. Editing package.json version.`);
|
||||
} else {
|
||||
const pkgJson = (await file(`${pkg.path}/package.json`).json()) as PackageJSON;
|
||||
pkgJson.version = devVersion;
|
||||
await write(`${pkg.path}/package.json`, JSON.stringify(pkgJson, null, '\t'));
|
||||
}
|
||||
|
||||
release.version = devVersion;
|
||||
} else if (dry) {
|
||||
info(`[DRY] Bumping ${pkg.name} via git-cliff.`);
|
||||
release.version = `${pkg.version}.DRY-dev.${Math.round(Date.now() / 1_000)}-${commitHash}`;
|
||||
} else {
|
||||
await $`pnpm --filter=${pkg.name} run release --preid "dev.${Math.round(Date.now() / 1_000)}-${commitHash} --skip-changelog"`;
|
||||
// Read again instead of parsing the output to be sure we're matching when checking against npm
|
||||
const pkgJson = (await file(`${pkg.path}/package.json`).json()) as PackageJSON;
|
||||
release.version = pkgJson.version;
|
||||
}
|
||||
}
|
||||
// Only need changelog for releases published to github
|
||||
else {
|
||||
try {
|
||||
// Find and parse changelog to post in github release
|
||||
const changelogFile = await file(`${pkg.path}/CHANGELOG.md`).text();
|
||||
|
||||
let changelogLines: string[] = [];
|
||||
let foundChangelog = false;
|
||||
|
||||
for (const line of changelogFile.split('\n')) {
|
||||
if (line.startsWith('# [')) {
|
||||
if (foundChangelog) {
|
||||
if (changelogLines.at(-1) === '') {
|
||||
changelogLines = changelogLines.slice(2, -1);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// Check changelog release version and assume no changelog if version does not match
|
||||
if (!line.startsWith(`# [${release.name === 'discord.js' ? `` : `${release.name}@`}${release.version}]`)) {
|
||||
break;
|
||||
}
|
||||
|
||||
foundChangelog = true;
|
||||
}
|
||||
|
||||
if (foundChangelog) {
|
||||
changelogLines.push(line);
|
||||
}
|
||||
}
|
||||
|
||||
release.changelog = changelogLines.join('\n');
|
||||
} catch (error) {
|
||||
// Probably just no changelog file but log just in case
|
||||
warning(`Error parsing changelog for ${pkg.name}, will use auto generated: ${error}`);
|
||||
}
|
||||
}
|
||||
|
||||
if (pkg.dependencies) {
|
||||
release.dependsOn = Object.keys(pkg.dependencies);
|
||||
}
|
||||
|
||||
releaseEntries.push(release);
|
||||
}
|
||||
|
||||
return releaseEntries;
|
||||
}
|
||||
|
||||
export async function generateReleaseTree(dev: boolean, dry: boolean, packageName?: string, exclude?: string[]) {
|
||||
let releaseEntries = await getReleaseEntries(dev, dry);
|
||||
// Try to early return if the package doesn't have deps
|
||||
if (packageName && packageName !== 'all') {
|
||||
const releaseEntry = releaseEntries.find((entry) => entry.name === packageName);
|
||||
if (!releaseEntry) {
|
||||
throw new Error(`Package ${packageName} not releaseable`);
|
||||
}
|
||||
|
||||
if (!releaseEntry.dependsOn) {
|
||||
return [[releaseEntry]];
|
||||
}
|
||||
}
|
||||
|
||||
// Generate the whole tree first, then prune if specified
|
||||
const releaseTree: ReleaseEntry[][] = [];
|
||||
const didRelease = new Set<string>();
|
||||
|
||||
while (releaseEntries.length) {
|
||||
const nextBranch: ReleaseEntry[] = [];
|
||||
const unreleased: ReleaseEntry[] = [];
|
||||
for (const entry of releaseEntries) {
|
||||
if (!entry.dependsOn) {
|
||||
nextBranch.push(entry);
|
||||
continue;
|
||||
}
|
||||
|
||||
const allDepsReleased = entry.dependsOn.every((dep) => didRelease.has(dep));
|
||||
if (allDepsReleased) {
|
||||
nextBranch.push(entry);
|
||||
} else {
|
||||
unreleased.push(entry);
|
||||
}
|
||||
}
|
||||
|
||||
// Update didRelease in a second loop to avoid loop order issues
|
||||
for (const release of nextBranch) {
|
||||
didRelease.add(release.name);
|
||||
}
|
||||
|
||||
if (releaseEntries.length === unreleased.length) {
|
||||
throw new Error(
|
||||
`One or more packages have dependents that can't be released: ${unreleased.map((entry) => entry.name).join(',')}`,
|
||||
);
|
||||
}
|
||||
|
||||
releaseTree.push(nextBranch);
|
||||
releaseEntries = unreleased;
|
||||
}
|
||||
|
||||
// Prune exclusions
|
||||
if ((!packageName || packageName === 'all') && Array.isArray(exclude) && exclude.length) {
|
||||
const neededPackages = new Set<string>();
|
||||
const excludedReleaseTree: ReleaseEntry[][] = [];
|
||||
|
||||
for (const releaseBranch of releaseTree.reverse()) {
|
||||
const newThisBranch: ReleaseEntry[] = [];
|
||||
|
||||
for (const entry of releaseBranch) {
|
||||
if (exclude.includes(entry.name) && !neededPackages.has(entry.name)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
newThisBranch.push(entry);
|
||||
for (const dep of entry.dependsOn ?? []) {
|
||||
neededPackages.add(dep);
|
||||
}
|
||||
}
|
||||
|
||||
if (newThisBranch.length) excludedReleaseTree.unshift(newThisBranch);
|
||||
}
|
||||
|
||||
return excludedReleaseTree;
|
||||
}
|
||||
|
||||
if (!packageName || packageName === 'all') {
|
||||
return releaseTree;
|
||||
}
|
||||
|
||||
// Prune the tree for the specified package
|
||||
const neededPackages = new Set<string>([packageName]);
|
||||
const packageReleaseTree: ReleaseEntry[][] = [];
|
||||
|
||||
for (const releaseBranch of releaseTree.reverse()) {
|
||||
const newThisBranch: ReleaseEntry[] = [];
|
||||
|
||||
for (const entry of releaseBranch) {
|
||||
if (neededPackages.has(entry.name)) {
|
||||
newThisBranch.push(entry);
|
||||
for (const dep of entry.dependsOn ?? []) {
|
||||
neededPackages.add(dep);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (newThisBranch.length) packageReleaseTree.unshift(newThisBranch);
|
||||
}
|
||||
|
||||
return packageReleaseTree;
|
||||
}
|
||||
47
packages/actions/src/releasePackages/index.ts
Normal file
47
packages/actions/src/releasePackages/index.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
import { getInput, startGroup, endGroup, getBooleanInput, info } from '@actions/core';
|
||||
import { program } from 'commander';
|
||||
import { generateReleaseTree } from './generateReleaseTree.js';
|
||||
import { releasePackage } from './releasePackage.js';
|
||||
|
||||
const excludeInput = getInput('exclude');
|
||||
let dryInput = false;
|
||||
let devInput = false;
|
||||
|
||||
try {
|
||||
devInput = getBooleanInput('dev');
|
||||
} catch {
|
||||
// We're not running in actions
|
||||
}
|
||||
|
||||
try {
|
||||
dryInput = getBooleanInput('dry');
|
||||
} catch {
|
||||
// We're not running in actions or the input isn't set (cron)
|
||||
}
|
||||
|
||||
program
|
||||
.name('release packages')
|
||||
.description('releases monorepo packages with proper sequencing')
|
||||
.argument('[package]', "release a specific package (and it's dependencies)", getInput('package'))
|
||||
.option(
|
||||
'-e, --exclude <packages...>',
|
||||
'exclude specific packages from releasing (will still release if necessary for another package)',
|
||||
excludeInput ? excludeInput.split(',') : [],
|
||||
)
|
||||
.option('--dry', 'skips actual publishing and outputs logs instead', dryInput)
|
||||
.option('--dev', 'publishes development versions and skips tagging / github releases', devInput)
|
||||
.parse();
|
||||
|
||||
const { exclude, dry, dev } = program.opts<{ dev: boolean; dry: boolean; exclude: string[] }>();
|
||||
const packageName = program.args[0]!;
|
||||
|
||||
const tree = await generateReleaseTree(dev, dry, packageName, exclude);
|
||||
for (const branch of tree) {
|
||||
startGroup(`Releasing ${branch.map((entry) => `${entry.name}@${entry.version}`).join(', ')}`);
|
||||
await Promise.all(branch.map(async (release) => releasePackage(release, dev, dry)));
|
||||
endGroup();
|
||||
}
|
||||
|
||||
info(
|
||||
`Successfully released ${tree.map((branch) => branch.map((entry) => `${entry.name}@${entry.version}`).join(', ')).join(', ')}`,
|
||||
);
|
||||
87
packages/actions/src/releasePackages/releasePackage.ts
Normal file
87
packages/actions/src/releasePackages/releasePackage.ts
Normal file
@@ -0,0 +1,87 @@
|
||||
import process from 'node:process';
|
||||
import { setInterval, clearInterval } from 'node:timers';
|
||||
import { info, warning } from '@actions/core';
|
||||
import { getOctokit, context } from '@actions/github';
|
||||
import { $ } from 'bun';
|
||||
import type { ReleaseEntry } from './generateReleaseTree.js';
|
||||
|
||||
let octokit: ReturnType<typeof getOctokit> | undefined;
|
||||
|
||||
if (process.env.GITHUB_TOKEN) {
|
||||
octokit = getOctokit(process.env.GITHUB_TOKEN);
|
||||
}
|
||||
|
||||
async function checkRegistry(release: ReleaseEntry) {
|
||||
const res = await fetch(`https://registry.npmjs.org/${release.name}/${release.version}`);
|
||||
return res.ok;
|
||||
}
|
||||
|
||||
async function gitTagAndRelease(release: ReleaseEntry, dry: boolean) {
|
||||
const tagName = `${release.name === 'discord.js' ? `` : `${release.name}@`}${release.version}`;
|
||||
// Don't throw, if this exits non-zero it's probably because the tag already exists
|
||||
await $`git tag ${tagName}`.nothrow();
|
||||
|
||||
if (dry) {
|
||||
info(`[DRY] Tag "${tagName}" created, skipping push and release creation.`);
|
||||
return;
|
||||
}
|
||||
|
||||
await $`git push origin ${tagName}`;
|
||||
|
||||
try {
|
||||
await octokit?.rest.repos.createRelease({
|
||||
...context.repo,
|
||||
tag_name: tagName,
|
||||
name: tagName,
|
||||
body: release.changelog ?? '',
|
||||
generate_release_notes: release.changelog === undefined,
|
||||
make_latest: release.name === 'discord.js' ? 'true' : 'false',
|
||||
});
|
||||
} catch (error) {
|
||||
warning(`Failed to create github release: ${error}`);
|
||||
}
|
||||
}
|
||||
|
||||
export async function releasePackage(release: ReleaseEntry, dev: boolean, dry: boolean) {
|
||||
// Sanity check against the registry first
|
||||
if (await checkRegistry(release)) {
|
||||
info(`${release.name}@${release.version} already published, skipping.`);
|
||||
return;
|
||||
}
|
||||
|
||||
if (dry) {
|
||||
info(`[DRY] Releasing ${release.name}@${release.version}`);
|
||||
} else {
|
||||
await $`pnpm --filter=${release.name} publish --provenance --no-git-checks ${dev ? '--tag=dev' : ''}`;
|
||||
}
|
||||
|
||||
if (!dev) await gitTagAndRelease(release, dry);
|
||||
|
||||
if (dry) return;
|
||||
|
||||
const before = performance.now();
|
||||
|
||||
// Poll registry to ensure next publishes won't fail
|
||||
await new Promise<void>((resolve, reject) => {
|
||||
const interval = setInterval(async () => {
|
||||
if (await checkRegistry(release)) {
|
||||
clearInterval(interval);
|
||||
resolve();
|
||||
return;
|
||||
}
|
||||
|
||||
if (performance.now() > before + 5 * 60 * 1_000) {
|
||||
clearInterval(interval);
|
||||
reject(new Error(`Release for ${release.name} failed.`));
|
||||
}
|
||||
}, 15_000);
|
||||
});
|
||||
|
||||
if (dev) {
|
||||
// Send and forget, deprecations are less important than releasing other dev versions and can be done manually
|
||||
void $`pnpm exec npm-deprecate --name "*dev*" --message "This version is deprecated. Please use a newer version." --package ${release.name}`
|
||||
.nothrow()
|
||||
// eslint-disable-next-line promise/prefer-await-to-then
|
||||
.then(() => {});
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,10 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/tsconfig.json",
|
||||
"extends": "../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"types": ["node"],
|
||||
"skipLibCheck": true
|
||||
},
|
||||
"include": ["src/**/*.ts", "src/**/*.js", "src/**/*.cjs", "src/**/*.mjs", "bin"],
|
||||
"exclude": ["node_modules"]
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ export default createTsupConfig({
|
||||
entry: [
|
||||
'src/index.ts',
|
||||
'src/formatTag/index.ts',
|
||||
'src/releasePackages/index.ts',
|
||||
'src/uploadDocumentation/index.ts',
|
||||
'src/uploadSearchIndices/index.ts',
|
||||
'src/uploadSplitDocumentation/index.ts',
|
||||
@@ -11,4 +12,5 @@ export default createTsupConfig({
|
||||
dts: false,
|
||||
format: 'esm',
|
||||
minify: 'terser',
|
||||
target: 'esnext',
|
||||
});
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/package.json",
|
||||
"name": "@discordjs/ui",
|
||||
"private": true,
|
||||
"version": "0.1.0",
|
||||
"description": "",
|
||||
"scripts": {
|
||||
|
||||
159
pnpm-lock.yaml
generated
159
pnpm-lock.yaml
generated
@@ -444,6 +444,9 @@ importers:
|
||||
'@actions/core':
|
||||
specifier: ^1.11.1
|
||||
version: 1.11.1
|
||||
'@actions/github':
|
||||
specifier: ^6.0.1
|
||||
version: 6.0.1
|
||||
'@actions/glob':
|
||||
specifier: ^0.5.0
|
||||
version: 0.5.0
|
||||
@@ -462,6 +465,9 @@ importers:
|
||||
cloudflare:
|
||||
specifier: ^4.4.1
|
||||
version: 4.4.1(encoding@0.1.13)
|
||||
commander:
|
||||
specifier: ^14.0.0
|
||||
version: 14.0.0
|
||||
meilisearch:
|
||||
specifier: ^0.38.0
|
||||
version: 0.38.0(encoding@0.1.13)
|
||||
@@ -478,6 +484,12 @@ importers:
|
||||
specifier: 7.11.0
|
||||
version: 7.11.0
|
||||
devDependencies:
|
||||
'@npm/types':
|
||||
specifier: ^2.1.0
|
||||
version: 2.1.0
|
||||
'@types/bun':
|
||||
specifier: ^1.2.19
|
||||
version: 1.2.19(@types/react@19.1.8)
|
||||
'@types/node':
|
||||
specifier: ^22.16.3
|
||||
version: 22.16.3
|
||||
@@ -1940,6 +1952,9 @@ packages:
|
||||
'@actions/exec@1.1.1':
|
||||
resolution: {integrity: sha512-+sCcHHbVdk93a0XT19ECtO/gIXoxvdsgQLzb2fE2/5sIZmWQuluYyjPQtrtTHdU1YzTZ7bAPN4sITq2xi1679w==}
|
||||
|
||||
'@actions/github@6.0.1':
|
||||
resolution: {integrity: sha512-xbZVcaqD4XnQAe35qSQqskb3SqIAfRyLBrHMd/8TuL7hJSz2QtbDwnNM8zWx4zO5l2fnGtseNE3MbEvD7BxVMw==}
|
||||
|
||||
'@actions/glob@0.5.0':
|
||||
resolution: {integrity: sha512-tST2rjPvJLRZLuT9NMUtyBjvj9Yo0MiJS3ow004slMvm8GFM+Zv9HvMJ7HWzfUyJnGrJvDsYkWBaaG3YKXRtCw==}
|
||||
|
||||
@@ -3475,6 +3490,10 @@ packages:
|
||||
resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==}
|
||||
engines: {node: '>= 8'}
|
||||
|
||||
'@npm/types@2.1.0':
|
||||
resolution: {integrity: sha512-humQVe2BrWR7Yum5hGDYBnIPnnZJvKSOH/I4QN1ZL2bdb4c4zQHaHupEJ3cOkSJ07G3YfN793ptbNh196BWLgA==}
|
||||
engines: {node: '>=18.6.0'}
|
||||
|
||||
'@npmcli/agent@3.0.0':
|
||||
resolution: {integrity: sha512-S79NdEgDQd/NGCay6TCoVzXSj74skRZIKJcpJjC5lOq34SZzyI6MqtiiWoiVWoVrTcGjNeC4ipbh1VIHlpfF5Q==}
|
||||
engines: {node: ^18.17.0 || >=20.5.0}
|
||||
@@ -3511,10 +3530,18 @@ packages:
|
||||
resolution: {integrity: sha512-/1uFzjVcfzqrgCeGW7+SZ4hv0qLWmKXVzFahZGJ6QuJBj6Myt9s17+JL86i76NV9YSnJRcGXJYQbAU0rn1YTCQ==}
|
||||
engines: {node: ^18.17.0 || >=20.5.0}
|
||||
|
||||
'@octokit/auth-token@4.0.0':
|
||||
resolution: {integrity: sha512-tY/msAuJo6ARbK6SPIxZrPBms3xPbfwBrulZe0Wtr/DIY9lje2HeV1uoebShn6mx7SjCHif6EjMvoREj+gZ+SA==}
|
||||
engines: {node: '>= 18'}
|
||||
|
||||
'@octokit/auth-token@5.1.1':
|
||||
resolution: {integrity: sha512-rh3G3wDO8J9wSjfI436JUKzHIxq8NaiL0tVeB2aXmG6p/9859aUOAjA9pmSPNGGZxfwmaJ9ozOJImuNVJdpvbA==}
|
||||
engines: {node: '>= 18'}
|
||||
|
||||
'@octokit/core@5.2.0':
|
||||
resolution: {integrity: sha512-1LFfa/qnMQvEOAdzlQymH0ulepxbxnCYAKJZfMci/5XJyIHWgEYnDmgnKakbTh7CH2tFQ5O60oYDvns4i9RAIg==}
|
||||
engines: {node: '>= 18'}
|
||||
|
||||
'@octokit/core@6.1.2':
|
||||
resolution: {integrity: sha512-hEb7Ma4cGJGEUNOAVmyfdB/3WirWMg5hDuNFVejGEDFqupeOysLc2sG6HJxY2etBp5YQu5Wtxwi020jS9xlUwg==}
|
||||
engines: {node: '>= 18'}
|
||||
@@ -3523,27 +3550,61 @@ packages:
|
||||
resolution: {integrity: sha512-XybpFv9Ms4hX5OCHMZqyODYqGTZ3H6K6Vva+M9LR7ib/xr1y1ZnlChYv9H680y77Vd/i/k+thXApeRASBQkzhA==}
|
||||
engines: {node: '>= 18'}
|
||||
|
||||
'@octokit/endpoint@9.0.6':
|
||||
resolution: {integrity: sha512-H1fNTMA57HbkFESSt3Y9+FBICv+0jFceJFPWDePYlR/iMGrwM5ph+Dd4XRQs+8X+PUFURLQgX9ChPfhJ/1uNQw==}
|
||||
engines: {node: '>= 18'}
|
||||
|
||||
'@octokit/graphql@7.1.0':
|
||||
resolution: {integrity: sha512-r+oZUH7aMFui1ypZnAvZmn0KSqAUgE1/tUXIWaqUCa1758ts/Jio84GZuzsvUkme98kv0WFY8//n0J1Z+vsIsQ==}
|
||||
engines: {node: '>= 18'}
|
||||
|
||||
'@octokit/graphql@8.1.2':
|
||||
resolution: {integrity: sha512-bdlj/CJVjpaz06NBpfHhp4kGJaRZfz7AzC+6EwUImRtrwIw8dIgJ63Xg0OzV9pRn3rIzrt5c2sa++BL0JJ8GLw==}
|
||||
engines: {node: '>= 18'}
|
||||
|
||||
'@octokit/openapi-types@20.0.0':
|
||||
resolution: {integrity: sha512-EtqRBEjp1dL/15V7WiX5LJMIxxkdiGJnabzYx5Apx4FkQIFgAfKumXeYAqqJCj1s+BMX4cPFIFC4OLCR6stlnA==}
|
||||
|
||||
'@octokit/openapi-types@22.2.0':
|
||||
resolution: {integrity: sha512-QBhVjcUa9W7Wwhm6DBFu6ZZ+1/t/oYxqc2tp81Pi41YNuJinbFRx8B133qVOrAaBbF7D/m0Et6f9/pZt9Rc+tg==}
|
||||
|
||||
'@octokit/plugin-paginate-rest@9.2.2':
|
||||
resolution: {integrity: sha512-u3KYkGF7GcZnSD/3UP0S7K5XUFT2FkOQdcfXZGZQPGv3lm4F2Xbf71lvjldr8c1H3nNbF+33cLEkWYbokGWqiQ==}
|
||||
engines: {node: '>= 18'}
|
||||
peerDependencies:
|
||||
'@octokit/core': '5'
|
||||
|
||||
'@octokit/plugin-rest-endpoint-methods@10.4.1':
|
||||
resolution: {integrity: sha512-xV1b+ceKV9KytQe3zCVqjg+8GTGfDYwaT1ATU5isiUyVtlVAO3HNdzpS4sr4GBx4hxQ46s7ITtZrAsxG22+rVg==}
|
||||
engines: {node: '>= 18'}
|
||||
peerDependencies:
|
||||
'@octokit/core': '5'
|
||||
|
||||
'@octokit/plugin-retry@7.1.2':
|
||||
resolution: {integrity: sha512-XOWnPpH2kJ5VTwozsxGurw+svB2e61aWlmk5EVIYZPwFK5F9h4cyPyj9CIKRyMXMHSwpIsI3mPOdpMmrRhe7UQ==}
|
||||
engines: {node: '>= 18'}
|
||||
peerDependencies:
|
||||
'@octokit/core': '>=6'
|
||||
|
||||
'@octokit/request-error@5.1.1':
|
||||
resolution: {integrity: sha512-v9iyEQJH6ZntoENr9/yXxjuezh4My67CBSu9r6Ve/05Iu5gNgnisNWOsoJHTP6k0Rr0+HQIpnH+kyammu90q/g==}
|
||||
engines: {node: '>= 18'}
|
||||
|
||||
'@octokit/request-error@6.1.6':
|
||||
resolution: {integrity: sha512-pqnVKYo/at0NuOjinrgcQYpEbv4snvP3bKMRqHaD9kIsk9u1LCpb2smHZi8/qJfgeNqLo5hNW4Z7FezNdEo0xg==}
|
||||
engines: {node: '>= 18'}
|
||||
|
||||
'@octokit/request@8.4.1':
|
||||
resolution: {integrity: sha512-qnB2+SY3hkCmBxZsR/MPCybNmbJe4KAlfWErXq+rBKkQJlbjdJeS85VI9r8UqeLYLvnAenU8Q1okM/0MBsAGXw==}
|
||||
engines: {node: '>= 18'}
|
||||
|
||||
'@octokit/request@9.1.4':
|
||||
resolution: {integrity: sha512-tMbOwGm6wDII6vygP3wUVqFTw3Aoo0FnVQyhihh8vVq12uO3P+vQZeo2CKMpWtPSogpACD0yyZAlVlQnjW71DA==}
|
||||
engines: {node: '>= 18'}
|
||||
|
||||
'@octokit/types@12.6.0':
|
||||
resolution: {integrity: sha512-1rhSOfRa6H9w4YwK0yrf5faDaDTb+yLyBUKOCV4xtCDB5VmIPqd/v9yr9o6SAzOAlRxMiRiCic6JVM1/kunVkw==}
|
||||
|
||||
'@octokit/types@13.6.2':
|
||||
resolution: {integrity: sha512-WpbZfZUcZU77DrSW4wbsSgTPfKcp286q3ItaIgvSbBpZJlu6mnYXAkjZz6LVZPXkEvLIM8McanyZejKTYUHipA==}
|
||||
|
||||
@@ -6027,6 +6088,9 @@ packages:
|
||||
'@types/body-parser@1.19.5':
|
||||
resolution: {integrity: sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==}
|
||||
|
||||
'@types/bun@1.2.19':
|
||||
resolution: {integrity: sha512-d9ZCmrH3CJ2uYKXQIUuZ/pUnTqIvLDS0SK7pFmbx8ma+ziH/FRMoAq5bYpRG7y+w1gl+HgyNZbtqgMq4W4e2Lg==}
|
||||
|
||||
'@types/chai@5.2.2':
|
||||
resolution: {integrity: sha512-8kB30R7Hwqf40JPiKhVzodJs2Qc1ZJ5zuT3uzw5Hq/dhNCl3G3l83jfpdI1e20BP348+fV7VIL/+FxaXkqBmWg==}
|
||||
|
||||
@@ -7406,6 +7470,9 @@ packages:
|
||||
resolution: {integrity: sha512-4Bcg1P8xhUuqcii/S0Z9wiHIrQVPMermM1any+MX5GeGD7faD3/msQUDGLol9wOcz4/jbg/WJnGqoJF6LiBdtg==}
|
||||
engines: {node: '>=10.0.0'}
|
||||
|
||||
before-after-hook@2.2.3:
|
||||
resolution: {integrity: sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==}
|
||||
|
||||
before-after-hook@3.0.2:
|
||||
resolution: {integrity: sha512-Nik3Sc0ncrMK4UUdXQmAnRtzmNQTAAXmXIopizwZ1W1t8QmfJj+zL4OA2I7XPTPW5z5TDqv4hRo/JzouDJnX3A==}
|
||||
|
||||
@@ -7485,6 +7552,11 @@ packages:
|
||||
resolution: {integrity: sha512-p1n8zyCkt1BVrKNFymOHjcDSAl7oq/gUvfgULv2EblgpPVQlQr9yHnWjg9IJ2MhfwPqiYqMMrr01OY7yQoK2yA==}
|
||||
engines: {node: '>=18.20'}
|
||||
|
||||
bun-types@1.2.19:
|
||||
resolution: {integrity: sha512-uAOTaZSPuYsWIXRpj7o56Let0g/wjihKCkeRqUBhlLVM/Bt+Fj9xTo+LhC1OV1XDaGkz4hNC80et5xgy+9KTHQ==}
|
||||
peerDependencies:
|
||||
'@types/react': ^19
|
||||
|
||||
bundle-require@5.1.0:
|
||||
resolution: {integrity: sha512-3WrrOuZiyaaZPWiEt4G3+IffISVC9HYlWueJEBWED4ZH4aIAC2PnkdnuRrR94M+w6yGWn4AglWtJtBI8YqvgoA==}
|
||||
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
|
||||
@@ -8354,6 +8426,9 @@ packages:
|
||||
resolution: {integrity: sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==}
|
||||
engines: {node: '>= 0.6'}
|
||||
|
||||
deprecation@2.3.1:
|
||||
resolution: {integrity: sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==}
|
||||
|
||||
dequal@2.0.3:
|
||||
resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==}
|
||||
engines: {node: '>=6'}
|
||||
@@ -13379,6 +13454,9 @@ packages:
|
||||
unist-util-visit@5.0.0:
|
||||
resolution: {integrity: sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==}
|
||||
|
||||
universal-user-agent@6.0.1:
|
||||
resolution: {integrity: sha512-yCzhz6FN2wU1NiiQRogkTQszlQSlpWaw8SvVegAc+bDxbzHgh1vX8uIe8OYyMH6DwH+sdTJsgMl36+mSMdRJIQ==}
|
||||
|
||||
universal-user-agent@7.0.2:
|
||||
resolution: {integrity: sha512-0JCqzSKnStlRRQfCdowvqy3cy0Dvtlb8xecj/H8JFZuCze4rwjPZQOgvFvn0Ws/usCHQFGpyr+pB9adaGwXn4Q==}
|
||||
|
||||
@@ -13957,6 +14035,16 @@ snapshots:
|
||||
dependencies:
|
||||
'@actions/io': 1.1.3
|
||||
|
||||
'@actions/github@6.0.1':
|
||||
dependencies:
|
||||
'@actions/http-client': 2.2.3
|
||||
'@octokit/core': 5.2.0
|
||||
'@octokit/plugin-paginate-rest': 9.2.2(@octokit/core@5.2.0)
|
||||
'@octokit/plugin-rest-endpoint-methods': 10.4.1(@octokit/core@5.2.0)
|
||||
'@octokit/request': 8.4.1
|
||||
'@octokit/request-error': 5.1.1
|
||||
undici: 5.29.0
|
||||
|
||||
'@actions/glob@0.5.0':
|
||||
dependencies:
|
||||
'@actions/core': 1.11.1
|
||||
@@ -15885,6 +15973,8 @@ snapshots:
|
||||
'@nodelib/fs.scandir': 2.1.5
|
||||
fastq: 1.18.0
|
||||
|
||||
'@npm/types@2.1.0': {}
|
||||
|
||||
'@npmcli/agent@3.0.0':
|
||||
dependencies:
|
||||
agent-base: 7.1.3
|
||||
@@ -15953,8 +16043,20 @@ snapshots:
|
||||
|
||||
'@npmcli/redact@3.0.0': {}
|
||||
|
||||
'@octokit/auth-token@4.0.0': {}
|
||||
|
||||
'@octokit/auth-token@5.1.1': {}
|
||||
|
||||
'@octokit/core@5.2.0':
|
||||
dependencies:
|
||||
'@octokit/auth-token': 4.0.0
|
||||
'@octokit/graphql': 7.1.0
|
||||
'@octokit/request': 8.4.1
|
||||
'@octokit/request-error': 5.1.1
|
||||
'@octokit/types': 13.6.2
|
||||
before-after-hook: 2.2.3
|
||||
universal-user-agent: 6.0.1
|
||||
|
||||
'@octokit/core@6.1.2':
|
||||
dependencies:
|
||||
'@octokit/auth-token': 5.1.1
|
||||
@@ -15970,14 +16072,37 @@ snapshots:
|
||||
'@octokit/types': 13.6.2
|
||||
universal-user-agent: 7.0.2
|
||||
|
||||
'@octokit/endpoint@9.0.6':
|
||||
dependencies:
|
||||
'@octokit/types': 13.6.2
|
||||
universal-user-agent: 6.0.1
|
||||
|
||||
'@octokit/graphql@7.1.0':
|
||||
dependencies:
|
||||
'@octokit/request': 8.4.1
|
||||
'@octokit/types': 13.6.2
|
||||
universal-user-agent: 6.0.1
|
||||
|
||||
'@octokit/graphql@8.1.2':
|
||||
dependencies:
|
||||
'@octokit/request': 9.1.4
|
||||
'@octokit/types': 13.6.2
|
||||
universal-user-agent: 7.0.2
|
||||
|
||||
'@octokit/openapi-types@20.0.0': {}
|
||||
|
||||
'@octokit/openapi-types@22.2.0': {}
|
||||
|
||||
'@octokit/plugin-paginate-rest@9.2.2(@octokit/core@5.2.0)':
|
||||
dependencies:
|
||||
'@octokit/core': 5.2.0
|
||||
'@octokit/types': 12.6.0
|
||||
|
||||
'@octokit/plugin-rest-endpoint-methods@10.4.1(@octokit/core@5.2.0)':
|
||||
dependencies:
|
||||
'@octokit/core': 5.2.0
|
||||
'@octokit/types': 12.6.0
|
||||
|
||||
'@octokit/plugin-retry@7.1.2(@octokit/core@6.1.2)':
|
||||
dependencies:
|
||||
'@octokit/core': 6.1.2
|
||||
@@ -15985,10 +16110,23 @@ snapshots:
|
||||
'@octokit/types': 13.6.2
|
||||
bottleneck: 2.19.5
|
||||
|
||||
'@octokit/request-error@5.1.1':
|
||||
dependencies:
|
||||
'@octokit/types': 13.6.2
|
||||
deprecation: 2.3.1
|
||||
once: 1.4.0
|
||||
|
||||
'@octokit/request-error@6.1.6':
|
||||
dependencies:
|
||||
'@octokit/types': 13.6.2
|
||||
|
||||
'@octokit/request@8.4.1':
|
||||
dependencies:
|
||||
'@octokit/endpoint': 9.0.6
|
||||
'@octokit/request-error': 5.1.1
|
||||
'@octokit/types': 13.6.2
|
||||
universal-user-agent: 6.0.1
|
||||
|
||||
'@octokit/request@9.1.4':
|
||||
dependencies:
|
||||
'@octokit/endpoint': 10.1.2
|
||||
@@ -15997,6 +16135,10 @@ snapshots:
|
||||
fast-content-type-parse: 2.0.0
|
||||
universal-user-agent: 7.0.2
|
||||
|
||||
'@octokit/types@12.6.0':
|
||||
dependencies:
|
||||
'@octokit/openapi-types': 20.0.0
|
||||
|
||||
'@octokit/types@13.6.2':
|
||||
dependencies:
|
||||
'@octokit/openapi-types': 22.2.0
|
||||
@@ -19299,6 +19441,12 @@ snapshots:
|
||||
'@types/connect': 3.4.38
|
||||
'@types/node': 22.16.3
|
||||
|
||||
'@types/bun@1.2.19(@types/react@19.1.8)':
|
||||
dependencies:
|
||||
bun-types: 1.2.19(@types/react@19.1.8)
|
||||
transitivePeerDependencies:
|
||||
- '@types/react'
|
||||
|
||||
'@types/chai@5.2.2':
|
||||
dependencies:
|
||||
'@types/deep-eql': 4.0.2
|
||||
@@ -21363,6 +21511,8 @@ snapshots:
|
||||
|
||||
basic-ftp@5.0.5: {}
|
||||
|
||||
before-after-hook@2.2.3: {}
|
||||
|
||||
before-after-hook@3.0.2: {}
|
||||
|
||||
bent@7.3.12:
|
||||
@@ -21443,6 +21593,11 @@ snapshots:
|
||||
|
||||
builtin-modules@4.0.0: {}
|
||||
|
||||
bun-types@1.2.19(@types/react@19.1.8):
|
||||
dependencies:
|
||||
'@types/node': 22.16.3
|
||||
'@types/react': 19.1.8
|
||||
|
||||
bundle-require@5.1.0(esbuild@0.25.5):
|
||||
dependencies:
|
||||
esbuild: 0.25.5
|
||||
@@ -22359,6 +22514,8 @@ snapshots:
|
||||
|
||||
depd@1.1.2: {}
|
||||
|
||||
deprecation@2.3.1: {}
|
||||
|
||||
dequal@2.0.3: {}
|
||||
|
||||
destr@2.0.3: {}
|
||||
@@ -29085,6 +29242,8 @@ snapshots:
|
||||
unist-util-is: 6.0.0
|
||||
unist-util-visit-parents: 6.0.1
|
||||
|
||||
universal-user-agent@6.0.1: {}
|
||||
|
||||
universal-user-agent@7.0.2: {}
|
||||
|
||||
universalify@2.0.1: {}
|
||||
|
||||
Reference in New Issue
Block a user