Remove js-yaml from root package json

This commit is contained in:
Carlos Monastyrski
2025-09-26 18:46:18 -03:00
parent 62c3092942
commit 44e7fb1989
8 changed files with 156 additions and 183 deletions
+2 -1
View File
@@ -73,7 +73,8 @@
"seed": "knex --knexfile ./dist/db/knexfile.ts --client pg seed:run",
"seed-dev": "knex --knexfile ./src/db/knexfile.ts --client pg seed:run",
"db:reset": "npm run migration:rollback -- --all && npm run migration:latest",
"email:dev": "email dev --dir src/services/smtp/emails"
"email:dev": "email dev --dir src/services/smtp/emails",
"validate-upgrade-path": "tsx ./scripts/validate-upgrade-path-file.ts"
},
"keywords": [],
"author": "",
@@ -0,0 +1,111 @@
/* eslint-disable no-console */
import { readFile } from "fs/promises";
import * as yaml from "js-yaml";
import * as path from "path";
import { z } from "zod";
import { upgradePathConfigSchema } from "../src/services/upgrade-path/upgrade-path-schemas";
async function validateUpgradePathConfig(): Promise<void> {
try {
const yamlPath = path.join(__dirname, "..", "upgrade-path.yaml");
const resolvedPath = path.resolve(yamlPath);
const expectedBaseDir = path.resolve(__dirname, "..");
if (!resolvedPath.startsWith(expectedBaseDir)) {
throw new Error("Invalid configuration file path");
}
try {
await readFile(yamlPath, "utf8");
} catch (error) {
if (error instanceof Error && "code" in error && error.code === "ENOENT") {
console.log("Warning: No upgrade-path.yaml file found");
return;
}
throw error;
}
const yamlContent = await readFile(yamlPath, "utf8");
if (yamlContent.length > 1024 * 1024) {
throw new Error("Config file too large (>1MB)");
}
let config: unknown;
try {
config = yaml.load(yamlContent, {
schema: yaml.FAILSAFE_SCHEMA,
filename: yamlPath,
onWarning: (warning) => {
console.log(`YAML Warning: ${warning.message}`);
}
});
} catch (yamlError) {
if (yamlError instanceof yaml.YAMLException) {
throw new Error(
`YAML parsing failed: ${yamlError.message} at line ${yamlError.mark?.line}, column ${yamlError.mark?.column}`
);
}
throw new Error(`YAML parsing failed: ${yamlError instanceof Error ? yamlError.message : "Unknown YAML error"}`);
}
if (!config) {
console.log("Warning: Empty configuration file");
return;
}
if (typeof config !== "object" || config === null) {
throw new Error("Configuration must be a valid YAML object");
}
const result = upgradePathConfigSchema.safeParse(config);
if (!result.success) {
console.log("Validation failed with the following errors:");
result.error.issues.forEach((issue: z.ZodIssue) => {
const issuePath = issue.path.length > 0 ? `[${issue.path.join(".")}]` : "";
console.log(` - ${issuePath}: ${issue.message}`);
});
throw new Error("Schema validation failed");
}
const validatedConfig = result.data;
const versions = validatedConfig?.versions || {};
const versionCount = Object.keys(versions).length;
if (versionCount === 0) {
console.log("Warning: No versions found in the configuration");
} else {
console.log(`Validated ${versionCount} version configuration(s)`);
const commonPatterns = [
/^v?\d+\.\d+\.\d+$/,
/^v?\d+\.\d+\.\d+\.\d+$/,
/^infisical\/v?\d+\.\d+\.\d+$/,
/^infisical\/v?\d+\.\d+\.\d+-\w+$/
];
for (const versionKey of Object.keys(versions)) {
const isCommonPattern = commonPatterns.some((pattern) => pattern.test(versionKey));
if (!isCommonPattern) {
console.log(`Warning: Version key '${versionKey}' doesn't match common patterns. This may be intentional.`);
}
}
}
console.log("upgrade-path.yaml format is valid");
} catch (error) {
console.error(`Validation failed: ${error instanceof Error ? error.message : "Unknown error"}`);
process.exit(1);
}
}
if (require.main === module) {
validateUpgradePathConfig().catch((error) => {
console.error("Unexpected error:", error);
process.exit(1);
});
}
export { validateUpgradePathConfig };
@@ -1,15 +1,9 @@
import RE2 from "re2";
import { z } from "zod";
import { BadRequestError } from "@app/lib/errors";
import { logger } from "@app/lib/logger";
import { publicEndpointLimit } from "@app/server/config/rateLimiter";
const versionSchema = z
.string()
.min(1)
.max(50)
.regex(new RE2(/^[a-zA-Z0-9._/-]+$/), "Invalid version format");
import { versionSchema } from "@app/services/upgrade-path/upgrade-path-schemas";
export const registerUpgradePathRouter = async (server: FastifyZodProvider) => {
server.route({
@@ -0,0 +1,24 @@
import RE2 from "re2";
import { z } from "zod";
export const versionSchema = z
.string()
.min(1)
.max(50)
.regex(new RE2(/^[a-zA-Z0-9._/-]+$/), "Invalid version format");
export const breakingChangeSchema = z.object({
title: z.string().min(1).max(200),
description: z.string().min(1).max(1000),
action: z.string().min(1).max(500)
});
export const versionConfigSchema = z.object({
breaking_changes: z.array(breakingChangeSchema).optional(),
db_schema_changes: z.string().max(1000).optional(),
notes: z.string().max(2000).optional()
});
export const upgradePathConfigSchema = z.object({
versions: z.record(versionSchema, versionConfigSchema).optional().nullable()
});
@@ -9,30 +9,13 @@ import { logger } from "@app/lib/logger";
import { fetchReleases } from "./github-client";
import { BreakingChange, FormattedRelease, UpgradePathConfig, UpgradePathResult, VersionConfig } from "./types";
import { versionConfigSchema, versionSchema } from "./upgrade-path-schemas";
export type TUpgradePathServiceFactory = {
keyStore: TKeyStoreFactory;
};
export type TUpgradePathService = ReturnType<typeof upgradePathServiceFactory>;
const versionSchema = z
.string()
.min(1)
.max(50)
.regex(new RE2(/^[a-zA-Z0-9._/-]+$/), "Invalid version format");
const breakingChangeSchema = z.object({
title: z.string().min(1).max(200),
description: z.string().min(1).max(1000),
action: z.string().min(1).max(500)
});
const versionConfigSchema = z.object({
breaking_changes: z.array(breakingChangeSchema).optional(),
db_schema_changes: z.string().max(1000).optional(),
notes: z.string().max(2000).optional()
});
interface CalculateUpgradePathParams {
fromVersion: string;
toVersion: string;