Skip to content

Commit

Permalink
Merge pull request #20 from palantir/mf/ua-versions
Browse files Browse the repository at this point in the history
Send consistent UserAgent strings
  • Loading branch information
mfedderly authored Feb 1, 2024
2 parents f40c43b + 61bc617 commit 0fce847
Show file tree
Hide file tree
Showing 51 changed files with 310 additions and 80 deletions.
2 changes: 1 addition & 1 deletion .lintstagedrc.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export default {
"*": (files) => {
const mrlFiles = micromatch(files, [
"package.json",
"**/package.json",
// "**/package.json",
"tsconfig.json",
"**/tsconfig.json",
], {});
Expand Down
1 change: 1 addition & 0 deletions examples/basic/cli/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ export const clientCtx = createClientContext(
Ontology,
process.env.FOUNDRY_STACK,
() => process.env.FOUNDRY_USER_TOKEN!,
`typescript-sdk/dev osdk-cli/dev`,
);

async function runTests() {
Expand Down
2 changes: 1 addition & 1 deletion examples/basic/sdk/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
},
"scripts": {
"clean": "rm -rf lib dist types build tsconfig.tsbuildinfo",
"codegen": "rm -rf src/generatedNoCheck/* && osdk unstable typescript generate --outDir src/generatedNoCheck --ontologyPath ontology.json --beta true --packageType module",
"codegen": "rm -rf src/generatedNoCheck/* && osdk unstable typescript generate --outDir src/generatedNoCheck --ontologyPath ontology.json --beta true --packageType module --version dev",
"dev:transpile": "tsup --watch",
"fix-lint": "eslint . --fix && dprint fmt --config $(find-up dprint.json)",
"lint": "eslint . && dprint check --config $(find-up dprint.json)",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
export const OntologyMetadata = {
ontologyRid: 'ridHere',
ontologyApiName: 'OntologyApiName',
userAgent: 'foundry-typescript-osdk/2.0.0',
userAgent: 'typescript-sdk/dev osdk-cli/dev',
};
2 changes: 1 addition & 1 deletion examples/one_dot_one/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
},
"scripts": {
"clean": "rm -rf lib dist types build tsconfig.tsbuildinfo",
"codegen": "rm -rf src/generatedNoCheck/* && osdk unstable typescript generate --outDir src/generatedNoCheck --ontologyPath ontology.json",
"codegen": "rm -rf src/generatedNoCheck/* && osdk unstable typescript generate --outDir src/generatedNoCheck --ontologyPath ontology.json --version dev",
"dev:transpile": "tsup --watch",
"fix-lint": "eslint . --fix && dprint fmt --config $(find-up dprint.json)",
"lint": "eslint . && dprint check --config $(find-up dprint.json)",
Expand Down
4 changes: 2 additions & 2 deletions examples/one_dot_one/src/generatedNoCheck/Ontology.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export const Ontology: {
metadata: {
ontologyRid: 'ridHere';
ontologyApiName: 'OntologyApiName';
userAgent: 'foundry-typescript-osdk/0.0.1';
userAgent: 'typescript-sdk/dev osdk-cli/dev';
};
objects: {
Todo: typeof Todo;
Expand All @@ -34,7 +34,7 @@ export const Ontology: {
metadata: {
ontologyRid: 'ridHere' as const,
ontologyApiName: 'OntologyApiName' as const,
userAgent: 'foundry-typescript-osdk/0.0.1' as const,
userAgent: 'typescript-sdk/dev osdk-cli/dev' as const,
},
objects: {
Todo,
Expand Down
2 changes: 1 addition & 1 deletion examples/todoapp/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"license": "Apache-2.0",
"scripts": {
"build": "tsc && vite build",
"codegen": "rm -rf src/generatedNoCheck/* src/generatedNoCheck2/* && osdk unstable typescript generate --outDir src/generatedNoCheck --ontologyPath ontology.json && osdk unstable typescript generate --outDir src/generatedNoCheck2 --beta --ontologyPath ontology.json",
"codegen": "rm -rf src/generatedNoCheck/* src/generatedNoCheck2/* && osdk unstable typescript generate --outDir src/generatedNoCheck --ontologyPath ontology.json --version dev && osdk unstable typescript generate --outDir src/generatedNoCheck2 --beta --ontologyPath ontology.json --version dev",
"dev": "vite",
"lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
"preview": "vite preview"
Expand Down
4 changes: 2 additions & 2 deletions examples/todoapp/src/generatedNoCheck/Ontology.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export const Ontology: {
metadata: {
ontologyRid: 'ri.ontology.main.ontology.a35bb7f9-2c57-4199-a1cd-af461d88bd6e';
ontologyApiName: 'ontology-d097f725-ab77-46cf-83c0-e3cb9186bff1';
userAgent: 'foundry-typescript-osdk/0.0.1';
userAgent: 'typescript-sdk/dev osdk-cli/dev';
};
objects: {
Todo: typeof Todo;
Expand All @@ -25,7 +25,7 @@ export const Ontology: {
metadata: {
ontologyRid: 'ri.ontology.main.ontology.a35bb7f9-2c57-4199-a1cd-af461d88bd6e' as const,
ontologyApiName: 'ontology-d097f725-ab77-46cf-83c0-e3cb9186bff1' as const,
userAgent: 'foundry-typescript-osdk/0.0.1' as const,
userAgent: 'typescript-sdk/dev osdk-cli/dev' as const,
},
objects: {
Todo,
Expand Down
2 changes: 1 addition & 1 deletion examples/todoapp/src/generatedNoCheck2/OntologyMetadata.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
export const OntologyMetadata = {
ontologyRid: 'ri.ontology.main.ontology.a35bb7f9-2c57-4199-a1cd-af461d88bd6e',
ontologyApiName: 'ontology-d097f725-ab77-46cf-83c0-e3cb9186bff1',
userAgent: 'foundry-typescript-osdk/2.0.0',
userAgent: 'typescript-sdk/dev osdk-cli/dev',
};
7 changes: 7 additions & 0 deletions monorepo/mytsup/tsup.mjs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { readFile } from "fs/promises";

/**
* @param {import('tsup').Options} options
* @param {{cjsExtension?: ".cjs" | ".js"}} ourOptions
Expand All @@ -6,6 +8,8 @@
export default async (options, ourOptions) => {
const babel = (await import("esbuild-plugin-babel")).default;

const packageJson = await readFile("package.json").then(f => JSON.parse(f));

return {
entry: [
"src/index.ts",
Expand All @@ -18,6 +22,9 @@ export default async (options, ourOptions) => {
js: format === "cjs" ? (ourOptions?.cjsExtension ?? ".cjs") : ".mjs",
};
},
env: {
PACKAGE_VERSION: packageJson.version,
},
outDir: "build/js",
clean: true,
silent: true,
Expand Down
5 changes: 5 additions & 0 deletions packages/cli/changelog/@unreleased/pr-20.v2.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
type: fix
fix:
description: Send consistent UserAgent strings
links:
- https://github.com/palantir/osdk-ts/pull/20
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,5 @@ export interface TypescriptGenerateArgs {
clientId?: string;
beta?: boolean;
packageType: "commonjs" | "module";
version: string;
}
22 changes: 17 additions & 5 deletions packages/cli/src/commands/typescript/generate/generate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/

import type { CommandModule } from "yargs";
import { isValidSemver } from "../../../util/isValidSemver.js";
import type { TypescriptGenerateArgs } from "./TypescriptGenerateArgs.js";

export const command: CommandModule<
Expand Down Expand Up @@ -67,23 +68,34 @@ export const command: CommandModule<
default: "commonjs",
choices: ["commonjs", "module"],
},
version: {
type: "string",
description: "Version of the generated code, or 'dev'",
demandOption: true,
},
} as const,
).group(
["ontologyPath", "outDir"],
["ontologyPath", "outDir", "version"],
"Generate from a local file",
).group(
["stack", "clientId", "outDir", "ontologyWritePath"],
["stack", "clientId", "outDir", "ontologyWritePath", "version"],
"OR Generate from a stack",
)
.check(
(argv) => {
if (argv.ontologyPath || argv.stack) {
return true;
} else {
if (!argv.ontologyPath && !argv.stack) {
throw new Error(
"Error: Must specify either ontologyPath or stack and clientId",
);
}

if (argv.version !== "dev" && !isValidSemver(argv.version)) {
throw new Error(
"Error: Version must be 'dev' or a valid semver version",
);
}

return true;
},
);
},
Expand Down
17 changes: 16 additions & 1 deletion packages/cli/src/commands/typescript/generate/handleGenerate.mts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ import * as fs from "node:fs";
import invokeLoginFlow from "../../auth/login/loginFlow.js";
import type { TypescriptGenerateArgs } from "./TypescriptGenerateArgs.js";

const USER_AGENT = `osdk-cli/${process.env.PACKAGE_VERSION}`;

export default async function handleGenerate(args: TypescriptGenerateArgs) {
let success = false;
if (args.ontologyPath) {
Expand Down Expand Up @@ -70,11 +72,12 @@ async function generateFromStack(args: TypescriptGenerateArgs) {
const { fetch } = createClientContext(
{
metadata: {
userAgent: "@osdk/cli/0.0.0 ()",
userAgent: USER_AGENT,
},
},
args.stack!,
() => token.access_token,
USER_AGENT,
);

try {
Expand Down Expand Up @@ -123,13 +126,15 @@ async function generateClientSdk(
if (args.beta) {
await generateClientSdkVersionTwoPointZero(
ontology,
getUserAgent(args.version),
minimalFs,
args.outDir,
args.packageType,
);
} else {
await generateClientSdkVersionOneDotOne(
ontology,
getUserAgent(args.version),
minimalFs,
args.outDir,
args.packageType,
Expand All @@ -141,3 +146,13 @@ async function generateClientSdk(
}
return true;
}

// If the user passed us `dev` as our version, we use that for both our generated package version AND the cli version.
// This makes it so that releases don't force us to have to regenerate the code when the version strings change.
function getUserAgent(version: string) {
if (version === "dev") {
return "typescript-sdk/dev osdk-cli/dev";
} else {
return `typescript-sdk/${version} ${USER_AGENT}`;
}
}
35 changes: 0 additions & 35 deletions packages/cli/src/readCliVersionFromPackageJson.ts

This file was deleted.

23 changes: 23 additions & 0 deletions packages/cli/src/util/isValidSemver.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* 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.
*/

// https://semver.org/#is-there-a-suggested-regular-expression-regex-to-check-a-semver-string
const semver =
/^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/;

export function isValidSemver(semverString: string): boolean {
return semver.test(semverString);
}
3 changes: 1 addition & 2 deletions packages/cli/src/yargs/logVersionMiddleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
*/

import type { CliCommonArgs } from "../CliCommonArgs.js";
import { readCliVersionFromPackageJson } from "../readCliVersionFromPackageJson.js";

let firstTime = true;
export async function logVersionMiddleware(args: CliCommonArgs) {
Expand All @@ -25,7 +24,7 @@ export async function logVersionMiddleware(args: CliCommonArgs) {
const consola = Consola.consola;

consola.info(
`Palantir OSDK CLI ${await readCliVersionFromPackageJson()}`,
`Palantir OSDK CLI ${process.env.PACKAGE_VERSION}`,
);

consola.level = 3 + args.verbose; // so 1 -v is debug logs and -vv is trace
Expand Down
5 changes: 5 additions & 0 deletions packages/client/changelog/@unreleased/pr-20.v2.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
type: fix
fix:
description: Send consistent UserAgent strings
links:
- https://github.com/palantir/osdk-ts/pull/20
1 change: 1 addition & 0 deletions packages/client/generateMockOntology.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ delete ontologyWithoutUnsupportedAction.actionTypes["unsupported-action"];

await generateClientSdkVersionTwoPointZero(
ontologyWithoutUnsupportedAction,
"typescript-sdk/dev osdk-cli/dev",
{
writeFile: (path, contents) => {
return writeFile(path, contents, "utf-8");
Expand Down
50 changes: 50 additions & 0 deletions packages/client/src/createClient.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* 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 { mockFetchResponse, MockOntology } from "@osdk/shared.test";
import type { MockedFunction } from "vitest";
import { describe, expect, it, vi } from "vitest";
import { createClient } from "./createClient.js";
import { USER_AGENT } from "./util/UserAgent.js";

describe(createClient, () => {
it("Passes the expected userAgent string", async () => {
const fetchFunction: MockedFunction<typeof globalThis.fetch> = vi.fn();

const client = createClient(
MockOntology,
"https://mock.com",
() => "Token",
fetchFunction,
);

mockFetchResponse(fetchFunction, { data: [] });

await client.objects.Task.fetchPageOrThrow();
expect(fetchFunction).toHaveBeenCalledTimes(1);

const userAgent = (fetchFunction.mock.calls[0][1]?.headers as Headers).get(
"Fetch-User-Agent",
);
const parts = userAgent?.split(" ") ?? [];
const [packageUA, generatorUA] = MockOntology.metadata.userAgent
.split(" ");
expect(parts).toHaveLength(3);
expect(parts[0]).toEqual(packageUA);
expect(parts[1]).toEqual(generatorUA);
expect(parts[2]).toEqual(USER_AGENT); // the client USER_AGENT has an undefined version during vitest runs
});
});
3 changes: 2 additions & 1 deletion packages/client/src/createClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import type { Client } from "./Client.js";
import { createObjectSet } from "./objectSet/createObjectSet.js";
import type { ObjectSetFactory } from "./objectSet/ObjectSet.js";
import { createObjectSetCreator } from "./ObjectSetCreator.js";
import { USER_AGENT } from "./util/UserAgent.js";

export function createClient<O extends OntologyDefinition<any>>(
ontology: O,
Expand All @@ -32,7 +33,7 @@ export function createClient<O extends OntologyDefinition<any>>(
ontology,
stack,
tokenProvider,
"@osdk/client/0.0.0 ()",
USER_AGENT,
fetchFn,
);

Expand Down
Loading

0 comments on commit 0fce847

Please sign in to comment.