GitHub app installation
This commit is contained in:
@@ -49,6 +49,12 @@ const EnvironmentSchema = z.object({
|
||||
PULSAR_AUDIENCE: z.string().optional(),
|
||||
PULSAR_DEBUG: z.string().optional(),
|
||||
INTERNAL_TRIGGER_API_KEY: z.string().optional(),
|
||||
GITHUB_APP_NAME: z.string().optional(),
|
||||
GITHUB_APP_ID: z.string().optional(),
|
||||
GITHUB_APP_CLIENT_ID: z.string().optional(),
|
||||
GITHUB_APP_CLIENT_SECRET: z.string().optional(),
|
||||
GITHUB_APP_PRIVATE_KEY: z.string().optional(),
|
||||
GITHUB_APP_WEBHOOK_SECRET: z.string().optional(),
|
||||
});
|
||||
|
||||
export type Environment = z.infer<typeof EnvironmentSchema>;
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
import invariant from "tiny-invariant";
|
||||
import { Container } from "~/components/layout/Container";
|
||||
import { Title } from "~/components/primitives/text/Title";
|
||||
import { useCurrentEnvironment } from "~/hooks/useEnvironments";
|
||||
import { useCurrentOrganization } from "~/hooks/useOrganizations";
|
||||
|
||||
export default function NewWorkflowPage() {
|
||||
const environment = useCurrentEnvironment();
|
||||
const currentOrganization = useCurrentOrganization();
|
||||
invariant(currentOrganization, "Organization must be defined");
|
||||
invariant(environment, "Environment must be defined");
|
||||
|
||||
return (
|
||||
<Container>
|
||||
<Title>Deploy a new workflow</Title>
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
import { LoaderArgs, redirect } from "@remix-run/server-runtime";
|
||||
import { z } from "zod";
|
||||
import { StartAppInstallation } from "~/services/github/startAppInstallation.server";
|
||||
import { requireUserId } from "~/services/session.server";
|
||||
|
||||
const ParamsSchema = z.object({
|
||||
organizationSlug: z.string(),
|
||||
});
|
||||
|
||||
export async function loader({ request, params }: LoaderArgs) {
|
||||
const userId = await requireUserId(request);
|
||||
const { organizationSlug } = ParamsSchema.parse(params);
|
||||
|
||||
const service = new StartAppInstallation();
|
||||
|
||||
const redirectTo = await service.call({
|
||||
userId,
|
||||
organizationSlug,
|
||||
});
|
||||
|
||||
return redirect(redirectTo ?? `/orgs/${organizationSlug}`);
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
import { EmitterWebhookEventName } from "@octokit/webhooks";
|
||||
import { ActionArgs } from "@remix-run/server-runtime";
|
||||
import { webhooks } from "~/services/github/githubApp.server";
|
||||
|
||||
export async function action({ request }: ActionArgs) {
|
||||
if (!webhooks) {
|
||||
return new Response("", { status: 200 });
|
||||
}
|
||||
|
||||
const payload = await request.text();
|
||||
const headers = Object.fromEntries(request.headers.entries());
|
||||
|
||||
const id = headers["x-github-delivery"];
|
||||
const name = headers["x-github-event"];
|
||||
const signature = headers["x-hub-signature"];
|
||||
|
||||
await webhooks.verifyAndReceive({
|
||||
id,
|
||||
name: name as EmitterWebhookEventName,
|
||||
payload,
|
||||
signature,
|
||||
});
|
||||
|
||||
return new Response("", { status: 200 });
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
import { LoaderArgs, redirect } from "@remix-run/server-runtime";
|
||||
import { z } from "zod";
|
||||
import { AppInstallationCallback } from "~/services/github/appInstallationCallback.server";
|
||||
import { requireUserId } from "~/services/session.server";
|
||||
|
||||
const ParamSchema = z.object({
|
||||
code: z.string(),
|
||||
state: z.string(),
|
||||
installation_id: z.string(),
|
||||
});
|
||||
|
||||
export async function loader({ request }: LoaderArgs) {
|
||||
await requireUserId(request);
|
||||
|
||||
const url = new URL(request.url);
|
||||
const params = Object.fromEntries(url.searchParams.entries());
|
||||
|
||||
const service = new AppInstallationCallback();
|
||||
|
||||
const authorization = await service.call(ParamSchema.parse(params));
|
||||
|
||||
if (authorization) {
|
||||
return redirect(`/orgs/${authorization.organization.slug}/workflows/start`);
|
||||
} else {
|
||||
return redirect(`/`);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
import type { PrismaClient } from "~/db.server";
|
||||
import { prisma } from "~/db.server";
|
||||
import {
|
||||
getAppInstallation,
|
||||
oauthApp,
|
||||
octokit,
|
||||
} from "~/services/github/githubApp.server";
|
||||
|
||||
export class AppInstallationCallback {
|
||||
#prismaClient: PrismaClient;
|
||||
|
||||
constructor(prismaClient: PrismaClient = prisma) {
|
||||
this.#prismaClient = prismaClient;
|
||||
}
|
||||
|
||||
public async call({
|
||||
code,
|
||||
state,
|
||||
installation_id,
|
||||
}: {
|
||||
code: string;
|
||||
state: string;
|
||||
installation_id: string;
|
||||
}) {
|
||||
if (!oauthApp || !octokit) {
|
||||
return;
|
||||
}
|
||||
|
||||
const attempt =
|
||||
await this.#prismaClient.gitHubAppAuthorizationAttempt.findUnique({
|
||||
where: {
|
||||
id: state,
|
||||
},
|
||||
});
|
||||
|
||||
if (!attempt) {
|
||||
return;
|
||||
}
|
||||
|
||||
const installation = await getAppInstallation({
|
||||
installation_id: Number(installation_id),
|
||||
});
|
||||
|
||||
if (!installation) {
|
||||
return;
|
||||
}
|
||||
|
||||
const { authentication } = await oauthApp.createToken({ code, state });
|
||||
|
||||
const authorization =
|
||||
await this.#prismaClient.gitHubAppAuthorization.create({
|
||||
data: {
|
||||
user: {
|
||||
connect: {
|
||||
id: attempt.userId,
|
||||
},
|
||||
},
|
||||
organization: {
|
||||
connect: {
|
||||
id: attempt.organizationId,
|
||||
},
|
||||
},
|
||||
token: authentication.token,
|
||||
// @ts-ignore
|
||||
tokenExpiresAt: new Date(authentication.expiresAt),
|
||||
// @ts-ignore
|
||||
refreshToken: authentication.refreshToken,
|
||||
// @ts-ignore
|
||||
refreshTokenExpiresAt: new Date(authentication.refreshTokenExpiresAt),
|
||||
installationId: installation.id,
|
||||
account: installation.account ?? {},
|
||||
permissions: installation.permissions,
|
||||
repositorySelection: installation.repository_selection,
|
||||
accessTokensUrl: installation.access_tokens_url,
|
||||
repositoriesUrl: installation.repositories_url,
|
||||
htmlUrl: installation.html_url,
|
||||
events: installation.events,
|
||||
},
|
||||
include: {
|
||||
organization: {
|
||||
select: {
|
||||
slug: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
await this.#prismaClient.gitHubAppAuthorizationAttempt.delete({
|
||||
where: {
|
||||
id: attempt.id,
|
||||
},
|
||||
});
|
||||
|
||||
return authorization;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,168 @@
|
||||
import { Webhooks, EmitterWebhookEvent } from "@octokit/webhooks";
|
||||
import { Octokit } from "@octokit/core";
|
||||
import { createAppAuth } from "@octokit/auth-app";
|
||||
import { OAuthApp } from "@octokit/oauth-app";
|
||||
import { createUnauthenticatedAuth } from "@octokit/auth-unauthenticated";
|
||||
import { env } from "~/env.server";
|
||||
import { Options } from "@octokit/oauth-app/dist-types/types";
|
||||
import type { Endpoints } from "@octokit/types";
|
||||
|
||||
export const octokit = env.GITHUB_APP_PRIVATE_KEY
|
||||
? new Octokit({
|
||||
authStrategy: createAppAuth,
|
||||
auth: {
|
||||
appId: env.GITHUB_APP_ID,
|
||||
privateKey: Buffer.from(env.GITHUB_APP_PRIVATE_KEY, "base64").toString(
|
||||
"utf8"
|
||||
),
|
||||
clientId: env.GITHUB_APP_CLIENT_ID,
|
||||
clientSecret: env.GITHUB_APP_CLIENT_SECRET,
|
||||
},
|
||||
log: {
|
||||
debug: console.log,
|
||||
info: console.log,
|
||||
warn: console.warn,
|
||||
error: console.error,
|
||||
},
|
||||
})
|
||||
: undefined;
|
||||
|
||||
export const oauthApp = createOauthApp();
|
||||
|
||||
export const webhooks = createWebhooks();
|
||||
|
||||
declare global {
|
||||
var __github_webhooks__:
|
||||
| Webhooks<EmitterWebhookEvent & { octokit: Octokit }>
|
||||
| undefined;
|
||||
var __github_oauth_app__: OAuthApp<Options<"github-app">> | undefined;
|
||||
}
|
||||
|
||||
function createOauthApp() {
|
||||
if (typeof global.__github_oauth_app__ !== "undefined") {
|
||||
return global.__github_oauth_app__;
|
||||
}
|
||||
|
||||
if (typeof env.GITHUB_APP_CLIENT_ID === "undefined") {
|
||||
return;
|
||||
}
|
||||
|
||||
if (typeof env.GITHUB_APP_CLIENT_SECRET === "undefined") {
|
||||
return;
|
||||
}
|
||||
|
||||
global.__github_oauth_app__ = new OAuthApp({
|
||||
clientId: env.GITHUB_APP_CLIENT_ID,
|
||||
clientSecret: env.GITHUB_APP_CLIENT_SECRET,
|
||||
clientType: "github-app",
|
||||
});
|
||||
|
||||
global.__github_oauth_app__.on("token", async (event) => {});
|
||||
|
||||
return __github_oauth_app__;
|
||||
}
|
||||
|
||||
function createWebhooks() {
|
||||
if (typeof global.__github_webhooks__ !== "undefined") {
|
||||
return global.__github_webhooks__;
|
||||
}
|
||||
|
||||
if (
|
||||
typeof env.GITHUB_APP_WEBHOOK_SECRET === "undefined" ||
|
||||
typeof octokit === "undefined"
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
global.__github_webhooks__ = __webhooks(
|
||||
octokit,
|
||||
env.GITHUB_APP_WEBHOOK_SECRET
|
||||
);
|
||||
|
||||
global.__github_webhooks__.on("push", ({ octokit, payload }) => {});
|
||||
global.__github_webhooks__.onAny((event) => {});
|
||||
|
||||
return global.__github_webhooks__;
|
||||
}
|
||||
|
||||
function __webhooks(
|
||||
appOctokit: Octokit,
|
||||
secret: string
|
||||
// Explict return type for better debugability and performance,
|
||||
// see https://github.com/octokit/app.js/pull/201
|
||||
): Webhooks<EmitterWebhookEvent & { octokit: Octokit }> {
|
||||
return new Webhooks({
|
||||
secret,
|
||||
transform: async (event) => {
|
||||
if (
|
||||
!("installation" in event.payload) ||
|
||||
typeof event.payload.installation !== "object"
|
||||
) {
|
||||
const octokit = new (appOctokit.constructor as typeof Octokit)({
|
||||
authStrategy: createUnauthenticatedAuth,
|
||||
auth: {
|
||||
reason: `"installation" key missing in webhook event payload`,
|
||||
},
|
||||
});
|
||||
|
||||
return {
|
||||
...event,
|
||||
octokit,
|
||||
};
|
||||
}
|
||||
|
||||
const installationId = event.payload.installation.id;
|
||||
const octokit = (await appOctokit.auth({
|
||||
type: "installation",
|
||||
installationId,
|
||||
factory(auth: any) {
|
||||
return new auth.octokit.constructor({
|
||||
...auth.octokitOptions,
|
||||
authStrategy: createAppAuth,
|
||||
...{
|
||||
auth: {
|
||||
...auth,
|
||||
installationId,
|
||||
},
|
||||
},
|
||||
});
|
||||
},
|
||||
})) as Octokit;
|
||||
|
||||
// set `x-github-delivery` header on all requests sent in response to the current
|
||||
// event. This allows GitHub Support to correlate the request with the event.
|
||||
// This is not documented and not considered public API, the header may change.
|
||||
// Once we document this as best practice on https://docs.github.com/en/rest/guides/best-practices-for-integrators
|
||||
// we will make it official
|
||||
/* istanbul ignore next */
|
||||
octokit.hook.before("request", (options) => {
|
||||
options.headers["x-github-delivery"] = event.id;
|
||||
});
|
||||
|
||||
return {
|
||||
...event,
|
||||
octokit,
|
||||
};
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
type GetAppInstallationEndpoint =
|
||||
Endpoints["GET /app/installations/{installation_id}"];
|
||||
|
||||
export async function getAppInstallation({
|
||||
installation_id,
|
||||
}: GetAppInstallationEndpoint["parameters"]) {
|
||||
if (typeof octokit === "undefined") {
|
||||
return;
|
||||
}
|
||||
|
||||
const response = await octokit.request(
|
||||
"GET /app/installations/{installation_id}",
|
||||
{
|
||||
installation_id,
|
||||
}
|
||||
);
|
||||
|
||||
return response.data;
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
import type { PrismaClient } from "~/db.server";
|
||||
import { prisma } from "~/db.server";
|
||||
import { env } from "~/env.server";
|
||||
|
||||
export class StartAppInstallation {
|
||||
#prismaClient: PrismaClient;
|
||||
|
||||
constructor(prismaClient: PrismaClient = prisma) {
|
||||
this.#prismaClient = prismaClient;
|
||||
}
|
||||
|
||||
public async call({
|
||||
userId,
|
||||
organizationSlug,
|
||||
}: {
|
||||
userId: string;
|
||||
organizationSlug: string;
|
||||
}) {
|
||||
if (!env.GITHUB_APP_NAME) {
|
||||
return;
|
||||
}
|
||||
|
||||
const organization = await this.#prismaClient.organization.findUnique({
|
||||
where: {
|
||||
slug: organizationSlug,
|
||||
},
|
||||
});
|
||||
|
||||
if (!organization) {
|
||||
return;
|
||||
}
|
||||
|
||||
const attempt = await prisma.gitHubAppAuthorizationAttempt.create({
|
||||
data: {
|
||||
organizationId: organization.id,
|
||||
userId,
|
||||
},
|
||||
});
|
||||
|
||||
return `https://github.com/apps/${env.GITHUB_APP_NAME}/installations/new?state=${attempt.id}`;
|
||||
}
|
||||
}
|
||||
@@ -58,6 +58,12 @@
|
||||
"@lezer/highlight": "^1.1.2",
|
||||
"@nangohq/pizzly-frontend": "^0.3.7",
|
||||
"@nangohq/pizzly-node": "^0.4.1",
|
||||
"@octokit/app": "^13.1.2",
|
||||
"@octokit/auth-app": "^4.0.9",
|
||||
"@octokit/auth-unauthenticated": "^3.0.4",
|
||||
"@octokit/core": "^4.2.0",
|
||||
"@octokit/oauth-app": "^4.2.0",
|
||||
"@octokit/webhooks": "^10.4.0",
|
||||
"@prisma/client": "^4.3.0",
|
||||
"@remix-run/express": "^1.7.2",
|
||||
"@remix-run/node": "^1.7.2",
|
||||
@@ -134,6 +140,7 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@faker-js/faker": "^7.6.0",
|
||||
"@octokit/types": "^9.0.0",
|
||||
"@remix-run/dev": "^1.7.2",
|
||||
"@remix-run/eslint-config": "^1.7.2",
|
||||
"@swc/core": "^1.3.4",
|
||||
@@ -166,6 +173,7 @@
|
||||
"@types/slug": "^5.0.3",
|
||||
"@vitejs/plugin-react": "^2.0.1",
|
||||
"@vitest/coverage-c8": "^0.23.4",
|
||||
"auth-unauthenticated": "link:@types/@octokit/auth-unauthenticated",
|
||||
"autoprefixer": "^10.4.7",
|
||||
"c8": "^7.11.3",
|
||||
"cli-ux": "^6.0.9",
|
||||
@@ -194,7 +202,8 @@
|
||||
"typescript": "^4.8.4",
|
||||
"vite": "^3.1.4",
|
||||
"vite-tsconfig-paths": "^3.5.1",
|
||||
"vitest": "^0.23.4"
|
||||
"vitest": "^0.23.4",
|
||||
"webhooks": "link:@types/@octokit/webhooks"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16.0.0"
|
||||
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
-- CreateTable
|
||||
CREATE TABLE "GitHubAppAuthorization" (
|
||||
"id" TEXT NOT NULL,
|
||||
"userId" TEXT NOT NULL,
|
||||
"organizationId" TEXT NOT NULL,
|
||||
"token" TEXT NOT NULL,
|
||||
"tokenExpiresAt" TIMESTAMP(3) NOT NULL,
|
||||
"refreshToken" TEXT NOT NULL,
|
||||
"refreshTokenExpiresAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "GitHubAppAuthorization_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "GitHubAppAuthorization" ADD CONSTRAINT "GitHubAppAuthorization_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "GitHubAppAuthorization" ADD CONSTRAINT "GitHubAppAuthorization_organizationId_fkey" FOREIGN KEY ("organizationId") REFERENCES "Organization"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
-- CreateEnum
|
||||
CREATE TYPE "GitHubAppAuthorizationStatus" AS ENUM ('PENDING', 'AUTHORIZED');
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "GitHubAppAuthorization" ADD COLUMN "status" "GitHubAppAuthorizationStatus" NOT NULL DEFAULT 'PENDING';
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
Warnings:
|
||||
|
||||
- You are about to drop the column `status` on the `GitHubAppAuthorization` table. All the data in the column will be lost.
|
||||
|
||||
*/
|
||||
-- AlterTable
|
||||
ALTER TABLE "GitHubAppAuthorization" DROP COLUMN "status";
|
||||
|
||||
-- DropEnum
|
||||
DROP TYPE "GitHubAppAuthorizationStatus";
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "GitHubAppAuthorizationAttempt" (
|
||||
"id" TEXT NOT NULL,
|
||||
"userId" TEXT NOT NULL,
|
||||
"organizationId" TEXT NOT NULL,
|
||||
|
||||
CONSTRAINT "GitHubAppAuthorizationAttempt_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
Warnings:
|
||||
|
||||
- A unique constraint covering the columns `[installationId]` on the table `GitHubAppAuthorization` will be added. If there are existing duplicate values, this will fail.
|
||||
- Added the required column `accessTokensUrls` to the `GitHubAppAuthorization` table without a default value. This is not possible if the table is not empty.
|
||||
- Added the required column `account` to the `GitHubAppAuthorization` table without a default value. This is not possible if the table is not empty.
|
||||
- Added the required column `htmlUrl` to the `GitHubAppAuthorization` table without a default value. This is not possible if the table is not empty.
|
||||
- Added the required column `installationId` to the `GitHubAppAuthorization` table without a default value. This is not possible if the table is not empty.
|
||||
- Added the required column `permissions` to the `GitHubAppAuthorization` table without a default value. This is not possible if the table is not empty.
|
||||
- Added the required column `repositoriesUrl` to the `GitHubAppAuthorization` table without a default value. This is not possible if the table is not empty.
|
||||
- Added the required column `repositorySelection` to the `GitHubAppAuthorization` table without a default value. This is not possible if the table is not empty.
|
||||
|
||||
*/
|
||||
-- AlterTable
|
||||
ALTER TABLE "GitHubAppAuthorization" ADD COLUMN "accessTokensUrls" TEXT NOT NULL,
|
||||
ADD COLUMN "account" JSONB NOT NULL,
|
||||
ADD COLUMN "events" TEXT[],
|
||||
ADD COLUMN "htmlUrl" TEXT NOT NULL,
|
||||
ADD COLUMN "installationId" INTEGER NOT NULL,
|
||||
ADD COLUMN "permissions" JSONB NOT NULL,
|
||||
ADD COLUMN "repositoriesUrl" TEXT NOT NULL,
|
||||
ADD COLUMN "repositorySelection" TEXT NOT NULL;
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "GitHubAppAuthorization_installationId_key" ON "GitHubAppAuthorization"("installationId");
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
/*
|
||||
Warnings:
|
||||
|
||||
- You are about to drop the column `accessTokensUrls` on the `GitHubAppAuthorization` table. All the data in the column will be lost.
|
||||
- Added the required column `accessTokensUrl` to the `GitHubAppAuthorization` table without a default value. This is not possible if the table is not empty.
|
||||
|
||||
*/
|
||||
-- AlterTable
|
||||
ALTER TABLE "GitHubAppAuthorization" DROP COLUMN "accessTokensUrls",
|
||||
ADD COLUMN "accessTokensUrl" TEXT NOT NULL;
|
||||
@@ -28,7 +28,8 @@ model User {
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
organizations Organization[]
|
||||
organizations Organization[]
|
||||
gitHubAppAuthorizations GitHubAppAuthorization[]
|
||||
}
|
||||
|
||||
enum AuthenticationMethod {
|
||||
@@ -44,15 +45,16 @@ model Organization {
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
users User[]
|
||||
workflows Workflow[]
|
||||
environments RuntimeEnvironment[]
|
||||
apiConnections APIConnection[]
|
||||
events TriggerEvent[]
|
||||
externalSources ExternalSource[]
|
||||
eventRules EventRule[]
|
||||
schedulerSources SchedulerSource[]
|
||||
internalSources InternalSource[]
|
||||
users User[]
|
||||
workflows Workflow[]
|
||||
environments RuntimeEnvironment[]
|
||||
apiConnections APIConnection[]
|
||||
events TriggerEvent[]
|
||||
externalSources ExternalSource[]
|
||||
eventRules EventRule[]
|
||||
schedulerSources SchedulerSource[]
|
||||
internalSources InternalSource[]
|
||||
gitHubAppAuthorizations GitHubAppAuthorization[]
|
||||
}
|
||||
|
||||
model APIConnection {
|
||||
@@ -556,3 +558,33 @@ model FetchResponse {
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
}
|
||||
|
||||
model GitHubAppAuthorizationAttempt {
|
||||
id String @id @default(cuid())
|
||||
userId String
|
||||
organizationId String
|
||||
}
|
||||
|
||||
model GitHubAppAuthorization {
|
||||
id String @id @default(cuid())
|
||||
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade, onUpdate: Cascade)
|
||||
userId String
|
||||
|
||||
organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade, onUpdate: Cascade)
|
||||
organizationId String
|
||||
|
||||
installationId Int @unique
|
||||
account Json
|
||||
permissions Json
|
||||
repositorySelection String
|
||||
accessTokensUrl String
|
||||
repositoriesUrl String
|
||||
htmlUrl String
|
||||
events String[]
|
||||
|
||||
token String
|
||||
tokenExpiresAt DateTime
|
||||
refreshToken String
|
||||
refreshTokenExpiresAt DateTime
|
||||
}
|
||||
|
||||
Generated
+291
-14
@@ -50,6 +50,13 @@ importers:
|
||||
'@lezer/highlight': ^1.1.2
|
||||
'@nangohq/pizzly-frontend': ^0.3.7
|
||||
'@nangohq/pizzly-node': ^0.4.1
|
||||
'@octokit/app': ^13.1.2
|
||||
'@octokit/auth-app': ^4.0.9
|
||||
'@octokit/auth-unauthenticated': ^3.0.4
|
||||
'@octokit/core': ^4.2.0
|
||||
'@octokit/oauth-app': ^4.2.0
|
||||
'@octokit/types': ^9.0.0
|
||||
'@octokit/webhooks': ^10.4.0
|
||||
'@prisma/client': ^4.3.0
|
||||
'@remix-run/dev': ^1.7.2
|
||||
'@remix-run/eslint-config': ^1.7.2
|
||||
@@ -98,6 +105,7 @@ importers:
|
||||
'@uiw/react-codemirror': ^4.13.2
|
||||
'@vitejs/plugin-react': ^2.0.1
|
||||
'@vitest/coverage-c8': ^0.23.4
|
||||
auth-unauthenticated: link:@types/@octokit/auth-unauthenticated
|
||||
autoprefixer: ^10.4.7
|
||||
bcryptjs: ^2.4.3
|
||||
c8: ^7.11.3
|
||||
@@ -181,6 +189,7 @@ importers:
|
||||
vite: ^3.1.4
|
||||
vite-tsconfig-paths: ^3.5.1
|
||||
vitest: ^0.23.4
|
||||
webhooks: link:@types/@octokit/webhooks
|
||||
zod: ^3.20.2
|
||||
zod-error: ^1.1.0
|
||||
dependencies:
|
||||
@@ -202,6 +211,12 @@ importers:
|
||||
'@lezer/highlight': 1.1.3
|
||||
'@nangohq/pizzly-frontend': 0.3.7
|
||||
'@nangohq/pizzly-node': 0.4.1
|
||||
'@octokit/app': 13.1.2
|
||||
'@octokit/auth-app': 4.0.9
|
||||
'@octokit/auth-unauthenticated': 3.0.4
|
||||
'@octokit/core': 4.2.0
|
||||
'@octokit/oauth-app': 4.2.0
|
||||
'@octokit/webhooks': 10.5.1
|
||||
'@prisma/client': 4.8.1_prisma@4.8.1
|
||||
'@remix-run/express': 1.12.0_express@4.18.2
|
||||
'@remix-run/node': 1.12.0
|
||||
@@ -277,6 +292,7 @@ importers:
|
||||
zod-error: 1.1.0
|
||||
devDependencies:
|
||||
'@faker-js/faker': 7.6.0
|
||||
'@octokit/types': 9.0.0
|
||||
'@remix-run/dev': 1.12.0
|
||||
'@remix-run/eslint-config': 1.12.0_ol4nhuzbuflsbzk2mijpqykzba
|
||||
'@swc/core': 1.3.26
|
||||
@@ -309,6 +325,7 @@ importers:
|
||||
'@types/slug': 5.0.3
|
||||
'@vitejs/plugin-react': 2.2.0_vite@3.2.5
|
||||
'@vitest/coverage-c8': 0.23.4_happy-dom@6.0.4
|
||||
auth-unauthenticated: link:@types/@octokit/auth-unauthenticated
|
||||
autoprefixer: 10.4.13_postcss@8.4.21
|
||||
c8: 7.12.0
|
||||
cli-ux: 6.0.9
|
||||
@@ -337,6 +354,7 @@ importers:
|
||||
vite: 3.2.5_@types+node@18.11.18
|
||||
vite-tsconfig-paths: 3.6.0_vite@3.2.5
|
||||
vitest: 0.23.4_happy-dom@6.0.4
|
||||
webhooks: link:@types/@octokit/webhooks
|
||||
|
||||
apps/wss:
|
||||
specifiers:
|
||||
@@ -4494,25 +4512,206 @@ packages:
|
||||
engines: {node: '>=12.0.0'}
|
||||
dev: true
|
||||
|
||||
/@octokit/openapi-types/14.0.0:
|
||||
resolution: {integrity: sha512-HNWisMYlR8VCnNurDU6os2ikx0s0VyEjDYHNS/h4cgb8DeOxQ0n72HyinUtdDVxJhFy3FWLGl0DJhfEWk3P5Iw==}
|
||||
dev: false
|
||||
|
||||
/@octokit/request-error/3.0.2:
|
||||
resolution: {integrity: sha512-WMNOFYrSaX8zXWoJg9u/pKgWPo94JXilMLb2VManNOby9EZxrQaBe/QSC4a1TzpAlpxofg2X/jMnCyZgL6y7eg==}
|
||||
/@octokit/app/13.1.2:
|
||||
resolution: {integrity: sha512-Kf+h5sa1SOI33hFsuHvTsWj1jUrjp1x4MuiJBq7U/NicfEGa6nArPUoDnyfP/YTmcQ5cQ5yvOgoIBkbwPg6kzQ==}
|
||||
engines: {node: '>= 14'}
|
||||
dependencies:
|
||||
'@octokit/types': 8.1.0
|
||||
'@octokit/auth-app': 4.0.9
|
||||
'@octokit/auth-unauthenticated': 3.0.4
|
||||
'@octokit/core': 4.2.0
|
||||
'@octokit/oauth-app': 4.2.0
|
||||
'@octokit/plugin-paginate-rest': 6.0.0_@octokit+core@4.2.0
|
||||
'@octokit/types': 9.0.0
|
||||
'@octokit/webhooks': 10.5.1
|
||||
transitivePeerDependencies:
|
||||
- encoding
|
||||
dev: false
|
||||
|
||||
/@octokit/auth-app/4.0.9:
|
||||
resolution: {integrity: sha512-VFpKIXhHO+kVJtane5cEvdYPtjDKCOI0uKsRrsZfJP+uEu7rcPbQCLCcRKgyT+mUIzGr1IIOmwP/lFqSip1dXA==}
|
||||
engines: {node: '>= 14'}
|
||||
dependencies:
|
||||
'@octokit/auth-oauth-app': 5.0.5
|
||||
'@octokit/auth-oauth-user': 2.1.1
|
||||
'@octokit/request': 6.2.3
|
||||
'@octokit/request-error': 3.0.3
|
||||
'@octokit/types': 9.0.0
|
||||
'@types/lru-cache': 5.1.1
|
||||
deprecation: 2.3.1
|
||||
lru-cache: 6.0.0
|
||||
universal-github-app-jwt: 1.1.1
|
||||
universal-user-agent: 6.0.0
|
||||
transitivePeerDependencies:
|
||||
- encoding
|
||||
dev: false
|
||||
|
||||
/@octokit/auth-oauth-app/5.0.5:
|
||||
resolution: {integrity: sha512-UPX1su6XpseaeLVCi78s9droxpGtBWIgz9XhXAx9VXabksoF0MyI5vaa1zo1njyYt6VaAjFisC2A2Wchcu2WmQ==}
|
||||
engines: {node: '>= 14'}
|
||||
dependencies:
|
||||
'@octokit/auth-oauth-device': 4.0.4
|
||||
'@octokit/auth-oauth-user': 2.1.1
|
||||
'@octokit/request': 6.2.3
|
||||
'@octokit/types': 9.0.0
|
||||
'@types/btoa-lite': 1.0.0
|
||||
btoa-lite: 1.0.0
|
||||
universal-user-agent: 6.0.0
|
||||
transitivePeerDependencies:
|
||||
- encoding
|
||||
dev: false
|
||||
|
||||
/@octokit/auth-oauth-device/4.0.4:
|
||||
resolution: {integrity: sha512-Xl85BZYfqCMv+Uvz33nVVUjE7I/PVySNaK6dRRqlkvYcArSr9vRcZC9KVjXYObGRTCN6mISeYdakAZvWEN4+Jw==}
|
||||
engines: {node: '>= 14'}
|
||||
dependencies:
|
||||
'@octokit/oauth-methods': 2.0.5
|
||||
'@octokit/request': 6.2.3
|
||||
'@octokit/types': 9.0.0
|
||||
universal-user-agent: 6.0.0
|
||||
transitivePeerDependencies:
|
||||
- encoding
|
||||
dev: false
|
||||
|
||||
/@octokit/auth-oauth-user/2.1.1:
|
||||
resolution: {integrity: sha512-JgqnNNPf9CaWLxWm9uh2WgxcaVYhxBR09NVIPTiMU2dVZ3FObOHs3njBiLNw+zq84k+rEdm5Y7AsiASrZ84Apg==}
|
||||
engines: {node: '>= 14'}
|
||||
dependencies:
|
||||
'@octokit/auth-oauth-device': 4.0.4
|
||||
'@octokit/oauth-methods': 2.0.5
|
||||
'@octokit/request': 6.2.3
|
||||
'@octokit/types': 9.0.0
|
||||
btoa-lite: 1.0.0
|
||||
universal-user-agent: 6.0.0
|
||||
transitivePeerDependencies:
|
||||
- encoding
|
||||
dev: false
|
||||
|
||||
/@octokit/auth-token/3.0.3:
|
||||
resolution: {integrity: sha512-/aFM2M4HVDBT/jjDBa84sJniv1t9Gm/rLkalaz9htOm+L+8JMj1k9w0CkUdcxNyNxZPlTxKPVko+m1VlM58ZVA==}
|
||||
engines: {node: '>= 14'}
|
||||
dependencies:
|
||||
'@octokit/types': 9.0.0
|
||||
dev: false
|
||||
|
||||
/@octokit/auth-unauthenticated/3.0.4:
|
||||
resolution: {integrity: sha512-AT74XGBylcLr4lmUp1s6mjSUgphGdlse21Qjtv5DzpX1YOl5FXKwvNcZWESdhyBbpDT8VkVyLFqa/7a7eqpPNw==}
|
||||
engines: {node: '>= 14'}
|
||||
dependencies:
|
||||
'@octokit/request-error': 3.0.3
|
||||
'@octokit/types': 9.0.0
|
||||
dev: false
|
||||
|
||||
/@octokit/core/4.2.0:
|
||||
resolution: {integrity: sha512-AgvDRUg3COpR82P7PBdGZF/NNqGmtMq2NiPqeSsDIeCfYFOZ9gddqWNQHnFdEUf+YwOj4aZYmJnlPp7OXmDIDg==}
|
||||
engines: {node: '>= 14'}
|
||||
dependencies:
|
||||
'@octokit/auth-token': 3.0.3
|
||||
'@octokit/graphql': 5.0.5
|
||||
'@octokit/request': 6.2.3
|
||||
'@octokit/request-error': 3.0.3
|
||||
'@octokit/types': 9.0.0
|
||||
before-after-hook: 2.2.3
|
||||
universal-user-agent: 6.0.0
|
||||
transitivePeerDependencies:
|
||||
- encoding
|
||||
dev: false
|
||||
|
||||
/@octokit/endpoint/7.0.5:
|
||||
resolution: {integrity: sha512-LG4o4HMY1Xoaec87IqQ41TQ+glvIeTKqfjkCEmt5AIwDZJwQeVZFIEYXrYY6yLwK+pAScb9Gj4q+Nz2qSw1roA==}
|
||||
engines: {node: '>= 14'}
|
||||
dependencies:
|
||||
'@octokit/types': 9.0.0
|
||||
is-plain-object: 5.0.0
|
||||
universal-user-agent: 6.0.0
|
||||
dev: false
|
||||
|
||||
/@octokit/graphql/5.0.5:
|
||||
resolution: {integrity: sha512-Qwfvh3xdqKtIznjX9lz2D458r7dJPP8l6r4GQkIdWQouZwHQK0mVT88uwiU2bdTU2OtT1uOlKpRciUWldpG0yQ==}
|
||||
engines: {node: '>= 14'}
|
||||
dependencies:
|
||||
'@octokit/request': 6.2.3
|
||||
'@octokit/types': 9.0.0
|
||||
universal-user-agent: 6.0.0
|
||||
transitivePeerDependencies:
|
||||
- encoding
|
||||
dev: false
|
||||
|
||||
/@octokit/oauth-app/4.2.0:
|
||||
resolution: {integrity: sha512-gyGclT77RQMkVUEW3YBeAKY+LBSc5u3eC9Wn/Uwt3WhuKuu9mrV18EnNpDqmeNll+mdV02yyBROU29Tlili6gg==}
|
||||
engines: {node: '>= 14'}
|
||||
dependencies:
|
||||
'@octokit/auth-oauth-app': 5.0.5
|
||||
'@octokit/auth-oauth-user': 2.1.1
|
||||
'@octokit/auth-unauthenticated': 3.0.4
|
||||
'@octokit/core': 4.2.0
|
||||
'@octokit/oauth-authorization-url': 5.0.0
|
||||
'@octokit/oauth-methods': 2.0.5
|
||||
'@types/aws-lambda': 8.10.110
|
||||
fromentries: 1.3.2
|
||||
universal-user-agent: 6.0.0
|
||||
transitivePeerDependencies:
|
||||
- encoding
|
||||
dev: false
|
||||
|
||||
/@octokit/oauth-authorization-url/5.0.0:
|
||||
resolution: {integrity: sha512-y1WhN+ERDZTh0qZ4SR+zotgsQUE1ysKnvBt1hvDRB2WRzYtVKQjn97HEPzoehh66Fj9LwNdlZh+p6TJatT0zzg==}
|
||||
engines: {node: '>= 14'}
|
||||
dev: false
|
||||
|
||||
/@octokit/oauth-methods/2.0.5:
|
||||
resolution: {integrity: sha512-yQP6B5gE3axNxuM3U9KqWs/ErAQ+WLPaPgC/7EjsZsQibkf8sjdAfF8/y/EJW+Dd05XQvadX4WhQZPMnO1SE1A==}
|
||||
engines: {node: '>= 14'}
|
||||
dependencies:
|
||||
'@octokit/oauth-authorization-url': 5.0.0
|
||||
'@octokit/request': 6.2.3
|
||||
'@octokit/request-error': 3.0.3
|
||||
'@octokit/types': 9.0.0
|
||||
btoa-lite: 1.0.0
|
||||
transitivePeerDependencies:
|
||||
- encoding
|
||||
dev: false
|
||||
|
||||
/@octokit/openapi-types/16.0.0:
|
||||
resolution: {integrity: sha512-JbFWOqTJVLHZSUUoF4FzAZKYtqdxWu9Z5m2QQnOyEa04fOFljvyh7D3GYKbfuaSWisqehImiVIMG4eyJeP5VEA==}
|
||||
|
||||
/@octokit/plugin-paginate-rest/6.0.0_@octokit+core@4.2.0:
|
||||
resolution: {integrity: sha512-Sq5VU1PfT6/JyuXPyt04KZNVsFOSBaYOAq2QRZUwzVlI10KFvcbUo8lR258AAQL1Et60b0WuVik+zOWKLuDZxw==}
|
||||
engines: {node: '>= 14'}
|
||||
peerDependencies:
|
||||
'@octokit/core': '>=4'
|
||||
dependencies:
|
||||
'@octokit/core': 4.2.0
|
||||
'@octokit/types': 9.0.0
|
||||
dev: false
|
||||
|
||||
/@octokit/request-error/3.0.3:
|
||||
resolution: {integrity: sha512-crqw3V5Iy2uOU5Np+8M/YexTlT8zxCfI+qu+LxUB7SZpje4Qmx3mub5DfEKSO8Ylyk0aogi6TYdf6kxzh2BguQ==}
|
||||
engines: {node: '>= 14'}
|
||||
dependencies:
|
||||
'@octokit/types': 9.0.0
|
||||
deprecation: 2.3.1
|
||||
once: 1.4.0
|
||||
dev: false
|
||||
|
||||
/@octokit/types/8.1.0:
|
||||
resolution: {integrity: sha512-N4nLjzkiWBqVQqljTTsCrbvHGoWdWfcCeZjbHdggw7a9HbJMnxbK8A+UWdqwR4out30JarlSa3eqKyVK0n5aBg==}
|
||||
/@octokit/request/6.2.3:
|
||||
resolution: {integrity: sha512-TNAodj5yNzrrZ/VxP+H5HiYaZep0H3GU0O7PaF+fhDrt8FPrnkei9Aal/txsN/1P7V3CPiThG0tIvpPDYUsyAA==}
|
||||
engines: {node: '>= 14'}
|
||||
dependencies:
|
||||
'@octokit/openapi-types': 14.0.0
|
||||
'@octokit/endpoint': 7.0.5
|
||||
'@octokit/request-error': 3.0.3
|
||||
'@octokit/types': 9.0.0
|
||||
is-plain-object: 5.0.0
|
||||
node-fetch: 2.6.7
|
||||
universal-user-agent: 6.0.0
|
||||
transitivePeerDependencies:
|
||||
- encoding
|
||||
dev: false
|
||||
|
||||
/@octokit/types/9.0.0:
|
||||
resolution: {integrity: sha512-LUewfj94xCMH2rbD5YJ+6AQ4AVjFYTgpp6rboWM5T7N3IsIF65SBEOVcYMGAEzO/kKNiNaW4LoWtoThOhH06gw==}
|
||||
dependencies:
|
||||
'@octokit/openapi-types': 16.0.0
|
||||
|
||||
/@octokit/webhooks-methods/3.0.2:
|
||||
resolution: {integrity: sha512-Vlnv5WBscf07tyAvfDbp7pTkMZUwk7z7VwEF32x6HqI+55QRwBTcT+D7DDjZXtad/1dU9E32x0HmtDlF9VIRaQ==}
|
||||
engines: {node: '>= 14'}
|
||||
@@ -4526,7 +4725,7 @@ packages:
|
||||
resolution: {integrity: sha512-6yGcfVbQGIkRm/vlU4Ld4r0YNOT6ly5Kp+t6R3UAT0amxGASFtZLzOJry0UQfvvidCxK5qT9jHXU0QUp6alatA==}
|
||||
engines: {node: '>= 14'}
|
||||
dependencies:
|
||||
'@octokit/request-error': 3.0.2
|
||||
'@octokit/request-error': 3.0.3
|
||||
'@octokit/webhooks-methods': 3.0.2
|
||||
'@octokit/webhooks-types': 6.7.0
|
||||
aggregate-error: 3.1.0
|
||||
@@ -5392,6 +5591,10 @@ packages:
|
||||
resolution: {integrity: sha512-XTIieEY+gvJ39ChLcB4If5zHtPxt3Syj5rgZR+e1ctpmK8NjPf0zFqsz4JpLJT0xla9GFDKjy8Cpu331nrmE1Q==}
|
||||
dev: true
|
||||
|
||||
/@types/aws-lambda/8.10.110:
|
||||
resolution: {integrity: sha512-r6egf2Cwv/JaFTTrF9OXFVUB3j/SXTgM9BwrlbBRjWAa2Tu6GWoDoLflppAZ8uSfbUJdXvC7Br3DjuN9pQ2NUQ==}
|
||||
dev: false
|
||||
|
||||
/@types/bcryptjs/2.4.2:
|
||||
resolution: {integrity: sha512-LiMQ6EOPob/4yUL66SZzu6Yh77cbzJFYll+ZfaPiPPFswtIlA/Fs1MzdKYA7JApHU49zQTbJGX3PDmCpIdDBRQ==}
|
||||
dev: true
|
||||
@@ -5403,6 +5606,10 @@ packages:
|
||||
'@types/node': 18.11.18
|
||||
dev: true
|
||||
|
||||
/@types/btoa-lite/1.0.0:
|
||||
resolution: {integrity: sha512-wJsiX1tosQ+J5+bY5LrSahHxr2wT+uME5UDwdN1kg4frt40euqA+wzECkmq4t5QbveHiJepfdThgQrPw6KiSlg==}
|
||||
dev: false
|
||||
|
||||
/@types/cacheable-request/6.0.3:
|
||||
resolution: {integrity: sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==}
|
||||
dependencies:
|
||||
@@ -5564,6 +5771,12 @@ packages:
|
||||
resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==}
|
||||
dev: true
|
||||
|
||||
/@types/jsonwebtoken/9.0.1:
|
||||
resolution: {integrity: sha512-c5ltxazpWabia/4UzhIoaDcIza4KViOQhdbjRlfcIGVnsE3c3brkz9Z+F/EeJIECOQP7W7US2hNE930cWWkPiw==}
|
||||
dependencies:
|
||||
'@types/node': 18.11.18
|
||||
dev: false
|
||||
|
||||
/@types/keyv/3.1.4:
|
||||
resolution: {integrity: sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==}
|
||||
dependencies:
|
||||
@@ -5574,6 +5787,10 @@ packages:
|
||||
resolution: {integrity: sha512-BdZ5BCCvho3EIXw6wUCXHe7rS53AIDPLE+JzwgT+OsJk53oBfbSmZZ7CX4VaRoN78N+TJpFi9QPlfIVNmJYWxQ==}
|
||||
dev: true
|
||||
|
||||
/@types/lru-cache/5.1.1:
|
||||
resolution: {integrity: sha512-ssE3Vlrys7sdIzs5LOxCzTVMsU7i9oa/IaW92wF32JFb3CVczqOkru2xspuKczHEbG3nvmPY7IFqVmGGHdNbYw==}
|
||||
dev: false
|
||||
|
||||
/@types/marked/4.0.8:
|
||||
resolution: {integrity: sha512-HVNzMT5QlWCOdeuBsgXP8EZzKUf0+AXzN+sLmjvaB3ZlLqO+e4u0uXrdw9ub69wBKFs+c6/pA4r9sy6cCDvImw==}
|
||||
dev: true
|
||||
@@ -6575,6 +6792,10 @@ packages:
|
||||
resolution: {integrity: sha512-V/Hy/X9Vt7f3BbPJEi8BdVFMByHi+jNXrYkW3huaybV/kQ0KJg0Y6PkEMbn+zeT+i+SiKZ/HMqJGIIt4LZDqNQ==}
|
||||
dev: false
|
||||
|
||||
/before-after-hook/2.2.3:
|
||||
resolution: {integrity: sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==}
|
||||
dev: false
|
||||
|
||||
/better-path-resolve/1.0.0:
|
||||
resolution: {integrity: sha512-pbnl5XzGBdrFU/wT4jqmJVPn2B6UHPBOhzMQkY/SPUPB6QtUXtmBHBIwCbXJol93mOpGMnQyP/+BB19q04xj7g==}
|
||||
engines: {node: '>=4'}
|
||||
@@ -6715,10 +6936,18 @@ packages:
|
||||
update-browserslist-db: 1.0.10_browserslist@4.21.4
|
||||
dev: true
|
||||
|
||||
/btoa-lite/1.0.0:
|
||||
resolution: {integrity: sha512-gvW7InbIyF8AicrqWoptdW08pUxuhq8BEgowNajy9RhiE86fmGAGl+bLKo6oB8QP0CkqHLowfN0oJdKC/J6LbA==}
|
||||
dev: false
|
||||
|
||||
/buffer-crc32/0.2.13:
|
||||
resolution: {integrity: sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==}
|
||||
dev: true
|
||||
|
||||
/buffer-equal-constant-time/1.0.1:
|
||||
resolution: {integrity: sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==}
|
||||
dev: false
|
||||
|
||||
/buffer-from/1.1.2:
|
||||
resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==}
|
||||
|
||||
@@ -7941,6 +8170,12 @@ packages:
|
||||
safer-buffer: 2.1.2
|
||||
dev: true
|
||||
|
||||
/ecdsa-sig-formatter/1.0.11:
|
||||
resolution: {integrity: sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==}
|
||||
dependencies:
|
||||
safe-buffer: 5.2.1
|
||||
dev: false
|
||||
|
||||
/editorconfig/0.15.3:
|
||||
resolution: {integrity: sha512-M9wIMFx96vq0R4F+gRpY3o2exzb8hEj/n9S8unZtHSvYjibBp/iMufSzvmOcV/laG0ZtuTVGtiJggPOSW2r93g==}
|
||||
hasBin: true
|
||||
@@ -9348,6 +9583,10 @@ packages:
|
||||
resolution: {integrity: sha512-twe20eF1OxVxp/ML/kq2p1uc6KvFK/+vs8WjEbeKmV2He22MKm7YF2ANIt+EOqhJ5L3K/SuuPhk0hWQDjOM23g==}
|
||||
dev: true
|
||||
|
||||
/fromentries/1.3.2:
|
||||
resolution: {integrity: sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg==}
|
||||
dev: false
|
||||
|
||||
/fs-constants/1.0.0:
|
||||
resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==}
|
||||
dev: true
|
||||
@@ -10449,6 +10688,11 @@ packages:
|
||||
dependencies:
|
||||
isobject: 3.0.1
|
||||
|
||||
/is-plain-object/5.0.0:
|
||||
resolution: {integrity: sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
dev: false
|
||||
|
||||
/is-reference/3.0.1:
|
||||
resolution: {integrity: sha512-baJJdQLiYaJdvFbJqXrcGv3WU3QCzBlUcI5QhbesIm6/xPsvmO+2CDoi/GMOFBQEQm+PXkwOPrp9KK5ozZsp2w==}
|
||||
dependencies:
|
||||
@@ -10851,6 +11095,16 @@ packages:
|
||||
resolution: {integrity: sha512-S6cATIPVv1z0IlxdN+zUk5EPjkGCdnhN4wVSBlvoUO1tOLJootbo9CquNJmbIh4yikWHiUedhRYrNPn1arpEmQ==}
|
||||
dev: false
|
||||
|
||||
/jsonwebtoken/9.0.0:
|
||||
resolution: {integrity: sha512-tuGfYXxkQGDPnLJ7SibiQgVgeDgfbPq2k2ICcbgqW8WxWLBAxKQM/ZCu/IT8SOSwmaYl4dpTFCW5xZv7YbbWUw==}
|
||||
engines: {node: '>=12', npm: '>=6'}
|
||||
dependencies:
|
||||
jws: 3.2.2
|
||||
lodash: 4.17.21
|
||||
ms: 2.1.3
|
||||
semver: 7.3.8
|
||||
dev: false
|
||||
|
||||
/jsprim/2.0.2:
|
||||
resolution: {integrity: sha512-gqXddjPqQ6G40VdnI6T6yObEC+pDNvyP95wdQhkWkg7crHH3km5qP1FsOXEkzEQwnz6gz5qGTn1c2Y52wP3OyQ==}
|
||||
engines: {'0': node >=0.6.0}
|
||||
@@ -10880,6 +11134,21 @@ packages:
|
||||
resolution: {integrity: sha512-pBxcB3LFc8QVgdggvZWyeys+hnrNWg4OcZIU/1X59k5jQdLBlCsYGRQaz234SqoRLTCgMH00fY0xRJH+F9METQ==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
/jwa/1.4.1:
|
||||
resolution: {integrity: sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==}
|
||||
dependencies:
|
||||
buffer-equal-constant-time: 1.0.1
|
||||
ecdsa-sig-formatter: 1.0.11
|
||||
safe-buffer: 5.2.1
|
||||
dev: false
|
||||
|
||||
/jws/3.2.2:
|
||||
resolution: {integrity: sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==}
|
||||
dependencies:
|
||||
jwa: 1.4.1
|
||||
safe-buffer: 5.2.1
|
||||
dev: false
|
||||
|
||||
/keyv/3.1.0:
|
||||
resolution: {integrity: sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==}
|
||||
dependencies:
|
||||
@@ -11166,7 +11435,6 @@ packages:
|
||||
engines: {node: '>=10'}
|
||||
dependencies:
|
||||
yallist: 4.0.0
|
||||
dev: true
|
||||
|
||||
/lru-cache/7.14.1:
|
||||
resolution: {integrity: sha512-ysxwsnTKdAx96aTRdhDOCQfDgbHnt8SK0KY8SEjO0wHinhWOFTESbjVCMPbU1uGXg/ch4lifqx0wfjOawU2+WA==}
|
||||
@@ -13930,7 +14198,6 @@ packages:
|
||||
hasBin: true
|
||||
dependencies:
|
||||
lru-cache: 6.0.0
|
||||
dev: true
|
||||
|
||||
/send/0.18.0:
|
||||
resolution: {integrity: sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==}
|
||||
@@ -15305,6 +15572,17 @@ packages:
|
||||
unist-util-visit-parents: 5.1.1
|
||||
dev: true
|
||||
|
||||
/universal-github-app-jwt/1.1.1:
|
||||
resolution: {integrity: sha512-G33RTLrIBMFmlDV4u4CBF7dh71eWwykck4XgaxaIVeZKOYZRAAxvcGMRFTUclVY6xoUPQvO4Ne5wKGxYm/Yy9w==}
|
||||
dependencies:
|
||||
'@types/jsonwebtoken': 9.0.1
|
||||
jsonwebtoken: 9.0.0
|
||||
dev: false
|
||||
|
||||
/universal-user-agent/6.0.0:
|
||||
resolution: {integrity: sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w==}
|
||||
dev: false
|
||||
|
||||
/universalify/0.1.2:
|
||||
resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==}
|
||||
engines: {node: '>= 4.0.0'}
|
||||
@@ -15879,7 +16157,6 @@ packages:
|
||||
|
||||
/yallist/4.0.0:
|
||||
resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==}
|
||||
dev: true
|
||||
|
||||
/yaml/1.10.2:
|
||||
resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==}
|
||||
|
||||
Reference in New Issue
Block a user