Skip to content
This repository was archived by the owner on Jan 12, 2026. It is now read-only.
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
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "openapi-workspaces",
"license": "MIT",
"private": true,
"version": "0.42.15",
"version": "0.42.16",
"workspaces": [
"projects/json-pointer-helpers",
"projects/openapi-io",
Expand Down
2 changes: 1 addition & 1 deletion projects/json-pointer-helpers/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "@useoptic/json-pointer-helpers",
"license": "MIT",
"packageManager": "yarn@3.5.0",
"version": "0.42.15",
"version": "0.42.16",
"main": "build/index.js",
"types": "build/index.d.ts",
"files": [
Expand Down
2 changes: 1 addition & 1 deletion projects/openapi-io/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "@useoptic/openapi-io",
"license": "MIT",
"packageManager": "yarn@3.5.0",
"version": "0.42.15",
"version": "0.42.16",
"main": "build/index.js",
"types": "build/index.d.ts",
"files": [
Expand Down
2 changes: 1 addition & 1 deletion projects/openapi-utilities/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "@useoptic/openapi-utilities",
"license": "MIT",
"packageManager": "yarn@3.5.0",
"version": "0.42.15",
"version": "0.42.16",
"main": "build/index.js",
"types": "build/index.d.ts",
"files": [
Expand Down
2 changes: 1 addition & 1 deletion projects/optic-ci/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "@useoptic/optic-ci",
"license": "MIT",
"packageManager": "yarn@3.5.0",
"version": "0.42.15",
"version": "0.42.16",
"main": "build/index.js",
"types": "build/index.d.ts",
"files": [
Expand Down
2 changes: 1 addition & 1 deletion projects/optic/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "@useoptic/optic",
"license": "MIT",
"packageManager": "yarn@3.5.0",
"version": "0.42.15",
"version": "0.42.16",
"main": "build/index.js",
"types": "build/index.d.ts",
"files": [
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`diff-all diff all against a cloud tag 1`] = `
"Diffing cloud:main to spec.json
"Diffing cloud:api-id@main to spec.json

specification details:
- /x-optic-url added
Expand Down Expand Up @@ -30,6 +30,74 @@ Checks
0 passed
1 errors

Warning - the following OpenAPI specs were detected but did not have valid x-optic-url keys. optic diff-all --compare-from cloud:{tag}' can only runs on specs that have been added to optic

Run the \`optic api add\` command to add these specs to optic
spec-no-url.json (untracked)

"
`;

exports[`diff-all diff all in --generated 1`] = `
"Diffing cloud:generated-api@main to spec-no-url.json

specification details:
- /openapi changed

GET /api/users: removed

GET /example: added

POST /example: added

PUT /example: added

PATCH /example: added

Checks

 FAIL  GET /api/users
removed rule [error]: prevent operation removal
x cannot remove an operation. This is a breaking change.
at paths > /api/users > get (empty.json:1:45)



4 operations added, 1 removed
0 passed
1 errors

✔ Uploaded results of diff to http://localhost:3001/organizations/org-id/apis/generated-api/runs/run-id
Diffing cloud:api-id@main to spec.json

specification details:
- /x-optic-url added
- /openapi changed

GET /api/users: removed

GET /example: added

POST /example: added

PUT /example: added

PATCH /example: added

Checks

 FAIL  GET /api/users
removed rule [error]: prevent operation removal
x cannot remove an operation. This is a breaking change.
at paths > /api/users > get (empty.json:1:45)



4 operations added, 1 removed
0 passed
1 errors

✔ Uploaded results of diff to http://localhost:3001/organizations/org-id/apis/api-id/runs/run-id
"
`;

Expand Down
34 changes: 34 additions & 0 deletions projects/optic/src/__tests__/integration/diff-all.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,18 @@ setupTestServer(({ url, method }) => {
specUrl: `${process.env.BWTS_HOST_OVERRIDE}/spec`,
sourcemapUrl: `${process.env.BWTS_HOST_OVERRIDE}/sourcemap`,
});
} else if (method === 'GET' && /\/api\/apis/.test(url)) {
return JSON.stringify({
apis: [null],
});
} else if (method === 'POST' && /\/api\/api$/.test(url)) {
return JSON.stringify({
id: 'generated-api',
});
} else if (method === 'GET' && /\/api\/token\/orgs/.test(url)) {
return JSON.stringify({
organizations: [{ id: 'org-id', name: 'org-blah' }],
});
}
return JSON.stringify({});
});
Expand Down Expand Up @@ -184,4 +196,26 @@ describe('diff-all', () => {
expect(code).toBe(1);
expect(normalizeWorkspace(workspace, combined)).toMatchSnapshot();
});

test('diff all in --generated', async () => {
const workspace = await setupWorkspace('diff-all/cloud-diff', {
repo: true,
commit: true,
});

await run(
`sed -i.bak 's/string/number/' spec-no-url.json spec-no-url.json`,
false,
workspace
);
process.env.OPTIC_TOKEN = '123';

const { combined, code } = await runOptic(
workspace,
'diff-all --compare-from cloud:main --check --upload --generated'
);

expect(code).toBe(1);
expect(normalizeWorkspace(workspace, combined)).toMatchSnapshot();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
{
"openapi": "3.0.1",
"paths": {
"/example": {
"get": {
"operationId": "my-op",
"responses": {}
},
"post": {
"operationId": "postOriginalaa",
"responses": {}
},
"put": {
"operationId": "putOriginalaa",
"responses": {}
},
"patch": {
"operationId": "putOriginaaal",
"responses": {
"200": {
"description": "hello",
"content": {
"application/json": {
"example": "hello",
"schema": {
"type": "string"
}
}
}
}
}
}
}
},
"info": {
"version": "0.0.0",
"title": "Empty"
}
}
6 changes: 6 additions & 0 deletions projects/optic/src/client/optic-backend-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,9 @@ export type Standard = {
};

export type StandardConfig = { name: string; config: any }[];

export type Api = {
api_id: string;
organization_id: string;
path: string;
};
12 changes: 12 additions & 0 deletions projects/optic/src/client/optic-backend.ts
Original file line number Diff line number Diff line change
Expand Up @@ -178,10 +178,22 @@ export class OpticBackendClient extends JsonHttpClient {
return this.postJson(`/api/runs2`, run);
}

public async getApis(
paths: string[],
web_url: string
): Promise<{ apis: (Types.Api | null)[] }> {
return this.getJson<{ apis: (Types.Api | null)[] }>(
`/api/apis?paths=${paths
.map((p) => encodeURIComponent(p))
.join(',')}&web_url=${encodeURIComponent(web_url)}`
);
}

public async createApi(
organizationId: string,
opts: {
name: string;
path?: string;
web_url?: string;
default_branch: string;
default_tag?: string;
Expand Down
8 changes: 6 additions & 2 deletions projects/optic/src/commands/api/add.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Command } from 'commander';
import prompts from 'prompts';
import open from 'open';
import path, { parse } from 'path';
import path from 'path';
import fs from 'node:fs/promises';
import ora from 'ora';
import { OpticCliConfig, VCS } from '../../config';
Expand Down Expand Up @@ -194,7 +194,11 @@ async function crawlCandidateSpecs(
orgId,
forward_effective_at_to_tags: true,
});
specsToTag.push([specId, sha, parseResult.context?.effective_at]);
const effective_at =
parseResult.context?.vcs === 'git'
? parseResult.context.effective_at
: undefined;
specsToTag.push([specId, sha, effective_at]);
}

if (!alreadyTracked) {
Expand Down
Loading