@stepzen/sdk 0.0.0-experimental-20221114-610843f6
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 +21 -0
- package/README.md +30 -0
- package/lib/client-v2.d.ts +50 -0
- package/lib/client-v2.d.ts.map +1 -0
- package/lib/client-v2.js +91 -0
- package/lib/client-v2.js.map +1 -0
- package/lib/client.d.ts +33 -0
- package/lib/client.d.ts.map +1 -0
- package/lib/client.js +95 -0
- package/lib/client.js.map +1 -0
- package/lib/commands/account.d.ts +10 -0
- package/lib/commands/account.d.ts.map +1 -0
- package/lib/commands/account.js +39 -0
- package/lib/commands/account.js.map +1 -0
- package/lib/commands/authenticate.d.ts +4 -0
- package/lib/commands/authenticate.d.ts.map +1 -0
- package/lib/commands/authenticate.js +25 -0
- package/lib/commands/authenticate.js.map +1 -0
- package/lib/commands/deploy.d.ts +4 -0
- package/lib/commands/deploy.d.ts.map +1 -0
- package/lib/commands/deploy.js +46 -0
- package/lib/commands/deploy.js.map +1 -0
- package/lib/commands/getPublicAccount.d.ts +7 -0
- package/lib/commands/getPublicAccount.d.ts.map +1 -0
- package/lib/commands/getPublicAccount.js +59 -0
- package/lib/commands/getPublicAccount.js.map +1 -0
- package/lib/commands/list.d.ts +4 -0
- package/lib/commands/list.d.ts.map +1 -0
- package/lib/commands/list.js +29 -0
- package/lib/commands/list.js.map +1 -0
- package/lib/commands/upload.d.ts +4 -0
- package/lib/commands/upload.d.ts.map +1 -0
- package/lib/commands/upload.js +64 -0
- package/lib/commands/upload.js.map +1 -0
- package/lib/commands-v2/account.d.ts +9 -0
- package/lib/commands-v2/account.d.ts.map +1 -0
- package/lib/commands-v2/account.js +68 -0
- package/lib/commands-v2/account.js.map +1 -0
- package/lib/commands-v2/deploy.d.ts +15 -0
- package/lib/commands-v2/deploy.d.ts.map +1 -0
- package/lib/commands-v2/deploy.js +90 -0
- package/lib/commands-v2/deploy.js.map +1 -0
- package/lib/commands-v2/getPublicAccount.d.ts +8 -0
- package/lib/commands-v2/getPublicAccount.d.ts.map +1 -0
- package/lib/commands-v2/getPublicAccount.js +46 -0
- package/lib/commands-v2/getPublicAccount.js.map +1 -0
- package/lib/commands-v2/list.d.ts +12 -0
- package/lib/commands-v2/list.d.ts.map +1 -0
- package/lib/commands-v2/list.js +58 -0
- package/lib/commands-v2/list.js.map +1 -0
- package/lib/index.d.ts +12 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +26 -0
- package/lib/index.js.map +1 -0
- package/lib/init-v2.d.ts +33 -0
- package/lib/init-v2.d.ts.map +1 -0
- package/lib/init-v2.js +33 -0
- package/lib/init-v2.js.map +1 -0
- package/lib/init.d.ts +33 -0
- package/lib/init.d.ts.map +1 -0
- package/lib/init.js +31 -0
- package/lib/init.js.map +1 -0
- package/lib/shared/constants.d.ts +7 -0
- package/lib/shared/constants.d.ts.map +1 -0
- package/lib/shared/constants.js +11 -0
- package/lib/shared/constants.js.map +1 -0
- package/lib/shared/graphql-client.d.ts +38 -0
- package/lib/shared/graphql-client.d.ts.map +1 -0
- package/lib/shared/graphql-client.js +80 -0
- package/lib/shared/graphql-client.js.map +1 -0
- package/lib/shared/payloads.d.ts +10 -0
- package/lib/shared/payloads.d.ts.map +1 -0
- package/lib/shared/payloads.js +123 -0
- package/lib/shared/payloads.js.map +1 -0
- package/lib/shared/request.d.ts +4 -0
- package/lib/shared/request.d.ts.map +1 -0
- package/lib/shared/request.js +25 -0
- package/lib/shared/request.js.map +1 -0
- package/lib/shared/transpiling.d.ts +15 -0
- package/lib/shared/transpiling.d.ts.map +1 -0
- package/lib/shared/transpiling.js +29 -0
- package/lib/shared/transpiling.js.map +1 -0
- package/lib/shared/types.d.ts +194 -0
- package/lib/shared/types.d.ts.map +1 -0
- package/lib/shared/types.js +4 -0
- package/lib/shared/types.js.map +1 -0
- package/lib/shared/validation.d.ts +3 -0
- package/lib/shared/validation.d.ts.map +1 -0
- package/lib/shared/validation.js +47 -0
- package/lib/shared/validation.js.map +1 -0
- package/package.json +52 -0
- package/src/client-v2.ts +120 -0
- package/src/client.ts +133 -0
- package/src/commands/account.ts +54 -0
- package/src/commands/authenticate.ts +30 -0
- package/src/commands/deploy.ts +72 -0
- package/src/commands/getPublicAccount.ts +77 -0
- package/src/commands/list.ts +50 -0
- package/src/commands/upload.ts +91 -0
- package/src/commands-v2/account.ts +98 -0
- package/src/commands-v2/deploy.ts +145 -0
- package/src/commands-v2/getPublicAccount.ts +67 -0
- package/src/commands-v2/list.ts +91 -0
- package/src/index.ts +27 -0
- package/src/init-v2.ts +44 -0
- package/src/init.ts +45 -0
- package/src/shared/constants.ts +9 -0
- package/src/shared/graphql-client.ts +136 -0
- package/src/shared/payloads.ts +153 -0
- package/src/shared/request.ts +28 -0
- package/src/shared/transpiling.ts +49 -0
- package/src/shared/types.ts +235 -0
- package/src/shared/validation.ts +52 -0
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
// Copyright (c) 2020,2021,2022, StepZen, Inc.
|
|
2
|
+
|
|
3
|
+
// This file contains helpers that zip a file or directory
|
|
4
|
+
|
|
5
|
+
import * as archiver from 'archiver'
|
|
6
|
+
import * as debug from 'debug'
|
|
7
|
+
import * as FormData from 'form-data'
|
|
8
|
+
import * as fs from 'fs'
|
|
9
|
+
import * as glob from 'glob'
|
|
10
|
+
import * as os from 'os'
|
|
11
|
+
import * as path from 'path'
|
|
12
|
+
import * as yaml from 'yaml'
|
|
13
|
+
import {transpileConfigurationset} from './transpiling'
|
|
14
|
+
import {validateConfigurationset} from './validation'
|
|
15
|
+
import {Configuration, SchemaFiles} from './types'
|
|
16
|
+
|
|
17
|
+
type YamlPayload = FormData
|
|
18
|
+
type ZipPayload = FormData
|
|
19
|
+
|
|
20
|
+
// This function takes a (yaml) file path
|
|
21
|
+
// and creates a FormData payload, containing the yaml content as 'yaml'
|
|
22
|
+
export const generateYamlPayload = async (
|
|
23
|
+
file: string | undefined,
|
|
24
|
+
): Promise<YamlPayload> => {
|
|
25
|
+
return new Promise((resolve, reject) => {
|
|
26
|
+
const payload = new FormData()
|
|
27
|
+
|
|
28
|
+
if (file) {
|
|
29
|
+
if (!fs.existsSync(file)) {
|
|
30
|
+
reject(new Error(`File does not exist: ${file}`))
|
|
31
|
+
}
|
|
32
|
+
const content = fs.readFileSync(file, 'utf8')
|
|
33
|
+
debug('stepzen:sdk:payload')(`adding YAML payload\n${content}`)
|
|
34
|
+
payload.append('yaml', fs.readFileSync(file))
|
|
35
|
+
resolve(payload)
|
|
36
|
+
} else {
|
|
37
|
+
reject(new Error('File not specified'))
|
|
38
|
+
}
|
|
39
|
+
})
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// This function takes a directory path, and optional data object,
|
|
43
|
+
// and creates a FormData payload, containing the directory contents as 'zip',
|
|
44
|
+
// and any other items in the data object.
|
|
45
|
+
export const generateZipPayload = async (
|
|
46
|
+
directory: string | undefined,
|
|
47
|
+
data: object | undefined,
|
|
48
|
+
filters: RegExp[],
|
|
49
|
+
): Promise<ZipPayload> => {
|
|
50
|
+
return new Promise((resolve, reject) => {
|
|
51
|
+
const payload = new FormData()
|
|
52
|
+
|
|
53
|
+
if (data) {
|
|
54
|
+
for (const [key, value] of Object.entries(data)) {
|
|
55
|
+
payload.append(key, value)
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Store it in /tmp. Create a WriteStream
|
|
60
|
+
const filepath = path.join(os.tmpdir(), `stepzen-payload-${Date.now()}.zip`)
|
|
61
|
+
const output = fs.createWriteStream(filepath)
|
|
62
|
+
|
|
63
|
+
// We're making a zip file
|
|
64
|
+
const archive = archiver('zip', {
|
|
65
|
+
zlib: {level: 9},
|
|
66
|
+
})
|
|
67
|
+
|
|
68
|
+
// We're piping it to the WriteStream
|
|
69
|
+
archive.pipe(output)
|
|
70
|
+
|
|
71
|
+
// If we've specified a directory, add it to the archive
|
|
72
|
+
if (directory) {
|
|
73
|
+
if (!fs.existsSync(directory)) {
|
|
74
|
+
reject(new Error(`Directory does not exist: ${directory}`))
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Get all the files in the directory (and all subdirectories).
|
|
78
|
+
const allFiles = glob.sync('**', {cwd: directory})
|
|
79
|
+
|
|
80
|
+
// Loop through each file, because we want to filter them
|
|
81
|
+
// We add them manually, because when we use glob, it embeds
|
|
82
|
+
// a full path, and we want everything to explicitly
|
|
83
|
+
// start at the root of the archive.
|
|
84
|
+
allFiles.forEach(file => {
|
|
85
|
+
const include = filters.some(filter => file.match(filter))
|
|
86
|
+
|
|
87
|
+
if (include) {
|
|
88
|
+
debug('stepzen:archive')(file)
|
|
89
|
+
archive.file(path.join(directory, file), {name: file})
|
|
90
|
+
}
|
|
91
|
+
})
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// Once we're done, append a ReadStream to the tmp file
|
|
95
|
+
output.on('close', () => {
|
|
96
|
+
const stream = fs.createReadStream(filepath)
|
|
97
|
+
payload.append('zip', stream)
|
|
98
|
+
// Remove the temporary zip
|
|
99
|
+
stream.on('close', () => {
|
|
100
|
+
fs.unlinkSync(filepath)
|
|
101
|
+
})
|
|
102
|
+
// This is where we return the payload
|
|
103
|
+
resolve(payload)
|
|
104
|
+
})
|
|
105
|
+
|
|
106
|
+
// Archive the file or directory
|
|
107
|
+
archive.finalize()
|
|
108
|
+
})
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export const generateSchemaFilesPayload = (
|
|
112
|
+
workspaceFolderPath: string,
|
|
113
|
+
): SchemaFiles => {
|
|
114
|
+
if (!fs.existsSync(workspaceFolderPath)) {
|
|
115
|
+
throw new Error(
|
|
116
|
+
`Failed to read folder ${workspaceFolderPath}. Does it exist?`,
|
|
117
|
+
)
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
const files = glob
|
|
121
|
+
.sync('**/*.graphql', {cwd: workspaceFolderPath})
|
|
122
|
+
.map(file => {
|
|
123
|
+
return {
|
|
124
|
+
name: file,
|
|
125
|
+
content: fs.readFileSync(`${workspaceFolderPath}/${file}`, 'utf8'),
|
|
126
|
+
}
|
|
127
|
+
})
|
|
128
|
+
|
|
129
|
+
if (files.length === 0) {
|
|
130
|
+
throw new Error(
|
|
131
|
+
`Failed to find any .graphql files in ${workspaceFolderPath}`,
|
|
132
|
+
)
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
return {
|
|
136
|
+
files,
|
|
137
|
+
entryPoint: 'index.graphql',
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
export const generateConfigurationPayload = async (
|
|
142
|
+
configFilePath?: string,
|
|
143
|
+
): Promise<Configuration | null> => {
|
|
144
|
+
if (!configFilePath) {
|
|
145
|
+
return null
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
await validateConfigurationset(configFilePath)
|
|
149
|
+
const transpiled = await transpileConfigurationset(configFilePath)
|
|
150
|
+
debug('stepzen:sdk')(`effective config written to ${transpiled}`)
|
|
151
|
+
const content = fs.readFileSync(transpiled, 'utf-8')
|
|
152
|
+
return yaml.parse(content, {schema: 'failsafe'}) || null
|
|
153
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
// Copyright (c) 2020,2021,2022, StepZen, Inc.
|
|
2
|
+
|
|
3
|
+
import * as os from 'os'
|
|
4
|
+
import * as isWsl from 'is-wsl'
|
|
5
|
+
import {SDKConfiguration, StepZenAccount, ZenCtlRequestHeaders} from './types'
|
|
6
|
+
|
|
7
|
+
const {version} = require('../../package.json')
|
|
8
|
+
|
|
9
|
+
// mimics the logic from @oclif/config
|
|
10
|
+
// https://github.com/oclif/core/blob/d7067d13c7d80c9e0064455c27ac1ebb6ee53fd2/src/config/config.ts#L128
|
|
11
|
+
const arch = os.arch() === 'ia32' ? 'x86' : (os.arch() as any)
|
|
12
|
+
const platform = isWsl ? 'wsl' : (os.platform() as any)
|
|
13
|
+
|
|
14
|
+
export const getUserAgent = (sdkConfig: SDKConfiguration): string => {
|
|
15
|
+
return `${sdkConfig.appName} stepzen-sdk/${version} (${platform}; ${arch}; node-${process.version})`
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export const getRequestHeaders = (
|
|
19
|
+
account: StepZenAccount,
|
|
20
|
+
sdkConfig: SDKConfiguration,
|
|
21
|
+
): ZenCtlRequestHeaders => {
|
|
22
|
+
return {
|
|
23
|
+
authorization: `Apikey ${account.adminkey}`,
|
|
24
|
+
host: `${account.account}.${account.domain}`,
|
|
25
|
+
'stepzen-cli-version': version,
|
|
26
|
+
'user-agent': getUserAgent(sdkConfig),
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
// Copyright (c) 2020,2021,2022, StepZen, Inc.
|
|
2
|
+
|
|
3
|
+
import * as dotenv from 'dotenv'
|
|
4
|
+
import * as debug from 'debug'
|
|
5
|
+
import * as fs from 'fs-extra'
|
|
6
|
+
import * as os from 'os'
|
|
7
|
+
import * as path from 'path'
|
|
8
|
+
import {transpile} from '@stepzen/transpiler'
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* @returns `undefined` when called without arguments
|
|
12
|
+
*/
|
|
13
|
+
export async function transpileConfigurationset(): Promise<undefined>
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Strip off any unsupported properties and substitute any STEPZEN_*
|
|
17
|
+
* placeholders with matching environment variables (load a `.env` file
|
|
18
|
+
* if present next to the `config.yaml` file).
|
|
19
|
+
*
|
|
20
|
+
* @param file path to a `config.yaml` file
|
|
21
|
+
* @returns path to a temp copy of `config.yaml` file with all clean-up
|
|
22
|
+
* and substitutions made
|
|
23
|
+
*/
|
|
24
|
+
export async function transpileConfigurationset(file: string): Promise<string>
|
|
25
|
+
|
|
26
|
+
export async function transpileConfigurationset(file?: string) {
|
|
27
|
+
if (!file) {
|
|
28
|
+
return
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const source = file.substring(0, file.lastIndexOf('/'))
|
|
32
|
+
debug('stepzen:dotenv')(
|
|
33
|
+
`loading .env from ${path.resolve(source)}` +
|
|
34
|
+
`, at sdk/src/shared/transpiling.ts`,
|
|
35
|
+
)
|
|
36
|
+
dotenv.config({path: path.resolve(source, '.env')})
|
|
37
|
+
|
|
38
|
+
const tmp = path.join(os.tmpdir(), `stepzen-transpiler-${Date.now()}`)
|
|
39
|
+
const configPath = path.join(tmp, 'config.yaml')
|
|
40
|
+
|
|
41
|
+
fs.ensureDirSync(tmp)
|
|
42
|
+
fs.copyFileSync(file, configPath)
|
|
43
|
+
|
|
44
|
+
const result = await transpile(tmp)
|
|
45
|
+
|
|
46
|
+
fs.emptyDirSync(tmp)
|
|
47
|
+
fs.writeFileSync(configPath, result.config || '')
|
|
48
|
+
return configPath
|
|
49
|
+
}
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
// Copyright (c) 2020,2021,2022, StepZen, Inc.
|
|
2
|
+
|
|
3
|
+
export interface StepZenAccount {
|
|
4
|
+
account: string
|
|
5
|
+
adminkey: string
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* ZenCtl base URL, e.g. `https://fakefish.stepzen.io` for production,
|
|
9
|
+
* or `http://localhost` for local tests.
|
|
10
|
+
*
|
|
11
|
+
* Determined by taking the first option that is defined:
|
|
12
|
+
* - the `server` config property explicily passed into the `init()` function
|
|
13
|
+
* - the `STEPZEN_SERVER_URL` environment variable
|
|
14
|
+
* - the `https://{account}.stepzen.io` default value
|
|
15
|
+
*
|
|
16
|
+
* The `{account}` placeholder (if present) is replaced by the provided account
|
|
17
|
+
* name
|
|
18
|
+
*/
|
|
19
|
+
server: string
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* ZenCtl domain, e.g. `stepzen.io`. This is only relevant for local testing
|
|
23
|
+
* when ZenCtl is running on localhost. In that case an additional `Host` HTTP
|
|
24
|
+
* header is added to requests, using a non-localhost host name constructed
|
|
25
|
+
* from this property.
|
|
26
|
+
*
|
|
27
|
+
* Determined by taking the first option that is defined:
|
|
28
|
+
* - the `domain` config property explicily passed into the `init()` function
|
|
29
|
+
* - the `STEPZEN_DOMAIN` environment variable
|
|
30
|
+
* - the `stepzen.io` default value
|
|
31
|
+
*/
|
|
32
|
+
domain: string
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export type StepZenCredentials = {
|
|
36
|
+
account: string
|
|
37
|
+
adminkey: string
|
|
38
|
+
apikey: string
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export type UserCredentialsClientOptions = Pick<
|
|
42
|
+
StepZenAccount,
|
|
43
|
+
'account' | 'adminkey'
|
|
44
|
+
> &
|
|
45
|
+
Partial<StepZenAccount>
|
|
46
|
+
|
|
47
|
+
export type AnonymousClientOptions = {
|
|
48
|
+
publicAccountToken: string
|
|
49
|
+
server?: StepZenAccount['server']
|
|
50
|
+
domain?: StepZenAccount['domain']
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export interface StepZenDeploy {
|
|
54
|
+
configurationsets?: string[]
|
|
55
|
+
destination: string
|
|
56
|
+
schema: string
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export interface StepZenList {
|
|
60
|
+
type: 'deployments' | 'schemas' | 'configurationsets'
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export interface StepZenUpload {
|
|
64
|
+
destination: string
|
|
65
|
+
directory?: string
|
|
66
|
+
file?: string
|
|
67
|
+
type: string
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export interface ZenCtlRequestHeaders {
|
|
71
|
+
authorization: string
|
|
72
|
+
host: string
|
|
73
|
+
'stepzen-cli-version': string
|
|
74
|
+
'user-agent': string
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export interface ZenCtlResponse {
|
|
78
|
+
errors?: Array<string>
|
|
79
|
+
message?: string
|
|
80
|
+
results?: Array<string>
|
|
81
|
+
success: boolean
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export interface SDKConfiguration {
|
|
85
|
+
/**
|
|
86
|
+
* The name and version of that app that uses the SDK,
|
|
87
|
+
* e.g. `stepzen-cli/0.9.32`
|
|
88
|
+
*
|
|
89
|
+
* It is appended to the user-agent string in all requests made to StepZen
|
|
90
|
+
* through the SDK and becomes availabe in the log analytics.
|
|
91
|
+
*/
|
|
92
|
+
appName: string
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export interface SDKConfigurationV2 extends SDKConfiguration {
|
|
96
|
+
/**
|
|
97
|
+
* The name and version of that app that uses the SDK,
|
|
98
|
+
* e.g. `stepzen-cli/0.9.32`
|
|
99
|
+
*
|
|
100
|
+
* It is appended to the user-agent string in all requests made to StepZen
|
|
101
|
+
* through the SDK and becomes availabe in the log analytics.
|
|
102
|
+
*/
|
|
103
|
+
appName: string
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Version of ZenCtl API to use:
|
|
107
|
+
* - `undefined`, `v1`: implies the v1 REST API at /ctl/admin/
|
|
108
|
+
* - `v2`: implies the v2 GraphQL API
|
|
109
|
+
*/
|
|
110
|
+
apiVersion: string
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* URL of the ZenCtl GraphQL API,
|
|
114
|
+
* e.g. https://stepzen.stepzen.net/api/zenctl2/__graphql
|
|
115
|
+
*/
|
|
116
|
+
zenctlApiUrl: string
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* URL of the StepZen getPublicAccount GraphQL API,
|
|
120
|
+
* e.g. https://stepzen.stepzen.net/api/publicaccount/__graphql
|
|
121
|
+
*/
|
|
122
|
+
publicAccountApiUrl: string
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
export interface ZenCtlSuccessResponseV2<T> {
|
|
126
|
+
data: T
|
|
127
|
+
error: undefined
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
export interface ZenCtlErrorResponseV2 {
|
|
131
|
+
data: undefined
|
|
132
|
+
error: {
|
|
133
|
+
message: string
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
export type ZenCtlResponseV2<T> =
|
|
138
|
+
| ZenCtlSuccessResponseV2<T>
|
|
139
|
+
| ZenCtlErrorResponseV2
|
|
140
|
+
|
|
141
|
+
export interface StepZenCredentialsV2 {
|
|
142
|
+
account: string
|
|
143
|
+
adminKey: string
|
|
144
|
+
apiKeys: string[]
|
|
145
|
+
deploymentType: string
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
export interface StepZenAccountV2 {
|
|
149
|
+
account: string
|
|
150
|
+
ownerEmail: string
|
|
151
|
+
adminKey: string
|
|
152
|
+
apiKeys: string[]
|
|
153
|
+
deploymentType: string
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
export interface StepZenEndpointV2 {
|
|
157
|
+
account: string
|
|
158
|
+
deploymentType: string
|
|
159
|
+
folderName: string
|
|
160
|
+
endpointName: string
|
|
161
|
+
public: boolean
|
|
162
|
+
endpointType: string
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
export interface SchemaFiles {
|
|
166
|
+
files: SchemaFile[]
|
|
167
|
+
entryPoint?: String
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
export interface SchemaFile {
|
|
171
|
+
name: string
|
|
172
|
+
content: string
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
export interface Configuration {
|
|
176
|
+
configurationset?: ConfigurationSet[]
|
|
177
|
+
ruleset?: QueryRule[]
|
|
178
|
+
access?: Policies
|
|
179
|
+
deployment?: DeploymentSettings
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
export interface ConfigurationSet {
|
|
183
|
+
configuration?: Record<string, any>
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
export interface QueryRule {
|
|
187
|
+
query: string
|
|
188
|
+
disabled?: boolean
|
|
189
|
+
rules?: Rule[]
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
export interface Rule {
|
|
193
|
+
predicate: string
|
|
194
|
+
action: string
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
export interface Policies {
|
|
198
|
+
policies?: Policy[]
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
export interface Policy {
|
|
202
|
+
type?: string
|
|
203
|
+
rules?: FieldRule[]
|
|
204
|
+
policyDefault?: FieldCondition
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
export interface FieldRule {
|
|
208
|
+
name?: string
|
|
209
|
+
description?: string
|
|
210
|
+
condition: string
|
|
211
|
+
fields?: string[]
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
export interface FieldCondition {
|
|
215
|
+
condition: string
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
export interface DeploymentSettings {
|
|
219
|
+
identity?: IdentitySettings
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
export interface IdentitySettings {
|
|
223
|
+
keys?: JWTKey[]
|
|
224
|
+
issuer?: string
|
|
225
|
+
subject?: string
|
|
226
|
+
audience?: string
|
|
227
|
+
claims?: string[]
|
|
228
|
+
jwksendpoint?: string
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
export interface JWTKey {
|
|
232
|
+
algorithm?: string
|
|
233
|
+
keyid?: string
|
|
234
|
+
key?: string
|
|
235
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
// Copyright (c) 2020,2021,2022, StepZen, Inc.
|
|
2
|
+
|
|
3
|
+
import * as debug from 'debug'
|
|
4
|
+
import * as fs from 'fs'
|
|
5
|
+
import * as glob from 'glob'
|
|
6
|
+
import * as yaml from 'yaml'
|
|
7
|
+
|
|
8
|
+
// Validate the Configurationset file
|
|
9
|
+
export const validateConfigurationset = async (file: string | undefined) => {
|
|
10
|
+
if (!file) {
|
|
11
|
+
debug('stepzen:sdk')(
|
|
12
|
+
`validateConfigurationset() expected 'file' to be a` +
|
|
13
|
+
` non-empty string but got ${file}`,
|
|
14
|
+
)
|
|
15
|
+
throw new Error('You must provide a file path')
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
if (!fs.existsSync(file)) {
|
|
19
|
+
debug('stepzen:sdk')(`validateConfigurationset() expected ${file} to exist`)
|
|
20
|
+
throw new Error('The file does not exist')
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const content = fs.readFileSync(file, 'utf8')
|
|
24
|
+
|
|
25
|
+
// Ensure the file is valid YAML
|
|
26
|
+
try {
|
|
27
|
+
yaml.parse(content)
|
|
28
|
+
} catch (error) {
|
|
29
|
+
debug('stepzen:sdk')(
|
|
30
|
+
`validateConfigurationset() expected ${file} to parse as YAML,` +
|
|
31
|
+
` but got an error ${error}`,
|
|
32
|
+
)
|
|
33
|
+
throw new Error('The file is not valid YAML')
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Validate the Schema directory
|
|
38
|
+
export const validateSchema = async (directory: string | undefined) => {
|
|
39
|
+
if (!directory) {
|
|
40
|
+
throw new Error('You must provide a directory path')
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (!fs.existsSync(directory)) {
|
|
44
|
+
throw new Error('The directory does not exist')
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Ensure there's a root `index.graphql` file
|
|
48
|
+
const allSchemaFiles = glob.sync('index.graphql', {cwd: directory})
|
|
49
|
+
if (allSchemaFiles.length === 0) {
|
|
50
|
+
throw new Error('Schemas must include an `index.graphql` file')
|
|
51
|
+
}
|
|
52
|
+
}
|