Security News
New Python Packaging Proposal Aims to Solve Phantom Dependency Problem with SBOMs
PEP 770 proposes adding SBOM support to Python packages to improve transparency and catch hidden non-Python dependencies that security tools often miss.
api-smart-diff
Advanced tools
Generate the diff between two API specifications (OpenAPI, AsyncAPI, JsonSchema)
This package provides utils to compute the diff between two Json based API documents - online demo
npm install api-smart-diff --save
import { apiDiff } from 'api-smart-diff'
const diffs = apiDiff(oldSpec, newSpec)
// {
// action: "add" | "remove" | "replace" | "rename",
// after: 'value in newSpec',
// before: 'value in oldSpec',
// path: ['path, 'in', 'array', 'format'],
// type: "annotation" | "breaking" | "non-breaking" | "unclassified" | "deprecated"
// }
const merged = apiMerge(oldSpec, newSpec)
A browser version of api-smart-diff
is also available via CDN:
<script src="https://cdn.jsdelivr.net/npm/api-smart-diff@latest/browser/api-smart-diff.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/api-smart-diff@latest/browser/api-smart-diff.js"></script>
Reference api-smart-diff.min.js
in your HTML and use the global variable ApiSmartDiff
.
<script>
var diffs = ApiSmartDiff.apiDiff(oldSpec, newSpec)
var merged = ApiSmartDiff.apiMerge(oldSpec, newSpec)
</script>
Package provides the following public functions:
apiDiff (before, after, options?: CompareOptions): Array<Diff>
Calculates the difference list between two objects and classify difference in accordinance with before document type: OpenApi3, AsyncApi2, JsonSchema.
apiDiffTree (before, after, options?: CompareOptions): object
Calculates the difference tree between two objects and classify difference in accordinance with before document type: OpenApi3, AsyncApi2, JsonSchema.
apiMerge (before, after, options?: MergeOptions): object
Merge two objects and inject difference as meta data.
The apiDiff function calculates the difference between two objects.
before: any
- the origin objectafter: any
- the object being compared structurally with the origin object\options: CompareOptions
[optional] - comparison optionstype CompareOptions = {
rules?: Rules
trimStrings?: boolean
caseSensitive?: boolean
strictArrays?: boolean
externalRefs?: { [key: string]: any }
}
rules
- custom match and classification rulestrimString
- ignore spaces in matching, default false
caseSensitive
- ignore case in matching, default false
strictArrays
- use strict match algorithm for array items, default false
externalRefs
- object with external refsFunction returns array of differences:
type Diff = {
action: "add" | "remove" | "replace" | "rename"
path: Array<string | number>
before?: any
after?: any
type: "breaking" | "non-breaking" | "annotation" | "unclassified" | "deprecated"
}
const diffs = apiDiff(before, after)
if (diffs.length) {
// do something with the changes
}
The apiDiff function calculates the difference between two objects.
before: any
- the origin objectafter: any
- the object being compared structurally with the origin object\options: CompareOptions
[optional] - comparison optionsFunction returns object with $diff
key for all differences:
type Diff = {
action: "add" | "remove" | "replace" | "rename"
before?: any
after?: any
type: "breaking" | "non-breaking" | "annotation" | "unclassified" | "deprecated"
}
const diff = apiDiffTree(before, after)
// do something with the changes object
The apiDiff function calculates the difference between two objects.
before: any
- the origin objectafter: any
- the object being compared structurally with the origin object\options: MergeOptions
[optional] - comparison optionstype MergeOptions<T> = CompareOptions & {
resolveUnchangedRefs?: boolean
arrayMeta?: boolean
formatMergedMeta?: (diff: T) => any
metaKey?: string | symbol
}
Additional to compare options:
arrayMeta
- inject meta to arrays for items changes, default false
resolveUnchangedRefs
- resolve refs even if no changes, default false
metaKey
- key for diff metadata, default $diff
formatMergedMeta
- custom formatting function for metaFunction returns merged object with metadata. Metadata includes merged keys and differences:
type MergedMeta = {
[key: string]: MergedKeyMeta | MergedArrayMeta
}
type MergedKeyMeta = {
type: DiffType
action: ActionType
replaced?: any
}
type MergedArrayMeta = {
array: { [key: number]: MergedArrayMeta }
}
const apiKey = Symbol("diff")
const merged = apiMerge(before, after, { apiKey })
// do something with merged object
import { apiDiff, changeDoc, changeDocOpenApiRules } from "api-smart-diff"
const diff = apiDiff(before, after, {
formatMergedMeta: (diff) => ({ ...diff, description: changeDoc(diff, before, after, changeDocOpenApiRules) })
})
Custom match and classification rules can be defined as object:
type Rules = {
// root property (or array item) rule
"/"?: Rule
// rule for all unspecified properties (or nested array items)
"/*"?: Rule | Rules | (before) => Rules
// rule for specified properties
[key: `/${string}`]?: Rule | Rules | (before) => Rules
// custom match function for object (or array)
"#"?: (before, after) => boolean
}
// Change classifier
type Rule = [
DiffType | (ctx: IChangeContext) => DiffType, // add
DiffType | (ctx: IChangeContext) => DiffType, // remove
DiffType | (ctx: IChangeContext) => DiffType // replace (rename)
]
// Current path Change context
interface IChageContext {
before: any // before value
after: any // after value
root: IChageContext // get root Change context
up: (n?: number) => IChageContext // get parent Change Context
}
Please check predefined rules in /src/rules
folder to get examples
When contributing, keep in mind that it is an objective of api-smart-diff
to have no package dependencies. This may change in the future, but for now, no-dependencies.
Please run the unit tests before submitting your PR: npm test
. Hopefully your PR includes additional unit tests to illustrate your change/modification!
MIT
FAQs
Generate the diff between two API specifications (OpenAPI, AsyncAPI, GraphApi, JsonSchema)
The npm package api-smart-diff receives a total of 843 weekly downloads. As such, api-smart-diff popularity was classified as not popular.
We found that api-smart-diff demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 0 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
PEP 770 proposes adding SBOM support to Python packages to improve transparency and catch hidden non-Python dependencies that security tools often miss.
Security News
Socket CEO Feross Aboukhadijeh discusses open source security challenges, including zero-day attacks and supply chain risks, on the Cyber Security Council podcast.
Security News
Research
Socket researchers uncover how threat actors weaponize Out-of-Band Application Security Testing (OAST) techniques across the npm, PyPI, and RubyGems ecosystems to exfiltrate sensitive data.