async function generateBinaryInputTypes()

in packages/tasks-gen/scripts/inference-codegen.ts [110:187]


async function generateBinaryInputTypes(
	path2generated: string,
	inputSpec: JSONSchemaSpec,
	outputSpec: JSONSchemaSpec
): Promise<void> {
	const tsSource = ts.createSourceFile(
		path.basename(path2generated),
		await fs.readFile(path2generated, { encoding: "utf-8" }),
		ts.ScriptTarget.ES2022
	);

	const inputRootName = inputSpec.title;
	const outputRootName = outputSpec.title;
	if (typeof inputRootName !== "string" || typeof outputRootName !== "string") {
		return;
	}
	const topLevelNodes = tsSource.getChildAt(0).getChildren();

	let newNodes = [...topLevelNodes];

	for (const interfaceNode of topLevelNodes.filter(
		(node): node is ts.InterfaceDeclaration => node.kind === ts.SyntaxKind.InterfaceDeclaration
	)) {
		if (interfaceNode.name.escapedText !== inputRootName && interfaceNode.name.escapedText !== outputRootName) {
			continue;
		}

		const spec = interfaceNode.name.escapedText === inputRootName ? inputSpec : outputSpec;

		interfaceNode.forEachChild((child) => {
			if (child.kind !== ts.SyntaxKind.PropertySignature) {
				return;
			}
			const propSignature = child as ts.PropertySignature;
			if (!propSignature.type) {
				return;
			}
			const propName = propSignature.name.getText(tsSource);

			const propIsMedia =
				// eslint-disable-next-line @typescript-eslint/no-explicit-any
				typeof (spec as any)["properties"]?.[propName]?.["comment"] === "string"
					? // eslint-disable-next-line @typescript-eslint/no-explicit-any
					  !!(spec as any)["properties"][propName]["comment"].includes("type=binary")
					: false;
			if (!propIsMedia) {
				return;
			}
			const updatedType = ts.factory.createTypeReferenceNode("Blob");
			const updated = ts.factory.updatePropertySignature(
				propSignature,
				propSignature.modifiers,
				propSignature.name,
				propSignature.questionToken,
				updatedType
			);
			const updatedInterface = ts.factory.updateInterfaceDeclaration(
				interfaceNode,
				interfaceNode.modifiers,
				interfaceNode.name,
				interfaceNode.typeParameters,
				interfaceNode.heritageClauses,
				[updated, ...interfaceNode.members.filter((member) => member.name?.getText(tsSource) !== propName)]
			);
			newNodes = [updatedInterface, ...newNodes.filter((node) => node !== interfaceNode)];
		});
	}
	const printer = ts.createPrinter();

	await fs.writeFile(
		path2generated,
		printer.printList(ts.ListFormat.MultiLine, ts.factory.createNodeArray(newNodes), tsSource),
		{
			flag: "w+",
			encoding: "utf-8",
		}
	);
}