Skip to content

Commit ad6fe9c

Browse files
committed
chore: merge branch 'feature/performance-optimization' into feature/hash
2 parents b78bb70 + 5c6cb18 commit ad6fe9c

File tree

146 files changed

+180181
-311410
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

146 files changed

+180181
-311410
lines changed

.github/super-linter.env

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,5 +41,8 @@ VALIDATE_TYPESCRIPT_STANDARD=false
4141
VALIDATE_CHECKOV=false
4242
VALIDATE_OPENAPI=false
4343

44+
# Skip GraphQL prettier, since we need GraphQL specs as is for testing purposes
45+
VALIDATE_GRAPHQL_PRETTIER=false
46+
4447
# Skip checking of specially broken specifications
4548
FILTER_REGEX_EXCLUDE=test/projects/broken/.*

package-lock.json

Lines changed: 11 additions & 11 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
"dependencies": {
3434
"@netcracker/qubership-apihub-api-diff": "feature-hash",
3535
"@netcracker/qubership-apihub-api-unifier": "feature-hash",
36-
"@netcracker/qubership-apihub-graphapi": "1.0.8",
36+
"@netcracker/qubership-apihub-graphapi": "feature-performance-optimization",
3737
"@netcracker/qubership-apihub-json-crawl": "1.0.4",
3838
"adm-zip": "0.5.10",
3939
"ajv": "^8.12.0",

src/apitypes/graphql/graphql.changes.ts

Lines changed: 100 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -14,36 +14,113 @@
1414
* limitations under the License.
1515
*/
1616

17-
import { VersionGraphQLOperation } from './graphql.types'
18-
import { removeComponents, takeIf } from '../../utils'
19-
import { apiDiff, COMPARE_MODE_OPERATION, Diff } from '@netcracker/qubership-apihub-api-diff'
20-
import { NORMALIZE_OPTIONS } from '../../consts'
21-
import { GraphApiSchema } from '@netcracker/qubership-apihub-graphapi'
22-
23-
export const graphqlOperationsCompare = async (current: VersionGraphQLOperation | undefined, previous: VersionGraphQLOperation | undefined): Promise<Diff[]> => {
24-
let previousOperation = removeComponents(previous?.data)
25-
let currentOperation = removeComponents(current?.data)
26-
if (!previousOperation && currentOperation) {
27-
previousOperation = getCopyWithEmptyOperations(currentOperation as GraphApiSchema)
28-
}
17+
import { isEmpty, slugify, takeIf } from '../../utils'
18+
import { aggregateDiffsWithRollup, apiDiff, Diff, DIFF_META_KEY, DIFFS_AGGREGATED_META_KEY } from '@netcracker/qubership-apihub-api-diff'
19+
import { NORMALIZE_OPTIONS, ORIGINS_SYMBOL } from '../../consts'
20+
import { GraphApiOperation, GraphApiSchema } from '@netcracker/qubership-apihub-graphapi'
21+
import { buildSchema } from 'graphql/utilities'
22+
import { buildGraphQLDocument } from './graphql.document'
23+
import {
24+
CompareOperationsPairContext,
25+
FILE_KIND,
26+
OperationChanges,
27+
ResolvedVersionDocument,
28+
WithAggregatedDiffs,
29+
WithDiffMetaRecord,
30+
} from '../../types'
31+
import { GRAPHQL_TYPE, GRAPHQL_TYPE_KEYS } from './graphql.consts'
32+
import { createOperationChange, getOperationTags, OperationsMap } from '../../components'
33+
34+
export const compareDocuments = async (
35+
operationsMap: OperationsMap,
36+
prevDoc: ResolvedVersionDocument | undefined,
37+
currDoc: ResolvedVersionDocument | undefined,
38+
ctx: CompareOperationsPairContext): Promise<{
39+
operationChanges: OperationChanges[]
40+
tags: Set<string>
41+
}> => {
42+
const { apiType, rawDocumentResolver, previousVersion, currentVersion, previousPackageId, currentPackageId } = ctx
43+
const prevFile = prevDoc && await rawDocumentResolver(previousVersion, previousPackageId, prevDoc.slug)
44+
const currFile = currDoc && await rawDocumentResolver(currentVersion, currentPackageId, currDoc.slug)
45+
const prevDocSchema = prevFile && buildSchema(await prevFile.text(), { noLocation: true })
46+
const currDocSchema = currFile && buildSchema(await currFile.text(), { noLocation: true })
47+
48+
let prevDocData = prevDocSchema && (await buildGraphQLDocument({
49+
...prevDoc,
50+
source: prevFile,
51+
kind: FILE_KIND.TEXT,
52+
data: prevDocSchema,
53+
}, prevDoc)).data
54+
let currDocData = currDocSchema && (await buildGraphQLDocument({
55+
...currDoc,
56+
source: currFile,
57+
kind: FILE_KIND.TEXT,
58+
data: currDocSchema,
59+
}, currDoc)).data
2960

30-
if (previousOperation && !currentOperation) {
31-
currentOperation = getCopyWithEmptyOperations(previousOperation as GraphApiSchema)
61+
if (!prevDocData && currDocData) {
62+
prevDocData = getCopyWithEmptyOperations(currDocData)
63+
}
64+
if (prevDocData && !currDocData) {
65+
currDocData = getCopyWithEmptyOperations(prevDocData)
3266
}
3367

34-
//todo think about normalize options
35-
const { diffs } = apiDiff(
36-
previousOperation,
37-
currentOperation,
68+
const { merged, diffs } = apiDiff(
69+
prevDocData,
70+
currDocData,
3871
{
3972
...NORMALIZE_OPTIONS,
40-
mode: COMPARE_MODE_OPERATION,
73+
metaKey: DIFF_META_KEY,
74+
originsFlag: ORIGINS_SYMBOL,
4175
normalizedResult: true,
42-
beforeSource: previous?.data,
43-
afterSource: current?.data,
4476
},
45-
)
46-
return diffs
77+
) as { merged: GraphApiSchema; diffs: Diff[] }
78+
79+
if (isEmpty(diffs)) {
80+
return { operationChanges: [], tags: new Set() }
81+
}
82+
83+
aggregateDiffsWithRollup(merged, DIFF_META_KEY, DIFFS_AGGREGATED_META_KEY)
84+
85+
const { currentGroup, previousGroup } = ctx
86+
87+
const tags = new Set<string>()
88+
const operationChanges: OperationChanges[] = []
89+
90+
for (const type of GRAPHQL_TYPE_KEYS) {
91+
const operationsByType = merged[type]
92+
if (!operationsByType) { continue }
93+
94+
for (const operationKey of Object.keys(operationsByType)) {
95+
const operationId = slugify(`${GRAPHQL_TYPE[type]}-${operationKey}`)
96+
const methodData = operationsByType[operationKey]
97+
98+
const { current, previous } = operationsMap[operationId] ?? {}
99+
if (!current && !previous) {
100+
throw new Error(`Can't find the ${operationId} operation from documents pair ${prevDoc?.fileId} and ${currDoc?.fileId}`)
101+
}
102+
const operationChanged = Boolean(current && previous)
103+
const operationAddedOrRemoved = !operationChanged
104+
105+
let operationDiffs: Diff[] = []
106+
if (operationChanged) {
107+
operationDiffs = [...(methodData as WithAggregatedDiffs<GraphApiOperation>)[DIFFS_AGGREGATED_META_KEY] ?? []]
108+
}
109+
if (operationAddedOrRemoved) {
110+
const operationAddedOrRemovedDiff = (merged[type] as WithDiffMetaRecord<Record<string, GraphApiOperation>>)[DIFF_META_KEY]?.[operationKey]
111+
operationAddedOrRemovedDiff && operationDiffs.push(operationAddedOrRemovedDiff)
112+
}
113+
114+
if (isEmpty(operationDiffs)) {
115+
continue
116+
}
117+
118+
operationChanges.push(createOperationChange(apiType, operationDiffs, previous, current, currentGroup, previousGroup))
119+
getOperationTags(current ?? previous).forEach(tag => tags.add(tag))
120+
}
121+
}
122+
123+
return { operationChanges, tags }
47124
}
48125

49126
function getCopyWithEmptyOperations(template: GraphApiSchema): GraphApiSchema {

src/apitypes/graphql/graphql.consts.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
* See the License for the specific language governing permissions and
1414
* limitations under the License.
1515
*/
16+
import { ResolvedVersionDocument, ZippableDocument } from '../../types'
1617

1718
export const GRAPHQL_API_TYPE = 'graphql' as const
1819

@@ -43,3 +44,7 @@ export const GRAPHQL_TYPE = {
4344
'mutations': 'mutation',
4445
'subscriptions': 'subscription',
4546
} as const
47+
48+
export function isGraphqlDocument(document: ZippableDocument | ResolvedVersionDocument): boolean {
49+
return Object.values(GRAPHQL_DOCUMENT_TYPE).some(type => document.type === type)
50+
}

src/apitypes/graphql/graphql.document.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,18 @@
1414
* limitations under the License.
1515
*/
1616

17-
import { buildFromIntrospection, buildFromSchema, GraphApiSchema, printGraphApi } from '@netcracker/qubership-apihub-graphapi'
17+
import {
18+
buildFromIntrospection,
19+
buildFromSchema,
20+
GraphApiSchema,
21+
printGraphApi,
22+
} from '@netcracker/qubership-apihub-graphapi'
1823
import type { GraphQLSchema, IntrospectionQuery } from 'graphql'
1924

20-
import type { DocumentBuilder, DocumentDumper } from '../../types'
25+
import { BuildConfigFile, DocumentDumper, TextFile, VersionDocument } from '../../types'
2126
import { GRAPHQL_DOCUMENT_TYPE } from './graphql.consts'
2227

23-
export const buildGraphQLDocument: DocumentBuilder<GraphApiSchema> = async (parsedFile, file) => {
28+
export const buildGraphQLDocument: (parsedFile: TextFile, file: BuildConfigFile) => Promise<VersionDocument<GraphApiSchema>> = async (parsedFile, file) => {
2429
let graphapi: GraphApiSchema
2530
if (parsedFile.type === GRAPHQL_DOCUMENT_TYPE.INTROSPECTION) {
2631
const introspection = (parsedFile?.data && '__schema' in parsedFile.data ? parsedFile?.data : parsedFile.data?.data) as IntrospectionQuery

src/apitypes/graphql/graphql.operation.ts

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -88,18 +88,13 @@ export const buildGraphQLOperation = (
8888

8989
const apiKind = document.apiKind || API_KIND.BWC
9090

91-
92-
const dataHash = syncDebugPerformance('[ModelsAndOperationHashing]', () => {
91+
syncDebugPerformance('[ModelsAndOperationHashing]', () => {
9392
calculateSpecRefs(document.data, singleOperationRefsOnlySpec, singleOperationSpec)
94-
const dataHash = calculateObjectHash(singleOperationSpec)
95-
return dataHash
9693
}, debugCtx)
9794

98-
99-
10095
return {
10196
operationId,
102-
dataHash,
97+
documentId: document.slug,
10398
apiType: GRAPHQL_API_TYPE,
10499
apiKind: rawToApiKind(apiKind),
105100
deprecated: !!singleOperationEffectiveSpec[type]?.[method]?.directives?.deprecated,

src/apitypes/graphql/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import { buildGraphQLOperations } from './graphql.operations'
2121
import { GRAPHQL_API_TYPE, GRAPHQL_DOCUMENT_TYPE } from './graphql.consts'
2222
import { parseGraphQLFile } from './graphql.parser'
2323
import { ApiBuilder } from '../../types'
24-
import { graphqlOperationsCompare } from './graphql.changes'
24+
import { compareDocuments } from './graphql.changes'
2525

2626
export * from './graphql.consts'
2727

@@ -32,5 +32,5 @@ export const graphqlApiBuilder: ApiBuilder<GraphApiSchema> = {
3232
buildDocument: buildGraphQLDocument,
3333
buildOperations: buildGraphQLOperations,
3434
dumpDocument: dumpGraphQLDocument,
35-
compareOperationsData: graphqlOperationsCompare,
35+
compareDocuments: compareDocuments,
3636
}

src/apitypes/rest/index.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,15 @@ import { OpenAPIV3 } from 'openapi-types'
1818

1919
import { buildRestDocument, createRestExportDocument, dumpRestDocument } from './rest.document'
2020
import { REST_API_TYPE, REST_DOCUMENT_TYPE } from './rest.consts'
21-
import { compareRestOperationsData } from './rest.changes'
21+
import { compareDocuments } from './rest.changes'
2222
import { buildRestOperations } from './rest.operations'
2323
import { parseRestFile } from './rest.parser'
2424
import { ApiBuilder } from '../../types'
2525
import { calculateNormalizedOperationId } from '../../utils'
2626

2727
export * from './rest.consts'
28+
export type { RestOperationData } from './rest.types'
29+
export { createCopyWithPrefixGroupOperationsOnly } from './rest.changes'
2830

2931
export const restApiBuilder: ApiBuilder<OpenAPIV3.Document> = {
3032
apiType: REST_API_TYPE,
@@ -33,7 +35,7 @@ export const restApiBuilder: ApiBuilder<OpenAPIV3.Document> = {
3335
buildDocument: buildRestDocument,
3436
buildOperations: buildRestOperations,
3537
dumpDocument: dumpRestDocument,
36-
compareOperationsData: compareRestOperationsData,
38+
compareDocuments: compareDocuments,
3739
createNormalizedOperationId: calculateNormalizedOperationId,
3840
createExportDocument: createRestExportDocument,
3941
}

0 commit comments

Comments
 (0)