UNPKG

2.67 kBJavaScriptView Raw
1'use strict'
2const diff = require('deep-diff')
3
4function toNamedObject(arr, modifier = obj => obj) {
5 if (!arr) {
6 return {}
7 }
8 return arr.reduce((obj, value) => {
9 obj[value.name] = modifier(value)
10 return obj
11 }, {})
12}
13
14function toNamedArray(obj, modifier = obj => obj) {
15 if (!obj) {
16 return []
17 }
18 return Object.entries(obj).map(([key, value]) => {
19 return modifier(Object.assign({}, value, { name: key }))
20 })
21}
22
23function toDiffableSchema(schema) {
24 const types = toNamedObject(schema.__schema.types, type => {
25 if (type.fields) {
26 type = Object.assign({}, type, {
27 fields: toNamedObject(type.fields)
28 })
29 }
30 if (type.enumValues) {
31 type = Object.assign({}, type, {
32 enumValues: toNamedObject(type.enumValues)
33 })
34 }
35 return type
36 })
37
38 const directives = toNamedObject(schema.__schema.directives)
39
40 return Object.assign({}, schema, {
41 __schema: Object.assign({}, schema.__schema, {
42 types,
43 directives
44 })
45 })
46}
47
48function fromDiffableSchema(schema) {
49 const types = toNamedArray(schema.__schema.types, type => {
50 if (type.fields) {
51 type = Object.assign({}, type, {
52 fields: toNamedArray(type.fields)
53 })
54 }
55 if (type.enumValues) {
56 type = Object.assign({}, type, {
57 enumValues: toNamedArray(type.enumValues)
58 })
59 }
60 return type
61 })
62
63 const directives = toNamedArray(schema.__schema.directives)
64
65 return Object.assign({}, schema, {
66 __schema: Object.assign({}, schema.__schema, {
67 types,
68 directives
69 })
70 })
71}
72
73function diffSchema(oldSchema, newSchema, options = {}) {
74 const oldDiffableSchema = toDiffableSchema(oldSchema)
75 const newDiffableSchema = toDiffableSchema(newSchema)
76 const changes = diff(oldDiffableSchema, newDiffableSchema)
77 const diffSchema = changes.reduce((schema, change) => {
78 diff.applyChange(schema, newDiffableSchema, change)
79 return schema
80 }, {})
81 const schema = fromDiffableSchema(diffSchema)
82 const newTypes = newDiffableSchema.__schema.types
83 schema.__schema.types = schema.__schema.types.map(type => {
84 if (options.processTypeDiff) {
85 type = options.processTypeDiff(type)
86 }
87 type = Object.assign({}, newTypes[type.name], type)
88 if (type.fields) {
89 const newFields = newTypes[type.name].fields
90 type.fields = type.fields.map(field => newFields[field.name])
91 }
92 if (type.enumValues) {
93 const newEnumValues = newTypes[type.name].enumValues
94 type.enumValues = type.enumValues.map(
95 enumValue => newEnumValues[enumValue.name]
96 )
97 }
98 return type
99 })
100 return schema
101}
102
103module.exports = diffSchema