@pikku/core 0.12.100 → 0.12.101
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/CHANGELOG.md +24 -0
- package/dist/services/http-personas.d.ts +36 -6
- package/dist/services/http-personas.js +128 -9
- package/dist/services/persona-sign-in.d.ts +0 -10
- package/dist/services/persona-sign-in.js +11 -9
- package/dist/wirings/cli/cli-runner.js +2 -11
- package/dist/wirings/cli/format-cli-error.d.ts +24 -0
- package/dist/wirings/cli/format-cli-error.js +68 -0
- package/dist/wirings/virtual-user/virtual-user-scaffold.d.ts +0 -1
- package/dist/wirings/virtual-user/virtual-user-scaffold.js +0 -4
- package/package.json +1 -1
- package/src/services/http-personas-converse.test.ts +29 -20
- package/src/services/http-personas.test.ts +66 -0
- package/src/services/http-personas.ts +138 -9
- package/src/services/persona-sign-in.test.ts +22 -28
- package/src/services/persona-sign-in.ts +11 -19
- package/src/wirings/cli/cli-runner.test.ts +104 -0
- package/src/wirings/cli/cli-runner.ts +2 -11
- package/src/wirings/cli/format-cli-error.test.ts +91 -0
- package/src/wirings/cli/format-cli-error.ts +96 -0
- package/src/wirings/virtual-user/virtual-user-scaffold.ts +0 -5
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { isExpectedError } from '../../errors/error-handler.js'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* A `PikkuFetchError` — recognised by shape, not by `instanceof`, because
|
|
5
|
+
* `@pikku/client-fetch` depends on core and core cannot depend back on it.
|
|
6
|
+
*/
|
|
7
|
+
type FetchFailure = {
|
|
8
|
+
status: number
|
|
9
|
+
statusText: string
|
|
10
|
+
response: { url?: string }
|
|
11
|
+
message?: string
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const isFetchFailure = (error: unknown): error is FetchFailure => {
|
|
15
|
+
const candidate = error as Partial<FetchFailure> | null
|
|
16
|
+
return (
|
|
17
|
+
typeof candidate?.status === 'number' &&
|
|
18
|
+
typeof candidate?.statusText === 'string' &&
|
|
19
|
+
typeof candidate?.response === 'object' &&
|
|
20
|
+
candidate.response !== null
|
|
21
|
+
)
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* The user asked to see the machinery. `--verbose`/`-v` is the flag the CLI
|
|
26
|
+
* already documents; `PIKKU_DEBUG` is for the times the flag cannot be typed —
|
|
27
|
+
* a command that does not declare the option, or a CLI run from a script.
|
|
28
|
+
*/
|
|
29
|
+
export const wantsStackTrace = (
|
|
30
|
+
args: string[],
|
|
31
|
+
env: Record<string, string | undefined> = process.env
|
|
32
|
+
): boolean =>
|
|
33
|
+
args.includes('--verbose') ||
|
|
34
|
+
args.includes('-v') ||
|
|
35
|
+
(env.PIKKU_DEBUG !== undefined &&
|
|
36
|
+
env.PIKKU_DEBUG !== '' &&
|
|
37
|
+
env.PIKKU_DEBUG !== '0')
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* What the CLI prints when a command throws.
|
|
41
|
+
*
|
|
42
|
+
* A stack trace is an answer to "which line of pikku broke", and almost every
|
|
43
|
+
* failure a user actually hits is not that question: a missing role, an expired
|
|
44
|
+
* token, a gateway that is down. Those errors are written to be read, so the
|
|
45
|
+
* message alone is the whole output — an expected error is one deliberately
|
|
46
|
+
* raised as `PikkuError` (or carrying `expected: true`), and everything else
|
|
47
|
+
* keeps its stack, because an unexpected `TypeError` with its frames removed is
|
|
48
|
+
* a bug nobody can diagnose.
|
|
49
|
+
*
|
|
50
|
+
* A stack already begins with `Name: message`, so it is returned as-is: the
|
|
51
|
+
* `console.error('Error:', error)` this replaced produced the doubled
|
|
52
|
+
* `Error: Error: …` prefix that made even real traces look broken.
|
|
53
|
+
*/
|
|
54
|
+
export const formatCLIError = (
|
|
55
|
+
error: unknown,
|
|
56
|
+
{ verbose = false }: { verbose?: boolean } = {}
|
|
57
|
+
): string => {
|
|
58
|
+
if (isFetchFailure(error)) {
|
|
59
|
+
return formatFetchFailure(error, verbose)
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const stack = (error as { stack?: unknown } | null)?.stack
|
|
63
|
+
const message = (error as { message?: unknown } | null)?.message
|
|
64
|
+
|
|
65
|
+
if (!isExpectedError(error)) {
|
|
66
|
+
return typeof stack === 'string' && stack ? stack : String(error)
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const text = typeof message === 'string' && message ? message : String(error)
|
|
70
|
+
return verbose && typeof stack === 'string' && stack
|
|
71
|
+
? `${text}\n${stack}`
|
|
72
|
+
: text
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* A failed HTTP call, as the line the user needs: which status, from which URL.
|
|
77
|
+
*
|
|
78
|
+
* Never the `Response` itself. Node inspects an error's own properties when it
|
|
79
|
+
* prints one, so a thrown fetch error used to dump the headers, the body stream
|
|
80
|
+
* and the redirect flags — pages of output whose only real content was the
|
|
81
|
+
* status code.
|
|
82
|
+
*/
|
|
83
|
+
const formatFetchFailure = (error: FetchFailure, verbose: boolean): string => {
|
|
84
|
+
const url = error.response?.url
|
|
85
|
+
const where = url ? ` from ${url}` : ''
|
|
86
|
+
const summary = `${error.status} ${error.statusText}${where}`
|
|
87
|
+
const message = error.message
|
|
88
|
+
const text =
|
|
89
|
+
message && message !== error.statusText
|
|
90
|
+
? `${message}\n ${summary}`
|
|
91
|
+
: summary
|
|
92
|
+
const stack = (error as { stack?: unknown }).stack
|
|
93
|
+
return verbose && typeof stack === 'string' && stack
|
|
94
|
+
? `${text}\n${stack}`
|
|
95
|
+
: text
|
|
96
|
+
}
|
|
@@ -77,7 +77,6 @@ export const VIRTUAL_USER_VARIABLES = {
|
|
|
77
77
|
* fallback for a run nobody handed a token to, which is what a schedule is.
|
|
78
78
|
*/
|
|
79
79
|
operatorToken: 'FABRIC_OPERATOR_TOKEN',
|
|
80
|
-
createMissing: 'PIKKU_PERSONA_CREATE_MISSING',
|
|
81
80
|
} as const
|
|
82
81
|
|
|
83
82
|
/**
|
|
@@ -560,9 +559,6 @@ export const executeVirtualUserRun = async ({
|
|
|
560
559
|
)
|
|
561
560
|
}
|
|
562
561
|
|
|
563
|
-
const createMissing =
|
|
564
|
-
String(await variables.get(VIRTUAL_USER_VARIABLES.createMissing)) ===
|
|
565
|
-
'true'
|
|
566
562
|
const model = await variables.get(VIRTUAL_USER_VARIABLES.model)
|
|
567
563
|
if (!model) {
|
|
568
564
|
throw new Error(
|
|
@@ -606,7 +602,6 @@ export const executeVirtualUserRun = async ({
|
|
|
606
602
|
? {
|
|
607
603
|
operator: {
|
|
608
604
|
token,
|
|
609
|
-
createMissing,
|
|
610
605
|
signInPath: signInPathFor(configuredSignInPath, 'fabric'),
|
|
611
606
|
},
|
|
612
607
|
}
|