@wyxos/zephyr 0.3.3 → 0.4.0
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/README.md +71 -0
- package/bin/zephyr.mjs +15 -23
- package/package.json +1 -1
- package/src/application/configuration/select-deployment-target.mjs +94 -9
- package/src/application/deploy/build-remote-deployment-plan.mjs +134 -3
- package/src/application/deploy/execute-remote-deployment-plan.mjs +2 -2
- package/src/application/deploy/resolve-pending-snapshot.mjs +21 -1
- package/src/application/deploy/run-deployment.mjs +36 -7
- package/src/application/release/release-node-package.mjs +64 -17
- package/src/application/release/release-packagist-package.mjs +54 -19
- package/src/cli/options.mjs +122 -0
- package/src/config/project.mjs +32 -1
- package/src/config/servers.mjs +32 -2
- package/src/dependency-scanner.mjs +11 -1
- package/src/deploy/locks.mjs +40 -24
- package/src/main.mjs +199 -71
- package/src/project/bootstrap.mjs +10 -1
- package/src/release/shared.mjs +15 -5
- package/src/release-node.mjs +27 -17
- package/src/release-packagist.mjs +26 -15
- package/src/runtime/app-context.mjs +33 -6
- package/src/runtime/errors.mjs +46 -0
- package/src/runtime/local-command.mjs +12 -3
- package/src/runtime/prompt.mjs +40 -2
- package/src/utils/output.mjs +45 -0
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
export class ZephyrError extends Error {
|
|
2
|
+
constructor(message, {
|
|
3
|
+
code = 'ZEPHYR_FAILURE',
|
|
4
|
+
data = {},
|
|
5
|
+
cause
|
|
6
|
+
} = {}) {
|
|
7
|
+
super(message, cause ? {cause} : undefined)
|
|
8
|
+
this.name = this.constructor.name
|
|
9
|
+
this.code = code
|
|
10
|
+
this.data = data
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export class PromptRequiredError extends ZephyrError {
|
|
15
|
+
constructor(message, {
|
|
16
|
+
data = {},
|
|
17
|
+
cause
|
|
18
|
+
} = {}) {
|
|
19
|
+
super(message, {
|
|
20
|
+
code: 'ZEPHYR_PROMPT_REQUIRED',
|
|
21
|
+
data,
|
|
22
|
+
cause
|
|
23
|
+
})
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export class InvalidCliOptionsError extends ZephyrError {
|
|
28
|
+
constructor(message, {
|
|
29
|
+
data = {},
|
|
30
|
+
cause
|
|
31
|
+
} = {}) {
|
|
32
|
+
super(message, {
|
|
33
|
+
code: 'ZEPHYR_INVALID_OPTIONS',
|
|
34
|
+
data,
|
|
35
|
+
cause
|
|
36
|
+
})
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export function getErrorCode(error) {
|
|
41
|
+
if (error && typeof error === 'object' && typeof error.code === 'string' && error.code.length > 0) {
|
|
42
|
+
return error.code
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return 'ZEPHYR_FAILURE'
|
|
46
|
+
}
|
|
@@ -1,10 +1,20 @@
|
|
|
1
|
+
import process from 'node:process'
|
|
2
|
+
|
|
1
3
|
export function createLocalCommandRunners({ runCommandBase, runCommandCaptureBase }) {
|
|
2
4
|
if (!runCommandBase || !runCommandCaptureBase) {
|
|
3
5
|
throw new Error('createLocalCommandRunners requires runCommandBase and runCommandCaptureBase')
|
|
4
6
|
}
|
|
5
7
|
|
|
6
|
-
const runCommand = async (command, args, {
|
|
7
|
-
|
|
8
|
+
const runCommand = async (command, args, {
|
|
9
|
+
silent = false,
|
|
10
|
+
cwd,
|
|
11
|
+
forwardStdoutToStderr = false
|
|
12
|
+
} = {}) => {
|
|
13
|
+
const stdio = silent
|
|
14
|
+
? 'ignore'
|
|
15
|
+
: forwardStdoutToStderr
|
|
16
|
+
? ['ignore', process.stderr, process.stderr]
|
|
17
|
+
: 'inherit'
|
|
8
18
|
return runCommandBase(command, args, { cwd, stdio })
|
|
9
19
|
}
|
|
10
20
|
|
|
@@ -15,4 +25,3 @@ export function createLocalCommandRunners({ runCommandBase, runCommandCaptureBas
|
|
|
15
25
|
|
|
16
26
|
return { runCommand, runCommandCapture }
|
|
17
27
|
}
|
|
18
|
-
|
package/src/runtime/prompt.mjs
CHANGED
|
@@ -1,9 +1,48 @@
|
|
|
1
|
-
|
|
1
|
+
import {PromptRequiredError} from './errors.mjs'
|
|
2
|
+
|
|
3
|
+
function buildPromptMessage(questions = []) {
|
|
4
|
+
const messages = questions
|
|
5
|
+
.map((question) => question?.message)
|
|
6
|
+
.filter((message) => typeof message === 'string' && message.trim().length > 0)
|
|
7
|
+
|
|
8
|
+
return messages[0] ?? 'Zephyr requires interactive input to continue.'
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function createRunPrompt({
|
|
12
|
+
inquirer,
|
|
13
|
+
interactive = true,
|
|
14
|
+
emitEvent,
|
|
15
|
+
workflow = 'deploy'
|
|
16
|
+
}) {
|
|
2
17
|
if (!inquirer) {
|
|
3
18
|
throw new Error('createRunPrompt requires inquirer')
|
|
4
19
|
}
|
|
5
20
|
|
|
6
21
|
return async function runPrompt(questions) {
|
|
22
|
+
if (!interactive) {
|
|
23
|
+
const message = buildPromptMessage(questions)
|
|
24
|
+
const error = new PromptRequiredError(message, {
|
|
25
|
+
data: {
|
|
26
|
+
workflow,
|
|
27
|
+
questions: Array.isArray(questions)
|
|
28
|
+
? questions.map((question) => ({
|
|
29
|
+
name: question?.name ?? null,
|
|
30
|
+
type: question?.type ?? null,
|
|
31
|
+
message: question?.message ?? null
|
|
32
|
+
}))
|
|
33
|
+
: []
|
|
34
|
+
}
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
emitEvent?.('prompt_required', {
|
|
38
|
+
message,
|
|
39
|
+
code: error.code,
|
|
40
|
+
data: error.data
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
throw error
|
|
44
|
+
}
|
|
45
|
+
|
|
7
46
|
if (typeof globalThis !== 'undefined' && globalThis.__zephyrPrompt) {
|
|
8
47
|
return globalThis.__zephyrPrompt(questions)
|
|
9
48
|
}
|
|
@@ -11,4 +50,3 @@ export function createRunPrompt({ inquirer }) {
|
|
|
11
50
|
return inquirer.prompt(questions)
|
|
12
51
|
}
|
|
13
52
|
}
|
|
14
|
-
|
package/src/utils/output.mjs
CHANGED
|
@@ -25,6 +25,36 @@ export function writeStderr(message = '') {
|
|
|
25
25
|
}
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
+
export function createJsonEventEmitter({
|
|
29
|
+
workflow,
|
|
30
|
+
writeEvent = writeStdoutLine
|
|
31
|
+
} = {}) {
|
|
32
|
+
return function emitEvent(event, {
|
|
33
|
+
level,
|
|
34
|
+
message = '',
|
|
35
|
+
data = {},
|
|
36
|
+
code
|
|
37
|
+
} = {}) {
|
|
38
|
+
const payload = {
|
|
39
|
+
event,
|
|
40
|
+
timestamp: new Date().toISOString(),
|
|
41
|
+
workflow,
|
|
42
|
+
message
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if (level) {
|
|
46
|
+
payload.level = level
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (code) {
|
|
50
|
+
payload.code = code
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
payload.data = data ?? {}
|
|
54
|
+
writeEvent(JSON.stringify(payload))
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
28
58
|
export function formatLogMessage(message = '', prefix = '') {
|
|
29
59
|
const text = message == null ? '' : String(message)
|
|
30
60
|
|
|
@@ -52,3 +82,18 @@ export function createChalkLogger(chalk, {
|
|
|
52
82
|
logError: (message = '') => writeStderrLine(chalk.red(formatLogMessage(message, prefixes.error)))
|
|
53
83
|
}
|
|
54
84
|
}
|
|
85
|
+
|
|
86
|
+
export function createJsonLogger({
|
|
87
|
+
emitEvent
|
|
88
|
+
} = {}) {
|
|
89
|
+
if (typeof emitEvent !== 'function') {
|
|
90
|
+
throw new Error('createJsonLogger requires emitEvent')
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
return {
|
|
94
|
+
logProcessing: (message = '', data = {}) => emitEvent('log', {level: 'processing', message: String(message ?? ''), data}),
|
|
95
|
+
logSuccess: (message = '', data = {}) => emitEvent('log', {level: 'success', message: String(message ?? ''), data}),
|
|
96
|
+
logWarning: (message = '', data = {}) => emitEvent('log', {level: 'warning', message: String(message ?? ''), data}),
|
|
97
|
+
logError: (message = '', data = {}) => emitEvent('log', {level: 'error', message: String(message ?? ''), data})
|
|
98
|
+
}
|
|
99
|
+
}
|