Skip to content

Commit a895364

Browse files
committed
- generate cjs too
1 parent fdb8fa4 commit a895364

File tree

10 files changed

+345
-55
lines changed

10 files changed

+345
-55
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
index.cjs
2+
index.js
3+
index.d.ts
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
// babel.config.js
2+
module.exports = {
3+
presets: [["@babel/preset-env", { targets: { node: true } }]],
4+
};

libs/js/oracledb/langchain-oracledb/package.json

Lines changed: 28 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -14,75 +14,64 @@
1414
},
1515
"homepage": "https://github.com/langchain-ai/langchainjs/tree/main/libs/langchain-oracle/",
1616
"scripts": {
17-
"build": "tsc",
18-
"build:compile": "tsc -p tsconfig.json",
19-
"lint:eslint": "eslint --cache src/",
20-
"lint:dpdm": "dpdm --skip-dynamic-imports circular --exit-code circular:1 --no-warning --no-tree src/*.ts src/**/*.ts",
21-
"lint": "pnpm lint:eslint && pnpm lint:dpdm",
22-
"lint:fix": "pnpm lint:eslint --fix && pnpm lint:dpdm",
23-
"pack:dry": "pnpm build && npm pack --dry-run",
24-
"pack": "pnpm build && npm pack",
25-
"publish": "pnpm build && npm publish",
26-
"clean": "rm -rf dist/",
17+
"build": "pnpm clean && pnpm build:esm && pnpm build:cjs && pnpm build:scripts",
18+
"build:esm": "NODE_OPTIONS=--max-old-space-size=4096 tsc --outDir dist/ && rm -rf dist/tests dist/**/tests",
19+
"build:cjs": "NODE_OPTIONS=--max-old-space-size=4096 tsc --outDir dist-cjs/ -p tsconfig.cjs.json && node scripts/move-cjs-to-dist.js && rm -rf dist-cjs",
20+
"build:watch": "node scripts/create-entrypoints.js && tsc --outDir dist/ --watch",
21+
"build:scripts": "node scripts/create-entrypoints.js && node scripts/check-tree-shaking.js",
22+
"lint": "NODE_OPTIONS=--max-old-space-size=4096 eslint src && dpdm --exit-code circular:1 --no-warning --no-tree src/*.ts src/**/*.ts",
23+
"lint:fix": "pnpm lint --fix",
24+
"clean": "rm -rf dist/ && NODE_OPTIONS=--max-old-space-size=4096 node scripts/create-entrypoints.js pre",
25+
"prepack": "pnpm build",
26+
"release": "release-it --only-version --config .release-it.json",
2727
"test": "vitest run",
2828
"test:watch": "vitest",
2929
"test:int": "vitest run --mode int",
3030
"test:standard:unit": "vitest run --mode standard-unit",
3131
"test:standard:int": "vitest run --mode standard-int",
3232
"test:standard": "pnpm test:standard:unit && pnpm test:standard:int",
33-
"format": "prettier --config .prettierrc --write \"src\"",
34-
"format:check": "prettier --config .prettierrc --check \"src\""
33+
"format": "prettier --write \"src\"",
34+
"format:check": "prettier --check \"src\""
3535
},
3636
"author": "LangChain",
3737
"license": "MIT",
3838
"dependencies": {
3939
"htmlparser2": "^10.0.0",
40-
"oracledb": "^6.6.0",
40+
"oracledb": "^6.10.0",
4141
"uuid": "^10.0.0"
4242
},
4343
"peerDependencies": {
4444
"@langchain/core": "^1.0.0",
4545
"@langchain/textsplitters": "^1.0.0"
4646
},
4747
"devDependencies": {
48-
"@cfworker/json-schema": "^4.1.1",
49-
"@eslint/js": "^9.39.1",
50-
"@jest/globals": "^29.5.0",
5148
"@langchain/core": "^1.0.0",
5249
"@langchain/textsplitters": "^1.0.0",
53-
"@swc/jest": "^0.2.29",
50+
"@swc/core": "^1.3.90",
5451
"@tsconfig/recommended": "^1.0.3",
55-
"@types/oracledb": "^6.6.0",
56-
"@typescript-eslint/eslint-plugin": "^8.48.1",
57-
"@typescript-eslint/parser": "^8.48.1",
58-
"@vitest/coverage-v8": "^3.2.4",
59-
"dotenv": "^16.6.1",
60-
"dpdm": "^3.14.0",
61-
"eslint": "^9",
62-
"eslint-config-prettier": "^10.1.8",
63-
"eslint-plugin-import": "^2.32.0",
52+
"@types/oracledb": "^6.10.0",
53+
"@typescript-eslint/eslint-plugin": "^6.12.0",
54+
"@typescript-eslint/parser": "^6.12.0",
55+
"@vitest/coverage-v8": "^4.0.15",
56+
"dotenv": "^17.2.3",
57+
"dpdm": "^3.12.0",
58+
"eslint": "^8.33.0",
59+
"eslint-config-prettier": "^8.6.0",
60+
"eslint-plugin-import": "^2.27.5",
6461
"eslint-plugin-no-instanceof": "^1.0.1",
65-
"jest": "^29.5.0",
66-
"jest-environment-node": "^29.6.4",
67-
"jiti": "^2.6.1",
62+
"eslint-plugin-prettier": "^4.2.1",
6863
"prettier": "^2.8.3",
6964
"rollup": "^4.5.2",
70-
"ts-jest": "^29.1.0",
71-
"typescript": "~5.8.3",
65+
"typescript": "<5.2.0",
7266
"typescript-eslint": "^8.48.1",
73-
"vitest": "^3.2.4",
74-
"zod": "^3.25.76"
67+
"vitest": "^3.2.4"
7568
},
7669
"publishConfig": {
7770
"access": "public"
7871
},
7972
"exports": {
8073
".": {
81-
"types": {
82-
"import": "./index.d.ts",
83-
"require": "./index.d.cts",
84-
"default": "./index.d.ts"
85-
},
74+
"types": "./index.d.ts",
8675
"import": "./index.js",
8776
"require": "./index.cjs"
8877
},
@@ -92,7 +81,6 @@
9281
"dist/",
9382
"index.cjs",
9483
"index.js",
95-
"index.d.ts",
96-
"index.d.cts"
84+
"index.d.ts"
9785
]
9886
}
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
import fs from "fs/promises";
2+
import { rollup } from "rollup";
3+
4+
const packageJson = JSON.parse(await fs.readFile("package.json", "utf-8"));
5+
6+
export function listEntrypoints() {
7+
const exports = packageJson.exports;
8+
const entrypoints = [];
9+
10+
for (const [key, value] of Object.entries(exports)) {
11+
if (key === "./package.json") {
12+
continue;
13+
}
14+
if (typeof value === "string") {
15+
entrypoints.push(value);
16+
} else if (typeof value === "object" && value.import) {
17+
entrypoints.push(value.import);
18+
}
19+
}
20+
21+
return entrypoints;
22+
}
23+
24+
export function listExternals() {
25+
return [
26+
...Object.keys(packageJson.dependencies),
27+
...Object.keys(packageJson.peerDependencies ?? {}),
28+
/node\:/,
29+
/@langchain\/core\//,
30+
];
31+
}
32+
33+
export async function checkTreeShaking() {
34+
const externals = listExternals();
35+
const entrypoints = listEntrypoints();
36+
const consoleLog = console.log;
37+
const reportMap = new Map();
38+
39+
for (const entrypoint of entrypoints) {
40+
let sideEffects = "";
41+
42+
console.log = function (...args) {
43+
const line = args.length ? args.join(" ") : "";
44+
if (line.trim().startsWith("First side effect in")) {
45+
sideEffects += line + "\n";
46+
}
47+
};
48+
49+
await rollup({
50+
external: externals,
51+
input: entrypoint,
52+
experimentalLogSideEffects: true,
53+
});
54+
55+
reportMap.set(entrypoint, {
56+
log: sideEffects,
57+
hasSideEffects: sideEffects.length > 0,
58+
});
59+
}
60+
61+
console.log = consoleLog;
62+
63+
let failed = false;
64+
for (const [entrypoint, report] of reportMap) {
65+
if (report.hasSideEffects) {
66+
failed = true;
67+
console.log("---------------------------------");
68+
console.log(`Tree shaking failed for ${entrypoint}`);
69+
console.log(report.log);
70+
}
71+
}
72+
73+
if (failed) {
74+
process.exit(1);
75+
} else {
76+
console.log("Tree shaking checks passed!");
77+
}
78+
}
79+
80+
checkTreeShaking();
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
import * as fs from "fs";
2+
import * as path from "path";
3+
4+
// This lists all the entrypoints for the library. Each key corresponds to an
5+
// importable path, eg. `import { AgentExecutor } from "langchain/agents"`.
6+
// The value is the path to the file in `src/` that exports the entrypoint.
7+
// This is used to generate the `exports` field in package.json.
8+
// Order is not important.
9+
const entrypoints = {
10+
"index": "index"
11+
};
12+
13+
// Entrypoints in this list require an optional dependency to be installed.
14+
// Therefore they are not tested in the generated test-exports-* packages.
15+
const requiresOptionalDependency = [];
16+
17+
const updateJsonFile = (relativePath, updateFunction) => {
18+
const contents = fs.readFileSync(relativePath).toString();
19+
const res = updateFunction(JSON.parse(contents));
20+
fs.writeFileSync(relativePath, JSON.stringify(res, null, 2) + "\n");
21+
};
22+
23+
const generateFiles = () => {
24+
const files = [...Object.entries(entrypoints), ["index", "index"]].flatMap(
25+
([key, value]) => {
26+
const nrOfDots = key.split("/").length - 1;
27+
const relativePath = "../".repeat(nrOfDots) || "./";
28+
const compiledPath = `${relativePath}dist/${value}.js`;
29+
return [
30+
[
31+
`${key}.cjs`,
32+
`module.exports = require('${relativePath}dist/${value}.cjs');`,
33+
],
34+
[`${key}.js`, `export * from '${compiledPath}'`],
35+
[`${key}.d.ts`, `export * from '${compiledPath}'`],
36+
];
37+
}
38+
);
39+
40+
return Object.fromEntries(files);
41+
};
42+
43+
const updateConfig = () => {
44+
const generatedFiles = generateFiles();
45+
const filenames = Object.keys(generatedFiles);
46+
47+
// Update package.json `exports` and `files` fields
48+
updateJsonFile("./package.json", (json) => ({
49+
...json,
50+
exports: Object.assign(
51+
Object.fromEntries(
52+
[...Object.keys(entrypoints)].map((key) => {
53+
let entryPoint = {
54+
types: `./${key}.d.ts`,
55+
import: `./${key}.js`,
56+
require: `./${key}.cjs`,
57+
};
58+
59+
return [key === "index" ? "." : `./${key}`, entryPoint];
60+
})
61+
),
62+
{ "./package.json": "./package.json" }
63+
),
64+
files: ["dist/", ...filenames],
65+
}));
66+
67+
// Write generated files
68+
Object.entries(generatedFiles).forEach(([filename, content]) => {
69+
fs.mkdirSync(path.dirname(filename), { recursive: true });
70+
fs.writeFileSync(filename, content);
71+
});
72+
73+
// Update .gitignore
74+
fs.writeFileSync("./.gitignore", filenames.join("\n") + "\n");
75+
};
76+
77+
const cleanGenerated = () => {
78+
const filenames = Object.keys(generateFiles());
79+
filenames.forEach((fname) => {
80+
try {
81+
fs.unlinkSync(fname);
82+
} catch {
83+
// ignore error
84+
}
85+
});
86+
};
87+
88+
const command = process.argv[2];
89+
90+
if (command === "pre") {
91+
cleanGenerated();
92+
} else {
93+
updateConfig();
94+
}
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
import ts from "typescript";
2+
import * as fs from "fs";
3+
4+
export function identifySecrets() {
5+
const secrets = new Set();
6+
7+
const tsConfig = ts.parseJsonConfigFileContent(
8+
ts.readJsonConfigFile("./tsconfig.json", (p) =>
9+
fs.readFileSync(p, "utf-8")
10+
),
11+
ts.sys,
12+
"./src/"
13+
);
14+
15+
for (const fileName of tsConfig.fileNames.filter(
16+
(fn) => !fn.endsWith("test.ts")
17+
)) {
18+
const sourceFile = ts.createSourceFile(
19+
fileName,
20+
fs.readFileSync(fileName, "utf-8"),
21+
tsConfig.options.target,
22+
true
23+
);
24+
sourceFile.forEachChild((node) => {
25+
switch (node.kind) {
26+
case ts.SyntaxKind.ClassDeclaration:
27+
case ts.SyntaxKind.ClassExpression: {
28+
node.forEachChild((node) => {
29+
// look for get lc_secrets()
30+
switch (node.kind) {
31+
case ts.SyntaxKind.GetAccessor: {
32+
const property = node;
33+
if (property.name.getText() === "lc_secrets") {
34+
// look for return { ... }
35+
property.body.statements.forEach((stmt) => {
36+
if (
37+
stmt.kind === ts.SyntaxKind.ReturnStatement &&
38+
stmt.expression.kind ===
39+
ts.SyntaxKind.ObjectLiteralExpression
40+
) {
41+
// collect secret identifier
42+
stmt.expression.properties.forEach((element) => {
43+
if (
44+
element.initializer.kind ===
45+
ts.SyntaxKind.StringLiteral
46+
) {
47+
const secret = element.initializer.text;
48+
49+
if (secret.toUpperCase() !== secret) {
50+
throw new Error(
51+
`Secret identifier must be uppercase: ${secret} at ${fileName}`
52+
);
53+
}
54+
if (/\s/.test(secret)) {
55+
throw new Error(
56+
`Secret identifier must not contain whitespace: ${secret} at ${fileName}`
57+
);
58+
}
59+
60+
secrets.add(secret);
61+
}
62+
});
63+
}
64+
});
65+
}
66+
break;
67+
}
68+
}
69+
});
70+
break;
71+
}
72+
}
73+
});
74+
}
75+
76+
return secrets;
77+
}

0 commit comments

Comments
 (0)