@stepzen/transpiler 0.0.33 → 0.0.36
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -1
- package/lib/actions/configure.js +15 -14
- package/lib/actions/configure.js.map +1 -0
- package/lib/actions/lint.js +6 -5
- package/lib/actions/lint.js.map +1 -0
- package/lib/actions/merge.d.ts +2 -0
- package/lib/actions/merge.js +80 -70
- package/lib/actions/merge.js.map +1 -0
- package/lib/actions/print.d.ts +1 -1
- package/lib/actions/print.js +2 -1
- package/lib/actions/print.js.map +1 -0
- package/lib/actions/stitch.js +14 -13
- package/lib/actions/stitch.js.map +1 -0
- package/lib/actions/transpile.js +7 -6
- package/lib/actions/transpile.js.map +1 -0
- package/lib/actions/validate.js +4 -3
- package/lib/actions/validate.js.map +1 -0
- package/lib/index.d.ts +7 -1
- package/lib/index.js +16 -16
- package/lib/index.js.map +1 -0
- package/lib/mutations/config/envvars.js +3 -2
- package/lib/mutations/config/envvars.js.map +1 -0
- package/lib/mutations/config/index.js +1 -0
- package/lib/mutations/config/index.js.map +1 -0
- package/lib/utils/constants.js +2 -1
- package/lib/utils/constants.js.map +1 -0
- package/lib/utils/dedupe-query-and-mutation-types.js +7 -6
- package/lib/utils/dedupe-query-and-mutation-types.js.map +1 -0
- package/lib/utils/ensure-query-and-mutation-types.d.ts +1 -1
- package/lib/utils/ensure-query-and-mutation-types.js +7 -6
- package/lib/utils/ensure-query-and-mutation-types.js.map +1 -0
- package/lib/utils/graphql-helpers.js +1 -0
- package/lib/utils/graphql-helpers.js.map +1 -0
- package/lib/utils/merge-helpers.d.ts +2 -1
- package/lib/utils/merge-helpers.js +16 -5
- package/lib/utils/merge-helpers.js.map +1 -0
- package/lib/utils/set-files-in-sdl.js +9 -8
- package/lib/utils/set-files-in-sdl.js.map +1 -0
- package/lib/utils/strip-empty-queries-and-mutations.d.ts +1 -1
- package/lib/utils/strip-empty-queries-and-mutations.js +7 -6
- package/lib/utils/strip-empty-queries-and-mutations.js.map +1 -0
- package/lib/validators/config-exists/index.d.ts +1 -1
- package/lib/validators/config-exists/index.js +11 -10
- package/lib/validators/config-exists/index.js.map +1 -0
- package/lib/validators/index.js +1 -0
- package/lib/validators/index.js.map +1 -0
- package/package.json +24 -16
- package/src/actions/configure.ts +120 -0
- package/src/actions/lint.ts +45 -0
- package/src/actions/merge.ts +202 -0
- package/src/actions/print.ts +8 -0
- package/src/actions/stitch.ts +105 -0
- package/src/actions/transpile.ts +70 -0
- package/src/actions/validate.ts +54 -0
- package/src/index.ts +7 -0
- package/src/mutations/config/envvars.ts +17 -0
- package/src/mutations/config/index.ts +3 -0
- package/src/utils/constants.ts +16 -0
- package/src/utils/dedupe-query-and-mutation-types.ts +74 -0
- package/src/utils/ensure-query-and-mutation-types.ts +52 -0
- package/src/utils/graphql-helpers.ts +3 -0
- package/src/utils/merge-helpers.ts +187 -0
- package/src/utils/set-files-in-sdl.ts +40 -0
- package/src/utils/strip-empty-queries-and-mutations.ts +43 -0
- package/src/validators/config-exists/index.ts +54 -0
- package/src/validators/index.ts +3 -0
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
import {BREAK, GraphQLSchema, visit} from 'graphql'
|
|
2
|
+
import {buildSchema} from 'graphql/utilities'
|
|
3
|
+
import fetch from 'node-fetch'
|
|
4
|
+
import * as fs from 'fs-extra'
|
|
5
|
+
import * as glob from 'glob'
|
|
6
|
+
import * as os from 'os'
|
|
7
|
+
import * as path from 'path'
|
|
8
|
+
import {replace} from 'lodash'
|
|
9
|
+
|
|
10
|
+
import {cloneDeep} from '../utils/graphql-helpers'
|
|
11
|
+
import {STEPZEN_DOMAIN} from './constants'
|
|
12
|
+
|
|
13
|
+
import configure from '../actions/configure'
|
|
14
|
+
import transpile from '../actions/transpile'
|
|
15
|
+
|
|
16
|
+
export const dedupeTempFolder = (dirpath: string) => {
|
|
17
|
+
do {
|
|
18
|
+
dirpath = replace(dirpath, os.tmpdir(), '')
|
|
19
|
+
} while (dirpath.includes(os.tmpdir()))
|
|
20
|
+
|
|
21
|
+
dirpath = path.join(os.tmpdir(), dirpath)
|
|
22
|
+
|
|
23
|
+
return dirpath
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export const findNextAvailableSubfolder = (folder: string, name: string) => {
|
|
27
|
+
let subfolder = name
|
|
28
|
+
let counter = 1
|
|
29
|
+
while (fs.existsSync(path.join(folder, subfolder))) {
|
|
30
|
+
const suffix = `${counter++}`.padStart(2, '0')
|
|
31
|
+
subfolder = `${name}-${suffix}`
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
return subfolder
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export const findQueryMutationInSchema = (
|
|
38
|
+
name: string,
|
|
39
|
+
files: any,
|
|
40
|
+
): Boolean => {
|
|
41
|
+
for (const file of files) {
|
|
42
|
+
let found = false
|
|
43
|
+
visit(file.ast, {
|
|
44
|
+
FieldDefinition(node) {
|
|
45
|
+
if (node.name.value === name) {
|
|
46
|
+
found = true
|
|
47
|
+
return BREAK
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
})
|
|
51
|
+
if (found) return true
|
|
52
|
+
}
|
|
53
|
+
return false
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export const findTypeInSchema = (name: string, files: any): Boolean => {
|
|
57
|
+
for (const file of files) {
|
|
58
|
+
let found = false
|
|
59
|
+
visit(file.ast, {
|
|
60
|
+
ObjectTypeDefinition(node) {
|
|
61
|
+
if (node.name.value === name) {
|
|
62
|
+
found = true
|
|
63
|
+
return BREAK
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
})
|
|
67
|
+
if (found) return true
|
|
68
|
+
}
|
|
69
|
+
return false
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export const getConfiguration = async (
|
|
73
|
+
directories: string[],
|
|
74
|
+
silent: boolean = false,
|
|
75
|
+
answers: any = {},
|
|
76
|
+
): Promise<string | boolean> => {
|
|
77
|
+
const tmp = path.join(os.tmpdir(), `stepzen-tmp-config-${Date.now()}`)
|
|
78
|
+
fs.ensureDirSync(tmp)
|
|
79
|
+
|
|
80
|
+
for (const directory of directories) {
|
|
81
|
+
const configs = [
|
|
82
|
+
...glob.sync('**/config.yaml', {cwd: directory}),
|
|
83
|
+
...glob.sync('**/stepzen.config.json', {cwd: directory}),
|
|
84
|
+
]
|
|
85
|
+
|
|
86
|
+
for (const config of configs) {
|
|
87
|
+
const configFolder = path.join(directory, config)
|
|
88
|
+
|
|
89
|
+
let writeFolder = path.join(tmp, directory, config)
|
|
90
|
+
writeFolder = dedupeTempFolder(writeFolder)
|
|
91
|
+
|
|
92
|
+
const content = fs.readFileSync(configFolder, 'utf8')
|
|
93
|
+
|
|
94
|
+
fs.ensureFileSync(writeFolder)
|
|
95
|
+
fs.writeFileSync(writeFolder, content)
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const configuration = await configure(tmp, silent, answers)
|
|
100
|
+
fs.removeSync(tmp)
|
|
101
|
+
return configuration
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
export const getExtensions = async (): Promise<string> => {
|
|
105
|
+
const domain = STEPZEN_DOMAIN.replace('.io', '.net')
|
|
106
|
+
const response = await fetch(`https://www.${domain}/directives.graphql`)
|
|
107
|
+
const text = await response.text()
|
|
108
|
+
return text
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export const getSchema = async (directory: string): Promise<GraphQLSchema> => {
|
|
112
|
+
const extensions = await getExtensions()
|
|
113
|
+
const transpiled = await transpile(directory)
|
|
114
|
+
return buildSchema(`${extensions}${os.EOL}${transpiled.schema}`)
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
export const mergeQueryMutationIntoSchema = (type: any, files: any) => {
|
|
118
|
+
files = files.map((file: any) => {
|
|
119
|
+
return {
|
|
120
|
+
...file,
|
|
121
|
+
ast: visit(file.ast, {
|
|
122
|
+
FieldDefinition(node) {
|
|
123
|
+
if (node.name.value === type.name.value) {
|
|
124
|
+
const directives = cloneDeep(type.directives)
|
|
125
|
+
const mutated: any = cloneDeep(node)
|
|
126
|
+
mutated.directives = directives
|
|
127
|
+
return mutated
|
|
128
|
+
}
|
|
129
|
+
},
|
|
130
|
+
}),
|
|
131
|
+
}
|
|
132
|
+
})
|
|
133
|
+
return files
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
export const mergeTypeIntoSchema = (type: any, files: any) => {
|
|
137
|
+
files = files.map((file: any) => {
|
|
138
|
+
return {
|
|
139
|
+
...file,
|
|
140
|
+
ast: visit(file.ast, {
|
|
141
|
+
ObjectTypeDefinition(node) {
|
|
142
|
+
if (node.name.value === type.name.value) {
|
|
143
|
+
const directives = cloneDeep(type.directives)
|
|
144
|
+
const fields = cloneDeep(type.fields)
|
|
145
|
+
const mutated: any = cloneDeep(node)
|
|
146
|
+
mutated.directives = directives
|
|
147
|
+
mutated.fields = fields
|
|
148
|
+
return mutated
|
|
149
|
+
}
|
|
150
|
+
},
|
|
151
|
+
}),
|
|
152
|
+
}
|
|
153
|
+
})
|
|
154
|
+
return files
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
export const removeQueryMutationFromSchema = (name: string, files: any) => {
|
|
158
|
+
files = files.map((file: any) => {
|
|
159
|
+
return {
|
|
160
|
+
...file,
|
|
161
|
+
ast: visit(file.ast, {
|
|
162
|
+
FieldDefinition(node) {
|
|
163
|
+
if (node.name.value === name) {
|
|
164
|
+
return null
|
|
165
|
+
}
|
|
166
|
+
},
|
|
167
|
+
}),
|
|
168
|
+
}
|
|
169
|
+
})
|
|
170
|
+
return files
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
export const removeTypeFromSchema = (name: string, files: any) => {
|
|
174
|
+
files = files.map((file: any) => {
|
|
175
|
+
return {
|
|
176
|
+
...file,
|
|
177
|
+
ast: visit(file.ast, {
|
|
178
|
+
ObjectTypeDefinition(node) {
|
|
179
|
+
if (node.name.value === name) {
|
|
180
|
+
return null
|
|
181
|
+
}
|
|
182
|
+
},
|
|
183
|
+
}),
|
|
184
|
+
}
|
|
185
|
+
})
|
|
186
|
+
return files
|
|
187
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import * as fs from 'fs'
|
|
2
|
+
import * as glob from 'glob'
|
|
3
|
+
import {parse, visit} from 'graphql'
|
|
4
|
+
import * as path from 'path'
|
|
5
|
+
|
|
6
|
+
import {cloneDeep} from './graphql-helpers'
|
|
7
|
+
import print from '../actions/print'
|
|
8
|
+
|
|
9
|
+
export default (source: string) => {
|
|
10
|
+
const files = glob
|
|
11
|
+
.sync('**/*.graphql', {cwd: source})
|
|
12
|
+
.filter(file => file !== 'index.graphql')
|
|
13
|
+
|
|
14
|
+
const output = path.join(source, 'index.graphql')
|
|
15
|
+
|
|
16
|
+
const index = fs.readFileSync(output, 'utf8')
|
|
17
|
+
|
|
18
|
+
let ast = parse(index)
|
|
19
|
+
ast = visit(ast, {
|
|
20
|
+
Directive(node) {
|
|
21
|
+
if (node.name.value === 'sdl') {
|
|
22
|
+
const mutated: any = cloneDeep(node)
|
|
23
|
+
|
|
24
|
+
mutated.arguments = mutated.arguments.map((arg: any) => {
|
|
25
|
+
if (arg.name.value === 'files') {
|
|
26
|
+
arg.value.values = files.map(file => ({
|
|
27
|
+
kind: 'StringValue',
|
|
28
|
+
value: file,
|
|
29
|
+
}))
|
|
30
|
+
}
|
|
31
|
+
return arg
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
return mutated
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
fs.writeFileSync(output, print(ast))
|
|
40
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import {DocumentNode, visit} from 'graphql'
|
|
2
|
+
|
|
3
|
+
import {cloneDeep} from './graphql-helpers'
|
|
4
|
+
|
|
5
|
+
export default (ast: DocumentNode): DocumentNode => {
|
|
6
|
+
// Loop through the AST and nuke `__query` and `__mutation` stubs
|
|
7
|
+
ast = visit(ast, {
|
|
8
|
+
ObjectTypeDefinition: {
|
|
9
|
+
enter(node) {
|
|
10
|
+
if (node.name.kind === 'Name' && node.name.value === 'Query') {
|
|
11
|
+
const mutated: any = cloneDeep(node)
|
|
12
|
+
mutated.fields = mutated.fields.filter((field: any) => {
|
|
13
|
+
return field.name.value !== '__query'
|
|
14
|
+
})
|
|
15
|
+
return mutated
|
|
16
|
+
}
|
|
17
|
+
if (node.name.kind === 'Name' && node.name.value === 'Mutation') {
|
|
18
|
+
const mutated: any = cloneDeep(node)
|
|
19
|
+
mutated.fields = mutated.fields.filter((field: any) => {
|
|
20
|
+
return field.name.value !== '__mutated'
|
|
21
|
+
})
|
|
22
|
+
return mutated
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
// Strip empty Queries and Mutations definitions
|
|
29
|
+
ast = visit(ast, {
|
|
30
|
+
ObjectTypeDefinition: {
|
|
31
|
+
enter(node) {
|
|
32
|
+
if (node.name.kind === 'Name' && node.name.value === 'Query') {
|
|
33
|
+
if (node.fields?.length === 0) return null
|
|
34
|
+
}
|
|
35
|
+
if (node.name.kind === 'Name' && node.name.value === 'Mutation') {
|
|
36
|
+
if (node.fields?.length === 0) return null
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
return ast
|
|
43
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import {DocumentNode, visit} from 'graphql'
|
|
2
|
+
import {filter, uniq} from 'lodash'
|
|
3
|
+
import * as fs from 'fs'
|
|
4
|
+
import * as path from 'path'
|
|
5
|
+
import * as yaml from 'yaml'
|
|
6
|
+
|
|
7
|
+
const STEPZEN_DEFAULTS = [
|
|
8
|
+
'fedex_default',
|
|
9
|
+
'holidayapi_default',
|
|
10
|
+
'ipapi_default',
|
|
11
|
+
'owm_default',
|
|
12
|
+
'ups_default',
|
|
13
|
+
]
|
|
14
|
+
|
|
15
|
+
export default (ast: DocumentNode, source: string) => {
|
|
16
|
+
let configs: any = []
|
|
17
|
+
|
|
18
|
+
visit(ast, {
|
|
19
|
+
Argument(node: any) {
|
|
20
|
+
const name = node.name?.value
|
|
21
|
+
const value = node.value?.value
|
|
22
|
+
|
|
23
|
+
if (name === 'configuration') {
|
|
24
|
+
configs = configs.concat(value)
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
configs = uniq(configs)
|
|
30
|
+
configs = filter(configs, config => !STEPZEN_DEFAULTS.includes(config))
|
|
31
|
+
|
|
32
|
+
if (configs.length > 0) {
|
|
33
|
+
const sourceConfig = path.join(source, 'config.yaml')
|
|
34
|
+
|
|
35
|
+
if (!fs.existsSync(sourceConfig)) {
|
|
36
|
+
throw new Error('No config.yaml found')
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const content = fs.readFileSync(sourceConfig, 'utf8')
|
|
40
|
+
const asYaml = yaml.parse(content)
|
|
41
|
+
|
|
42
|
+
for (const config of configs) {
|
|
43
|
+
const found = asYaml?.configurationset?.find((c: any) => {
|
|
44
|
+
return c?.configuration?.name === config
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
if (!found) {
|
|
48
|
+
throw new Error(`Could not find configuration item for "${config}"`)
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return true
|
|
54
|
+
}
|