Merge pull request #781 from Dokploy/remove-husky

Remove husky
This commit is contained in:
Mauricio Siu 2024-11-28 22:49:45 -06:00 committed by GitHub
commit fef19056fa
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
16 changed files with 395 additions and 284 deletions

View File

@ -1,4 +0,0 @@
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
pnpm commitlint --edit $1

View File

@ -1,6 +0,0 @@
// Skip Husky install in production and CI
if (process.env.NODE_ENV === "production" || process.env.CI === "true") {
process.exit(0);
}
const husky = (await import("husky")).default;
console.log(husky());

View File

@ -1 +0,0 @@
pnpm lint-staged

View File

@ -4,9 +4,6 @@ on:
pull_request:
branches: [main, canary]
env:
HUSKY: 0
jobs:
lint-and-typecheck:
runs-on: ubuntu-latest
@ -18,8 +15,7 @@ jobs:
node-version: 18.18.0
cache: "pnpm"
- run: pnpm install --frozen-lockfile
- run: pnpm run server:build
- run: pnpm biome ci
- run: pnpm run server:build
- run: pnpm typecheck
build-and-test:
@ -46,5 +42,5 @@ jobs:
node-version: 18.18.0
cache: "pnpm"
- run: pnpm install --frozen-lockfile
- run: pnpm run server:build
- run: pnpm run server:build
- run: pnpm test

View File

@ -1 +0,0 @@
npx commitlint --edit "$1"

View File

@ -1,6 +0,0 @@
// Skip Husky install in production and CI
if (process.env.NODE_ENV === "production" || process.env.CI === "true") {
process.exit(0);
}
const husky = (await import("husky")).default;
console.log(husky());

View File

@ -1,2 +0,0 @@
# pnpm run check
# git add .

View File

@ -30,6 +30,7 @@ const baseApp: ApplicationNested = {
appName: "",
autoDeploy: true,
serverId: "",
registryUrl: "",
branch: null,
dockerBuildStage: "",
project: {

View File

@ -12,6 +12,7 @@ const baseApp: ApplicationNested = {
serverId: "",
branch: null,
dockerBuildStage: "",
registryUrl: "",
buildArgs: null,
project: {
env: "",

View File

@ -34,7 +34,6 @@ export const SaveDockerProvider = ({ applicationId }: Props) => {
const { data, refetch } = api.application.one.useQuery({ applicationId });
const { mutateAsync } = api.application.saveDockerProvider.useMutation();
const form = useForm<DockerProvider>({
defaultValues: {
dockerImage: "",

View File

@ -76,7 +76,7 @@ export const AddDestination = () => {
const onSubmit = async (data: AddDestination) => {
await mutateAsync({
provider: data.provider,
provider: data.provider || "",
accessKey: data.accessKeyId,
bucket: data.bucket,
endpoint: data.endpoint,
@ -293,7 +293,7 @@ export const AddDestination = () => {
isLoading={isLoading}
onClick={async () => {
await testConnection({
provider: form.getValues("provider"),
provider: form.getValues("provider") || "",
accessKey: form.getValues("accessKeyId"),
bucket: form.getValues("bucket"),
endpoint: form.getValues("endpoint"),
@ -322,7 +322,7 @@ export const AddDestination = () => {
variant="secondary"
onClick={async () => {
await testConnection({
provider: form.getValues("provider"),
provider: form.getValues("provider") || "",
accessKey: form.getValues("accessKeyId"),
bucket: form.getValues("bucket"),
endpoint: form.getValues("endpoint"),

View File

@ -322,7 +322,7 @@ export const UpdateDestination = ({ destinationId }: Props) => {
variant={"secondary"}
onClick={async () => {
await testConnection({
provider: form.getValues("provider"),
provider: form.getValues("provider") || "",
accessKey: form.getValues("accessKeyId"),
bucket: form.getValues("bucket"),
endpoint: form.getValues("endpoint"),
@ -349,7 +349,7 @@ export const UpdateDestination = ({ destinationId }: Props) => {
variant="secondary"
onClick={async () => {
await testConnection({
provider: form.getValues("provider"),
provider: form.getValues("provider") || "",
accessKey: form.getValues("accessKeyId"),
bucket: form.getValues("bucket"),
endpoint: form.getValues("endpoint"),

45
lefthook.yml Normal file
View File

@ -0,0 +1,45 @@
# EXAMPLE USAGE:
#
# Refer for explanation to following link:
# https://github.com/evilmartians/lefthook/blob/master/docs/configuration.md
#
# pre-push:
# commands:
# packages-audit:
# tags: frontend security
# run: yarn audit
# gems-audit:
# tags: backend security
# run: bundle audit
#
# pre-commit:
# parallel: true
# commands:
# eslint:
# glob: "*.{js,ts,jsx,tsx}"
# run: yarn eslint {staged_files}
# rubocop:
# tags: backend style
# glob: "*.rb"
# exclude: '(^|/)(application|routes)\.rb$'
# run: bundle exec rubocop --force-exclusion {all_files}
# govet:
# tags: backend style
# files: git ls-files -m
# glob: "*.go"
# run: go vet {files}
# scripts:
# "hello.js":
# runner: node
# "any.go":
# runner: go run
commit-msg:
commands:
commitlint:
run: "npx commitlint --edit $1"
pre-commit:
commands:
lint-staged:
run: "pnpm check && npx lint-staged"

View File

@ -17,8 +17,7 @@
"build": "pnpm -r run build",
"format-and-lint": "biome check .",
"check": "biome check --write --no-errors-on-unmatched --files-ignore-unknown=true",
"format-and-lint:fix": "biome check . --write",
"prepare": "node .husky/install.mjs"
"format-and-lint:fix": "biome check . --write"
},
"devDependencies": {
"dotenv": "16.4.5",
@ -26,7 +25,7 @@
"tsx": "4.16.2",
"lint-staged": "^15.2.7",
"@biomejs/biome": "1.8.3",
"husky": "^9.1.6",
"lefthook": "1.8.4",
"@commitlint/cli": "^19.3.0",
"@commitlint/config-conventional": "^19.2.2",
"@types/node": "^18.17.0"

View File

@ -14,195 +14,195 @@ import { type Github, findGithubById } from "@dokploy/server/services/github";
import { execAsyncRemote } from "../process/execAsync";
export const authGithub = (githubProvider: Github): Octokit => {
if (!haveGithubRequirements(githubProvider)) {
throw new TRPCError({
code: "NOT_FOUND",
message: "Github Account not configured correctly",
});
}
if (!haveGithubRequirements(githubProvider)) {
throw new TRPCError({
code: "NOT_FOUND",
message: "Github Account not configured correctly",
});
}
const octokit: Octokit = new Octokit({
authStrategy: createAppAuth,
auth: {
appId: githubProvider?.githubAppId || 0,
privateKey: githubProvider?.githubPrivateKey || "",
installationId: githubProvider?.githubInstallationId,
},
});
const octokit: Octokit = new Octokit({
authStrategy: createAppAuth,
auth: {
appId: githubProvider?.githubAppId || 0,
privateKey: githubProvider?.githubPrivateKey || "",
installationId: githubProvider?.githubInstallationId,
},
});
return octokit;
return octokit;
};
export const getGithubToken = async (
octokit: ReturnType<typeof authGithub>
octokit: ReturnType<typeof authGithub>,
) => {
const installation = (await octokit.auth({
type: "installation",
})) as {
token: string;
};
const installation = (await octokit.auth({
type: "installation",
})) as {
token: string;
};
return installation.token;
return installation.token;
};
export const haveGithubRequirements = (githubProvider: Github) => {
return !!(
githubProvider?.githubAppId &&
githubProvider?.githubPrivateKey &&
githubProvider?.githubInstallationId
);
return !!(
githubProvider?.githubAppId &&
githubProvider?.githubPrivateKey &&
githubProvider?.githubInstallationId
);
};
const getErrorCloneRequirements = (entity: {
repository?: string | null;
owner?: string | null;
branch?: string | null;
repository?: string | null;
owner?: string | null;
branch?: string | null;
}) => {
const reasons: string[] = [];
const { repository, owner, branch } = entity;
const reasons: string[] = [];
const { repository, owner, branch } = entity;
if (!repository) reasons.push("1. Repository not assigned.");
if (!owner) reasons.push("2. Owner not specified.");
if (!branch) reasons.push("3. Branch not defined.");
if (!repository) reasons.push("1. Repository not assigned.");
if (!owner) reasons.push("2. Owner not specified.");
if (!branch) reasons.push("3. Branch not defined.");
return reasons;
return reasons;
};
export type ApplicationWithGithub = InferResultType<
"applications",
{ github: true }
"applications",
{ github: true }
>;
export type ComposeWithGithub = InferResultType<"compose", { github: true }>;
export const cloneGithubRepository = async (
entity: ApplicationWithGithub | ComposeWithGithub,
logPath: string,
isCompose = false
entity: ApplicationWithGithub | ComposeWithGithub,
logPath: string,
isCompose = false,
) => {
const { APPLICATIONS_PATH, COMPOSE_PATH } = paths();
const writeStream = createWriteStream(logPath, { flags: "a" });
const { appName, repository, owner, branch, githubId } = entity;
const { APPLICATIONS_PATH, COMPOSE_PATH } = paths();
const writeStream = createWriteStream(logPath, { flags: "a" });
const { appName, repository, owner, branch, githubId } = entity;
if (!githubId) {
throw new TRPCError({
code: "NOT_FOUND",
message: "GitHub Provider not found",
});
}
if (!githubId) {
throw new TRPCError({
code: "NOT_FOUND",
message: "GitHub Provider not found",
});
}
const requirements = getErrorCloneRequirements(entity);
const requirements = getErrorCloneRequirements(entity);
// Check if requirements are met
if (requirements.length > 0) {
writeStream.write(
`\nGitHub Repository configuration failed for application: ${appName}\n`
);
writeStream.write("Reasons:\n");
writeStream.write(requirements.join("\n"));
writeStream.end();
throw new TRPCError({
code: "BAD_REQUEST",
message: "Error: GitHub repository information is incomplete.",
});
}
// Check if requirements are met
if (requirements.length > 0) {
writeStream.write(
`\nGitHub Repository configuration failed for application: ${appName}\n`,
);
writeStream.write("Reasons:\n");
writeStream.write(requirements.join("\n"));
writeStream.end();
throw new TRPCError({
code: "BAD_REQUEST",
message: "Error: GitHub repository information is incomplete.",
});
}
const githubProvider = await findGithubById(githubId);
const basePath = isCompose ? COMPOSE_PATH : APPLICATIONS_PATH;
const outputPath = join(basePath, appName, "code");
const octokit = authGithub(githubProvider);
const token = await getGithubToken(octokit);
const repoclone = `github.com/${owner}/${repository}.git`;
await recreateDirectory(outputPath);
const cloneUrl = `https://oauth2:${token}@${repoclone}`;
const githubProvider = await findGithubById(githubId);
const basePath = isCompose ? COMPOSE_PATH : APPLICATIONS_PATH;
const outputPath = join(basePath, appName, "code");
const octokit = authGithub(githubProvider);
const token = await getGithubToken(octokit);
const repoclone = `github.com/${owner}/${repository}.git`;
await recreateDirectory(outputPath);
const cloneUrl = `https://oauth2:${token}@${repoclone}`;
try {
writeStream.write(`\nClonning Repo ${repoclone} to ${outputPath}: ✅\n`);
await spawnAsync(
"git",
[
"clone",
"--branch",
branch!,
"--depth",
"1",
"--recurse-submodules",
cloneUrl,
outputPath,
"--progress",
],
(data) => {
if (writeStream.writable) {
writeStream.write(data);
}
}
);
writeStream.write(`\nCloned ${repoclone}: ✅\n`);
} catch (error) {
writeStream.write(`ERROR Clonning: ${error}: ❌`);
throw error;
} finally {
writeStream.end();
}
try {
writeStream.write(`\nClonning Repo ${repoclone} to ${outputPath}: ✅\n`);
await spawnAsync(
"git",
[
"clone",
"--branch",
branch!,
"--depth",
"1",
"--recurse-submodules",
cloneUrl,
outputPath,
"--progress",
],
(data) => {
if (writeStream.writable) {
writeStream.write(data);
}
},
);
writeStream.write(`\nCloned ${repoclone}: ✅\n`);
} catch (error) {
writeStream.write(`ERROR Clonning: ${error}: ❌`);
throw error;
} finally {
writeStream.end();
}
};
export const getGithubCloneCommand = async (
entity: ApplicationWithGithub | ComposeWithGithub,
logPath: string,
isCompose = false
entity: ApplicationWithGithub | ComposeWithGithub,
logPath: string,
isCompose = false,
) => {
const { appName, repository, owner, branch, githubId, serverId } = entity;
const { appName, repository, owner, branch, githubId, serverId } = entity;
if (!serverId) {
throw new TRPCError({
code: "NOT_FOUND",
message: "Server not found",
});
}
if (!serverId) {
throw new TRPCError({
code: "NOT_FOUND",
message: "Server not found",
});
}
if (!githubId) {
const command = `
if (!githubId) {
const command = `
echo "Error: ❌ Github Provider not found" >> ${logPath};
exit 1;
`;
await execAsyncRemote(serverId, command);
throw new TRPCError({
code: "NOT_FOUND",
message: "GitHub Provider not found",
});
}
await execAsyncRemote(serverId, command);
throw new TRPCError({
code: "NOT_FOUND",
message: "GitHub Provider not found",
});
}
const requirements = getErrorCloneRequirements(entity);
const requirements = getErrorCloneRequirements(entity);
// Build log messages
let logMessages = "";
if (requirements.length > 0) {
logMessages += `\nGitHub Repository configuration failed for application: ${appName}\n`;
logMessages += "Reasons:\n";
logMessages += requirements.join("\n");
const escapedLogMessages = logMessages
.replace(/\\/g, "\\\\")
.replace(/"/g, '\\"')
.replace(/\n/g, "\\n");
// Build log messages
let logMessages = "";
if (requirements.length > 0) {
logMessages += `\nGitHub Repository configuration failed for application: ${appName}\n`;
logMessages += "Reasons:\n";
logMessages += requirements.join("\n");
const escapedLogMessages = logMessages
.replace(/\\/g, "\\\\")
.replace(/"/g, '\\"')
.replace(/\n/g, "\\n");
const bashCommand = `
const bashCommand = `
echo "${escapedLogMessages}" >> ${logPath};
exit 1; # Exit with error code
`;
await execAsyncRemote(serverId, bashCommand);
return;
}
const { COMPOSE_PATH, APPLICATIONS_PATH } = paths(true);
const githubProvider = await findGithubById(githubId);
const basePath = isCompose ? COMPOSE_PATH : APPLICATIONS_PATH;
const outputPath = join(basePath, appName, "code");
const octokit = authGithub(githubProvider);
const token = await getGithubToken(octokit);
const repoclone = `github.com/${owner}/${repository}.git`;
const cloneUrl = `https://oauth2:${token}@${repoclone}`;
await execAsyncRemote(serverId, bashCommand);
return;
}
const { COMPOSE_PATH, APPLICATIONS_PATH } = paths(true);
const githubProvider = await findGithubById(githubId);
const basePath = isCompose ? COMPOSE_PATH : APPLICATIONS_PATH;
const outputPath = join(basePath, appName, "code");
const octokit = authGithub(githubProvider);
const token = await getGithubToken(octokit);
const repoclone = `github.com/${owner}/${repository}.git`;
const cloneUrl = `https://oauth2:${token}@${repoclone}`;
const cloneCommand = `
const cloneCommand = `
rm -rf ${outputPath};
mkdir -p ${outputPath};
if ! git clone --branch ${branch} --depth 1 --recurse-submodules --progress ${cloneUrl} ${outputPath} >> ${logPath} 2>&1; then
@ -212,127 +212,127 @@ fi
echo "Cloned ${repoclone} to ${outputPath}: ✅" >> ${logPath};
`;
return cloneCommand;
return cloneCommand;
};
export const cloneRawGithubRepository = async (entity: Compose) => {
const { appName, repository, owner, branch, githubId } = entity;
const { appName, repository, owner, branch, githubId } = entity;
if (!githubId) {
throw new TRPCError({
code: "NOT_FOUND",
message: "GitHub Provider not found",
});
}
const { COMPOSE_PATH } = paths();
const githubProvider = await findGithubById(githubId);
const basePath = COMPOSE_PATH;
const outputPath = join(basePath, appName, "code");
const octokit = authGithub(githubProvider);
const token = await getGithubToken(octokit);
const repoclone = `github.com/${owner}/${repository}.git`;
await recreateDirectory(outputPath);
const cloneUrl = `https://oauth2:${token}@${repoclone}`;
try {
await spawnAsync("git", [
"clone",
"--branch",
branch!,
"--depth",
"1",
"--recurse-submodules",
cloneUrl,
outputPath,
"--progress",
]);
} catch (error) {
throw error;
}
if (!githubId) {
throw new TRPCError({
code: "NOT_FOUND",
message: "GitHub Provider not found",
});
}
const { COMPOSE_PATH } = paths();
const githubProvider = await findGithubById(githubId);
const basePath = COMPOSE_PATH;
const outputPath = join(basePath, appName, "code");
const octokit = authGithub(githubProvider);
const token = await getGithubToken(octokit);
const repoclone = `github.com/${owner}/${repository}.git`;
await recreateDirectory(outputPath);
const cloneUrl = `https://oauth2:${token}@${repoclone}`;
try {
await spawnAsync("git", [
"clone",
"--branch",
branch!,
"--depth",
"1",
"--recurse-submodules",
cloneUrl,
outputPath,
"--progress",
]);
} catch (error) {
throw error;
}
};
export const cloneRawGithubRepositoryRemote = async (compose: Compose) => {
const { appName, repository, owner, branch, githubId, serverId } = compose;
const { appName, repository, owner, branch, githubId, serverId } = compose;
if (!serverId) {
throw new TRPCError({
code: "NOT_FOUND",
message: "Server not found",
});
}
if (!githubId) {
throw new TRPCError({
code: "NOT_FOUND",
message: "GitHub Provider not found",
});
}
if (!serverId) {
throw new TRPCError({
code: "NOT_FOUND",
message: "Server not found",
});
}
if (!githubId) {
throw new TRPCError({
code: "NOT_FOUND",
message: "GitHub Provider not found",
});
}
const { COMPOSE_PATH } = paths(true);
const githubProvider = await findGithubById(githubId);
const basePath = COMPOSE_PATH;
const outputPath = join(basePath, appName, "code");
const octokit = authGithub(githubProvider);
const token = await getGithubToken(octokit);
const repoclone = `github.com/${owner}/${repository}.git`;
const cloneUrl = `https://oauth2:${token}@${repoclone}`;
try {
const command = `
const { COMPOSE_PATH } = paths(true);
const githubProvider = await findGithubById(githubId);
const basePath = COMPOSE_PATH;
const outputPath = join(basePath, appName, "code");
const octokit = authGithub(githubProvider);
const token = await getGithubToken(octokit);
const repoclone = `github.com/${owner}/${repository}.git`;
const cloneUrl = `https://oauth2:${token}@${repoclone}`;
try {
const command = `
rm -rf ${outputPath};
git clone --branch ${branch} --depth 1 ${cloneUrl} ${outputPath}
`;
await execAsyncRemote(serverId, command);
} catch (error) {
throw error;
}
await execAsyncRemote(serverId, command);
} catch (error) {
throw error;
}
};
export const getGithubRepositories = async (githubId?: string) => {
if (!githubId) {
return [];
}
if (!githubId) {
return [];
}
const githubProvider = await findGithubById(githubId);
const githubProvider = await findGithubById(githubId);
const octokit = new Octokit({
authStrategy: createAppAuth,
auth: {
appId: githubProvider.githubAppId,
privateKey: githubProvider.githubPrivateKey,
installationId: githubProvider.githubInstallationId,
},
});
const octokit = new Octokit({
authStrategy: createAppAuth,
auth: {
appId: githubProvider.githubAppId,
privateKey: githubProvider.githubPrivateKey,
installationId: githubProvider.githubInstallationId,
},
});
const repositories = (await octokit.paginate(
octokit.rest.apps.listReposAccessibleToInstallation
)) as unknown as Awaited<
ReturnType<typeof octokit.rest.apps.listReposAccessibleToInstallation>
>["data"]["repositories"];
const repositories = (await octokit.paginate(
octokit.rest.apps.listReposAccessibleToInstallation,
)) as unknown as Awaited<
ReturnType<typeof octokit.rest.apps.listReposAccessibleToInstallation>
>["data"]["repositories"];
return repositories;
return repositories;
};
export const getGithubBranches = async (
input: typeof apiFindGithubBranches._type
input: typeof apiFindGithubBranches._type,
) => {
if (!input.githubId) {
return [];
}
const githubProvider = await findGithubById(input.githubId);
if (!input.githubId) {
return [];
}
const githubProvider = await findGithubById(input.githubId);
const octokit = new Octokit({
authStrategy: createAppAuth,
auth: {
appId: githubProvider.githubAppId,
privateKey: githubProvider.githubPrivateKey,
installationId: githubProvider.githubInstallationId,
},
});
const octokit = new Octokit({
authStrategy: createAppAuth,
auth: {
appId: githubProvider.githubAppId,
privateKey: githubProvider.githubPrivateKey,
installationId: githubProvider.githubInstallationId,
},
});
const branches = (await octokit.paginate(octokit.rest.repos.listBranches, {
owner: input.owner,
repo: input.repo,
})) as unknown as Awaited<
ReturnType<typeof octokit.rest.repos.listBranches>
>["data"];
const branches = (await octokit.paginate(octokit.rest.repos.listBranches, {
owner: input.owner,
repo: input.repo,
})) as unknown as Awaited<
ReturnType<typeof octokit.rest.repos.listBranches>
>["data"];
return branches;
return branches;
};

View File

@ -30,9 +30,9 @@ importers:
esbuild:
specifier: 0.20.2
version: 0.20.2
husky:
specifier: ^9.1.6
version: 9.1.6
lefthook:
specifier: 1.8.4
version: 1.8.4
lint-staged:
specifier: ^15.2.7
version: 15.2.7
@ -4722,11 +4722,6 @@ packages:
resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==}
engines: {node: '>=16.17.0'}
husky@9.1.6:
resolution: {integrity: sha512-sqbjZKK7kf44hfdE94EoX8MZNk0n7HeW37O4YrVGCF4wzgQjp+akPAkfUK5LZ6KuR/6sqeAVuXHji+RzQgOn5A==}
engines: {node: '>=18'}
hasBin: true
hyperdyperid@1.2.0:
resolution: {integrity: sha512-Y93lCzHYgGWdrJ66yIktxiaGULYc6oGiABxhcO5AufBeOyoIdZF7bIfLaOrbM0iGIOXQQgxxRrFEnb+Y6w1n4A==}
engines: {node: '>=10.18'}
@ -4958,6 +4953,60 @@ packages:
leac@0.6.0:
resolution: {integrity: sha512-y+SqErxb8h7nE/fiEX07jsbuhrpO9lL8eca7/Y1nuWV2moNlXhyd59iDGcRf6moVyDMbmTNzL40SUyrFU/yDpg==}
lefthook-darwin-arm64@1.8.4:
resolution: {integrity: sha512-OS5MsU0gvd8LYSpuQCHtmDUqwNrJ/LjCO0LGC1wNepY4OkuVl9DfX+rQ506CVUQYZiGVcwy2/qPOOBjNzA5+wQ==}
cpu: [arm64]
os: [darwin]
lefthook-darwin-x64@1.8.4:
resolution: {integrity: sha512-QLRsqK9aTMRcVW8qz4pzI2OWnGCEcaEPJlIiFjwstYsS+wfkooxOS0UkfVMjy+QoGgEcki+cxF/FoY7lE7DDtw==}
cpu: [x64]
os: [darwin]
lefthook-freebsd-arm64@1.8.4:
resolution: {integrity: sha512-chnQ1m/Cmn9c0sLdk5HL2SToE5LBJv5uQMdH1IGRRcw+nEqWqrMnDXvM75caiJAyjmUGvPH3czKTJDzTFV1E+A==}
cpu: [arm64]
os: [freebsd]
lefthook-freebsd-x64@1.8.4:
resolution: {integrity: sha512-KQi+WBUdnGLnK0rHOR58kbMH5TDVN1ZjZLu66Pv9FCG7Y7shR1qtaTXu+wmxdRhMvaLeQIXRsUEPjNRC66yMmA==}
cpu: [x64]
os: [freebsd]
lefthook-linux-arm64@1.8.4:
resolution: {integrity: sha512-CXNcqIskLwTwQARidGdFqmNxpvOU3jsWPK4KA7pq2+QmlWJ64w98ebMvNBoUmRUCXqzmUm7Udf/jpfz2fobewQ==}
cpu: [arm64]
os: [linux]
lefthook-linux-x64@1.8.4:
resolution: {integrity: sha512-pVNITkFBxUCEtamWSM/res2Gd48+m9YKbNyIBndAuZVC5pKV5aGKZy2DNq6PWUPYiUDPx+7hoAtCJg/tlAiqhw==}
cpu: [x64]
os: [linux]
lefthook-openbsd-arm64@1.8.4:
resolution: {integrity: sha512-l+i/Dg5X36kYzhpMGSPE3rMbWy1KSytbLB9lY1PmxYb6LRH6iQTYIoxvLabVUwSBPSq8HtIFa50+bvC5+scfVA==}
cpu: [arm64]
os: [openbsd]
lefthook-openbsd-x64@1.8.4:
resolution: {integrity: sha512-CqhDDPPX8oHzMLgNi/Reba823DRzj+eMNWQ8axvSiIG+zmG1w20xZH5QSs/mD3tjrND90yfDd90mWMt181qPyA==}
cpu: [x64]
os: [openbsd]
lefthook-windows-arm64@1.8.4:
resolution: {integrity: sha512-dvpvorICmVjmw29Aiczg7DcaSzkd86bEBomiGq4UsAEk3+7ExLrlWJDLFsI6xLjMKmTxy+F7eXb2uDtuFC1N4g==}
cpu: [arm64]
os: [win32]
lefthook-windows-x64@1.8.4:
resolution: {integrity: sha512-e+y8Jt4/7PnoplhOuK48twjGVJEsU4T3J5kxD4mWfl6Cbit0YSn4bme9nW41eqCqTUqOm+ky29XlfnPHFX5ZNA==}
cpu: [x64]
os: [win32]
lefthook@1.8.4:
resolution: {integrity: sha512-XNyMaTWNRuADOaocYiHidgNkNDz8SCekpdNJ7lqceFcBT2zjumnb28/o7IMaNROpLBZdQkLkJXSeaQWGqn3kog==}
hasBin: true
lilconfig@2.1.0:
resolution: {integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==}
engines: {node: '>=10'}
@ -10940,8 +10989,6 @@ snapshots:
human-signals@5.0.0: {}
husky@9.1.6: {}
hyperdyperid@1.2.0: {}
i18next-fs-backend@2.3.2: {}
@ -11153,6 +11200,49 @@ snapshots:
leac@0.6.0: {}
lefthook-darwin-arm64@1.8.4:
optional: true
lefthook-darwin-x64@1.8.4:
optional: true
lefthook-freebsd-arm64@1.8.4:
optional: true
lefthook-freebsd-x64@1.8.4:
optional: true
lefthook-linux-arm64@1.8.4:
optional: true
lefthook-linux-x64@1.8.4:
optional: true
lefthook-openbsd-arm64@1.8.4:
optional: true
lefthook-openbsd-x64@1.8.4:
optional: true
lefthook-windows-arm64@1.8.4:
optional: true
lefthook-windows-x64@1.8.4:
optional: true
lefthook@1.8.4:
optionalDependencies:
lefthook-darwin-arm64: 1.8.4
lefthook-darwin-x64: 1.8.4
lefthook-freebsd-arm64: 1.8.4
lefthook-freebsd-x64: 1.8.4
lefthook-linux-arm64: 1.8.4
lefthook-linux-x64: 1.8.4
lefthook-openbsd-arm64: 1.8.4
lefthook-openbsd-x64: 1.8.4
lefthook-windows-arm64: 1.8.4
lefthook-windows-x64: 1.8.4
lilconfig@2.1.0: {}
lilconfig@3.1.2: {}