Repository: n8n-io/n8n
File: packages/@n8n/workflow-sdk/src/generate-types/generate-types.ts (TypeScript)

Code before:
			const insertIdx = firstNonNoticeIdx >= 0 ? firstNonNoticeIdx : 0;
			toolNode.properties.splice(insertIdx, 0, toolDescriptionProp);
		}
	}

	return toolNode;
}

// =============================================================================
// Main Entry Point
// =============================================================================

/**
 * Write files from a plan map to disk
 * Creates directories as needed
 */
/** Batch size for parallel file writes to avoid file descriptor exhaustion */
const WRITE_BATCH_SIZE = 100;

/**
 * Write files in parallel batches to stay within OS file descriptor limits.
 */
async function writeFilesInBatches(files: Array<{ path: string; content: string }>): Promise<void> {
	for (let i = 0; i < files.length; i += WRITE_BATCH_SIZE) {
		const batch = files.slice(i, i + WRITE_BATCH_SIZE);
		await Promise.all(batch.map(async (f) => await fs.promises.writeFile(f.path, f.content)));
	}
}

/**
 * Generate version-specific type files for a package
 * Creates directory structure: nodes/{package}/{nodeName}/v{version}.ts (or v{version}/) and index.ts
 * Each individual version gets its own file or directory (for split structure) with filtered properties
 *
 * For nodes with resource/operation or mode discriminators, creates split structure:
 *   v1/
 *     _shared.ts
 *     index.ts
 *     resource_ticket/
 *       operation_get.ts
 *       ...
 *
 * For nodes without discriminators, creates flat files:
 *   v1.ts
 *   v2.ts
 */
async function generateVersionSpecificFiles(
	packageDir: string,
	_packageName: string,
	nodesByName: Map<string, NodeTypeDescription[]>,
): Promise<NodeTypeDescription[]> {

Review comment (performance):
the async/await wrapper is redundant here I think as writeFile already returns a Promise, and Promise.all handles it. 

Can maybe simplify to: `await Promise.all(batch.map((f) => fs.promises.writeFile(f.path, f.content)));`

Code after:
			const insertIdx = firstNonNoticeIdx >= 0 ? firstNonNoticeIdx : 0;
			toolNode.properties.splice(insertIdx, 0, toolDescriptionProp);
		}
	}

	return toolNode;
}

// =============================================================================
// Main Entry Point
// =============================================================================

/** Batch size for parallel file writes to avoid file descriptor exhaustion */
const WRITE_BATCH_SIZE = 100;

/**
 * Write files in parallel batches to stay within OS file descriptor limits.
 */
async function writeFilesInBatches(files: Array<{ path: string; content: string }>): Promise<void> {
	for (let i = 0; i < files.length; i += WRITE_BATCH_SIZE) {
		const batch = files.slice(i, i + WRITE_BATCH_SIZE);
		// eslint-disable-next-line @typescript-eslint/promise-function-async
		await Promise.all(batch.map((f) => fs.promises.writeFile(f.path, f.content)));
	}
}

/**
 * Generate version-specific type files for a package
 * Creates directory structure: nodes/{package}/{nodeName}/v{version}.ts (or v{version}/) and index.ts
 * Each individual version gets its own file or directory (for split structure) with filtered properties
 *
 * For nodes with resource/operation or mode discriminators, creates split structure:
 *   v1/
 *     _shared.ts
 *     index.ts
 *     resource_ticket/
 *       operation_get.ts
 *       ...
 *
 * For nodes without discriminators, creates flat files:
 *   v1.ts
 *   v2.ts
 */
async function generateVersionSpecificFiles(
	packageDir: string,
	_packageName: string,
	nodesByName: Map<string, NodeTypeDescription[]>,
): Promise<NodeTypeDescription[]> {
	const allNodes: NodeTypeDescription[] = [];

	// Phase 1: Pure computation — generate all file contents in memory