mirror of
https://github.com/kunkunsh/kunkun.git
synced 2025-04-20 05:29:17 +00:00
feat: add repo ownership check for org in jsr validation algo
This commit is contained in:
parent
0af6ef2d0a
commit
f6b70bade0
@ -43,6 +43,7 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@huakunshen/jsr-client": "^0.1.5",
|
"@huakunshen/jsr-client": "^0.1.5",
|
||||||
|
"@octokit/rest": "^21.1.0",
|
||||||
"@tauri-apps/api": "^2.2.0",
|
"@tauri-apps/api": "^2.2.0",
|
||||||
"@tauri-apps/cli": "^2.2.2",
|
"@tauri-apps/cli": "^2.2.2",
|
||||||
"@tauri-apps/plugin-deep-link": "^2.2.0",
|
"@tauri-apps/plugin-deep-link": "^2.2.0",
|
||||||
|
@ -1,71 +1,75 @@
|
|||||||
import { describe, expect, test } from "bun:test";
|
import { describe, expect, test } from "bun:test"
|
||||||
import { validateJsrPackageAsKunkunExtension } from "../index";
|
import { validateJsrPackageAsKunkunExtension } from "../index"
|
||||||
|
|
||||||
describe("Validate Jsr package as Kunkun extension", () => {
|
describe("Validate Jsr package as Kunkun extension", () => {
|
||||||
test("Package not signed by GitHub Actions", async () => {
|
test("Package not signed by GitHub Actions", async () => {
|
||||||
expect(
|
expect(
|
||||||
(await validateJsrPackageAsKunkunExtension({
|
(
|
||||||
|
await validateJsrPackageAsKunkunExtension({
|
||||||
jsrPackage: {
|
jsrPackage: {
|
||||||
scope: "kunkun",
|
scope: "kunkun",
|
||||||
name: "api",
|
name: "api",
|
||||||
version: "0.0.47",
|
version: "0.0.47"
|
||||||
},
|
},
|
||||||
githubUsername: "kunkunsh",
|
githubUsername: "kunkunsh"
|
||||||
})).error,
|
})
|
||||||
).toBe("JSR package is not signed by GitHub Actions");
|
).error
|
||||||
});
|
).toBe("JSR package is not signed by GitHub Actions")
|
||||||
|
})
|
||||||
|
|
||||||
test("Non-existent package", async () => {
|
test("Non-existent package", async () => {
|
||||||
expect(
|
expect(
|
||||||
(await validateJsrPackageAsKunkunExtension({
|
(
|
||||||
|
await validateJsrPackageAsKunkunExtension({
|
||||||
jsrPackage: {
|
jsrPackage: {
|
||||||
scope: "kunkun",
|
scope: "kunkun",
|
||||||
name: "non-existent-package",
|
name: "non-existent-package",
|
||||||
version: "0.0.47",
|
version: "0.0.47"
|
||||||
},
|
},
|
||||||
githubUsername: "kunkunsh",
|
githubUsername: "kunkunsh"
|
||||||
})).error,
|
})
|
||||||
).toBe("JSR package does not exist");
|
).error
|
||||||
});
|
).toBe("JSR package does not exist")
|
||||||
|
})
|
||||||
|
|
||||||
test("Package not linked to a GitHub repository", async () => {
|
test("Package not linked to a GitHub repository", async () => {
|
||||||
expect(
|
expect(
|
||||||
(await validateJsrPackageAsKunkunExtension({
|
(
|
||||||
|
await validateJsrPackageAsKunkunExtension({
|
||||||
jsrPackage: {
|
jsrPackage: {
|
||||||
scope: "hk",
|
scope: "hk",
|
||||||
name: "tauri-plugin-network-api",
|
name: "tauri-plugin-network-api",
|
||||||
version: "2.0.3-beta.1",
|
version: "2.0.3-beta.1"
|
||||||
},
|
},
|
||||||
githubUsername: "kunkunsh",
|
githubUsername: "kunkunsh"
|
||||||
})).error,
|
})
|
||||||
).toBe("JSR package is not linked to a GitHub repository");
|
).error
|
||||||
});
|
).toBe("JSR package is not linked to a GitHub repository")
|
||||||
|
})
|
||||||
|
|
||||||
test("GitHub repository owner does not match JSR package owner", async () => {
|
test("GitHub repository owner does not match JSR package owner", async () => {
|
||||||
expect(
|
const res = await validateJsrPackageAsKunkunExtension({
|
||||||
(await validateJsrPackageAsKunkunExtension({
|
|
||||||
jsrPackage: {
|
jsrPackage: {
|
||||||
scope: "kunkun",
|
scope: "kunkun",
|
||||||
name: "ext-image-processing",
|
name: "ext-image-processing",
|
||||||
version: "0.0.6",
|
version: "0.0.6"
|
||||||
},
|
},
|
||||||
githubUsername: "kunkunsh", // should be HuakunShen
|
githubUsername: "Huakun"
|
||||||
})).error,
|
})
|
||||||
).toBe(
|
expect(res.error).toBe(
|
||||||
"GitHub repository owner does not match JSR package owner: HuakunShen !== kunkunsh",
|
"You (Huakun) are not authorized to publish this package. Only kunkunsh or its organization members can publish it."
|
||||||
);
|
)
|
||||||
});
|
})
|
||||||
|
|
||||||
test("A valid extension package", async () => {
|
test("A valid extension package", async () => {
|
||||||
expect(
|
const res = await await validateJsrPackageAsKunkunExtension({
|
||||||
(await validateJsrPackageAsKunkunExtension({
|
|
||||||
jsrPackage: {
|
jsrPackage: {
|
||||||
scope: "kunkun",
|
scope: "kunkun",
|
||||||
name: "ext-image-processing",
|
name: "ext-image-processing",
|
||||||
version: "0.0.6",
|
version: "0.0.6"
|
||||||
},
|
},
|
||||||
githubUsername: "HuakunShen",
|
githubUsername: "HuakunShen"
|
||||||
})).data,
|
})
|
||||||
).toBeDefined();
|
expect(res.data).toBeDefined()
|
||||||
});
|
})
|
||||||
});
|
})
|
||||||
|
34
packages/api/src/extensions/jsr/github.ts
Normal file
34
packages/api/src/extensions/jsr/github.ts
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
/**
|
||||||
|
* TODO: move this module to another folder
|
||||||
|
*/
|
||||||
|
import { Octokit } from "@octokit/rest"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a user is a public member of a GitHub organization
|
||||||
|
* @param orgName - The name of the GitHub organization
|
||||||
|
* @param username - The username of the user
|
||||||
|
* @returns A promise that resolves to a boolean indicating if the user is a public member of the organization
|
||||||
|
*/
|
||||||
|
export function userIsPublicMemberOfGitHubOrg(orgName: string, username: string): Promise<boolean> {
|
||||||
|
const octokit = new Octokit()
|
||||||
|
return octokit.orgs
|
||||||
|
.checkPublicMembershipForUser({ org: orgName, username })
|
||||||
|
.then(() => true)
|
||||||
|
.catch(() => false)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Only works if user grants read:org scope with the org when login
|
||||||
|
* @param orgName
|
||||||
|
* @param username
|
||||||
|
* @param githubToken
|
||||||
|
*/
|
||||||
|
export function authenticatedUserIsMemberOfGitHubOrg(
|
||||||
|
orgName: string,
|
||||||
|
githubToken: string
|
||||||
|
): Promise<boolean> {
|
||||||
|
const octokit = new Octokit({ auth: githubToken })
|
||||||
|
return octokit.orgs.listForAuthenticatedUser().then((res) => {
|
||||||
|
return res.data.some((org) => org.login === orgName)
|
||||||
|
})
|
||||||
|
}
|
@ -2,30 +2,31 @@ import {
|
|||||||
client,
|
client,
|
||||||
getPackage,
|
getPackage,
|
||||||
getPackageVersion,
|
getPackageVersion,
|
||||||
type GitHubRepository,
|
type GitHubRepository
|
||||||
} from "@huakunshen/jsr-client/hey-api-client";
|
} from "@huakunshen/jsr-client/hey-api-client"
|
||||||
import * as v from "valibot";
|
import * as v from "valibot"
|
||||||
import { ExtPackageJson } from "../../models/manifest";
|
import { ExtPackageJson } from "../../models/manifest"
|
||||||
import type { JsrPackageMetadata, NpmPkgMetadata } from "./models";
|
import { authenticatedUserIsMemberOfGitHubOrg, userIsPublicMemberOfGitHubOrg } from "./github"
|
||||||
|
import type { JsrPackageMetadata, NpmPkgMetadata } from "./models"
|
||||||
|
|
||||||
|
export * from "./github"
|
||||||
|
|
||||||
client.setConfig({
|
client.setConfig({
|
||||||
baseUrl: "https://api.jsr.io",
|
baseUrl: "https://api.jsr.io"
|
||||||
});
|
})
|
||||||
|
|
||||||
export function splitRawJsrPkgName(
|
export function splitRawJsrPkgName(packageName: string): Promise<{ scope: string; name: string }> {
|
||||||
packageName: string,
|
|
||||||
): Promise<{ scope: string; name: string }> {
|
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
// write a regex to match the scope and name
|
// write a regex to match the scope and name
|
||||||
const regex = /^@([^@]+)\/([^@]+)$/;
|
const regex = /^@([^@]+)\/([^@]+)$/
|
||||||
const match = packageName.match(regex);
|
const match = packageName.match(regex)
|
||||||
if (!match) {
|
if (!match) {
|
||||||
return reject(new Error("Invalid Jsr package name"));
|
return reject(new Error("Invalid Jsr package name"))
|
||||||
}
|
}
|
||||||
const [, rawScope, name] = match;
|
const [, rawScope, name] = match
|
||||||
const scope = rawScope.startsWith("@") ? rawScope.slice(1) : rawScope;
|
const scope = rawScope.startsWith("@") ? rawScope.slice(1) : rawScope
|
||||||
return resolve({ scope, name });
|
return resolve({ scope, name })
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -35,8 +36,7 @@ export function splitRawJsrPkgName(
|
|||||||
* @param name
|
* @param name
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export const translateJsrToNpmPkgName = (scope: string, name: string) =>
|
export const translateJsrToNpmPkgName = (scope: string, name: string) => `${scope}__${name}`
|
||||||
`${scope}__${name}`;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
/**
|
/**
|
||||||
@ -46,19 +46,13 @@ export const translateJsrToNpmPkgName = (scope: string, name: string) =>
|
|||||||
* @param version
|
* @param version
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export function getJsrPackageHtml(
|
export function getJsrPackageHtml(scope: string, name: string, version?: string) {
|
||||||
scope: string,
|
const url = `https://jsr.io/@${scope}/${name}${version ? `@${version}` : ""}`
|
||||||
name: string,
|
|
||||||
version?: string,
|
|
||||||
) {
|
|
||||||
const url = `https://jsr.io/@${scope}/${name}${
|
|
||||||
version ? `@${version}` : ""
|
|
||||||
}`;
|
|
||||||
return fetch(url, {
|
return fetch(url, {
|
||||||
headers: {
|
headers: {
|
||||||
"sec-fetch-dest": "document",
|
"sec-fetch-dest": "document"
|
||||||
},
|
}
|
||||||
}).then((res) => res.text());
|
}).then((res) => res.text())
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -68,29 +62,29 @@ export function getJsrPackageHtml(
|
|||||||
export async function isSignedByGitHubAction(
|
export async function isSignedByGitHubAction(
|
||||||
scope: string,
|
scope: string,
|
||||||
name: string,
|
name: string,
|
||||||
version: string,
|
version: string
|
||||||
): Promise<boolean> {
|
): Promise<boolean> {
|
||||||
const pkgVersion = await getPackageVersion({
|
const pkgVersion = await getPackageVersion({
|
||||||
path: {
|
path: {
|
||||||
scope,
|
scope,
|
||||||
package: name,
|
package: name,
|
||||||
version,
|
version
|
||||||
},
|
}
|
||||||
});
|
})
|
||||||
return !!pkgVersion.data?.rekorLogId;
|
return !!pkgVersion.data?.rekorLogId
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getJsrPackageGitHubRepo(
|
export async function getJsrPackageGitHubRepo(
|
||||||
scope: string,
|
scope: string,
|
||||||
name: string,
|
name: string
|
||||||
): Promise<GitHubRepository | null> {
|
): Promise<GitHubRepository | null> {
|
||||||
const pkg = await getPackage({
|
const pkg = await getPackage({
|
||||||
path: {
|
path: {
|
||||||
scope,
|
scope,
|
||||||
package: name,
|
package: name
|
||||||
},
|
}
|
||||||
});
|
})
|
||||||
return pkg.data?.githubRepository ?? null;
|
return pkg.data?.githubRepository ?? null
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -102,12 +96,9 @@ export async function getJsrPackageGitHubRepo(
|
|||||||
* @param name
|
* @param name
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export function getJsrPackageMetadata(
|
export function getJsrPackageMetadata(scope: string, name: string): Promise<JsrPackageMetadata> {
|
||||||
scope: string,
|
const url = `https://jsr.io/@${scope}/${name}/meta.json`
|
||||||
name: string,
|
return fetch(url).then((res) => res.json())
|
||||||
): Promise<JsrPackageMetadata> {
|
|
||||||
const url = `https://jsr.io/@${scope}/${name}/meta.json`;
|
|
||||||
return fetch(url).then((res) => res.json());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -122,12 +113,12 @@ export function getJsrPackageSrcFile(
|
|||||||
scope: string,
|
scope: string,
|
||||||
name: string,
|
name: string,
|
||||||
version: string,
|
version: string,
|
||||||
file: string,
|
file: string
|
||||||
): Promise<string | undefined> {
|
): Promise<string | undefined> {
|
||||||
const url = `https://jsr.io/@${scope}/${name}/${version}/${file}`;
|
const url = `https://jsr.io/@${scope}/${name}/${version}/${file}`
|
||||||
return fetch(url)
|
return fetch(url)
|
||||||
.then((res) => res.text())
|
.then((res) => res.text())
|
||||||
.catch(() => undefined);
|
.catch(() => undefined)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -136,15 +127,10 @@ export function getJsrPackageSrcFile(
|
|||||||
* @param name
|
* @param name
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export function getJsrNpmPkgMetadata(
|
export function getJsrNpmPkgMetadata(scope: string, name: string): Promise<NpmPkgMetadata> {
|
||||||
scope: string,
|
|
||||||
name: string,
|
|
||||||
): Promise<NpmPkgMetadata> {
|
|
||||||
// Sample: https://npm.jsr.io/@jsr/kunkun__api
|
// Sample: https://npm.jsr.io/@jsr/kunkun__api
|
||||||
const url = `https://npm.jsr.io/@jsr/${
|
const url = `https://npm.jsr.io/@jsr/${translateJsrToNpmPkgName(scope, name)}`
|
||||||
translateJsrToNpmPkgName(scope, name)
|
return fetch(url).then((res) => res.json())
|
||||||
}`;
|
|
||||||
return fetch(url).then((res) => res.json());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -154,14 +140,10 @@ export function getJsrNpmPkgMetadata(
|
|||||||
* @param version
|
* @param version
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export function getJsrNpmPackageVersionMetadata(
|
export function getJsrNpmPackageVersionMetadata(scope: string, name: string, version: string) {
|
||||||
scope: string,
|
|
||||||
name: string,
|
|
||||||
version: string,
|
|
||||||
) {
|
|
||||||
return getJsrNpmPkgMetadata(scope, name).then((metadata) => {
|
return getJsrNpmPkgMetadata(scope, name).then((metadata) => {
|
||||||
return metadata.versions[version];
|
return metadata.versions[version]
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -174,16 +156,11 @@ export function getJsrNpmPackageVersionMetadata(
|
|||||||
export async function getNpmPackageTarballUrl(
|
export async function getNpmPackageTarballUrl(
|
||||||
scope: string,
|
scope: string,
|
||||||
name: string,
|
name: string,
|
||||||
version: string,
|
version: string
|
||||||
): Promise<string | undefined> {
|
): Promise<string | undefined> {
|
||||||
const metadata = await getJsrNpmPackageVersionMetadata(
|
const metadata = await getJsrNpmPackageVersionMetadata(scope, name, version)
|
||||||
scope,
|
const tarballUrl: string | undefined = metadata?.dist.tarball
|
||||||
name,
|
return tarballUrl
|
||||||
version,
|
|
||||||
);
|
|
||||||
const tarballUrl: string | undefined = metadata?.dist
|
|
||||||
.tarball;
|
|
||||||
return tarballUrl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -192,12 +169,9 @@ export async function getNpmPackageTarballUrl(
|
|||||||
* @param name
|
* @param name
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export async function getAllVersionsOfJsrPackage(
|
export async function getAllVersionsOfJsrPackage(scope: string, name: string): Promise<string[]> {
|
||||||
scope: string,
|
const metadata = await getJsrNpmPkgMetadata(scope, name)
|
||||||
name: string,
|
return Object.keys(metadata.versions)
|
||||||
): Promise<string[]> {
|
|
||||||
const metadata = await getJsrNpmPkgMetadata(scope, name);
|
|
||||||
return Object.keys(metadata.versions);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -206,26 +180,22 @@ export async function getAllVersionsOfJsrPackage(
|
|||||||
* @param name
|
* @param name
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export function jsrPackageExists(
|
export function jsrPackageExists(scope: string, name: string, version?: string): Promise<boolean> {
|
||||||
scope: string,
|
|
||||||
name: string,
|
|
||||||
version?: string,
|
|
||||||
): Promise<boolean> {
|
|
||||||
if (version) {
|
if (version) {
|
||||||
return getPackageVersion({
|
return getPackageVersion({
|
||||||
path: {
|
path: {
|
||||||
scope,
|
scope,
|
||||||
package: name,
|
package: name,
|
||||||
version,
|
version
|
||||||
},
|
}
|
||||||
}).then((res) => res.response.ok && res.response.status === 200);
|
}).then((res) => res.response.ok && res.response.status === 200)
|
||||||
}
|
}
|
||||||
return getPackage({
|
return getPackage({
|
||||||
path: {
|
path: {
|
||||||
scope,
|
scope,
|
||||||
package: name,
|
package: name
|
||||||
},
|
}
|
||||||
}).then((res) => res.response.ok && res.response.status === 200);
|
}).then((res) => res.response.ok && res.response.status === 200)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -236,10 +206,10 @@ export function jsrPackageExists(
|
|||||||
export function getTarballSize(url: string): Promise<number> {
|
export function getTarballSize(url: string): Promise<number> {
|
||||||
return fetch(url, { method: "HEAD" }).then((res) => {
|
return fetch(url, { method: "HEAD" }).then((res) => {
|
||||||
if (!(res.ok && res.status === 200)) {
|
if (!(res.ok && res.status === 200)) {
|
||||||
throw new Error("Failed to fetch tarball size");
|
throw new Error("Failed to fetch tarball size")
|
||||||
}
|
}
|
||||||
return Number(res.headers.get("Content-Length"));
|
return Number(res.headers.get("Content-Length"))
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -254,40 +224,41 @@ export function getTarballSize(url: string): Promise<number> {
|
|||||||
*/
|
*/
|
||||||
export async function validateJsrPackageAsKunkunExtension(payload: {
|
export async function validateJsrPackageAsKunkunExtension(payload: {
|
||||||
jsrPackage: {
|
jsrPackage: {
|
||||||
scope: string;
|
scope: string
|
||||||
name: string;
|
name: string
|
||||||
version: string;
|
version: string
|
||||||
};
|
}
|
||||||
githubUsername: string;
|
githubUsername: string
|
||||||
tarballSizeLimit?: number;
|
tarballSizeLimit?: number
|
||||||
|
githubToken?: string
|
||||||
}): Promise<{
|
}): Promise<{
|
||||||
error?: string;
|
error?: string
|
||||||
data?: {
|
data?: {
|
||||||
pkgJson: ExtPackageJson;
|
pkgJson: ExtPackageJson
|
||||||
tarballUrl: string;
|
tarballUrl: string
|
||||||
shasum: string;
|
shasum: string
|
||||||
apiVersion: string;
|
apiVersion: string
|
||||||
tarballSize: number;
|
tarballSize: number
|
||||||
};
|
}
|
||||||
}> {
|
}> {
|
||||||
// check if jsr package exists
|
// check if jsr package exists
|
||||||
const jsrExists = await jsrPackageExists(
|
const jsrExists = await jsrPackageExists(
|
||||||
payload.jsrPackage.scope,
|
payload.jsrPackage.scope,
|
||||||
payload.jsrPackage.name,
|
payload.jsrPackage.name,
|
||||||
payload.jsrPackage.version,
|
payload.jsrPackage.version
|
||||||
);
|
)
|
||||||
if (!jsrExists) {
|
if (!jsrExists) {
|
||||||
return { error: "JSR package does not exist" };
|
return { error: "JSR package does not exist" }
|
||||||
}
|
}
|
||||||
/* -------------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------------- */
|
||||||
/* check if jsr pkg is linked to a github repo */
|
/* check if jsr pkg is linked to a github repo */
|
||||||
/* -------------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------------- */
|
||||||
const githubRepo = await getJsrPackageGitHubRepo(
|
const githubRepo = await getJsrPackageGitHubRepo(
|
||||||
payload.jsrPackage.scope,
|
payload.jsrPackage.scope,
|
||||||
payload.jsrPackage.name,
|
payload.jsrPackage.name
|
||||||
);
|
)
|
||||||
if (githubRepo === null) {
|
if (githubRepo === null) {
|
||||||
return { error: "JSR package is not linked to a GitHub repository" };
|
return { error: "JSR package is not linked to a GitHub repository" }
|
||||||
}
|
}
|
||||||
/* -------------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------------- */
|
||||||
/* check if jsr pkg is signed with github action */
|
/* check if jsr pkg is signed with github action */
|
||||||
@ -295,21 +266,34 @@ export async function validateJsrPackageAsKunkunExtension(payload: {
|
|||||||
const signed = await isSignedByGitHubAction(
|
const signed = await isSignedByGitHubAction(
|
||||||
payload.jsrPackage.scope,
|
payload.jsrPackage.scope,
|
||||||
payload.jsrPackage.name,
|
payload.jsrPackage.name,
|
||||||
payload.jsrPackage.version,
|
payload.jsrPackage.version
|
||||||
);
|
)
|
||||||
if (!signed) {
|
if (!signed) {
|
||||||
return { error: "JSR package is not signed by GitHub Actions" };
|
return { error: "JSR package is not signed by GitHub Actions" }
|
||||||
}
|
}
|
||||||
/* -------------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------------- */
|
||||||
/* check if user's github username is the same as repo's owner name */
|
/* check if user's github username is the same as repo's owner name */
|
||||||
/* -------------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------------- */
|
||||||
if (
|
if (!githubRepo.owner) {
|
||||||
githubRepo.owner?.toLowerCase() !== payload.githubUsername.toLowerCase()
|
return { error: "Package's Linked GitHub repository owner is not found." }
|
||||||
) {
|
}
|
||||||
|
if (githubRepo.owner.toLowerCase() !== payload.githubUsername.toLowerCase()) {
|
||||||
|
const isPublicMemeber = await userIsPublicMemberOfGitHubOrg(
|
||||||
|
githubRepo.owner,
|
||||||
|
payload.githubUsername
|
||||||
|
)
|
||||||
|
let isOrgMember = false
|
||||||
|
if (payload.githubToken) {
|
||||||
|
isOrgMember = await authenticatedUserIsMemberOfGitHubOrg(
|
||||||
|
githubRepo.owner,
|
||||||
|
payload.githubToken
|
||||||
|
)
|
||||||
|
}
|
||||||
|
if (!isPublicMemeber && !isOrgMember) {
|
||||||
return {
|
return {
|
||||||
error:
|
error: `You (${payload.githubUsername}) are not authorized to publish this package. Only ${githubRepo.owner} or its organization members can publish it.`
|
||||||
`GitHub repository owner does not match JSR package owner: ${githubRepo.owner} !== ${payload.githubUsername}`,
|
}
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
/* -------------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------------- */
|
||||||
/* check if jsr.json or deno.json has the same version as package.json */
|
/* check if jsr.json or deno.json has the same version as package.json */
|
||||||
@ -318,60 +302,57 @@ export async function validateJsrPackageAsKunkunExtension(payload: {
|
|||||||
payload.jsrPackage.scope,
|
payload.jsrPackage.scope,
|
||||||
payload.jsrPackage.name,
|
payload.jsrPackage.name,
|
||||||
payload.jsrPackage.version,
|
payload.jsrPackage.version,
|
||||||
"package.json",
|
"package.json"
|
||||||
);
|
)
|
||||||
if (!packageJsonContent) {
|
if (!packageJsonContent) {
|
||||||
return { error: "Could not find package.json in JSR package" };
|
return { error: "Could not find package.json in JSR package" }
|
||||||
}
|
}
|
||||||
let packageJson: any;
|
let packageJson: any
|
||||||
try {
|
try {
|
||||||
packageJson = JSON.parse(packageJsonContent);
|
packageJson = JSON.parse(packageJsonContent)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return { error: "Failed to parse package.json" };
|
return { error: "Failed to parse package.json" }
|
||||||
}
|
}
|
||||||
if (packageJson.version !== payload.jsrPackage.version) {
|
if (packageJson.version !== payload.jsrPackage.version) {
|
||||||
// no need to fetch jsr.json or deno.json content, as we already know the version is valid with JSR API
|
// no need to fetch jsr.json or deno.json content, as we already know the version is valid with JSR API
|
||||||
return {
|
return {
|
||||||
error:
|
error: "Package version in package.json does not match JSR package version"
|
||||||
"Package version in package.json does not match JSR package version",
|
}
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------------- */
|
||||||
/* validate package.json format against latest schema */
|
/* validate package.json format against latest schema */
|
||||||
/* -------------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------------- */
|
||||||
const parseResult = v.safeParse(ExtPackageJson, packageJson);
|
const parseResult = v.safeParse(ExtPackageJson, packageJson)
|
||||||
if (!parseResult.success) {
|
if (!parseResult.success) {
|
||||||
return { error: "package.json format not valid" };
|
return { error: "package.json format not valid" }
|
||||||
}
|
}
|
||||||
const npmPkgVersionMetadata = await getJsrNpmPackageVersionMetadata(
|
const npmPkgVersionMetadata = await getJsrNpmPackageVersionMetadata(
|
||||||
payload.jsrPackage.scope,
|
payload.jsrPackage.scope,
|
||||||
payload.jsrPackage.name,
|
payload.jsrPackage.name,
|
||||||
payload.jsrPackage.version,
|
payload.jsrPackage.version
|
||||||
);
|
)
|
||||||
const tarballUrl = npmPkgVersionMetadata.dist.tarball;
|
const tarballUrl = npmPkgVersionMetadata.dist.tarball
|
||||||
const shasum = npmPkgVersionMetadata.dist.shasum;
|
const shasum = npmPkgVersionMetadata.dist.shasum
|
||||||
if (!tarballUrl) {
|
if (!tarballUrl) {
|
||||||
return { error: "Could not get tarball URL for JSR package" };
|
return { error: "Could not get tarball URL for JSR package" }
|
||||||
}
|
}
|
||||||
const tarballSize = await getTarballSize(tarballUrl);
|
const tarballSize = await getTarballSize(tarballUrl)
|
||||||
const sizeLimit = payload.tarballSizeLimit ?? 50 * 1024 * 1024; // default to 50MB
|
const sizeLimit = payload.tarballSizeLimit ?? 50 * 1024 * 1024 // default to 50MB
|
||||||
if (tarballSize > sizeLimit) {
|
if (tarballSize > sizeLimit) {
|
||||||
return {
|
return {
|
||||||
error:
|
error: `Package tarball size (${tarballSize} bytes) exceeds limit of ${sizeLimit} bytes`
|
||||||
`Package tarball size (${tarballSize} bytes) exceeds limit of ${sizeLimit} bytes`,
|
}
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------------- */
|
||||||
/* get @kksh/api dependency version */
|
/* get @kksh/api dependency version */
|
||||||
/* -------------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------------- */
|
||||||
const apiVersion = parseResult.output.dependencies?.["@kksh/api"];
|
const apiVersion = parseResult.output.dependencies?.["@kksh/api"]
|
||||||
if (!apiVersion) {
|
if (!apiVersion) {
|
||||||
return {
|
return {
|
||||||
error:
|
error: `Extension ${packageJson.kunkun.identifier} doesn't not have @kksh/api as a dependency`
|
||||||
`Extension ${packageJson.kunkun.identifier} doesn't not have @kksh/api as a dependency`,
|
}
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@ -380,7 +361,7 @@ export async function validateJsrPackageAsKunkunExtension(payload: {
|
|||||||
tarballUrl,
|
tarballUrl,
|
||||||
shasum,
|
shasum,
|
||||||
apiVersion,
|
apiVersion,
|
||||||
tarballSize,
|
tarballSize
|
||||||
},
|
}
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
|
150
pnpm-lock.yaml
generated
150
pnpm-lock.yaml
generated
@ -342,6 +342,9 @@ importers:
|
|||||||
'@huakunshen/jsr-client':
|
'@huakunshen/jsr-client':
|
||||||
specifier: ^0.1.5
|
specifier: ^0.1.5
|
||||||
version: 0.1.5(axios@1.7.9)(react@18.3.1)(typescript@5.6.3)
|
version: 0.1.5(axios@1.7.9)(react@18.3.1)(typescript@5.6.3)
|
||||||
|
'@octokit/rest':
|
||||||
|
specifier: ^21.1.0
|
||||||
|
version: 21.1.0
|
||||||
'@tauri-apps/api':
|
'@tauri-apps/api':
|
||||||
specifier: ^2.2.0
|
specifier: ^2.2.0
|
||||||
version: 2.2.0
|
version: 2.2.0
|
||||||
@ -2756,6 +2759,58 @@ packages:
|
|||||||
'@nuxtjs/tailwindcss@6.12.2':
|
'@nuxtjs/tailwindcss@6.12.2':
|
||||||
resolution: {integrity: sha512-qPJiFH67CkTj/2kBGBzqXihOD1rQXMsbVS4vdQvfBxOBLPfGhU1yw7AATdhPl2BBjO2krjJLuZj39t7dnDYOwg==}
|
resolution: {integrity: sha512-qPJiFH67CkTj/2kBGBzqXihOD1rQXMsbVS4vdQvfBxOBLPfGhU1yw7AATdhPl2BBjO2krjJLuZj39t7dnDYOwg==}
|
||||||
|
|
||||||
|
'@octokit/auth-token@5.1.1':
|
||||||
|
resolution: {integrity: sha512-rh3G3wDO8J9wSjfI436JUKzHIxq8NaiL0tVeB2aXmG6p/9859aUOAjA9pmSPNGGZxfwmaJ9ozOJImuNVJdpvbA==}
|
||||||
|
engines: {node: '>= 18'}
|
||||||
|
|
||||||
|
'@octokit/core@6.1.3':
|
||||||
|
resolution: {integrity: sha512-z+j7DixNnfpdToYsOutStDgeRzJSMnbj8T1C/oQjB6Aa+kRfNjs/Fn7W6c8bmlt6mfy3FkgeKBRnDjxQow5dow==}
|
||||||
|
engines: {node: '>= 18'}
|
||||||
|
|
||||||
|
'@octokit/endpoint@10.1.2':
|
||||||
|
resolution: {integrity: sha512-XybpFv9Ms4hX5OCHMZqyODYqGTZ3H6K6Vva+M9LR7ib/xr1y1ZnlChYv9H680y77Vd/i/k+thXApeRASBQkzhA==}
|
||||||
|
engines: {node: '>= 18'}
|
||||||
|
|
||||||
|
'@octokit/graphql@8.1.2':
|
||||||
|
resolution: {integrity: sha512-bdlj/CJVjpaz06NBpfHhp4kGJaRZfz7AzC+6EwUImRtrwIw8dIgJ63Xg0OzV9pRn3rIzrt5c2sa++BL0JJ8GLw==}
|
||||||
|
engines: {node: '>= 18'}
|
||||||
|
|
||||||
|
'@octokit/openapi-types@23.0.1':
|
||||||
|
resolution: {integrity: sha512-izFjMJ1sir0jn0ldEKhZ7xegCTj/ObmEDlEfpFrx4k/JyZSMRHbO3/rBwgE7f3m2DHt+RrNGIVw4wSmwnm3t/g==}
|
||||||
|
|
||||||
|
'@octokit/plugin-paginate-rest@11.4.0':
|
||||||
|
resolution: {integrity: sha512-ttpGck5AYWkwMkMazNCZMqxKqIq1fJBNxBfsFwwfyYKTf914jKkLF0POMS3YkPBwp5g1c2Y4L79gDz01GhSr1g==}
|
||||||
|
engines: {node: '>= 18'}
|
||||||
|
peerDependencies:
|
||||||
|
'@octokit/core': '>=6'
|
||||||
|
|
||||||
|
'@octokit/plugin-request-log@5.3.1':
|
||||||
|
resolution: {integrity: sha512-n/lNeCtq+9ofhC15xzmJCNKP2BWTv8Ih2TTy+jatNCCq/gQP/V7rK3fjIfuz0pDWDALO/o/4QY4hyOF6TQQFUw==}
|
||||||
|
engines: {node: '>= 18'}
|
||||||
|
peerDependencies:
|
||||||
|
'@octokit/core': '>=6'
|
||||||
|
|
||||||
|
'@octokit/plugin-rest-endpoint-methods@13.3.0':
|
||||||
|
resolution: {integrity: sha512-LUm44shlmkp/6VC+qQgHl3W5vzUP99ZM54zH6BuqkJK4DqfFLhegANd+fM4YRLapTvPm4049iG7F3haANKMYvQ==}
|
||||||
|
engines: {node: '>= 18'}
|
||||||
|
peerDependencies:
|
||||||
|
'@octokit/core': '>=6'
|
||||||
|
|
||||||
|
'@octokit/request-error@6.1.6':
|
||||||
|
resolution: {integrity: sha512-pqnVKYo/at0NuOjinrgcQYpEbv4snvP3bKMRqHaD9kIsk9u1LCpb2smHZi8/qJfgeNqLo5hNW4Z7FezNdEo0xg==}
|
||||||
|
engines: {node: '>= 18'}
|
||||||
|
|
||||||
|
'@octokit/request@9.1.4':
|
||||||
|
resolution: {integrity: sha512-tMbOwGm6wDII6vygP3wUVqFTw3Aoo0FnVQyhihh8vVq12uO3P+vQZeo2CKMpWtPSogpACD0yyZAlVlQnjW71DA==}
|
||||||
|
engines: {node: '>= 18'}
|
||||||
|
|
||||||
|
'@octokit/rest@21.1.0':
|
||||||
|
resolution: {integrity: sha512-93iLxcKDJboUpmnUyeJ6cRIi7z7cqTZT1K7kRK4LobGxwTwpsa+2tQQbRQNGy7IFDEAmrtkf4F4wBj3D5rVlJQ==}
|
||||||
|
engines: {node: '>= 18'}
|
||||||
|
|
||||||
|
'@octokit/types@13.7.0':
|
||||||
|
resolution: {integrity: sha512-BXfRP+3P3IN6fd4uF3SniaHKOO4UXWBfkdR3vA8mIvaoO/wLjGN5qivUtW0QRitBHHMcfC41SLhNVYIZZE+wkA==}
|
||||||
|
|
||||||
'@parcel/watcher-android-arm64@2.5.0':
|
'@parcel/watcher-android-arm64@2.5.0':
|
||||||
resolution: {integrity: sha512-qlX4eS28bUcQCdribHkg/herLe+0A9RyYC+mm2PXpncit8z5b3nSqGVzMNR3CmtAOgRutiZ02eIJJgP/b1iEFQ==}
|
resolution: {integrity: sha512-qlX4eS28bUcQCdribHkg/herLe+0A9RyYC+mm2PXpncit8z5b3nSqGVzMNR3CmtAOgRutiZ02eIJJgP/b1iEFQ==}
|
||||||
engines: {node: '>= 10.0.0'}
|
engines: {node: '>= 10.0.0'}
|
||||||
@ -5551,6 +5606,9 @@ packages:
|
|||||||
bcrypt-pbkdf@1.0.2:
|
bcrypt-pbkdf@1.0.2:
|
||||||
resolution: {integrity: sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==}
|
resolution: {integrity: sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==}
|
||||||
|
|
||||||
|
before-after-hook@3.0.2:
|
||||||
|
resolution: {integrity: sha512-Nik3Sc0ncrMK4UUdXQmAnRtzmNQTAAXmXIopizwZ1W1t8QmfJj+zL4OA2I7XPTPW5z5TDqv4hRo/JzouDJnX3A==}
|
||||||
|
|
||||||
better-path-resolve@1.0.0:
|
better-path-resolve@1.0.0:
|
||||||
resolution: {integrity: sha512-pbnl5XzGBdrFU/wT4jqmJVPn2B6UHPBOhzMQkY/SPUPB6QtUXtmBHBIwCbXJol93mOpGMnQyP/+BB19q04xj7g==}
|
resolution: {integrity: sha512-pbnl5XzGBdrFU/wT4jqmJVPn2B6UHPBOhzMQkY/SPUPB6QtUXtmBHBIwCbXJol93mOpGMnQyP/+BB19q04xj7g==}
|
||||||
engines: {node: '>=4'}
|
engines: {node: '>=4'}
|
||||||
@ -6890,6 +6948,9 @@ packages:
|
|||||||
resolution: {integrity: sha512-TmpgSeJ2jUV+FNWnSy9iIE9bOV9nCNQ4it+K9BpCNT9JsQOfZYznWGSbMw+Wa4uusEss0IcL/trFVoRxS6IuAA==}
|
resolution: {integrity: sha512-TmpgSeJ2jUV+FNWnSy9iIE9bOV9nCNQ4it+K9BpCNT9JsQOfZYznWGSbMw+Wa4uusEss0IcL/trFVoRxS6IuAA==}
|
||||||
engines: {node: '>=8.0.0'}
|
engines: {node: '>=8.0.0'}
|
||||||
|
|
||||||
|
fast-content-type-parse@2.0.1:
|
||||||
|
resolution: {integrity: sha512-nGqtvLrj5w0naR6tDPfB4cUmYCqouzyQiz6C5y/LtcDllJdrcc6WaWW6iXyIIOErTa/XRybj28aasdn4LkVk6Q==}
|
||||||
|
|
||||||
fast-deep-equal@3.1.3:
|
fast-deep-equal@3.1.3:
|
||||||
resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
|
resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
|
||||||
|
|
||||||
@ -10296,6 +10357,9 @@ packages:
|
|||||||
unist-util-visit@5.0.0:
|
unist-util-visit@5.0.0:
|
||||||
resolution: {integrity: sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==}
|
resolution: {integrity: sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==}
|
||||||
|
|
||||||
|
universal-user-agent@7.0.2:
|
||||||
|
resolution: {integrity: sha512-0JCqzSKnStlRRQfCdowvqy3cy0Dvtlb8xecj/H8JFZuCze4rwjPZQOgvFvn0Ws/usCHQFGpyr+pB9adaGwXn4Q==}
|
||||||
|
|
||||||
universalify@0.1.2:
|
universalify@0.1.2:
|
||||||
resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==}
|
resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==}
|
||||||
engines: {node: '>= 4.0.0'}
|
engines: {node: '>= 4.0.0'}
|
||||||
@ -13098,6 +13162,68 @@ snapshots:
|
|||||||
- supports-color
|
- supports-color
|
||||||
- ts-node
|
- ts-node
|
||||||
|
|
||||||
|
'@octokit/auth-token@5.1.1': {}
|
||||||
|
|
||||||
|
'@octokit/core@6.1.3':
|
||||||
|
dependencies:
|
||||||
|
'@octokit/auth-token': 5.1.1
|
||||||
|
'@octokit/graphql': 8.1.2
|
||||||
|
'@octokit/request': 9.1.4
|
||||||
|
'@octokit/request-error': 6.1.6
|
||||||
|
'@octokit/types': 13.7.0
|
||||||
|
before-after-hook: 3.0.2
|
||||||
|
universal-user-agent: 7.0.2
|
||||||
|
|
||||||
|
'@octokit/endpoint@10.1.2':
|
||||||
|
dependencies:
|
||||||
|
'@octokit/types': 13.7.0
|
||||||
|
universal-user-agent: 7.0.2
|
||||||
|
|
||||||
|
'@octokit/graphql@8.1.2':
|
||||||
|
dependencies:
|
||||||
|
'@octokit/request': 9.1.4
|
||||||
|
'@octokit/types': 13.7.0
|
||||||
|
universal-user-agent: 7.0.2
|
||||||
|
|
||||||
|
'@octokit/openapi-types@23.0.1': {}
|
||||||
|
|
||||||
|
'@octokit/plugin-paginate-rest@11.4.0(@octokit/core@6.1.3)':
|
||||||
|
dependencies:
|
||||||
|
'@octokit/core': 6.1.3
|
||||||
|
'@octokit/types': 13.7.0
|
||||||
|
|
||||||
|
'@octokit/plugin-request-log@5.3.1(@octokit/core@6.1.3)':
|
||||||
|
dependencies:
|
||||||
|
'@octokit/core': 6.1.3
|
||||||
|
|
||||||
|
'@octokit/plugin-rest-endpoint-methods@13.3.0(@octokit/core@6.1.3)':
|
||||||
|
dependencies:
|
||||||
|
'@octokit/core': 6.1.3
|
||||||
|
'@octokit/types': 13.7.0
|
||||||
|
|
||||||
|
'@octokit/request-error@6.1.6':
|
||||||
|
dependencies:
|
||||||
|
'@octokit/types': 13.7.0
|
||||||
|
|
||||||
|
'@octokit/request@9.1.4':
|
||||||
|
dependencies:
|
||||||
|
'@octokit/endpoint': 10.1.2
|
||||||
|
'@octokit/request-error': 6.1.6
|
||||||
|
'@octokit/types': 13.7.0
|
||||||
|
fast-content-type-parse: 2.0.1
|
||||||
|
universal-user-agent: 7.0.2
|
||||||
|
|
||||||
|
'@octokit/rest@21.1.0':
|
||||||
|
dependencies:
|
||||||
|
'@octokit/core': 6.1.3
|
||||||
|
'@octokit/plugin-paginate-rest': 11.4.0(@octokit/core@6.1.3)
|
||||||
|
'@octokit/plugin-request-log': 5.3.1(@octokit/core@6.1.3)
|
||||||
|
'@octokit/plugin-rest-endpoint-methods': 13.3.0(@octokit/core@6.1.3)
|
||||||
|
|
||||||
|
'@octokit/types@13.7.0':
|
||||||
|
dependencies:
|
||||||
|
'@octokit/openapi-types': 23.0.1
|
||||||
|
|
||||||
'@parcel/watcher-android-arm64@2.5.0':
|
'@parcel/watcher-android-arm64@2.5.0':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
@ -16393,6 +16519,8 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
tweetnacl: 0.14.5
|
tweetnacl: 0.14.5
|
||||||
|
|
||||||
|
before-after-hook@3.0.2: {}
|
||||||
|
|
||||||
better-path-resolve@1.0.0:
|
better-path-resolve@1.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
is-windows: 1.0.2
|
is-windows: 1.0.2
|
||||||
@ -17601,8 +17729,8 @@ snapshots:
|
|||||||
'@typescript-eslint/parser': 8.15.0(eslint@8.57.1)(typescript@5.6.3)
|
'@typescript-eslint/parser': 8.15.0(eslint@8.57.1)(typescript@5.6.3)
|
||||||
eslint: 8.57.1
|
eslint: 8.57.1
|
||||||
eslint-import-resolver-node: 0.3.9
|
eslint-import-resolver-node: 0.3.9
|
||||||
eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@8.15.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.15.0(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1))(eslint@8.57.1)
|
eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@8.15.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0)(eslint@8.57.1)
|
||||||
eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.15.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.15.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.15.0(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1)
|
eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.15.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1)
|
||||||
eslint-plugin-jsx-a11y: 6.10.2(eslint@8.57.1)
|
eslint-plugin-jsx-a11y: 6.10.2(eslint@8.57.1)
|
||||||
eslint-plugin-react: 7.37.2(eslint@8.57.1)
|
eslint-plugin-react: 7.37.2(eslint@8.57.1)
|
||||||
eslint-plugin-react-hooks: 5.0.0(eslint@8.57.1)
|
eslint-plugin-react-hooks: 5.0.0(eslint@8.57.1)
|
||||||
@ -17630,37 +17758,37 @@ snapshots:
|
|||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.15.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.15.0(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1))(eslint@8.57.1):
|
eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.15.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0)(eslint@8.57.1):
|
||||||
dependencies:
|
dependencies:
|
||||||
'@nolyfill/is-core-module': 1.0.39
|
'@nolyfill/is-core-module': 1.0.39
|
||||||
debug: 4.4.0(supports-color@9.4.0)
|
debug: 4.4.0(supports-color@9.4.0)
|
||||||
enhanced-resolve: 5.17.1
|
enhanced-resolve: 5.17.1
|
||||||
eslint: 8.57.1
|
eslint: 8.57.1
|
||||||
eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.15.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.15.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.15.0(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1)
|
eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.15.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1)
|
||||||
fast-glob: 3.3.2
|
fast-glob: 3.3.2
|
||||||
get-tsconfig: 4.8.1
|
get-tsconfig: 4.8.1
|
||||||
is-bun-module: 1.2.1
|
is-bun-module: 1.2.1
|
||||||
is-glob: 4.0.3
|
is-glob: 4.0.3
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.15.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.15.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.15.0(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1)
|
eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.15.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1)
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- '@typescript-eslint/parser'
|
- '@typescript-eslint/parser'
|
||||||
- eslint-import-resolver-node
|
- eslint-import-resolver-node
|
||||||
- eslint-import-resolver-webpack
|
- eslint-import-resolver-webpack
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
eslint-module-utils@2.12.0(@typescript-eslint/parser@8.15.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.15.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.15.0(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1):
|
eslint-module-utils@2.12.0(@typescript-eslint/parser@8.15.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1):
|
||||||
dependencies:
|
dependencies:
|
||||||
debug: 3.2.7
|
debug: 3.2.7
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
'@typescript-eslint/parser': 8.15.0(eslint@8.57.1)(typescript@5.6.3)
|
'@typescript-eslint/parser': 8.15.0(eslint@8.57.1)(typescript@5.6.3)
|
||||||
eslint: 8.57.1
|
eslint: 8.57.1
|
||||||
eslint-import-resolver-node: 0.3.9
|
eslint-import-resolver-node: 0.3.9
|
||||||
eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@8.15.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.15.0(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1))(eslint@8.57.1)
|
eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@8.15.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0)(eslint@8.57.1)
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.15.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.15.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.15.0(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1):
|
eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.15.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1):
|
||||||
dependencies:
|
dependencies:
|
||||||
'@rtsao/scc': 1.1.0
|
'@rtsao/scc': 1.1.0
|
||||||
array-includes: 3.1.8
|
array-includes: 3.1.8
|
||||||
@ -17671,7 +17799,7 @@ snapshots:
|
|||||||
doctrine: 2.1.0
|
doctrine: 2.1.0
|
||||||
eslint: 8.57.1
|
eslint: 8.57.1
|
||||||
eslint-import-resolver-node: 0.3.9
|
eslint-import-resolver-node: 0.3.9
|
||||||
eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.15.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.15.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.15.0(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1)
|
eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.15.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1)
|
||||||
hasown: 2.0.2
|
hasown: 2.0.2
|
||||||
is-core-module: 2.15.1
|
is-core-module: 2.15.1
|
||||||
is-glob: 4.0.3
|
is-glob: 4.0.3
|
||||||
@ -17981,6 +18109,8 @@ snapshots:
|
|||||||
pure-rand: 6.1.0
|
pure-rand: 6.1.0
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
fast-content-type-parse@2.0.1: {}
|
||||||
|
|
||||||
fast-deep-equal@3.1.3: {}
|
fast-deep-equal@3.1.3: {}
|
||||||
|
|
||||||
fast-equals@5.0.1: {}
|
fast-equals@5.0.1: {}
|
||||||
@ -21902,6 +22032,8 @@ snapshots:
|
|||||||
unist-util-is: 6.0.0
|
unist-util-is: 6.0.0
|
||||||
unist-util-visit-parents: 6.0.1
|
unist-util-visit-parents: 6.0.1
|
||||||
|
|
||||||
|
universal-user-agent@7.0.2: {}
|
||||||
|
|
||||||
universalify@0.1.2: {}
|
universalify@0.1.2: {}
|
||||||
|
|
||||||
universalify@2.0.1: {}
|
universalify@2.0.1: {}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user