Files
langgraph/libs/sdk-js/scripts/create-entrypoints.js
T

130 lines
4.0 KiB
JavaScript

import * as fs from "fs";
import * as path from "path";
// This lists all the entrypoints for the library. Each key corresponds to an
// importable path, eg. `import { Foo } from "langgraph-sdk/client"`.
// The value is the path to the file in `src/` that exports the entrypoint.
// This is used to generate the `exports` field in package.json.
// Order is not important.
const entrypoints = { client: "client" };
const updateJsonFile = (relativePath, updateFunction) => {
const contents = fs.readFileSync(relativePath).toString();
const res = updateFunction(JSON.parse(contents));
fs.writeFileSync(relativePath, JSON.stringify(res, null, 2) + "\n");
};
const generateFiles = () => {
const files = [...Object.entries(entrypoints), ["index", "index"]].flatMap(
([key, value]) => {
const nrOfDots = key.split("/").length - 1;
const relativePath = "../".repeat(nrOfDots) || "./";
const compiledPath = `${relativePath}dist/${value}`;
return [
[`${key}.cjs`, `module.exports = require('${compiledPath}.cjs');`],
[`${key}.js`, `export * from '${compiledPath}.mjs'`],
[`${key}.d.ts`, `export * from '${compiledPath}.mjs'`],
[`${key}.d.cts`, `export * from '${compiledPath}.cjs'`],
];
},
);
return Object.fromEntries(files);
};
const updateConfig = () => {
// Update tsconfig.json `typedocOptions.entryPoints` field
updateJsonFile("./tsconfig.json", (json) => ({
...json,
typedocOptions: {
...json.typedocOptions,
entryPoints: [...Object.keys(entrypoints)].map((key) => {
const basePath = `src/${entrypoints[key]}`;
if (fs.existsSync(`${basePath}.mts`)) {
return `${basePath}.mts`;
} else if (fs.existsSync(`${basePath}.ts`)) {
return `${basePath}.ts`;
} else {
console.warn(
`Warning: Neither ${basePath}.mts nor ${basePath}.ts found for entrypoint ${key}`,
);
return `${basePath}.ts`; // Default to .ts if neither exists
}
}),
},
}));
const generatedFiles = generateFiles();
const filenames = Object.keys(generatedFiles);
// Update package.json `exports` and `files` fields
updateJsonFile("./package.json", (json) => ({
...json,
exports: Object.assign(
Object.fromEntries(
["index", ...Object.keys(entrypoints)].map((key) => {
let entryPoint = {
types: {
import: `./${key}.d.ts`,
require: `./${key}.d.cts`,
default: `./${key}.d.ts`,
},
import: `./${key}.js`,
require: `./${key}.cjs`,
};
return [key === "index" ? "." : `./${key}`, entryPoint];
}),
),
{
"./package.json": "./package.json",
},
),
files: ["dist/", ...filenames],
}));
// Write generated files
Object.entries(generatedFiles).forEach(([filename, content]) => {
fs.mkdirSync(path.dirname(filename), {
recursive: true,
});
fs.writeFileSync(filename, content);
});
const gitignore = fs.readFileSync("./.gitignore").toString();
const lines = gitignore.split("\n");
const startMarker = "## GENERATED create-entrypoints.js";
const endMarker = "## END GENERATED create-entrypoints.js";
const startIdx = lines.findIndex((line) => line.includes(startMarker));
const endIdx = lines.findIndex((line) => line.includes(endMarker));
const newLines = lines.slice(0, startIdx + 1);
if (startIdx === -1) {
newLines.push(startMarker);
}
newLines.push(...filenames.map((fname) => `/${fname}`));
if (endIdx === -1) {
newLines.push(endMarker);
}
newLines.push(...lines.slice(endIdx));
fs.writeFileSync("./.gitignore", newLines.join("\n"));
};
const cleanGenerated = () => {
const filenames = Object.keys(generateFiles());
filenames.forEach((fname) => {
try {
fs.unlinkSync(fname);
} catch {
// ignore error
}
});
};
const command = process.argv[2];
if (command === "clean") {
cleanGenerated();
} else {
updateConfig();
}