@stepzen/transpiler 0.28.0-experimental.dd6fead → 0.28.0-experimental.f225ee8
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/lib/actions/configure.js +3 -3
- package/lib/actions/configure.js.map +1 -1
- package/lib/actions/lint.d.ts.map +1 -1
- package/lib/actions/lint.js +20 -12
- package/lib/actions/lint.js.map +1 -1
- package/lib/actions/merge.d.ts +7 -6
- package/lib/actions/merge.d.ts.map +1 -1
- package/lib/actions/merge.js +42 -26
- package/lib/actions/merge.js.map +1 -1
- package/lib/actions/stitch.d.ts +2 -2
- package/lib/actions/stitch.d.ts.map +1 -1
- package/lib/actions/stitch.js +30 -12
- package/lib/actions/stitch.js.map +1 -1
- package/lib/actions/transpile.d.ts.map +1 -1
- package/lib/actions/transpile.js +9 -3
- package/lib/actions/transpile.js.map +1 -1
- package/lib/actions/validate.js +4 -4
- package/lib/actions/validate.js.map +1 -1
- package/lib/utils/copy-workspace-content.js +4 -4
- package/lib/utils/copy-workspace-content.js.map +1 -1
- package/lib/utils/merge-helpers.d.ts.map +1 -1
- package/lib/utils/merge-helpers.js +23 -18
- package/lib/utils/merge-helpers.js.map +1 -1
- package/lib/utils/rmtemp.d.ts +11 -0
- package/lib/utils/rmtemp.d.ts.map +1 -0
- package/lib/utils/rmtemp.js +43 -0
- package/lib/utils/rmtemp.js.map +1 -0
- package/lib/utils/set-files-in-sdl.d.ts +2 -2
- package/lib/utils/set-files-in-sdl.d.ts.map +1 -1
- package/lib/utils/set-files-in-sdl.js +12 -12
- package/lib/utils/set-files-in-sdl.js.map +1 -1
- package/package.json +14 -12
- package/src/actions/configure.ts +3 -3
- package/src/actions/lint.ts +20 -17
- package/src/actions/merge.ts +70 -39
- package/src/actions/stitch.ts +32 -15
- package/src/actions/transpile.ts +9 -4
- package/src/actions/validate.ts +4 -4
- package/src/utils/copy-workspace-content.ts +4 -4
- package/src/utils/merge-helpers.ts +23 -19
- package/src/utils/rmtemp.ts +48 -0
- package/src/utils/set-files-in-sdl.ts +16 -13
package/src/actions/stitch.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {clone, cloneDeep} from 'lodash'
|
|
2
2
|
import {parse, print, visit} from 'graphql'
|
|
3
|
-
import * as
|
|
3
|
+
import * as fsx from 'fs-extra'
|
|
4
4
|
import * as glob from 'glob'
|
|
5
5
|
import * as os from 'os'
|
|
6
6
|
import * as path from 'path'
|
|
@@ -9,15 +9,13 @@ import * as prettier from 'prettier'
|
|
|
9
9
|
import dedupeQueryAndMutationTypes from '../utils/dedupe-query-and-mutation-types'
|
|
10
10
|
import {ALL_GRAPHQL_FILES} from '../utils/constants'
|
|
11
11
|
import {getAllGraphQLFiles} from '../utils/copy-workspace-content'
|
|
12
|
+
import {rmtemp} from '../utils/rmtemp'
|
|
12
13
|
|
|
13
|
-
|
|
14
|
-
source: string,
|
|
15
|
-
output: string = path.join(os.tmpdir(), `stepzen-tmp-${Date.now()}`),
|
|
16
|
-
) => {
|
|
14
|
+
const doStitch = (source: string, output: string) => {
|
|
17
15
|
// Ensure source and output directories exist
|
|
18
|
-
if (!
|
|
16
|
+
if (!fsx.existsSync(source))
|
|
19
17
|
throw new Error(`Cannot find source directory ${source}`)
|
|
20
|
-
|
|
18
|
+
fsx.ensureDirSync(output, 0o700)
|
|
21
19
|
|
|
22
20
|
// Get a list of files.
|
|
23
21
|
let ast: any
|
|
@@ -26,8 +24,8 @@ export default (
|
|
|
26
24
|
// If there's an index.graphQL - get files argument in @sdl directive
|
|
27
25
|
const sourceIndex = path.join(source, 'index.graphql')
|
|
28
26
|
|
|
29
|
-
if (
|
|
30
|
-
const index =
|
|
27
|
+
if (fsx.existsSync(sourceIndex)) {
|
|
28
|
+
const index = fsx.readFileSync(sourceIndex, 'utf8')
|
|
31
29
|
ast = parse(index)
|
|
32
30
|
ast = visit(ast, {
|
|
33
31
|
Directive(node) {
|
|
@@ -58,7 +56,7 @@ export default (
|
|
|
58
56
|
const content = glob
|
|
59
57
|
.sync('**/*.graphql', {cwd: source})
|
|
60
58
|
.map((file: string) => {
|
|
61
|
-
const graphql =
|
|
59
|
+
const graphql = fsx.readFileSync(`${source}/${file}`, 'utf8')
|
|
62
60
|
return graphql
|
|
63
61
|
})
|
|
64
62
|
ast = parse(content.join(os.EOL))
|
|
@@ -74,7 +72,7 @@ export default (
|
|
|
74
72
|
// Check all the files exist
|
|
75
73
|
for (const file of files) {
|
|
76
74
|
const find = path.join(source, file)
|
|
77
|
-
if (!
|
|
75
|
+
if (!fsx.existsSync(find)) {
|
|
78
76
|
throw new Error(
|
|
79
77
|
`Cannot find file ${file} referenced in the @sdl directive in index.graphql`,
|
|
80
78
|
)
|
|
@@ -86,7 +84,7 @@ export default (
|
|
|
86
84
|
let stitched = `${printed}${os.EOL}`
|
|
87
85
|
for (const file of files) {
|
|
88
86
|
const find = path.join(source, file)
|
|
89
|
-
const content =
|
|
87
|
+
const content = fsx.readFileSync(find, 'utf8')
|
|
90
88
|
stitched += `${content}${os.EOL}`
|
|
91
89
|
}
|
|
92
90
|
|
|
@@ -98,16 +96,35 @@ export default (
|
|
|
98
96
|
|
|
99
97
|
// Write to output folder
|
|
100
98
|
const outputIndex = path.join(output, 'index.graphql')
|
|
101
|
-
|
|
99
|
+
fsx.writeFileSync(outputIndex, stitched)
|
|
102
100
|
|
|
103
101
|
// Copy config if exists, too
|
|
104
102
|
const sourceConfig = path.join(source, 'config.yaml')
|
|
105
103
|
const outputConfig = path.join(output, 'config.yaml')
|
|
106
104
|
|
|
107
|
-
if (
|
|
108
|
-
|
|
105
|
+
if (fsx.existsSync(sourceConfig)) {
|
|
106
|
+
fsx.copyFileSync(sourceConfig, outputConfig)
|
|
109
107
|
}
|
|
110
108
|
|
|
111
109
|
// Return output folder
|
|
112
110
|
return output
|
|
113
111
|
}
|
|
112
|
+
|
|
113
|
+
const stitch = (source: string, output?: string) => {
|
|
114
|
+
if (output) {
|
|
115
|
+
return doStitch(source, output)
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
output = path.join(os.tmpdir(), `stepzen-tmp-${Date.now()}`)
|
|
119
|
+
try {
|
|
120
|
+
return doStitch(source, output)
|
|
121
|
+
} catch (error) {
|
|
122
|
+
// In case of an error delete the temp output folder created earlier so that
|
|
123
|
+
// it does not "leak". In case of a success, deleting the output folder is
|
|
124
|
+
// the caller responsibility.
|
|
125
|
+
rmtemp(output)
|
|
126
|
+
throw error
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
export default stitch
|
package/src/actions/transpile.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {parse} from 'graphql'
|
|
2
2
|
import * as dotenv from 'dotenv'
|
|
3
3
|
import * as debug from 'debug'
|
|
4
4
|
import * as fs from 'fs'
|
|
@@ -10,6 +10,7 @@ import stitch from '../actions/stitch'
|
|
|
10
10
|
import configure from './configure'
|
|
11
11
|
|
|
12
12
|
import configMutations from '../mutations/config'
|
|
13
|
+
import {rmtemp} from '../utils/rmtemp'
|
|
13
14
|
|
|
14
15
|
/**
|
|
15
16
|
* Read a StepZen workspace directory, apply StepZen-specific schema and config
|
|
@@ -61,9 +62,13 @@ export default async (source: string) => {
|
|
|
61
62
|
|
|
62
63
|
if (graphqlFiles.length > 0) {
|
|
63
64
|
const stitched = await stitch(source)
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
65
|
+
try {
|
|
66
|
+
const index = path.join(stitched, 'index.graphql')
|
|
67
|
+
const graphql = fs.readFileSync(index, 'utf8')
|
|
68
|
+
schema = print(parse(graphql))
|
|
69
|
+
} finally {
|
|
70
|
+
rmtemp(stitched)
|
|
71
|
+
}
|
|
67
72
|
}
|
|
68
73
|
|
|
69
74
|
return {
|
package/src/actions/validate.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import {buildASTSchema, DocumentNode, parse, print} from 'graphql'
|
|
2
|
-
import * as
|
|
2
|
+
import * as fsx from 'fs-extra'
|
|
3
3
|
import * as os from 'os'
|
|
4
4
|
import * as path from 'path'
|
|
5
5
|
|
|
@@ -16,18 +16,18 @@ export default (
|
|
|
16
16
|
},
|
|
17
17
|
) => {
|
|
18
18
|
// Ensure source and output directories exist
|
|
19
|
-
if (!
|
|
19
|
+
if (!fsx.existsSync(source)) {
|
|
20
20
|
throw new Error(`Cannot find source directory ${source}`)
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
// Ensure index.graphql exists
|
|
24
|
-
if (!
|
|
24
|
+
if (!fsx.existsSync(`${source}/index.graphql`)) {
|
|
25
25
|
throw new Error(`Cannot find index.graphql in ${source}`)
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
// Get the index.graphql file
|
|
29
29
|
const file = path.join(source, 'index.graphql')
|
|
30
|
-
const index =
|
|
30
|
+
const index = fsx.readFileSync(file, 'utf8')
|
|
31
31
|
|
|
32
32
|
// Parse
|
|
33
33
|
let ast: DocumentNode = parse(
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as fsx from 'fs-extra'
|
|
2
2
|
import * as glob from 'glob'
|
|
3
3
|
import * as path from 'path'
|
|
4
4
|
import {flatMap} from 'lodash'
|
|
@@ -24,7 +24,7 @@ const IGNORED_PATTERNS = ['node_modules/**']
|
|
|
24
24
|
* Exclude special folders, e.g. node_modules
|
|
25
25
|
*/
|
|
26
26
|
export default (srcPath: string, dstPath: string) => {
|
|
27
|
-
if (!
|
|
27
|
+
if (!fsx.existsSync(srcPath)) {
|
|
28
28
|
throw new Error(`Cannot find source directory ${srcPath}`)
|
|
29
29
|
}
|
|
30
30
|
|
|
@@ -36,8 +36,8 @@ export default (srcPath: string, dstPath: string) => {
|
|
|
36
36
|
).forEach(relativePath => {
|
|
37
37
|
const srcFileFullPath = path.join(srcPath, relativePath)
|
|
38
38
|
const dstFileFullPath = path.join(dstPath, relativePath)
|
|
39
|
-
|
|
40
|
-
|
|
39
|
+
fsx.ensureDirSync(path.dirname(dstFileFullPath))
|
|
40
|
+
fsx.copyFileSync(srcFileFullPath, dstFileFullPath)
|
|
41
41
|
})
|
|
42
42
|
}
|
|
43
43
|
|
|
@@ -2,7 +2,7 @@ import * as debug from 'debug'
|
|
|
2
2
|
import {BREAK, GraphQLSchema, visit} from 'graphql'
|
|
3
3
|
import {buildSchema} from 'graphql/utilities'
|
|
4
4
|
import fetch from '@stepzen/fetch'
|
|
5
|
-
import * as
|
|
5
|
+
import * as fsx from 'fs-extra'
|
|
6
6
|
import * as glob from 'glob'
|
|
7
7
|
import * as os from 'os'
|
|
8
8
|
import * as path from 'path'
|
|
@@ -13,6 +13,7 @@ import {STEPZEN_SERVER_URL} from './constants'
|
|
|
13
13
|
|
|
14
14
|
import configure from '../actions/configure'
|
|
15
15
|
import transpile from '../actions/transpile'
|
|
16
|
+
import {rmtemp} from './rmtemp'
|
|
16
17
|
|
|
17
18
|
export const dedupeTempFolder = (dirpath: string) => {
|
|
18
19
|
do {
|
|
@@ -27,7 +28,7 @@ export const dedupeTempFolder = (dirpath: string) => {
|
|
|
27
28
|
export const findNextAvailableSubfolder = (folder: string, name: string) => {
|
|
28
29
|
let subfolder = name
|
|
29
30
|
let counter = 1
|
|
30
|
-
while (
|
|
31
|
+
while (fsx.existsSync(path.join(folder, subfolder))) {
|
|
31
32
|
const suffix = `${counter++}`.padStart(2, '0')
|
|
32
33
|
subfolder = `${name}-${suffix}`
|
|
33
34
|
}
|
|
@@ -76,30 +77,33 @@ export const getConfiguration = async (
|
|
|
76
77
|
answers: any = {},
|
|
77
78
|
): Promise<string | boolean> => {
|
|
78
79
|
const tmp = path.join(os.tmpdir(), `stepzen-tmp-config-${Date.now()}`)
|
|
79
|
-
|
|
80
|
+
fsx.ensureDirSync(tmp)
|
|
80
81
|
|
|
81
|
-
|
|
82
|
-
const
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
82
|
+
try {
|
|
83
|
+
for (const directory of directories) {
|
|
84
|
+
const configs = [
|
|
85
|
+
...glob.sync('**/config.yaml', {cwd: directory}),
|
|
86
|
+
...glob.sync('**/stepzen.config.json', {cwd: directory}),
|
|
87
|
+
]
|
|
86
88
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
+
for (const config of configs) {
|
|
90
|
+
const configFolder = path.join(directory, config)
|
|
89
91
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
+
let writeFolder = path.join(tmp, directory, config)
|
|
93
|
+
writeFolder = dedupeTempFolder(writeFolder)
|
|
92
94
|
|
|
93
|
-
|
|
95
|
+
const content = fsx.readFileSync(configFolder, 'utf8')
|
|
94
96
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
+
fsx.ensureFileSync(writeFolder)
|
|
98
|
+
fsx.writeFileSync(writeFolder, content, {mode: 0o600})
|
|
99
|
+
}
|
|
97
100
|
}
|
|
98
|
-
}
|
|
99
101
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
102
|
+
const configuration = await configure(tmp, silent, answers)
|
|
103
|
+
return configuration
|
|
104
|
+
} finally {
|
|
105
|
+
rmtemp(tmp)
|
|
106
|
+
}
|
|
103
107
|
}
|
|
104
108
|
|
|
105
109
|
export const getExtensions = async (): Promise<string> => {
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
// Copyright (c) 2020,2021,2022,2023, StepZen, Inc.
|
|
2
|
+
|
|
3
|
+
import * as fs from 'fs'
|
|
4
|
+
import * as path from 'path'
|
|
5
|
+
import * as os from 'os'
|
|
6
|
+
import * as debug from 'debug'
|
|
7
|
+
|
|
8
|
+
// ----------------------------------------------------------------------------
|
|
9
|
+
// THIS ENTIRE FILE IS COPIED FROM packages/cli/src/shared/rmtemp.ts
|
|
10
|
+
// (because there is no effective way to share util classes between packages yet)
|
|
11
|
+
// ----------------------------------------------------------------------------
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Verify that the given path is indeed inside the tmp folder,
|
|
15
|
+
* and delete it recursively suppressing any errors.
|
|
16
|
+
*
|
|
17
|
+
* If the given path is not inside the tmp folder, do nothing.
|
|
18
|
+
*
|
|
19
|
+
* @param {*} fileOrDirPath path to a temp file or folder to delete
|
|
20
|
+
*/
|
|
21
|
+
export const rmtemp = (fileOrDirPath?: string) => {
|
|
22
|
+
if (!fileOrDirPath) {
|
|
23
|
+
return
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// https://stackoverflow.com/a/45242825
|
|
27
|
+
const relative = path.relative(os.tmpdir(), fileOrDirPath)
|
|
28
|
+
const isInTemp =
|
|
29
|
+
relative && !relative.startsWith('..') && !path.isAbsolute(relative)
|
|
30
|
+
|
|
31
|
+
if (isInTemp) {
|
|
32
|
+
try {
|
|
33
|
+
fs.rmSync(fileOrDirPath, {recursive: true, force: true})
|
|
34
|
+
} catch (error) {
|
|
35
|
+
// ignore errors
|
|
36
|
+
debug('stepzen:rmtemp')(
|
|
37
|
+
`WARN: caught an exception while deleting ${fileOrDirPath}: `,
|
|
38
|
+
error,
|
|
39
|
+
)
|
|
40
|
+
}
|
|
41
|
+
} else {
|
|
42
|
+
debug('stepzen:rmtemp')(
|
|
43
|
+
`WARN: got a temp path ${fileOrDirPath} out of the TMP folder -- ignoring`,
|
|
44
|
+
)
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export default rmtemp
|
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import * as fs from 'fs'
|
|
2
2
|
import * as glob from 'glob'
|
|
3
3
|
import {
|
|
4
|
+
ConstDirectiveNode,
|
|
4
5
|
DirectiveNode,
|
|
6
|
+
Kind,
|
|
5
7
|
ListValueNode,
|
|
6
8
|
parse,
|
|
7
9
|
SchemaDefinitionNode,
|
|
8
10
|
StringValueNode,
|
|
11
|
+
OperationTypeNode,
|
|
9
12
|
visit,
|
|
10
13
|
} from 'graphql'
|
|
11
14
|
import * as path from 'path'
|
|
@@ -23,28 +26,28 @@ export const createOrUpdateSdlDirective = (
|
|
|
23
26
|
allGraphQLFiles: readonly string[],
|
|
24
27
|
origSdlDirective?: DeepWriteable<DirectiveNode>,
|
|
25
28
|
) => {
|
|
26
|
-
let sdlDirective: DeepWriteable<
|
|
29
|
+
let sdlDirective: DeepWriteable<ConstDirectiveNode>
|
|
27
30
|
if (origSdlDirective) {
|
|
28
31
|
sdlDirective = cloneDeep(origSdlDirective)
|
|
29
32
|
} else {
|
|
30
33
|
sdlDirective = {
|
|
31
|
-
kind:
|
|
34
|
+
kind: Kind.DIRECTIVE,
|
|
32
35
|
name: {
|
|
33
|
-
kind:
|
|
36
|
+
kind: Kind.NAME,
|
|
34
37
|
value: 'sdl',
|
|
35
38
|
},
|
|
36
39
|
arguments: [
|
|
37
40
|
{
|
|
38
|
-
kind:
|
|
41
|
+
kind: Kind.ARGUMENT,
|
|
39
42
|
name: {
|
|
40
|
-
kind:
|
|
43
|
+
kind: Kind.NAME,
|
|
41
44
|
value: 'files',
|
|
42
45
|
},
|
|
43
46
|
value: {
|
|
44
|
-
kind:
|
|
47
|
+
kind: Kind.LIST,
|
|
45
48
|
values: [
|
|
46
49
|
{
|
|
47
|
-
kind:
|
|
50
|
+
kind: Kind.STRING,
|
|
48
51
|
value: ALL_GRAPHQL_FILES,
|
|
49
52
|
},
|
|
50
53
|
],
|
|
@@ -72,7 +75,7 @@ export const createOrUpdateSdlDirective = (
|
|
|
72
75
|
allGraphQLFiles.forEach(file => fileset.add(normalizePathSep(file)))
|
|
73
76
|
}
|
|
74
77
|
filesValueNodes.values = [...fileset].map(file => ({
|
|
75
|
-
kind:
|
|
78
|
+
kind: Kind.STRING,
|
|
76
79
|
value: file,
|
|
77
80
|
}))
|
|
78
81
|
}
|
|
@@ -87,18 +90,18 @@ export const createSchemaElement = (
|
|
|
87
90
|
allGraphQLFiles: readonly string[],
|
|
88
91
|
) => {
|
|
89
92
|
const schemaElement: DeepWriteable<SchemaDefinitionNode> = {
|
|
90
|
-
kind:
|
|
93
|
+
kind: Kind.SCHEMA_DEFINITION,
|
|
91
94
|
directives: [
|
|
92
95
|
createOrUpdateSdlDirective(importedGraphQLFiles, allGraphQLFiles),
|
|
93
96
|
],
|
|
94
97
|
operationTypes: [
|
|
95
98
|
{
|
|
96
|
-
kind:
|
|
97
|
-
operation:
|
|
99
|
+
kind: Kind.OPERATION_TYPE_DEFINITION,
|
|
100
|
+
operation: OperationTypeNode.QUERY,
|
|
98
101
|
type: {
|
|
99
|
-
kind:
|
|
102
|
+
kind: Kind.NAMED_TYPE,
|
|
100
103
|
name: {
|
|
101
|
-
kind:
|
|
104
|
+
kind: Kind.NAME,
|
|
102
105
|
value: 'Query',
|
|
103
106
|
},
|
|
104
107
|
},
|