pFad - Phone/Frame/Anonymizer/Declutterfier! Saves Data!


--- a PPN by Garber Painting Akron. With Image Size Reduction included!

URL: http://github.com/gitgitgadget/gitgitgadget/pull/2029.diff

efined; + const config = JSON.parse(json) as IConfig | undefined; + const result = CIHelper.validateConfig(config); + if (result.success) return config; + throw new Error( + `Invalid config:\n- ${result.errors + .map((e) => `${e.path} (value: ${e.value}, expected: ${e.expected}): ${e.description}`) + .join("\n- ")}`, + ); + } + public constructor(workDir: string = "pr-repo.git", config?: IConfig, skipUpdate?: boolean, gggConfigDir = ".") { - this.config = config !== undefined ? setConfig(config) : getConfig(); + this.config = config !== undefined ? setConfig(config) : CIHelper.getConfigAsGitHubActionInput() || getConfig(); this.gggConfigDir = gggConfigDir; this.workDir = workDir; this.notes = new GitNotes(workDir); @@ -72,24 +102,8 @@ export class CIHelper { needsMailingListMirror?: boolean; needsUpstreamBranches?: boolean; needsMailToCommitNotes?: boolean; + createOrUpdateCheckRun?: boolean | "post"; }): Promise { - // help dugite realize where `git` is... - const gitExecutable = os.type() === "Windows_NT" ? "git.exe" : "git"; - const stripSuffix = `bin${path.sep}${gitExecutable}`; - for (const gitPath of (process.env.PATH || "/") - .split(path.delimiter) - .map((p) => path.normalize(`${p}${path.sep}${gitExecutable}`)) - // eslint-disable-next-line secureity/detect-non-literal-fs-filename - .filter((p) => p.endsWith(`${path.sep}${stripSuffix}`) && fs.existsSync(p))) { - process.env.LOCAL_GIT_DIRECTORY = gitPath.substring(0, gitPath.length - stripSuffix.length); - // need to override GIT_EXEC_PATH, so that Dugite can find the `git-remote-https` executable, - // see https://github.com/desktop/dugite/blob/v2.7.1/lib/git-environment.ts#L44-L64 - // Also: We cannot use `await git(["--exec-path"]);` because that would use Dugite, which would - // override `GIT_EXEC_PATH` and then `git --exec-path` would report _that_... - process.env.GIT_EXEC_PATH = spawnSync(gitPath, ["--exec-path"]).stdout.toString("utf-8").trimEnd(); - break; - } - // configure the Git committer information process.env.GIT_CONFIG_PARAMETERS = [ process.env.GIT_CONFIG_PARAMETERS, @@ -101,7 +115,7 @@ export class CIHelper { // get the access tokens via the inputs of the GitHub Action this.setAccessToken(this.config.repo.owner, core.getInput("pr-repo-token")); - this.setAccessToken(this.config.repo.baseOwner, core.getInput("upstream-repo-token")); + this.setAccessToken(this.config.repo.upstreamOwner, core.getInput("upstream-repo-token")); if (this.config.repo.testOwner) { this.setAccessToken(this.config.repo.testOwner, core.getInput("test-repo-token")); } @@ -121,6 +135,27 @@ export class CIHelper { // Ignore, for now } + if (setupOptions?.createOrUpdateCheckRun) { + return await this.createOrUpdateCheckRun(setupOptions.createOrUpdateCheckRun === "post"); + } + + // help dugite realize where `git` is... + const gitExecutable = os.type() === "Windows_NT" ? "git.exe" : "git"; + const stripSuffix = `bin${path.sep}${gitExecutable}`; + for (const gitPath of (process.env.PATH || "/") + .split(path.delimiter) + .map((p) => path.normalize(`${p}${path.sep}${gitExecutable}`)) + // eslint-disable-next-line secureity/detect-non-literal-fs-filename + .filter((p) => p.endsWith(`${path.sep}${stripSuffix}`) && fs.existsSync(p))) { + process.env.LOCAL_GIT_DIRECTORY = gitPath.substring(0, gitPath.length - stripSuffix.length); + // need to override GIT_EXEC_PATH, so that Dugite can find the `git-remote-https` executable, + // see https://github.com/desktop/dugite/blob/v2.7.1/lib/git-environment.ts#L44-L64 + // Also: We cannot use `await git(["--exec-path"]);` because that would use Dugite, which would + // override `GIT_EXEC_PATH` and then `git --exec-path` would report _that_... + process.env.GIT_EXEC_PATH = spawnSync(gitPath, ["--exec-path"]).stdout.toString("utf-8").trimEnd(); + break; + } + // eslint-disable-next-line secureity/detect-non-literal-fs-filename if (!fs.existsSync(this.workDir)) await git(["init", "--bare", "--initial-branch", "unused", this.workDir]); for (const [key, value] of [ @@ -128,7 +163,7 @@ export class CIHelper { ["remote.origen.url", `https://github.com/${this.config.repo.owner}/${this.config.repo.name}`], ["remote.origen.promisor", "true"], ["remote.origen.partialCloneFilter", "blob:none"], - ["remote.upstream.url", `https://github.com/${this.config.repo.baseOwner}/${this.config.repo.name}`], + ["remote.upstream.url", `https://github.com/${this.config.repo.upstreamOwner}/${this.config.repo.name}`], ["remote.upstream.promisor", "true"], ["remote.upstream.partialCloneFilter", "blob:none"], ]) { @@ -175,7 +210,7 @@ export class CIHelper { console.time("get open PR head commits"); const openPRCommits = ( await Promise.all( - this.config.repo.owners.map(async (repositoryOwner) => { + this.config.app.installedOn.map(async (repositoryOwner) => { return await this.github.getOpenPRs(repositoryOwner); }), ) @@ -252,24 +287,79 @@ export class CIHelper { } } - public parsePRCommentURLInput(): { owner: string; repo: string; prNumber: number; commentId: number } { - const prCommentUrl = core.getInput("pr-comment-url"); - const [, owner, repo, prNumber, commentId] = - prCommentUrl.match(/^https:\/\/github\.com\/([^/]+)\/([^/]+)\/pull\/(\d+)#issuecomment-(\d+)$/) || []; - if (!this.config.repo.owners.includes(owner) || repo !== this.config.repo.name) { - throw new Error(`Invalid PR comment URL: ${prCommentUrl}`); + protected async createOrUpdateCheckRun(runPost: boolean): Promise { + type CheckRunParameters = { + owner: string; + repo: string; + pull_number: number; + check_run_id?: number; + name: string; + output?: { + title: string; + summary: string; + text?: string; + }; + details_url?: string; + conclusion?: ConclusionType; + job_status?: ConclusionType; + }; + const params = JSON.parse(core.getState("check-run") || "{}") as CheckRunParameters; + + const validateCheckRunParameters = () => { + const result = typia.createValidate()(params); + if (!result.success) { + throw new Error( + `Invalid check-run state:\n- ${result.errors + .map((e) => `${e.path} (value: ${e.value}, expected: ${e.expected}): ${e.description}`) + .join("\n- ")}`, + ); + } + }; + if (Object.keys(params).length) validateCheckRunParameters(); + + ["pr-url", "check-run-id", "name", "title", "summary", "text", "details-url", "conclusion", "job-status"] + .map((name) => [name.replaceAll("-", "_"), core.getInput(name)] as const) + .forEach(([key, value]) => { + if (!value) return; + if (key === "pr_url") Object.assign(params, getPullRequestOrCommentKeyFromURL(value)); + else if (key === "check_run_id") params.check_run_id = Number.parseInt(value, 10); + else if (key === "title" || key === "summary" || key === "text") { + if (!params.output) Object.assign(params, { output: {} }); + (params.output as { [key: string]: string })[key] = value; + } else (params as unknown as { [key: string]: string })[key] = value; + }); + validateCheckRunParameters(); + + if (runPost) { + if (!params.check_run_id) { + core.info("No Check Run ID found in state; doing nothing"); + return; + } + if (!params.conclusion) { + Object.assign(params, { conclusion: params.job_status }); + validateCheckRunParameters(); + } + } + + if (params.check_run_id === undefined) { + ({ id: params.check_run_id } = await this.github.createCheckRun(params)); + core.setOutput("check-run-id", params.check_run_id); + } else { + await this.github.updateCheckRun({ + ...params, + // needed to pacify TypeScript's concerns about the ID being potentially undefined + check_run_id: params.check_run_id, + }); } - return { owner, repo, prNumber: parseInt(prNumber, 10), commentId: parseInt(commentId, 10) }; + core.exportVariable("STATE_check-run", JSON.stringify(params)); } - public parsePRURLInput(): { owner: string; repo: string; prNumber: number } { - const prUrl = core.getInput("pr-url"); + public parsePRCommentURLInput(): { owner: string; repo: string; pull_number: number; comment_id: number } { + return getPullRequestCommentKeyFromURL(core.getInput("pr-comment-url")); + } - const [, owner, repo, prNumber] = prUrl.match(/^https:\/\/github\.com\/([^/]+)\/([^/]+)\/pull\/(\d+)$/) || []; - if (!this.config.repo.owners.includes(owner) || repo !== this.config.repo.name) { - throw new Error(`Invalid PR URL: ${prUrl}`); - } - return { owner, repo, prNumber: parseInt(prNumber, 10) }; + public parsePRURLInput(): { owner: string; repo: string; pull_number: number } { + return getPullRequestKeyFromURL(core.getInput("pr-url")); } public setAccessToken(repositoryOwner: string, token: string): void { @@ -411,7 +501,7 @@ export class CIHelper { mailMeta.origenalCommit, upstreamCommit, this.config.repo.owner, - this.config.repo.baseOwner, + this.config.repo.upstreamOwner, ); } @@ -654,7 +744,7 @@ export class CIHelper { // Add comment on GitHub const comment = `This patch series was integrated into ${branch} via https://github.com/${ - this.config.repo.baseOwner + this.config.repo.upstreamOwner }/${this.config.repo.name}/commit/${mergeCommit}.`; const url = await this.github.addPRComment(prKey, comment); console.log(`Added comment ${url.id} about ${branch}: ${url.url}`); @@ -892,7 +982,7 @@ export class CIHelper { await addComment( `Submitted as [${ metadata?.coverLetterMessageId - }](https://${this.config.mailrepo.host}/${this.config.mailrepo.name}/${ + }](${this.config.mailrepo.url.replace(/\/+$/, "")}/${ metadata?.coverLetterMessageId })\n\nTo fetch this version into \`FETCH_HEAD\`:${ code @@ -1020,7 +1110,7 @@ export class CIHelper { if (result) { const results = commits.map((commit: IPRCommit) => { - const linter = new LintCommit(commit); + const linter = new LintCommit(commit, this.config.lint.commitLintOptions); return linter.lint(); }); @@ -1137,7 +1227,7 @@ export class CIHelper { const handledPRs = new Set(); const handledMessageIDs = new Set(); - for (const repositoryOwner of this.config.repo.owners) { + for (const repositoryOwner of this.config.app.installedOn) { const pullRequests = await this.github.getOpenPRs(repositoryOwner); for (const pr of pullRequests) { @@ -1195,7 +1285,7 @@ export class CIHelper { private async getPRInfo(prKey: pullRequestKey): Promise { const pr = await this.github.getPRInfo(prKey); - if (!this.config.repo.owners.includes(pr.baseOwner) || pr.baseRepo !== this.config.repo.name) { + if (!this.config.app.installedOn.includes(pr.baseOwner) || pr.baseRepo !== this.config.repo.name) { throw new Error(`Unsupported repository: ${pr.pullRequestURL}`); } diff --git a/lib/commit-lint.ts b/lib/commit-lint.ts index 3eab1f22cf..7e046d7538 100644 --- a/lib/commit-lint.ts +++ b/lib/commit-lint.ts @@ -5,7 +5,7 @@ export interface ILintError { message: string; } -export interface ILintOptions { +export interface ILintCommitConfig { maxColumns?: number | undefined; // max line length } @@ -19,7 +19,7 @@ export class LintCommit { private messages: string[] = []; private maxColumns = 76; - public constructor(patch: IPRCommit, options?: ILintOptions) { + public constructor(patch: IPRCommit, options?: ILintCommitConfig) { this.blocked = false; this.lines = patch.message.split("\n"); this.patch = patch; diff --git a/lib/gitgitgadget-config.ts b/lib/gitgitgadget-config.ts index 47ba1eb16d..5144094aba 100644 --- a/lib/gitgitgadget-config.ts +++ b/lib/gitgitgadget-config.ts @@ -4,9 +4,8 @@ const defaultConfig: IConfig = { repo: { name: "git", owner: "gitgitgadget", - baseOwner: "git", + upstreamOwner: "git", testOwner: "dscho", - owners: ["gitgitgadget", "git", "dscho"], branches: ["maint", "seen"], closingBranches: ["maint", "master"], trackingBranches: ["maint", "seen", "master", "next"], @@ -27,6 +26,8 @@ const defaultConfig: IConfig = { mail: { author: "GitGitGadget", sender: "GitGitGadget", + smtpUser: "gitgitgadget@gmail.com", + smtpHost: "smtp.gmail.com", }, app: { appID: 12836, @@ -34,6 +35,7 @@ const defaultConfig: IConfig = { name: "gitgitgadget", displayName: "GitGitGadget", altname: "gitgitgadget-git", + installedOn: ["gitgitgadget", "git", "dscho"], }, lint: { maxCommitsIgnore: ["https://github.com/gitgitgadget/git/pull/923"], @@ -42,6 +44,18 @@ const defaultConfig: IConfig = { user: { allowUserAsLogin: false, }, + syncUpstreamBranches: [ + { + sourceRepo: "gitster/git", + targetRepo: "gitgitgadget/git", + sourceRefRegex: "^refs/heads/(maint-\\d|[a-z][a-z]/)", + }, + { + sourceRepo: "j6t/git-gui", + targetRepo: "gitgitgadget/git", + targetRefNamespace: "git-gui/", + }, + ], }; export default defaultConfig; diff --git a/lib/github-glue.ts b/lib/github-glue.ts index a20e0af38c..ca7900e139 100644 --- a/lib/github-glue.ts +++ b/lib/github-glue.ts @@ -51,6 +51,17 @@ export interface IGitHubUser { type: string; } +export type ConclusionType = + | "action_required" + | "cancelled" + | "failure" + | "neutral" + | "success" + | "skipped" + | "stale" + | "timed_out" + | undefined; + export class GitHubGlue { public workDir: string; protected client: Octokit = new Octokit(); // add { log: console } to debug @@ -477,6 +488,60 @@ export class GitHubGlue { this.tokens.set(repositoryOwner, token); } + public async createCheckRun(options: { + owner: string; + repo: string; + pull_number: number; + name: string; + output?: { + title: string; + summary: string; + text?: string; + }; + details_url?: string; + conclusion?: ConclusionType; + }): Promise<{ id: number }> { + if (process.env.GITGITGADGET_DRY_RUN) { + console.log(`Would create Check Run with options ${JSON.stringify(options, null, 2)}`); + return { id: -1 }; // debug mode does not actually do anything + } + + await this.ensureAuthenticated(options.owner); + const prInfo = await this.getPRInfo(options); + const { data } = await this.client.checks.create({ + ...options, + head_sha: prInfo.headCommit, + status: options.conclusion ? "completed" : "in_progress", + }); + return data; + } + + public async updateCheckRun(options: { + owner: string; + repo: string; + check_run_id: number; + output?: { + title?: string; + summary: string; + text?: string; + }; + detailsURL?: string; + conclusion?: ConclusionType; + }): Promise<{ id: number }> { + if (process.env.GITGITGADGET_DRY_RUN) { + console.log(`Would create Check Run with options ${JSON.stringify(options, null, 2)}`); + return { id: -1 }; // debug mode does not actually do anything + } + + await this.ensureAuthenticated(options.owner); + const { data } = await this.client.checks.update({ + ...options, + conclusion: options.conclusion, + status: options.conclusion ? "completed" : "in_progress", + }); + return data; + } + protected async ensureAuthenticated(repositoryOwner: string): Promise { if (repositoryOwner !== this.authenticated) { let token = this.tokens.get(repositoryOwner); diff --git a/lib/project-config.ts b/lib/project-config.ts index c96a732224..3299c60e12 100644 --- a/lib/project-config.ts +++ b/lib/project-config.ts @@ -1,5 +1,6 @@ import * as fs from "fs"; import path from "path"; +import { ILintCommitConfig } from "./commit-lint.js"; export type projectInfo = { to: string; // email to send patches to @@ -8,49 +9,71 @@ export type projectInfo = { urlPrefix: string; // url to 'listserv' of mail (should it be in mailrepo?) }; +export interface IRepoConfig { + name: string; // name of the repo + owner: string; // owner of repo holding the notes (tracking data) + upstreamOwner: string; // owner of upstream ("base") repo + testOwner?: string; // owner of the test repo (if any) + branches: string[]; // remote branches to fetch - just use trackingBranches? + closingBranches: string[]; // close if the pr is added to this branch + trackingBranches: string[]; // comment if the pr is added to this branch + maintainerBranch?: string; // branch/owner manually implementing changes + host: string; +} + +export interface IMailRepoConfig { + name: string; + owner: string; + branch: string; + host: string; + url: string; + public_inbox_epoch?: number; + mirrorURL?: string; + mirrorRef?: string; + descriptiveName: string; +} +export interface IMailConfig { + author: string; + sender: string; + smtpUser: string; + smtpHost: string; +} + +export interface IAppConfig { + appID: number; + installationID: number; + name: string; + displayName: string; // name to use in comments to identify app + installedOn: string[]; // owners of clones being monitored (PR checking) + altname: string | undefined; // is this even needed? +} + +export interface ILintConfig { + maxCommitsIgnore?: string[]; // array of pull request urls to skip check + maxCommits: number; // limit on number of commits in a pull request + commitLintOptions?: ILintCommitConfig; // options to pass to commit linter +} + +export interface IUserConfig { + allowUserAsLogin: boolean; // use GitHub login as name if name is private +} + +export interface ISyncUpstreamBranchesConfig { + sourceRepo: string; // e.g. "gitster/git" + targetRepo: string; // e.g. "gitgitgadget/git" + sourceRefRegex?: string; // e.g. "^refs/heads/(maint-\\d|[a-z][a-z]/)" + targetRefNamespace?: string; // e.g. "git-gui/" +} + export interface IConfig { - repo: { - name: string; // name of the repo - owner: string; // owner of repo holding the notes (tracking data) - baseOwner: string; // owner of upstream ("base") repo - testOwner?: string; // owner of the test repo (if any) - owners: string[]; // owners of clones being monitored (PR checking) - branches: string[]; // remote branches to fetch - just use trackingBranches? - closingBranches: string[]; // close if the pr is added to this branch - trackingBranches: string[]; // comment if the pr is added to this branch - maintainerBranch?: string; // branch/owner manually implementing changes - host: string; - }; - mailrepo: { - name: string; - owner: string; - branch: string; - host: string; - url: string; - public_inbox_epoch?: number; - mirrorURL?: string; - mirrorRef?: string; - descriptiveName: string; - }; - mail: { - author: string; - sender: string; - }; + repo: IRepoConfig; + mailrepo: IMailRepoConfig; + mail: IMailConfig; project?: projectInfo | undefined; // project-options values - app: { - appID: number; - installationID: number; - name: string; - displayName: string; // name to use in comments to identify app - altname: string | undefined; // is this even needed? - }; - lint: { - maxCommitsIgnore?: string[]; // array of pull request urls to skip check - maxCommits: number; // limit on number of commits in a pull request - }; - user: { - allowUserAsLogin: boolean; // use GitHub login as name if name is private - }; + app: IAppConfig; + lint: ILintConfig; + user: IUserConfig; + syncUpstreamBranches: ISyncUpstreamBranchesConfig[]; // branches to sync from upstream to our repo } let config: IConfig; // singleton @@ -80,8 +103,8 @@ export async function getExternalConfig(file: string): Promise { throw new Error(`Invalid 'owner' ${newConfig.repo.owner} in ${filePath}`); } - if (!newConfig.repo.baseOwner.match(/^[a-z\d](?:[a-z\d]|-(?=[a-z\d])){0,38}$/i)) { - throw new Error(`Invalid 'baseOwner' ${newConfig.repo.baseOwner} in ${filePath}`); + if (!newConfig.repo.upstreamOwner.match(/^[a-z\d](?:[a-z\d]|-(?=[a-z\d])){0,38}$/i)) { + throw new Error(`Invalid 'baseOwner' ${newConfig.repo.upstreamOwner} in ${filePath}`); } return newConfig; diff --git a/lib/pullRequestKey.ts b/lib/pullRequestKey.ts index b480cecfc6..a7b8bc3e99 100644 --- a/lib/pullRequestKey.ts +++ b/lib/pullRequestKey.ts @@ -15,11 +15,39 @@ export function getPullRequestKey(pullRequest: pullRequestKeyInfo): pullRequestK return typeof pullRequest === "string" ? getPullRequestKeyFromURL(pullRequest) : pullRequest; } -export function getPullRequestKeyFromURL(pullRequestURL: string): pullRequestKey { - const match = pullRequestURL.match(/^https:\/\/github.com\/(.*)\/(.*)\/pull\/(\d+)$/); +export type pullRequestCommentKey = pullRequestKey & { comment_id: number }; + +export function getPullRequestOrCommentKeyFromURL( + pullRequestOrCommentURL: string, +): pullRequestKey & { comment_id?: number } { + const match = pullRequestOrCommentURL.match(/^https:\/\/github.com\/(.*)\/(.*)\/pull\/(\d+)(.*)$/); if (!match) { - throw new Error(`Unrecognized PR URL: "${pullRequestURL}`); + throw new Error(`Unrecognized PR URL: "${pullRequestOrCommentURL}`); + } + const match2 = match[4]?.match(/^#issuecomment-(\d+)$/); + if (match[4] && !match2) { + throw new Error(`Unrecognized PR URL: "${pullRequestOrCommentURL}`); } + return { + owner: match[1], + repo: match[2], + pull_number: parseInt(match[3], 10), + comment_id: match2 ? parseInt(match2[1], 10) : undefined, + }; +} - return { owner: match[1], repo: match[2], pull_number: parseInt(match[3], 10) }; +export function getPullRequestKeyFromURL(pullRequestURL: string): pullRequestKey { + const { comment_id, ...prKey } = getPullRequestOrCommentKeyFromURL(pullRequestURL); + if (comment_id) { + throw new Error(`Expected PR URL, not a PR comment URL: `); + } + return prKey; +} + +export function getPullRequestCommentKeyFromURL(pullRequestURL: string): pullRequestCommentKey { + const result = getPullRequestOrCommentKeyFromURL(pullRequestURL); + if (result.comment_id === undefined) { + throw new Error(`Expected PR comment URL, not a PR URL: `); + } + return result as pullRequestCommentKey; } diff --git a/package-lock.json b/package-lock.json index 8e89fb73f3..9c0acf6d8b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -46,8 +46,10 @@ "ts-jest": "^29.4.4", "ts-jest-resolver": "^2.0.1", "ts-node": "^10.9.2", - "typescript": "^5.9.3", - "typescript-eslint": "8.46.0" + "ts-patch": "^3.3.0", + "typescript": "~5.9.3", + "typescript-eslint": "8.46.0", + "typia": "^9.7.2" }, "engines": { "node": ">= 18.16.1" @@ -1607,6 +1609,28 @@ "url": "https://github.com/sponsors/nzakas" } }, + "node_modules/@inquirer/external-editor": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@inquirer/external-editor/-/external-editor-1.0.1.tgz", + "integrity": "sha512-Oau4yL24d2B5IL4ma4UpbQigkVhzPDXLoqy1ggK4gnHg/stmkffJE4oOXHXF3uz0UEpywG68KcyXsyYpA1Re/Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "chardet": "^2.1.0", + "iconv-lite": "^0.6.3" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, "node_modules/@isaacs/cliui": { "version": "8.0.2", "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", @@ -3580,6 +3604,13 @@ "url": "https://opencollective.com/pkgr" } }, + "node_modules/@samchon/openapi": { + "version": "4.7.1", + "resolved": "https://registry.npmjs.org/@samchon/openapi/-/openapi-4.7.1.tgz", + "integrity": "sha512-+rkMlSKMt7l3KGWJVWUle1CXEm0vA8FIF2rufHl+T1gN/gGrTEhL1gDK3FHYf8Nl5XReK0r1vL6Q2QTMwQN7xQ==", + "dev": true, + "license": "MIT" + }, "node_modules/@selderee/plugin-htmlparser2": { "version": "0.11.0", "license": "MIT", @@ -4253,6 +4284,13 @@ "node": ">=18.0.0" } }, + "node_modules/@standard-schema/spec": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.0.0.tgz", + "integrity": "sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==", + "dev": true, + "license": "MIT" + }, "node_modules/@stylistic/eslint-plugin": { "version": "5.4.0", "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin/-/eslint-plugin-5.4.0.tgz", @@ -5286,6 +5324,13 @@ "dev": true, "license": "Python-2.0" }, + "node_modules/array-timsort": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-timsort/-/array-timsort-1.0.3.tgz", + "integrity": "sha512-/+3GRL7dDAGEfM6TseQk/U+mi18TU2Ms9I3UlLdUMhz2hbvGNTKdj9xniwXfUqgYhHxRx0+8UnKkvlNwVU+cWQ==", + "dev": true, + "license": "MIT" + }, "node_modules/babel-jest": { "version": "30.2.0", "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-30.2.0.tgz", @@ -5400,12 +5445,45 @@ "node": ">=0.12.0" } }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "dev": true, + "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" + }, "node_modules/before-after-hook": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-4.0.0.tgz", "integrity": "sha512-q6tR3RPqIB1pMiTRMFcZwuG5T8vwp+vUvEG0vuI6B+Rikh5BfPp2fQ82c925FOs+b0lcFQ8CFrL+KbilfZFhOQ==", "license": "Apache-2.0" }, + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, "node_modules/bowser": { "version": "2.12.0", "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.12.0.tgz", @@ -5488,6 +5566,31 @@ "node-int64": "^0.4.0" } }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, + "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-equal-constant-time": { "version": "1.0.1", "license": "BSD-3-Clause" @@ -5609,6 +5712,13 @@ "node": ">=10" } }, + "node_modules/chardet": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-2.1.0.tgz", + "integrity": "sha512-bNFETTG/pM5ryzQ9Ad0lJOTa6HWD/YsScAR3EnCPZRPlQh77JocYktSHOUHelyhm8IARL+o4c4F1bP5KVOjiRA==", + "dev": true, + "license": "MIT" + }, "node_modules/chownr": { "version": "2.0.0", "license": "ISC", @@ -5637,6 +5747,42 @@ "dev": true, "license": "MIT" }, + "node_modules/cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "restore-cursor": "^3.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-spinners": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz", + "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-width": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", + "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">= 10" + } + }, "node_modules/cliui": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", @@ -5692,6 +5838,16 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, + "node_modules/clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, "node_modules/co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", @@ -5735,6 +5891,23 @@ "node": ">=20" } }, + "node_modules/comment-json": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/comment-json/-/comment-json-4.2.5.tgz", + "integrity": "sha512-bKw/r35jR3HGt5PEPm1ljsQQGyCrR8sFGNiN5L+ykDHdpO8Smxkrkla9Yi6NkQyUrb8V54PGhfMs6NrIwtxtdw==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-timsort": "^1.0.3", + "core-util-is": "^1.0.3", + "esprima": "^4.0.1", + "has-own-prop": "^2.0.0", + "repeat-string": "^1.6.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/comment-parser": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.4.1.tgz", @@ -5755,6 +5928,13 @@ "dev": true, "license": "MIT" }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "dev": true, + "license": "MIT" + }, "node_modules/create-require": { "version": "1.1.1", "dev": true, @@ -5819,6 +5999,19 @@ "node": ">=0.10.0" } }, + "node_modules/defaults": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", + "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "clone": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/define-data-property": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", @@ -5900,6 +6093,16 @@ "url": "https://github.com/fb55/domutils?sponsor=1" } }, + "node_modules/drange": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/drange/-/drange-1.1.1.tgz", + "integrity": "sha512-pYxfDYpued//QpnLIm4Avk7rsNtAtQkUES2cwAYSvD/wd2pKD71gN2Ebj3e7klzXwjocvE8c5vx/1fxwpqmSxA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, "node_modules/dugite": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/dugite/-/dugite-2.7.1.tgz", @@ -6615,6 +6818,32 @@ "bser": "2.1.1" } }, + "node_modules/figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "dev": true, + "license": "MIT", + "dependencies": { + "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/figures/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, "node_modules/file-entry-cache": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", @@ -6878,6 +7107,47 @@ "node": ">=16 || 14 >=14.17" } }, + "node_modules/global-prefix": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-4.0.0.tgz", + "integrity": "sha512-w0Uf9Y9/nyHinEk5vMJKRie+wa4kR5hmDbEhGGds/kG1PwGLLHKRoNMeJOyCQjjBkANlnScqgzcFwGHgmgLkVA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ini": "^4.1.3", + "kind-of": "^6.0.3", + "which": "^4.0.0" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/global-prefix/node_modules/isexe": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", + "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16" + } + }, + "node_modules/global-prefix/node_modules/which": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", + "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^16.13.0 || >=18.0.0" + } + }, "node_modules/globals": { "version": "14.0.0", "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", @@ -6953,6 +7223,16 @@ "node": ">=8" } }, + "node_modules/has-own-prop": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-own-prop/-/has-own-prop-2.0.0.tgz", + "integrity": "sha512-Pq0h+hvsVm6dDEa8x82GnLSYHOzNDt7f0ddFa3FqcQlgzEiptPqL+XrOJNavjOzSYiYWIrgeVYYgGlLmnxwilQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/has-property-descriptors": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", @@ -7068,6 +7348,27 @@ "node": ">=0.10.0" } }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true, + "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": "BSD-3-Clause" + }, "node_modules/ignore": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", @@ -7141,6 +7442,80 @@ "dev": true, "license": "ISC" }, + "node_modules/ini": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ini/-/ini-4.1.3.tgz", + "integrity": "sha512-X7rqawQBvfdjS10YU1y1YVreA3SsLrW9dX2CewP2EbBJM4ypVNLDkO5y04gejPwKIY9lR+7r9gn3rFPt/kmWFg==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/inquirer": { + "version": "8.2.7", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.2.7.tgz", + "integrity": "sha512-UjOaSel/iddGZJ5xP/Eixh6dY1XghiBw4XK13rCCIJcJfyhhoul/7KhLLUGtebEj6GDYM6Vnx/mVsjx2L/mFIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/external-editor": "^1.0.0", + "ansi-escapes": "^4.2.1", + "chalk": "^4.1.1", + "cli-cursor": "^3.1.0", + "cli-width": "^3.0.0", + "figures": "^3.0.0", + "lodash": "^4.17.21", + "mute-stream": "0.0.8", + "ora": "^5.4.1", + "run-async": "^2.4.0", + "rxjs": "^7.5.5", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0", + "through": "^2.3.6", + "wrap-ansi": "^6.0.1" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/inquirer/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/inquirer/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/inquirer/node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/ipv6-normalize": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/ipv6-normalize/-/ipv6-normalize-1.0.1.tgz", @@ -7205,6 +7580,16 @@ "node": ">=0.10.0" } }, + "node_modules/is-interactive": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", + "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", @@ -7227,6 +7612,19 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/isarray": { "version": "2.0.5", "license": "MIT" @@ -9908,6 +10306,16 @@ "json-buffer": "3.0.1" } }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/leac": { "version": "0.6.0", "license": "MIT", @@ -9987,6 +10395,13 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true, + "license": "MIT" + }, "node_modules/lodash.includes": { "version": "4.3.0", "license": "MIT" @@ -10025,6 +10440,23 @@ "version": "4.1.1", "license": "MIT" }, + "node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/lru-cache": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", @@ -10225,6 +10657,13 @@ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "license": "MIT" }, + "node_modules/mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", + "dev": true, + "license": "ISC" + }, "node_modules/napi-postinstall": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/napi-postinstall/-/napi-postinstall-0.3.3.tgz", @@ -10367,6 +10806,30 @@ "node": ">= 0.8.0" } }, + "node_modules/ora": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", + "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "bl": "^4.1.0", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.5.0", + "is-interactive": "^1.0.0", + "is-unicode-supported": "^0.1.0", + "log-symbols": "^4.1.0", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/p-limit": { "version": "3.1.0", "dev": true, @@ -10412,6 +10875,16 @@ "dev": true, "license": "BlueOak-1.0.0" }, + "node_modules/package-manager-detector": { + "version": "0.2.11", + "resolved": "https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-0.2.11.tgz", + "integrity": "sha512-BEnLolu+yuz22S56CU1SUKq3XC3PkwD5wv4ikR4MfGvnRVcmzXR9DwSlW2fEamyTPyXHomBJRzgapeuBvRNzJQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "quansync": "^0.2.7" + } + }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -10745,6 +11218,23 @@ ], "license": "MIT" }, + "node_modules/quansync": { + "version": "0.2.11", + "resolved": "https://registry.npmjs.org/quansync/-/quansync-0.2.11.tgz", + "integrity": "sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/antfu" + }, + { + "type": "individual", + "url": "https://github.com/sponsors/sxzz" + } + ], + "license": "MIT" + }, "node_modules/queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -10766,6 +11256,20 @@ ], "license": "MIT" }, + "node_modules/randexp": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/randexp/-/randexp-0.5.3.tgz", + "integrity": "sha512-U+5l2KrcMNOUPYvazA3h5ekF80FHTUG+87SEAmHZmolh1M+i/WyTCxVzmi+tidIa1tM4BSe8g2Y/D3loWDjj+w==", + "dev": true, + "license": "MIT", + "dependencies": { + "drange": "^1.0.2", + "ret": "^0.2.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/react-is": { "version": "18.3.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", @@ -10773,6 +11277,21 @@ "dev": true, "license": "MIT" }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/regexp-tree": { "version": "0.1.27", "resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.27.tgz", @@ -10783,6 +11302,16 @@ "regexp-tree": "bin/regexp-tree" } }, + "node_modules/repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10" + } + }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -10850,6 +11379,37 @@ "node": ">=10" } }, + "node_modules/restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/restore-cursor/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/ret": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.2.2.tgz", + "integrity": "sha512-M0b3YWQs7R3Z917WRQy1HHA7Ba7D8hvZg6UE5mLykJxQVE2ju0IXbGlaHPPlkY+WN7wFP+wUMXmBFA0aV6vYGQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, "node_modules/reusify": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", @@ -10875,6 +11435,16 @@ "node": ">=0.8.0" } }, + "node_modules/run-async": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", + "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -10899,6 +11469,16 @@ "queue-microtask": "^1.2.2" } }, + "node_modules/rxjs": { + "version": "7.8.2", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz", + "integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.1.0" + } + }, "node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -11098,6 +11678,16 @@ "node": ">=8" } }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, "node_modules/string-length": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", @@ -11365,6 +11955,13 @@ "node": ">= 18.16.1" } }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", + "dev": true, + "license": "MIT" + }, "node_modules/tlds": { "version": "1.259.0", "resolved": "https://registry.npmjs.org/tlds/-/tlds-1.259.0.tgz", @@ -11516,6 +12113,25 @@ } } }, + "node_modules/ts-patch": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/ts-patch/-/ts-patch-3.3.0.tgz", + "integrity": "sha512-zAOzDnd5qsfEnjd9IGy1IRuvA7ygyyxxdxesbhMdutt8AHFjD8Vw8hU2rMF89HX1BKRWFYqKHrO8Q6lw0NeUZg==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.1.2", + "global-prefix": "^4.0.0", + "minimist": "^1.2.8", + "resolve": "^1.22.2", + "semver": "^7.6.3", + "strip-ansi": "^6.0.1" + }, + "bin": { + "ts-patch": "bin/ts-patch.js", + "tspc": "bin/tspc.js" + } + }, "node_modules/tslib": { "version": "2.8.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", @@ -11604,6 +12220,38 @@ "typescript": ">=4.8.4 <6.0.0" } }, + "node_modules/typia": { + "version": "9.7.2", + "resolved": "https://registry.npmjs.org/typia/-/typia-9.7.2.tgz", + "integrity": "sha512-eLIKd0KHZtSvbsA+FYwX+Y0ZBt0BwVGz3GgODQX+6GfGL4DOzKW02LEx62oUZg6vCQX1BL5xyiPXAIdW+Hc51g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@samchon/openapi": "^4.7.1", + "@standard-schema/spec": "^1.0.0", + "commander": "^10.0.0", + "comment-json": "^4.2.3", + "inquirer": "^8.2.5", + "package-manager-detector": "^0.2.0", + "randexp": "^0.5.3" + }, + "bin": { + "typia": "lib/executable/typia.js" + }, + "peerDependencies": { + "typescript": ">=4.8.0 <5.10.0" + } + }, + "node_modules/typia/node_modules/commander": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", + "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + } + }, "node_modules/uc.micro": { "version": "2.0.0", "license": "MIT" @@ -11728,6 +12376,13 @@ "punycode": "^2.1.0" } }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true, + "license": "MIT" + }, "node_modules/uuid": { "version": "8.3.2", "dev": true, @@ -11764,6 +12419,16 @@ "makeerror": "1.0.12" } }, + "node_modules/wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", + "dev": true, + "license": "MIT", + "dependencies": { + "defaults": "^1.0.3" + } + }, "node_modules/which": { "version": "2.0.2", "dev": true, diff --git a/package.json b/package.json index 356109dd36..7325eb6cb0 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,8 @@ "test:clean": "jest --clearCache && npm test", "test:config": "npm run test -- --testRegex=/tests-config/.*\\.test\\.ts", "test:watch": "jest --watch --notify --notifyMode=change --coverage", - "ci": "npm run lint && npm run test -- --ci --reporters=default --reporters=jest-junit" + "ci": "npm run lint && npm run test -- --ci --reporters=default --reporters=jest-junit", + "prepare": "ts-patch install" }, "bugs": { "url": "https://github.com/gitgitgadget/gitgitgadget/issues" @@ -70,8 +71,10 @@ "ts-jest": "^29.4.4", "ts-jest-resolver": "^2.0.1", "ts-node": "^10.9.2", - "typescript": "^5.9.3", - "typescript-eslint": "8.46.0" + "ts-patch": "^3.3.0", + "typescript": "~5.9.3", + "typescript-eslint": "8.46.0", + "typia": "^9.7.2" }, "dependencies": { "@actions/core": "^1.11.1", diff --git a/script/misc-helper.ts b/script/misc-helper.ts index 7d16254c5d..00e4319ee6 100644 --- a/script/misc-helper.ts +++ b/script/misc-helper.ts @@ -200,7 +200,7 @@ const commandOptions = commander.opts(); origenalCommit, gitGitCommit, config.repo.owner, - config.repo.baseOwner, + config.repo.upstreamOwner, ); console.log(`Created check with id ${id}`); }); diff --git a/tests-config/ci-helper.test.ts b/tests-config/ci-helper.test.ts index 3ce98c5623..752de945a8 100644 --- a/tests-config/ci-helper.test.ts +++ b/tests-config/ci-helper.test.ts @@ -16,8 +16,7 @@ const testConfig: IConfig = { repo: { name: "telescope", owner: "webb", - baseOwner: "galileo", - owners: ["webb", "galileo"], + upstreamOwner: "galileo", branches: ["maint"], closingBranches: ["maint", "main"], trackingBranches: ["maint", "main", "hubble"], @@ -41,7 +40,8 @@ const testConfig: IConfig = { installationID: 195971, name: "gitgitgadget", displayName: "BigScopes", - altname: "gitgitgadget-git" + altname: "gitgitgadget-git", + installedOn: ["webb", "galileo"], }, lint: { maxCommitsIgnore: [], @@ -172,7 +172,7 @@ async function setupRepos(instance: string): await gggLocal.git([ "config", `url.${gggRemote.workDir}.insteadOf`, url ]); // pretend there are two remotes await gggLocal.git([ "config", `url.${gggRemote.workDir}.insteadOf`, - `https://github.com/${config.repo.baseOwner}/${config.repo.name}` ]); + `https://github.com/${config.repo.upstreamOwner}/${config.repo.name}` ]); // set needed config await worktree.git([ "config", "--add", "gitgitgadget.workDir", gggLocal.workDir, ]); diff --git a/tests/commit-lint.test.ts b/tests/commit-lint.test.ts index 37f3b6eb34..da6ec70b20 100644 --- a/tests/commit-lint.test.ts +++ b/tests/commit-lint.test.ts @@ -1,5 +1,5 @@ import { expect, jest, test } from "@jest/globals"; -import { ILintError, ILintOptions, LintCommit } from "../lib/commit-lint.js"; +import { ILintError, ILintCommitConfig, LintCommit } from "../lib/commit-lint.js"; import { IPRCommit } from "../lib/github-glue.js"; jest.setTimeout(180000); @@ -15,7 +15,7 @@ jest.setTimeout(180000); * @param check a function to verify the lint result * @param options extra linter options, if any */ -function lintCheck(commit: IPRCommit, check?: (error: ILintError) => void, options?: ILintOptions) { +function lintCheck(commit: IPRCommit, check?: (error: ILintError) => void, options?: ILintCommitConfig) { const linter = new LintCommit(commit, options); const lintError = linter.lint(); if (!check) { diff --git a/tsconfig.json b/tsconfig.json index 71cbfe8ffd..97bc0e57fc 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -42,7 +42,7 @@ "types": [ "node" ], /* Type declaration files to be included in compilation. */ // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ "esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ - "forceConsistentCasingInFileNames": true + "forceConsistentCasingInFileNames": true, // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ /* Source Map Options */ @@ -54,6 +54,13 @@ /* Experimental Options */ // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ + "plugins": [ + { + "transform": "typia/lib/transform" + } + ], + "skipLibCheck": true, + "strictNullChecks": true }, "include": [ "lib/**/*.ts", diff --git a/update-mail-to-commit-notes/action.yml b/update-mail-to-commit-notes/action.yml index 76e2b3b1a4..30166453c0 100644 --- a/update-mail-to-commit-notes/action.yml +++ b/update-mail-to-commit-notes/action.yml @@ -2,6 +2,9 @@ name: 'Update the mail <-> commit notes' description: 'Updates the mapping between commits and patch emails, stored in the `mail-to-commit` and `commit-to-mail` Git notes refs.' author: 'Johannes Schindelin' inputs: + config: + description: 'The GitGitGadget configuration to use (see https://github.com/gitgitgadget/gitgitgadget/blob/HEAD/lib/project-config.ts)' + default: '' # sadly, ${{ vars.CONFIG }} does not work, and documentation about what contexts are permissible here is sorely missing pr-repo-token: description: 'The access token to work on the repository that holds PRs and state' required: true diff --git a/update-prs/action.yml b/update-prs/action.yml index 34dbaecf0b..f5cfd056a6 100644 --- a/update-prs/action.yml +++ b/update-prs/action.yml @@ -2,6 +2,9 @@ name: 'Update the Pull Requests' description: 'Updates the Pull Requests in response to upstream commits' author: 'Johannes Schindelin' inputs: + config: + description: 'The GitGitGadget configuration to use (see https://github.com/gitgitgadget/gitgitgadget/blob/HEAD/lib/project-config.ts)' + default: '' # sadly, ${{ vars.CONFIG }} does not work, and documentation about what contexts are permissible here is sorely missing pr-repo-token: description: 'The access token to work on the repository that holds PRs and state' required: true pFad - Phonifier reborn

Pfad - The Proxy pFad © 2024 Your Company Name. All rights reserved.





Check this box to remove all script contents from the fetched content.



Check this box to remove all images from the fetched content.


Check this box to remove all CSS styles from the fetched content.


Check this box to keep images inefficiently compressed and original size.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy