firstPublishedDate: getFirstPublishedDate()

in lib/recipes-data/src/lib/extract-recipes.ts [67:137]


			firstPublishedDate: getFirstPublishedDate(block, content),
			publishedDate: getPublishedDate(block, content),
		};
		return block.elements
			.filter((elem) => elem.type === ElementType.RECIPE)
			.map((recp) =>
				parseJsonBlob(
					content.id,
					recp.recipeTypeData?.recipeJson as string,
					sponsorship,
					recipeDates,
				),
			);
	}
}

export function getFirstPublishedDate(
	block: Block,
	content: Content,
): Date | undefined {
	return block.firstPublishedDate
		? capiDateTimeToDate(block.firstPublishedDate)
		: content.fields?.firstPublicationDate
		? capiDateTimeToDate(content.fields.firstPublicationDate)
		: undefined;
}

export function getPublishedDate(
	block: Block,
	content: Content,
): Date | undefined {
	const feastChannel = content.channels?.find(
		(channel) => channel.channelId === 'feast',
	);
	return block.publishedDate
		? capiDateTimeToDate(block.publishedDate)
		: feastChannel?.fields.publicationDate
		? capiDateTimeToDate(feastChannel.fields.publicationDate)
		: undefined;
}

/**
 * Most recipes have a UUID-style `id` field, so we pass that through.
 * However some of the ones that were extracted by D&I have a numeric field still.
 * In that case, we concatenate the canonical ID onto the numeric value and then sha1 the lot.
 * @param recipeIdField incoming ID of the recipe
 * @param canonicalId canonical ID of the article
 * @returns a useful unique ID for the recipe
 */
function determineRecipeUID(
	recipeIdField: string,
	canonicalId: string,
): string {
	if (recipeIdField.match(/^\d+$/)) {
		const hasher = createHash('sha1');
		//do the same as https://github.com/guardian/flexible-content/blob/6e963d9027d02a4f3af4637dbe6498934d904a4f/flexible-content-integration/src/main/scala/com/gu/flexiblecontent/integration/dispatcher/RecipesImportDispatcher.scala#L213
		const stringToHash = `${recipeIdField}-${canonicalId}`;
		return hasher.update(stringToHash).digest('hex');
	} else {
		return recipeIdField;
	}
}

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