@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.
Files changed (66) hide show
  1. package/LICENSE +1 -1
  2. package/lib/actions/configure.js +15 -14
  3. package/lib/actions/configure.js.map +1 -0
  4. package/lib/actions/lint.js +6 -5
  5. package/lib/actions/lint.js.map +1 -0
  6. package/lib/actions/merge.d.ts +2 -0
  7. package/lib/actions/merge.js +80 -70
  8. package/lib/actions/merge.js.map +1 -0
  9. package/lib/actions/print.d.ts +1 -1
  10. package/lib/actions/print.js +2 -1
  11. package/lib/actions/print.js.map +1 -0
  12. package/lib/actions/stitch.js +14 -13
  13. package/lib/actions/stitch.js.map +1 -0
  14. package/lib/actions/transpile.js +7 -6
  15. package/lib/actions/transpile.js.map +1 -0
  16. package/lib/actions/validate.js +4 -3
  17. package/lib/actions/validate.js.map +1 -0
  18. package/lib/index.d.ts +7 -1
  19. package/lib/index.js +16 -16
  20. package/lib/index.js.map +1 -0
  21. package/lib/mutations/config/envvars.js +3 -2
  22. package/lib/mutations/config/envvars.js.map +1 -0
  23. package/lib/mutations/config/index.js +1 -0
  24. package/lib/mutations/config/index.js.map +1 -0
  25. package/lib/utils/constants.js +2 -1
  26. package/lib/utils/constants.js.map +1 -0
  27. package/lib/utils/dedupe-query-and-mutation-types.js +7 -6
  28. package/lib/utils/dedupe-query-and-mutation-types.js.map +1 -0
  29. package/lib/utils/ensure-query-and-mutation-types.d.ts +1 -1
  30. package/lib/utils/ensure-query-and-mutation-types.js +7 -6
  31. package/lib/utils/ensure-query-and-mutation-types.js.map +1 -0
  32. package/lib/utils/graphql-helpers.js +1 -0
  33. package/lib/utils/graphql-helpers.js.map +1 -0
  34. package/lib/utils/merge-helpers.d.ts +2 -1
  35. package/lib/utils/merge-helpers.js +16 -5
  36. package/lib/utils/merge-helpers.js.map +1 -0
  37. package/lib/utils/set-files-in-sdl.js +9 -8
  38. package/lib/utils/set-files-in-sdl.js.map +1 -0
  39. package/lib/utils/strip-empty-queries-and-mutations.d.ts +1 -1
  40. package/lib/utils/strip-empty-queries-and-mutations.js +7 -6
  41. package/lib/utils/strip-empty-queries-and-mutations.js.map +1 -0
  42. package/lib/validators/config-exists/index.d.ts +1 -1
  43. package/lib/validators/config-exists/index.js +11 -10
  44. package/lib/validators/config-exists/index.js.map +1 -0
  45. package/lib/validators/index.js +1 -0
  46. package/lib/validators/index.js.map +1 -0
  47. package/package.json +24 -16
  48. package/src/actions/configure.ts +120 -0
  49. package/src/actions/lint.ts +45 -0
  50. package/src/actions/merge.ts +202 -0
  51. package/src/actions/print.ts +8 -0
  52. package/src/actions/stitch.ts +105 -0
  53. package/src/actions/transpile.ts +70 -0
  54. package/src/actions/validate.ts +54 -0
  55. package/src/index.ts +7 -0
  56. package/src/mutations/config/envvars.ts +17 -0
  57. package/src/mutations/config/index.ts +3 -0
  58. package/src/utils/constants.ts +16 -0
  59. package/src/utils/dedupe-query-and-mutation-types.ts +74 -0
  60. package/src/utils/ensure-query-and-mutation-types.ts +52 -0
  61. package/src/utils/graphql-helpers.ts +3 -0
  62. package/src/utils/merge-helpers.ts +187 -0
  63. package/src/utils/set-files-in-sdl.ts +40 -0
  64. package/src/utils/strip-empty-queries-and-mutations.ts +43 -0
  65. package/src/validators/config-exists/index.ts +54 -0
  66. 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
+ }
@@ -0,0 +1,3 @@
1
+ import configExists from './config-exists'
2
+
3
+ export default [configExists]