Skip to content

Export jinja files as TS module at build time #1296

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Mar 19, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/inference/.gitignore
Copy link
Member

@coyotte508 coyotte508 Mar 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It could still be committed

Copy link
Contributor Author

@Wauplin Wauplin Mar 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel that committing it would not bring much value but could be annoying in case of merge conflicts etc. (and adds a bigger diff in PRs)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm yeah i'd rather ignore it

Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
src/snippets/templates.exported.ts
21 changes: 8 additions & 13 deletions packages/inference/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,27 +26,21 @@
},
"files": [
"dist",
"src"
"src",
"!src/snippets/templates/**/*.jinja"
],
"source": "src/index.ts",
"types": "./dist/src/index.d.ts",
"main": "./dist/index.cjs",
"module": "./dist/index.js",
"exports": {
".": {
"types": "./dist/src/index.d.ts",
"require": "./dist/index.cjs",
"import": "./dist/index.js"
}
},
"browser": {
"./src/snippets/index.js": false,
"./dist/index.js": "./dist/browser/index.js",
"./dist/index.mjs": "./dist/browser/index.mjs"
"types": "./dist/src/index.d.ts",
"require": "./dist/index.cjs",
"import": "./dist/index.js"
},
"type": "module",
"scripts": {
"build": "tsup src/index.ts --format cjs,esm --clean && tsc --emitDeclarationOnly --declaration",
"build": "pnpm run export-templates && tsup src/index.ts --format cjs,esm --clean && tsc --emitDeclarationOnly --declaration",
"dts": "tsx scripts/generate-dts.ts && tsc --noEmit dist/index.d.ts",
"lint": "eslint --quiet --fix --ext .cjs,.ts .",
"lint:check": "eslint --ext .cjs,.ts .",
Expand All @@ -57,7 +51,8 @@
"test": "vitest run --config vitest.config.mts",
"test:browser": "vitest run --browser.name=chrome --browser.headless --config vitest.config.mts",
"check": "tsc",
"dev": "tsup src/index.ts --format cjs,esm --watch"
"dev": "pnpm run export-templates && tsup src/index.ts --format cjs,esm --watch",
"export-templates": "tsx scripts/export-templates.ts"
},
"dependencies": {
"@huggingface/tasks": "workspace:^",
Expand Down
54 changes: 54 additions & 0 deletions packages/inference/scripts/export-templates.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/* Script that export all jinja files from packages/inference/src/snippets/templates into a TS module.

Templates are exported in packages/inference/src/snippets/templates.exported.ts.
*/
import { readFileSync, writeFileSync, readdirSync } from "node:fs";
import path from "node:path";

const TEMPLATES_DIR = path.join(process.cwd(), "src", "snippets", "templates");

function exportTemplatesAsCode(): string {
/// language -> client -> templateName -> templateContent
const templates: Record<string, Record<string, Record<string, string>>> = {};

// Read all language directories
const languages = readdirSync(TEMPLATES_DIR);
for (const language of languages) {
const languagePath = path.join(TEMPLATES_DIR, language);
if (!readdirSync(languagePath).length) continue;

templates[language] = {};

// Read all client directories
const clients = readdirSync(languagePath);
for (const client of clients) {
const clientPath = path.join(languagePath, client);
if (!readdirSync(clientPath).length) continue;

templates[language][client] = {};

// Read all template files
const files = readdirSync(clientPath);
for (const file of files) {
if (!file.endsWith(".jinja")) continue;

const templatePath = path.join(clientPath, file);
const templateContent = readFileSync(templatePath, "utf8");
const templateName = path.basename(file, ".jinja");

templates[language][client][templateName] = templateContent;
}
}
}

const templatesJson = JSON.stringify(templates, null, 2);
return `// Generated file - do not edit directly
export const templates: Record<string, Record<string, Record<string, string>>> = ${templatesJson} as const;
`;
}

// Generate and write the templates file
const output = exportTemplatesAsCode();
const outputPath = path.join(process.cwd(), "src", "snippets", "templates.exported.ts");
writeFileSync(outputPath, output);
console.log("Templates exported successfully! 🚀");
30 changes: 6 additions & 24 deletions packages/inference/src/snippets/getInferenceSnippets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,7 @@ import {
import type { InferenceProvider, InferenceTask, RequestArgs } from "../types";
import { Template } from "@huggingface/jinja";
import { makeRequestOptionsFromResolvedModel } from "../lib/makeRequestOptions";
import fs from "fs";
import path from "path";
import { existsSync as pathExists } from "node:fs";
import { templates } from "./templates.exported";

const PYTHON_CLIENTS = ["huggingface_hub", "fal_client", "requests", "openai"] as const;
const JS_CLIENTS = ["fetch", "huggingface.js", "openai"] as const;
Expand Down Expand Up @@ -44,34 +42,18 @@ interface TemplateParams {

// Helpers to find + load templates

const rootDirFinder = (): string => {
let currentPath =
typeof import.meta !== "undefined" && import.meta.url
? path.normalize(new URL(import.meta.url).pathname) /// for ESM
: __dirname; /// for CJS

while (currentPath !== "/") {
if (pathExists(path.join(currentPath, "package.json"))) {
return currentPath;
}

currentPath = path.normalize(path.join(currentPath, ".."));
}

return "/";
};

const templatePath = (language: InferenceSnippetLanguage, client: Client, templateName: string): string =>
path.join(rootDirFinder(), "src", "snippets", "templates", language, client, `${templateName}.jinja`);
const hasTemplate = (language: InferenceSnippetLanguage, client: Client, templateName: string): boolean =>
pathExists(templatePath(language, client, templateName));
templates[language]?.[client]?.[templateName] !== undefined;

const loadTemplate = (
language: InferenceSnippetLanguage,
client: Client,
templateName: string
): ((data: TemplateParams) => string) => {
const template = fs.readFileSync(templatePath(language, client, templateName), "utf8");
const template = templates[language]?.[client]?.[templateName];
if (!template) {
throw new Error(`Template not found: ${language}/${client}/${templateName}`);
}
return (data: TemplateParams) => new Template(template).render({ ...data });
};

Expand Down
23 changes: 0 additions & 23 deletions packages/inference/tsup.config.ts

This file was deleted.