function parseJsonBlob()

in lib/recipes-data/src/lib/extract-recipes.ts [130:177]


function parseJsonBlob(
	canonicalId: string,
	recipeJson: string,
	sponsorship: Sponsorship[],
	recipeDates: RecipeDates,
): RecipeReferenceWithoutChecksum | null {
	try {
		const recipeData = JSON.parse(recipeJson) as Record<string, unknown> & {
			contributors: Array<string | Contributor>;
		} & RecipeWithImageData;

		const transforms: RecipeTransformationFunction[] = [
			handleFreeTextContribs,
			replaceImageUrlsWithFastly,
			addSponsorsTransform(sponsorship),
			addRecipeDatesTransform(recipeDates),
			replaceCanonicalArticle(canonicalId),
			temporaryCelebrationIdsFix,
		];

		const updatedRecipe = transforms.reduce(
			(acc, transform) => transform(acc),
			recipeData,
		);

		const rerendedJson = JSON.stringify(updatedRecipe);

		if (!recipeData.id) {
			console.error(
				`Recipe from ${canonicalId} has no ID field. Content was: ${recipeJson}`,
			);
			return null;
		} else {
			return <RecipeReferenceWithoutChecksum>{
				recipeUID: determineRecipeUID(recipeData.id, canonicalId),
				jsonBlob: rerendedJson,
				sponsorshipCount: sponsorship.length,
			};
		}
	} catch (err) {
		console.error(
			// eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access,@typescript-eslint/restrict-template-expressions -- err.toString() is untyped but OK
			`Recipe from ${canonicalId} was not parsable: ${err.toString()}`,
		);
		console.error(`Content was ${recipeJson}`);
		return null;
	}
}