Skip to content
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

Generator emits cjs #1138

Merged
merged 4 commits into from
Jan 29, 2025
Merged
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
5 changes: 5 additions & 0 deletions .changeset/quiet-lions-sort.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@osdk/foundry-sdk-generator": minor
---

We now generate osdk libs that support commonjs
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -68,7 +68,7 @@ jobs:

build:
name: Build and Test
timeout-minutes: 15
timeout-minutes: 20
Copy link
Contributor

Choose a reason for hiding this comment

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

Dang our tests taking long now

runs-on: ubuntu-latest
permissions:
contents: write
3 changes: 1 addition & 2 deletions .monorepolint.config.mjs
Original file line number Diff line number Diff line change
@@ -67,8 +67,7 @@ const privatePackages = [
"@osdk/monorepo.*",
"@osdk/platform-sdk-generator",
"@osdk/shared.test",
"@osdk/tests.verify-fallback-package-v2",
"@osdk/tests.verify-cjs-node16",
"@osdk/tests.*",
"@osdk/tool.*",
"@osdk/version-updater",
"@osdk/benchmarks.*",
20 changes: 10 additions & 10 deletions examples-extra/docs_example/src/generatedNoCheck/index.ts
Original file line number Diff line number Diff line change
@@ -6,13 +6,13 @@ export {
moveOffice,
promoteEmployee,
promoteEmployeeObject,
} from './ontology/actions';
export * as $Actions from './ontology/actions';
export {} from './ontology/interfaces';
export * as $Interfaces from './ontology/interfaces';
export { Employee, equipment, Office, Todo } from './ontology/objects';
export * as $Objects from './ontology/objects';
export {} from './ontology/queries';
export * as $Queries from './ontology/queries';
export { $osdkMetadata } from './OntologyMetadata';
export { $ontologyRid } from './OntologyMetadata';
} from './ontology/actions.js';
export * as $Actions from './ontology/actions.js';
export {} from './ontology/interfaces.js';
export * as $Interfaces from './ontology/interfaces.js';
export { Employee, equipment, Office, Todo } from './ontology/objects.js';
export * as $Objects from './ontology/objects.js';
export {} from './ontology/queries.js';
export * as $Queries from './ontology/queries.js';
export { $osdkMetadata } from './OntologyMetadata.js';
export { $ontologyRid } from './OntologyMetadata.js';
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
export { completeTodo } from './actions/completeTodo';
export { createOffice } from './actions/createOffice';
export { createOfficeAndEmployee } from './actions/createOfficeAndEmployee';
export { createTodo } from './actions/createTodo';
export { moveOffice } from './actions/moveOffice';
export { promoteEmployee } from './actions/promoteEmployee';
export { promoteEmployeeObject } from './actions/promoteEmployeeObject';
export { completeTodo } from './actions/completeTodo.js';
export { createOffice } from './actions/createOffice.js';
export { createOfficeAndEmployee } from './actions/createOfficeAndEmployee.js';
export { createTodo } from './actions/createTodo.js';
export { moveOffice } from './actions/moveOffice.js';
export { promoteEmployee } from './actions/promoteEmployee.js';
export { promoteEmployeeObject } from './actions/promoteEmployeeObject.js';
Original file line number Diff line number Diff line change
@@ -6,8 +6,8 @@ import type {
ApplyActionOptions,
ApplyBatchActionOptions,
} from '@osdk/client';
import { $osdkMetadata } from '../../OntologyMetadata';
import type { Todo } from '../objects/Todo';
import { $osdkMetadata } from '../../OntologyMetadata.js';
import type { Todo } from '../objects/Todo.js';

export namespace completeTodo {
// Represents the definition of the parameters for the action
Original file line number Diff line number Diff line change
@@ -6,7 +6,7 @@ import type {
ApplyActionOptions,
ApplyBatchActionOptions,
} from '@osdk/client';
import { $osdkMetadata } from '../../OntologyMetadata';
import { $osdkMetadata } from '../../OntologyMetadata.js';

export namespace createOffice {
// Represents the definition of the parameters for the action
Original file line number Diff line number Diff line change
@@ -6,7 +6,7 @@ import type {
ApplyActionOptions,
ApplyBatchActionOptions,
} from '@osdk/client';
import { $osdkMetadata } from '../../OntologyMetadata';
import { $osdkMetadata } from '../../OntologyMetadata.js';

export namespace createOfficeAndEmployee {
// Represents the definition of the parameters for the action
Original file line number Diff line number Diff line change
@@ -6,7 +6,7 @@ import type {
ApplyActionOptions,
ApplyBatchActionOptions,
} from '@osdk/client';
import { $osdkMetadata } from '../../OntologyMetadata';
import { $osdkMetadata } from '../../OntologyMetadata.js';

export namespace createTodo {
// Represents the definition of the parameters for the action
Original file line number Diff line number Diff line change
@@ -6,7 +6,7 @@ import type {
ApplyActionOptions,
ApplyBatchActionOptions,
} from '@osdk/client';
import { $osdkMetadata } from '../../OntologyMetadata';
import { $osdkMetadata } from '../../OntologyMetadata.js';

export namespace moveOffice {
// Represents the definition of the parameters for the action
Original file line number Diff line number Diff line change
@@ -6,7 +6,7 @@ import type {
ApplyActionOptions,
ApplyBatchActionOptions,
} from '@osdk/client';
import { $osdkMetadata } from '../../OntologyMetadata';
import { $osdkMetadata } from '../../OntologyMetadata.js';

export namespace promoteEmployee {
// Represents the definition of the parameters for the action
Original file line number Diff line number Diff line change
@@ -6,8 +6,8 @@ import type {
ApplyActionOptions,
ApplyBatchActionOptions,
} from '@osdk/client';
import { $osdkMetadata } from '../../OntologyMetadata';
import type { Employee } from '../objects/Employee';
import { $osdkMetadata } from '../../OntologyMetadata.js';
import type { Employee } from '../objects/Employee.js';

export namespace promoteEmployeeObject {
// Represents the definition of the parameters for the action
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export { Employee } from './objects/Employee';
export { equipment } from './objects/equipment';
export { Office } from './objects/Office';
export { Todo } from './objects/Todo';
export { Employee } from './objects/Employee.js';
export { equipment } from './objects/equipment.js';
export { Office } from './objects/Office.js';
export { Todo } from './objects/Todo.js';
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { PropertyDef as $PropertyDef } from '@osdk/client';
import { $osdkMetadata } from '../../OntologyMetadata';
import type { $ExpectedClientVersion } from '../../OntologyMetadata';
import { $osdkMetadata } from '../../OntologyMetadata.js';
import type { $ExpectedClientVersion } from '../../OntologyMetadata.js';
import type {
PropertyKeys as $PropertyKeys,
ObjectTypeDefinition as $ObjectTypeDefinition,
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { PropertyDef as $PropertyDef } from '@osdk/client';
import { $osdkMetadata } from '../../OntologyMetadata';
import type { $ExpectedClientVersion } from '../../OntologyMetadata';
import { $osdkMetadata } from '../../OntologyMetadata.js';
import type { $ExpectedClientVersion } from '../../OntologyMetadata.js';
import type {
PropertyKeys as $PropertyKeys,
ObjectTypeDefinition as $ObjectTypeDefinition,
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { PropertyDef as $PropertyDef } from '@osdk/client';
import { $osdkMetadata } from '../../OntologyMetadata';
import type { $ExpectedClientVersion } from '../../OntologyMetadata';
import { $osdkMetadata } from '../../OntologyMetadata.js';
import type { $ExpectedClientVersion } from '../../OntologyMetadata.js';
import type {
PropertyKeys as $PropertyKeys,
ObjectTypeDefinition as $ObjectTypeDefinition,
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { PropertyDef as $PropertyDef } from '@osdk/client';
import { $osdkMetadata } from '../../OntologyMetadata';
import type { $ExpectedClientVersion } from '../../OntologyMetadata';
import { $osdkMetadata } from '../../OntologyMetadata.js';
import type { $ExpectedClientVersion } from '../../OntologyMetadata.js';
import type {
PropertyKeys as $PropertyKeys,
ObjectTypeDefinition as $ObjectTypeDefinition,
20 changes: 10 additions & 10 deletions packages/e2e.sandbox.todoapp/src/generatedNoCheck2/index.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
export { completeTodo, createTodo } from './ontology/actions';
export * as $Actions from './ontology/actions';
export {} from './ontology/interfaces';
export * as $Interfaces from './ontology/interfaces';
export { Todo } from './ontology/objects';
export * as $Objects from './ontology/objects';
export {} from './ontology/queries';
export * as $Queries from './ontology/queries';
export { $osdkMetadata } from './OntologyMetadata';
export { $ontologyRid } from './OntologyMetadata';
export { completeTodo, createTodo } from './ontology/actions.js';
export * as $Actions from './ontology/actions.js';
export {} from './ontology/interfaces.js';
export * as $Interfaces from './ontology/interfaces.js';
export { Todo } from './ontology/objects.js';
export * as $Objects from './ontology/objects.js';
export {} from './ontology/queries.js';
export * as $Queries from './ontology/queries.js';
export { $osdkMetadata } from './OntologyMetadata.js';
export { $ontologyRid } from './OntologyMetadata.js';
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
export { completeTodo } from './actions/completeTodo';
export { createTodo } from './actions/createTodo';
export { completeTodo } from './actions/completeTodo.js';
export { createTodo } from './actions/createTodo.js';
Original file line number Diff line number Diff line change
@@ -6,8 +6,8 @@ import type {
ApplyActionOptions,
ApplyBatchActionOptions,
} from '@osdk/client';
import { $osdkMetadata } from '../../OntologyMetadata';
import type { Todo } from '../objects/Todo';
import { $osdkMetadata } from '../../OntologyMetadata.js';
import type { Todo } from '../objects/Todo.js';

export namespace completeTodo {
// Represents the definition of the parameters for the action
Original file line number Diff line number Diff line change
@@ -6,7 +6,7 @@ import type {
ApplyActionOptions,
ApplyBatchActionOptions,
} from '@osdk/client';
import { $osdkMetadata } from '../../OntologyMetadata';
import { $osdkMetadata } from '../../OntologyMetadata.js';

export namespace createTodo {
// Represents the definition of the parameters for the action
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export { Todo } from './objects/Todo';
export { Todo } from './objects/Todo.js';
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { PropertyDef as $PropertyDef } from '@osdk/client';
import { $osdkMetadata } from '../../OntologyMetadata';
import type { $ExpectedClientVersion } from '../../OntologyMetadata';
import { $osdkMetadata } from '../../OntologyMetadata.js';
import type { $ExpectedClientVersion } from '../../OntologyMetadata.js';
import type {
PropertyKeys as $PropertyKeys,
ObjectTypeDefinition as $ObjectTypeDefinition,
16 changes: 14 additions & 2 deletions packages/e2e.test.foundry-sdk-generator/generateMockOntology.js
Original file line number Diff line number Diff line change
@@ -17,6 +17,7 @@
// @ts-check
import { __testSeamOnly_NotSemverStable__GeneratePackageCommand as GeneratePackageCommand } from "@osdk/foundry-sdk-generator";
import { apiServer } from "@osdk/shared.test";
import { $ } from "execa";
import * as fs from "node:fs/promises";
import { tmpdir } from "node:os";
import * as path from "node:path";
@@ -98,13 +99,24 @@ async function setup() {
await safeStat(testApp2Dir, "should exist");
await safeStat(testApp2BetaDir, "should exist");

await $({
stdout: "inherit",
stderr: "inherit",
})`attw --pack ${path.join(testApp2Dir, "osdk")}`;

await $({
stdout: "inherit",
stderr: "inherit",
})`attw --pack ${path.join(testApp2BetaDir, "osdk")}`;

const finalOutDir = path.join(
path.dirname(fileURLToPath(import.meta.url)),
"src",
"generatedNoCheck",
);

fs.cp(dir, finalOutDir, { recursive: true });
await fs.rm(finalOutDir, { recursive: true, force: true });
await fs.cp(dir, finalOutDir, { recursive: true });
}

export async function teardown() {
@@ -121,7 +133,7 @@ await teardown();
*/
async function rmRf(testAppDir) {
try {
await fs.rm(testAppDir, { recursive: true });
await fs.rm(testAppDir, { recursive: true, force: true });
} catch (e) {
// console.debug("rm error", e);
// Only needed for regenerations
Original file line number Diff line number Diff line change
@@ -37,16 +37,16 @@ describe("Generate Package Command", () => {

const scriptsExport = packageJson["exports"]?.["."]?.["script"];
expect(scriptsExport).toEqual({
"default": "./dist/bundle/index.esm.js",
"types": "./dist/bundle/index.d.ts",
"types": "./dist/bundle/index.d.mts",
"default": "./dist/bundle/index.mjs",
});

const esmPath = path.join(generatedPath, scriptsExport.default);

expect(existsSync(esmPath), esmPath).toBe(true);

const contents = await fs.readFile(
path.join(generatedPath, "index.js"),
path.join(generatedPath, "esm", "index.js"),
"utf-8",
);
expect(contents).not.toContain("Object.defineProperty(exports,");
Original file line number Diff line number Diff line change
@@ -20,7 +20,6 @@ import {
createProgram,
createSourceFile,
ModuleKind,
ModuleResolutionKind,
ScriptTarget,
} from "typescript";

@@ -31,6 +30,7 @@ export interface CompilerOutput {

export function compileInMemory(
files: { [fileName: string]: string },
type: "cjs" | "esm",
): {
files: {
[fileName: string]: string;
@@ -39,9 +39,9 @@ export function compileInMemory(
} {
const inMemoryOutputFileSystem: { [fileName: string]: string } = {};
const compilerOptions: CompilerOptions = {
module: ModuleKind.NodeNext,
module: type === "cjs" ? ModuleKind.CommonJS : ModuleKind.ES2022,
target: ScriptTarget.ES2020,
moduleResolution: ModuleResolutionKind.NodeNext,
resolvePackageJsonExports: true,
Copy link
Contributor

Choose a reason for hiding this comment

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

So you have to explicitly set this now because you're not specifying moduleResolution anymore?

More concretely, if module is CommonJS, then moduleResolution becomes node10, in which case, it wont look at exports by default. But if its ES2022, then technically you don't need to explicitly set that line right cuz it'll default on?

Copy link
Member Author

Choose a reason for hiding this comment

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

Correct. So I want to be sure we are generating in a way that will work with Node16 so I turn this on.

declaration: true,
skipLibCheck: true,
};
Original file line number Diff line number Diff line change
@@ -41,6 +41,7 @@ export async function generatePackage(
},
): Promise<void> {
const { consola } = await import("consola");
let success = true;

const packagePath = join(options.outputDir, options.packageName);

@@ -82,16 +83,47 @@ export async function generatePackage(
beta: options.beta,
});

// writes to in memory fs that the compiler will read from
await hostFs.writeFile(
join(packagePath, "package.json"),
JSON.stringify(contents),
);
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
const compilerOutput: Record<
"esm" | "cjs",
ReturnType<typeof compileInMemory>
> = {} as any;

for (const type of ["esm", "cjs"] as const) {
// writes to in memory fs that the compiler will read from
await hostFs.writeFile(
join(packagePath, "package.json"),
JSON.stringify({
...contents,
type: type === "cjs" ? "commonjs" : "module",
}),
);

const compilerOutput = compileInMemory(inMemoryFileSystem);
compilerOutput.diagnostics.forEach(d =>
consola.error(`Error compiling file`, d.file?.fileName, d.messageText)
);
compilerOutput[type] = compileInMemory(inMemoryFileSystem, type);
compilerOutput[type].diagnostics.forEach(d => {
consola.error(`Error compiling file`, d.file?.fileName, d.messageText);
success = false;
});

await mkdir(join(packagePath, "dist", "bundle"), { recursive: true });

await mkdir(join(packagePath, "esm"), { recursive: true });
await mkdir(join(packagePath, "cjs"), { recursive: true });

for (const [path, contents] of Object.entries(compilerOutput[type].files)) {
const newPath = path.replace(
packagePath,
join(packagePath, type),
);
await mkdir(dirname(newPath), { recursive: true });
await writeFile(newPath, contents, { flag: "w" });
}

void await writeFile(
join(packagePath, type, "package.json"),
JSON.stringify({ type: type === "esm" ? "module" : "commonjs" }),
);
}

await mkdir(join(packagePath, "dist", "bundle"), { recursive: true });

@@ -107,28 +139,24 @@ export async function generatePackage(
bundleDts = await bundleDependencies(
[],
options.packageName,
compilerOutput.files,
compilerOutput["esm"].files,
undefined,
);
} catch (e) {
consola.error("Failed bundling DTS", e);
success = false;
}
} else {
consola.error(
"Could not find node_modules directory, skipping DTS bundling",
);
success = false;
}

await Promise.all([
...Object.entries(compilerOutput.files).map(async ([path, contents]) => {
await writeFile(path, contents, { flag: "w" });
}),
await writeFile(
join(packagePath, "dist", "bundle", "index.d.ts"),
bundleDts,
{ flag: "w" },
),
]);
await writeFile(
join(packagePath, "dist", "bundle", "index.d.mts"),
bundleDts,
{ flag: "w" },
);

const absolutePackagePath = isAbsolute(options.outputDir)
? options.outputDir
@@ -138,5 +166,10 @@ export async function generatePackage(
await generateBundles(absolutePackagePath, options.packageName);
} catch (e) {
consola.error(e);
success = false;
}

if (!success) {
throw new Error("Failed to generate package");
}
}
Original file line number Diff line number Diff line change
@@ -42,21 +42,29 @@ export async function generatePackageJson(options: {
const packageJson = {
name: options.packageName,
version: options.packageVersion,
main: "./index.js",
types: "./index.d.ts",
main: "./cjs/index.js",
Copy link
Contributor

Choose a reason for hiding this comment

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

So are these two fields cjs now because node10 default looks at the main field?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes

types: "./cjs/index.d.ts",
exports: {
".": {
types: "./index.d.ts",
script: {
types: "./dist/bundle/index.d.ts",
default: "./dist/bundle/index.esm.js",
types: "./dist/bundle/index.d.mts",
default: "./dist/bundle/index.mjs",
},
default: "./index.js",
require: {
types: "./cjs/index.d.ts",
default: "./cjs/index.js",
},
import: {
types: "./esm/index.d.ts",
default: "./esm/index.js",
},
types: "./cjs/index.d.ts",
default: "./cjs/index.js",
},
},
dependencies: packageDeps,
peerDependencies: packagePeerDeps,
type: "module",
type: "commonjs",
};

await writeFile(
20 changes: 13 additions & 7 deletions packages/foundry-sdk-generator/src/generate/generateBundles.ts
Original file line number Diff line number Diff line change
@@ -23,16 +23,16 @@ import nodePolyfill from "rollup-plugin-polyfill-node";
async function createRollupBuild(
absolutePackagePath: string,
packageName: string,
) {
const inputPath = `${absolutePackagePath}/${packageName}/index.js`;
): Promise<RollupBuild> {
const inputPath = `${absolutePackagePath}/${packageName}/esm/index.js`;

const { findUp } = await import("find-up");
const nodeModulesPath = await findUp("node_modules", {
cwd: __dirname,
type: "directory",
});

return rollup({
return await rollup({
input: inputPath,
plugins: [
nodeResolve({
@@ -64,8 +64,9 @@ async function writeRollupBuild(
packageName: string,
format: ModuleFormat,
) {
const outputPath =
`${absolutePackagePath}/${packageName}/dist/bundle/index.${format}.js`;
const outputPath = `${absolutePackagePath}/${packageName}/dist/bundle/index.${
format === "cjs" ? "cjs" : "mjs"
}`;

await Promise.all([
rollupBuild.write({
@@ -84,13 +85,18 @@ async function generateEsmBuild(
absolutePackagePath: string,
packageName: string,
) {
const umdBuild = await createRollupBuild(absolutePackagePath, packageName);
const umdBuild = await createRollupBuild(
absolutePackagePath,
packageName,
);
await writeRollupBuild(umdBuild, absolutePackagePath, packageName, "esm");
}

export async function generateBundles(
absolutePackagePath: string,
packageName: string,
): Promise<void> {
await Promise.all([generateEsmBuild(absolutePackagePath, packageName)]);
await Promise.all([
generateEsmBuild(absolutePackagePath, packageName),
]);
}
996 changes: 498 additions & 498 deletions packages/generator/src/v2.0/generateClientSdkVersionTwoPointZero.test.ts

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -38,7 +38,7 @@ export async function generateClientSdkVersionTwoPointZero(
externalSpts: Map<string, string> = new Map(),
forInternalUse: boolean = false,
): Promise<void> {
const importExt = packageType === "module" ? ".js" : "";
const importExt = ".js"; // turns out you can always use the extension

// Structurally, we need to have multiple ontologies read in
// with one per package.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/usr/bin/env node
// @ts-check
import { generateWithMockOntology } from "../build/esm/generateWithMockOntology.js";
await generateWithMockOntology();
64 changes: 64 additions & 0 deletions packages/tool.generate-with-mock-ontology/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
{
"name": "@osdk/tool.generate-with-mock-ontology",
"private": true,
"version": "0.0.1",
"license": "Apache-2.0",
"repository": {
"type": "git",
"url": "https://github.com/palantir/osdk-ts.git"
},
"exports": {
".": {
"import": {
"types": "./build/types/index.d.ts",
"default": "./build/esm/index.js"
},
"default": "./build/esm/index.js"
},
"./*": {
"import": {
"types": "./build/types/public/*.d.ts",
"default": "./build/esm/public/*.js"
},
"default": "./build/esm/public/*.js"
}
},
"scripts": {
"check-spelling": "cspell --quiet .",
"clean": "rm -rf lib dist types build tsconfig.tsbuildinfo",
"fix-lint": "eslint . --fix && dprint fmt --config $(find-up dprint.json)",
"lint": "eslint . && dprint check --config $(find-up dprint.json)",
"transpileEsm": "monorepo.tool.transpile -f esm -m normal -t node",
"transpileTypes": "monorepo.tool.transpile -f esm -m types -t node",
"typecheck": "tsc --noEmit --emitDeclarationOnly false"
},
"dependencies": {
"@osdk/api": "workspace:~",
"@osdk/client": "workspace:~",
"@test-app2/osdk": "link:./osdk/@test-app2/osdk"
},
"devDependencies": {
"@osdk/foundry-sdk-generator": "workspace:~",
"@osdk/monorepo.api-extractor": "workspace:~",
"@osdk/monorepo.tsconfig": "workspace:~",
"@osdk/shared.test": "workspace:~",
"execa": "^9.5.1",
"typescript": "~5.5.4"
},
"publishConfig": {
"access": "public"
},
"bin": {
"generate-with-mock-ontology": "./bin/generate-with-mock-ontology.mjs"
},
"files": [
"build/esm",
"build/types",
"CHANGELOG.md",
"package.json",
"templates",
"*.d.ts"
],
"module": "./build/esm/index.js",
"type": "module"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
/*
* Copyright 2024 Palantir Technologies, Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

// @ts-check
import { __testSeamOnly_NotSemverStable__GeneratePackageCommand as GeneratePackageCommand } from "@osdk/foundry-sdk-generator";
import { apiServer } from "@osdk/shared.test";
import { $ } from "execa";
import * as fs from "node:fs/promises";
import { tmpdir } from "node:os";
import * as path from "node:path";
import { safeStat } from "./safeStat.js";

export async function generateWithMockOntology(): Promise<void> {
try {
const dir = await fs.mkdtemp(
path.join(tmpdir(), "osdk-e2e-foundry-sdk-generator-"),
);

apiServer.listen();

const testApp2Dir = path.join(dir, "@test-app2");

await fs.rm(testApp2Dir, { recursive: true, force: true });
await safeStat(testApp2Dir, "should not exist");

await fs.mkdir(dir, { recursive: true });

const generatePackageCommand = new GeneratePackageCommand();

const baseArgs: Parameters<typeof generatePackageCommand["handler"]>[0] = {
packageName: "@test-app2/osdk",
packageVersion: "0.0.1",
outputDir: dir,
authToken: "myAccessToken",
foundryHostname: "https://stack.palantir.com",
ontology:
"ri.ontology.main.ontology.698267cc-6b48-4d98-beff-29beb24e9361",
objectTypes: [
"Employee",
"Office",
"objectTypeWithAllPropertyTypes",
"ObjectWithTimestampPrimaryKey",
"equipment",
],
actionTypes: [
"createOffice",
"moveOffice",
"createOfficeAndEmployee",
"actionTakesObjectSet",
],
queryTypes: [
"addOne",
"incrementPersonAge",
"returnsTimestamp",
"returnsDate",
"returnsObject",
"twoDimensionalAggregationFunction",
"threeDimensionalAggregationFunction",
],
interfaceTypes: [
"FooInterface",
],
linkTypes: ["employee.peeps", "employee.lead", "employee.officeLink"],
palantirOnlyTest: true,
_: [],
$0: "",
};

await generatePackageCommand.handler({
...baseArgs,
packageName: "@test-app2/osdk",
beta: false,
});

await safeStat(testApp2Dir, "should exist");

await $({
stdout: "inherit",
stderr: "inherit",
})`attw --pack ${
path.join(testApp2Dir, "osdk")
} --ignore-rules internal-resolution-error`;

const finalOutDir = path.join(
process.cwd(),
"osdk",
);

await fs.rm(path.join(finalOutDir, "@test-app2"), {
recursive: true,
force: true,
});
await fs.cp(dir, finalOutDir, { recursive: true });
} finally {
// eslint-disable-next-line no-console
console.log("teardown: stopping API server");
apiServer.close();
}
}
17 changes: 17 additions & 0 deletions packages/tool.generate-with-mock-ontology/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/*
* Copyright 2025 Palantir Technologies, Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

export { generateWithMockOntology } from "./generateWithMockOntology.js";
42 changes: 42 additions & 0 deletions packages/tool.generate-with-mock-ontology/src/safeStat.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* Copyright 2025 Palantir Technologies, Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import type { Stats } from "node:fs";
import * as fs from "node:fs/promises";

export async function safeStat(
filePath: string,
type?: "should exist" | "should not exist",
): Promise<Stats | undefined> {
try {
const ret = await fs.stat(filePath);
if (type === "should not exist") {
throw new Error(`Expected ${filePath} to not exist`);
}

// eslint-disable-next-line no-console
console.log(`safeStat: ${filePath} exists`);
return ret;
} catch (e) {
if (type === "should exist") {
throw new Error(`Expected ${filePath} to exist`);
}

// eslint-disable-next-line no-console
console.log(`safeStat: ${filePath} does not exist`);
return undefined;
}
}
11 changes: 11 additions & 0 deletions packages/tool.generate-with-mock-ontology/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"extends": "@osdk/monorepo.tsconfig/base.json",
"compilerOptions": {
"rootDir": "src",
"outDir": "build/esm"
},
"include": [
"./src/**/*"
],
"references": []
}
27 changes: 27 additions & 0 deletions packages/tool.generate-with-mock-ontology/vitest.config.mts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* Copyright 2023 Palantir Technologies, Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import { configDefaults, defineConfig } from "vitest/config";

export default defineConfig({
test: {
pool: "forks",
exclude: [...configDefaults.exclude, "**/build/**/*"],
fakeTimers: {
toFake: ["setTimeout", "clearTimeout", "Date"],
},
},
});
480 changes: 284 additions & 196 deletions pnpm-lock.yaml

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions tests/verify-cjs-node10/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/osdk/*
!/osdk/.gitkeep
Empty file.
23 changes: 23 additions & 0 deletions tests/verify-cjs-node10/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"name": "@osdk/tests.verify-cjs-node10",
"private": true,
"version": "0.0.3",
"license": "Apache-2.0",
"repository": {
"type": "git",
"url": "https://github.com/palantir/osdk-ts.git"
},
"scripts": {
"codegen": "generate-with-mock-ontology",
"typecheck": "tsc --noEmit"
},
"dependencies": {
"@osdk/api": "workspace:~",
"@osdk/client": "workspace:~",
"@test-app2/osdk": "link:./osdk/@test-app2/osdk"
},
"devDependencies": {
"@osdk/tool.generate-with-mock-ontology": "workspace:~",
"typescript": "~5.5.4"
}
}
13 changes: 13 additions & 0 deletions tests/verify-cjs-node10/src/test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import * as Client from "@osdk/client";
import * as sdk from "@test-app2/osdk";
Client.createClient({} as any, "", async () => "");

import * as Api from "@osdk/api";
type Q = Api.InterfaceMetadata;

import * as Unstable from "@osdk/client/unstable-do-not-use";
Unstable.augment({ type: "object", apiName: "foo" } as any);

if (sdk.$Objects.Employee.apiName !== "Employee") {
throw new Error("Expected Employee");
}
8 changes: 8 additions & 0 deletions tests/verify-cjs-node10/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"compilerOptions": {
"module": "CommonJS",
"moduleResolution": "node10",
"target": "es2020",
"skipLibCheck": true
}
}
12 changes: 12 additions & 0 deletions tests/verify-cjs-node10/turbo.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"extends": ["//"],
"tasks": {
"codegen": {
"outputs": ["osdk/@test-app2/**/*"],
"dependsOn": [
"@osdk/tool.generate-with-mock-ontology#transpile",
"^transpile"
]
}
}
}
2 changes: 2 additions & 0 deletions tests/verify-cjs-node16/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/osdk/*
!/osdk/.gitkeep
8 changes: 7 additions & 1 deletion tests/verify-cjs-node16/package.json
Original file line number Diff line number Diff line change
@@ -8,10 +8,16 @@
"url": "https://github.com/palantir/osdk-ts.git"
},
"scripts": {
"codegen": "generate-with-mock-ontology",
"typecheck": "tsc --noEmit"
},
"dependencies": {
"@osdk/api": "workspace:~",
"@osdk/client": "workspace:~"
"@osdk/client": "workspace:~",
"@test-app2/osdk": "link:./osdk/@test-app2/osdk"
},
"devDependencies": {
"@osdk/tool.generate-with-mock-ontology": "workspace:~",
"typescript": "~5.5.4"
}
}
5 changes: 5 additions & 0 deletions tests/verify-cjs-node16/src/test.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
import * as Client from "@osdk/client";
import * as sdk from "@test-app2/osdk";
Client.createClient({} as any, "", async () => "");

import * as Api from "@osdk/api";
type Q = Api.InterfaceMetadata;

import * as Unstable from "@osdk/client/unstable-do-not-use";
Unstable.augment({ type: "object", apiName: "foo" } as any);

if (sdk.$Objects.Employee.apiName !== "Employee") {
throw new Error("Expected Employee");
}
12 changes: 12 additions & 0 deletions tests/verify-cjs-node16/turbo.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"extends": ["//"],
"tasks": {
"codegen": {
"outputs": ["osdk/@test-app2/**/*"],
"dependsOn": [
"@osdk/tool.generate-with-mock-ontology#transpile",
"^transpile"
]
}
}
}
2 changes: 2 additions & 0 deletions tests/verify-esm-node16/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/osdk/*
!/osdk/.gitkeep
23 changes: 23 additions & 0 deletions tests/verify-esm-node16/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"name": "@osdk/tests.verify-esm-node16",
"private": true,
"version": "0.0.3",
"license": "Apache-2.0",
"repository": {
"type": "git",
"url": "https://github.com/palantir/osdk-ts.git"
},
"scripts": {
"codegen": "generate-with-mock-ontology",
"typecheck": "tsc --noEmit"
},
"dependencies": {
"@osdk/api": "workspace:~",
"@osdk/client": "workspace:~",
"@test-app2/osdk": "link:./osdk/@test-app2/osdk"
},
"devDependencies": {
"@osdk/tool.generate-with-mock-ontology": "workspace:~",
"typescript": "~5.5.4"
}
}
13 changes: 13 additions & 0 deletions tests/verify-esm-node16/src/test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import * as Client from "@osdk/client";
import * as sdk from "@test-app2/osdk";
Client.createClient({} as any, "", async () => "");

import * as Api from "@osdk/api";
type Q = Api.InterfaceMetadata;

import * as Unstable from "@osdk/client/unstable-do-not-use";
Unstable.augment({ type: "object", apiName: "foo" } as any);

if (sdk.$Objects.Employee.apiName !== "Employee") {
throw new Error("Expected Employee");
}
8 changes: 8 additions & 0 deletions tests/verify-esm-node16/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"compilerOptions": {
"module": "node16",
"moduleResolution": "node16",
"target": "es2020",
"skipLibCheck": true
}
}
12 changes: 12 additions & 0 deletions tests/verify-esm-node16/turbo.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"extends": ["//"],
"tasks": {
"codegen": {
"outputs": ["osdk/@test-app2/**/*"],
"dependsOn": [
"@osdk/tool.generate-with-mock-ontology#transpile",
"^transpileCjs"
]
}
}
}
3 changes: 0 additions & 3 deletions turbo.json
Original file line number Diff line number Diff line change
@@ -92,9 +92,6 @@
"@osdk/tests.verify-fallback-package-v2#typecheck": {
"dependsOn": ["^transpileCjs"]
},
"@osdk/tests.verify-cjs-node16#typecheck": {
"dependsOn": ["^transpileCjs"]
},

"@osdk/monorepo.tsup#typecheck": {
"outputLogs": "new-only",

Unchanged files with check annotations Beta

this.errorCode = errorCode;
this.statusCode = statusCode;
this.errorInstanceId = errorInstanceId;
this.parameters = parameters;

Check warning on line 39 in packages/shared.net.errors/src/PalantirApiError.ts

GitHub Actions / Build and Test (18)

Unsafe assignment of an `any` value

Check warning on line 39 in packages/shared.net.errors/src/PalantirApiError.ts

GitHub Actions / Build and Test (22)

Unsafe assignment of an `any` value
}
}
const sourcePackageJsonPath = await findUp("package.json");
if (!sourcePackageJsonPath) throw new Error("package.json is missing");
const sourcePackageJson = JSON.parse(

Check warning on line 31 in packages/create-app.template-packager/src/index.ts

GitHub Actions / Build and Test (18)

Unsafe assignment of an `any` value

Check warning on line 31 in packages/create-app.template-packager/src/index.ts

GitHub Actions / Build and Test (22)

Unsafe assignment of an `any` value
await fs.readFile(sourcePackageJsonPath, "utf-8"),
);
let output: string;
if (destPath === "package.json.hbs") {
const packageJson = JSON.parse(body.toString("utf-8"));

Check warning on line 58 in packages/create-app.template-packager/src/index.ts

GitHub Actions / Build and Test (18)

Unsafe assignment of an `any` value

Check warning on line 58 in packages/create-app.template-packager/src/index.ts

GitHub Actions / Build and Test (22)

Unsafe assignment of an `any` value
for (
const d of ["dependencies", "devDependencies", "peerDependencies"]
) {
if (sourcePackageJson[d]) {

Check warning on line 63 in packages/create-app.template-packager/src/index.ts

GitHub Actions / Build and Test (18)

Unsafe member access [d] on an `any` value

Check warning on line 63 in packages/create-app.template-packager/src/index.ts

GitHub Actions / Build and Test (22)

Unsafe member access [d] on an `any` value
if (!packageJson[d]) {

Check warning on line 64 in packages/create-app.template-packager/src/index.ts

GitHub Actions / Build and Test (18)

Unsafe member access [d] on an `any` value

Check warning on line 64 in packages/create-app.template-packager/src/index.ts

GitHub Actions / Build and Test (22)

Unsafe member access [d] on an `any` value
packageJson[d] = {};

Check warning on line 65 in packages/create-app.template-packager/src/index.ts

GitHub Actions / Build and Test (18)

Unsafe member access [d] on an `any` value

Check warning on line 65 in packages/create-app.template-packager/src/index.ts

GitHub Actions / Build and Test (22)

Unsafe member access [d] on an `any` value
}
Object.assign(packageJson[d], sourcePackageJson[d]);

Check warning on line 67 in packages/create-app.template-packager/src/index.ts

GitHub Actions / Build and Test (18)

Unsafe member access [d] on an `any` value

Check warning on line 67 in packages/create-app.template-packager/src/index.ts

GitHub Actions / Build and Test (18)

Unsafe member access [d] on an `any` value

Check warning on line 67 in packages/create-app.template-packager/src/index.ts

GitHub Actions / Build and Test (22)

Unsafe member access [d] on an `any` value

Check warning on line 67 in packages/create-app.template-packager/src/index.ts

GitHub Actions / Build and Test (22)

Unsafe member access [d] on an `any` value
delete packageJson[d]["@osdk/create-app.template-packager"];

Check warning on line 68 in packages/create-app.template-packager/src/index.ts

GitHub Actions / Build and Test (18)

Unsafe member access [d] on an `any` value

Check warning on line 68 in packages/create-app.template-packager/src/index.ts

GitHub Actions / Build and Test (22)

Unsafe member access [d] on an `any` value
for (const key of Object.keys(packageJson[d])) {

Check warning on line 69 in packages/create-app.template-packager/src/index.ts

GitHub Actions / Build and Test (18)

Unsafe argument of type `any` assigned to a parameter of type `{}`

Check warning on line 69 in packages/create-app.template-packager/src/index.ts

GitHub Actions / Build and Test (22)

Unsafe argument of type `any` assigned to a parameter of type `{}`
if (key.startsWith("@osdk/monorepo.")) {
delete packageJson[d][key];
}
});
server.on("error", (e) => {
if ((e as any).code === "EADDRINUSE") {

Check warning on line 48 in packages/cli.common/src/commands/auth/login/loginFlow.ts

GitHub Actions / Build and Test (20)

Unsafe member access .code on an `any` value
consola.error(
`Port ${port} is already in use, unable to perform authentication flow.`,
);
function generateRandomString(length = 128) {
const characters =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~";
let output: string[] = [];

Check warning on line 115 in packages/cli.common/src/commands/auth/login/loginFlow.ts

GitHub Actions / Build and Test (20)

'output' is never reassigned. Use 'const' instead
let array = new Uint8Array(1);

Check warning on line 116 in packages/cli.common/src/commands/auth/login/loginFlow.ts

GitHub Actions / Build and Test (20)

'array' is never reassigned. Use 'const' instead
const maxIndex = 256 - (256 % characters.length);
while (output.length < length) {
method: "POST",
});
const responseText: TokenResponse = await response.json();

Check warning on line 193 in packages/cli.common/src/commands/auth/login/loginFlow.ts

GitHub Actions / Build and Test (20)

Unsafe assignment of an `any` value
return responseText;
} catch (e) {
throw new Error(
`Failed to get token: ${
(e as { cause?: any })?.cause?.toString() ?? e?.toString()

Check warning on line 198 in packages/cli.common/src/commands/auth/login/loginFlow.ts

GitHub Actions / Build and Test (20)

Unsafe call of a(n) `any` typed value

Check warning on line 198 in packages/cli.common/src/commands/auth/login/loginFlow.ts

GitHub Actions / Build and Test (20)

Unsafe member access .toString on an `any` value
?? "Unknown error"
}`,
);
.demandCommand()
.middleware(logLevelMiddleware, true)
.strict()
.fail(async (msg, err, argv) => {

Check warning on line 44 in packages/cli.common/src/getYargsBase.ts

GitHub Actions / Build and Test (20)

Async arrow function has no 'await' expression
if (err instanceof ExitProcessError) {
consola.error(err.message);
if (err.tip != null) {
}
consola.debug(err.stack);
} else {
if (err && err instanceof YargsCheckError === false) {

Check warning on line 53 in packages/cli.common/src/getYargsBase.ts

GitHub Actions / Build and Test (20)

This expression unnecessarily compares a boolean value to a boolean instead of using it directly
throw err;
} else {
argv.showHelp();
import type { CliCommonArgs } from "../CliCommonArgs.js";
let firstTime = true;
export async function logLevelMiddleware(args: CliCommonArgs): Promise<void> {

Check warning on line 21 in packages/cli.common/src/yargs/logLevelMiddleware.ts

GitHub Actions / Build and Test (20)

Async function 'logLevelMiddleware' has no 'await' expression
if (firstTime) {
firstTime = false;
it.each(["1.2.3", "~1.2.3", "^1.2.3"])(
`replaces "%s" with "${expectedPrefix}1.2.3"`,
async (version) => {
const result = await changeVersionPrefix(version, expectedPrefix);

Check warning on line 25 in packages/generator-utils/src/changeVersionPrefix.test.ts

GitHub Actions / Build and Test (20)

Unexpected `await` of a non-Promise (non-"Thenable") value
expect(result).toEqual(`${expectedPrefix}1.2.3`);
},
);