@microsoft/managed-apps-cli 0.6.1 → 0.8.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 +56 -10
- package/dist/ArgumentProvider.d.ts +21 -2
- package/dist/ArgumentProvider.d.ts.map +1 -1
- package/dist/ArgumentProvider.js +47 -3
- package/dist/ArgumentProvider.js.map +1 -1
- package/dist/Authentication/ActiveAccountStore.d.ts +24 -0
- package/dist/Authentication/ActiveAccountStore.d.ts.map +1 -0
- package/dist/Authentication/ActiveAccountStore.js +54 -0
- package/dist/Authentication/ActiveAccountStore.js.map +1 -0
- package/dist/Authentication/NodeMsalAuthenticationProvider.d.ts +57 -3
- package/dist/Authentication/NodeMsalAuthenticationProvider.d.ts.map +1 -1
- package/dist/Authentication/NodeMsalAuthenticationProvider.js +187 -27
- package/dist/Authentication/NodeMsalAuthenticationProvider.js.map +1 -1
- package/dist/Cli.d.ts.map +1 -1
- package/dist/Cli.js +8 -2
- package/dist/Cli.js.map +1 -1
- package/dist/CliSettings.d.ts.map +1 -1
- package/dist/CliSettings.js +1 -2
- package/dist/CliSettings.js.map +1 -1
- package/dist/CliUtils.d.ts +2 -1
- package/dist/CliUtils.d.ts.map +1 -1
- package/dist/CliUtils.js +4 -0
- package/dist/CliUtils.js.map +1 -1
- package/dist/Constants/CommandRegistry.d.ts.map +1 -1
- package/dist/Constants/CommandRegistry.js +44 -6
- package/dist/Constants/CommandRegistry.js.map +1 -1
- package/dist/Constants/HelpStrings.d.ts +75 -3
- package/dist/Constants/HelpStrings.d.ts.map +1 -1
- package/dist/Constants/HelpStrings.js +143 -41
- package/dist/Constants/HelpStrings.js.map +1 -1
- package/dist/Errors/GitHubErrorMap.d.ts +3 -3
- package/dist/Errors/GitHubErrorMap.d.ts.map +1 -1
- package/dist/Errors/GitHubErrorMap.js +12 -7
- package/dist/Errors/GitHubErrorMap.js.map +1 -1
- package/dist/FS/CliFs.d.ts.map +1 -1
- package/dist/FS/CliFs.js.map +1 -1
- package/dist/HttpClient/CliHttpClient.d.ts +17 -0
- package/dist/HttpClient/CliHttpClient.d.ts.map +1 -1
- package/dist/HttpClient/CliHttpClient.js +112 -1
- package/dist/HttpClient/CliHttpClient.js.map +1 -1
- package/dist/Logger/CliLogger.d.ts.map +1 -1
- package/dist/Logger/CliLogger.js +1 -1
- package/dist/Logger/CliLogger.js.map +1 -1
- package/dist/Logger/ConsoleWriter.d.ts.map +1 -1
- package/dist/Logger/ConsoleWriter.js +7 -7
- package/dist/Logger/ConsoleWriter.js.map +1 -1
- package/dist/Middletier/FunctionsBundler.d.ts +17 -0
- package/dist/Middletier/FunctionsBundler.d.ts.map +1 -0
- package/dist/Middletier/FunctionsBundler.js +165 -0
- package/dist/Middletier/FunctionsBundler.js.map +1 -0
- package/dist/Middletier/PackFunctions.d.ts +52 -0
- package/dist/Middletier/PackFunctions.d.ts.map +1 -0
- package/dist/Middletier/PackFunctions.js +122 -0
- package/dist/Middletier/PackFunctions.js.map +1 -0
- package/dist/Types/Cli.types.d.ts +42 -1
- package/dist/Types/Cli.types.d.ts.map +1 -1
- package/dist/Types/Command.types.d.ts +14 -3
- package/dist/Types/Command.types.d.ts.map +1 -1
- package/dist/Types/Command.types.js +4 -0
- package/dist/Types/Command.types.js.map +1 -1
- package/dist/Utils/BuildPolling.d.ts +18 -0
- package/dist/Utils/BuildPolling.d.ts.map +1 -0
- package/dist/Utils/BuildPolling.js +63 -0
- package/dist/Utils/BuildPolling.js.map +1 -0
- package/dist/Utils/BuildVerbDescriptionTable.d.ts +11 -1
- package/dist/Utils/BuildVerbDescriptionTable.d.ts.map +1 -1
- package/dist/Utils/BuildVerbDescriptionTable.js +73 -17
- package/dist/Utils/BuildVerbDescriptionTable.js.map +1 -1
- package/dist/Utils/ConsoleOutput.d.ts.map +1 -1
- package/dist/Utils/ConsoleOutput.js +15 -12
- package/dist/Utils/ConsoleOutput.js.map +1 -1
- package/dist/Utils/DcfRecovery.d.ts +84 -0
- package/dist/Utils/DcfRecovery.d.ts.map +1 -0
- package/dist/Utils/DcfRecovery.js +258 -0
- package/dist/Utils/DcfRecovery.js.map +1 -0
- package/dist/Utils/EnhanceNetworkError.d.ts.map +1 -1
- package/dist/Utils/EnhanceNetworkError.js +2 -0
- package/dist/Utils/EnhanceNetworkError.js.map +1 -1
- package/dist/Utils/EnvVars.d.ts +1 -1
- package/dist/Utils/EnvVars.d.ts.map +1 -1
- package/dist/Utils/EnvVars.js.map +1 -1
- package/dist/Utils/EnvironmentRoutingUtils.d.ts +8 -0
- package/dist/Utils/EnvironmentRoutingUtils.d.ts.map +1 -0
- package/dist/Utils/EnvironmentRoutingUtils.js +45 -0
- package/dist/Utils/EnvironmentRoutingUtils.js.map +1 -0
- package/dist/Utils/GitHubDcfFlow.d.ts +4 -5
- package/dist/Utils/GitHubDcfFlow.d.ts.map +1 -1
- package/dist/Utils/GitHubDcfFlow.js +4 -5
- package/dist/Utils/GitHubDcfFlow.js.map +1 -1
- package/dist/Utils/GitUtils.d.ts +5 -0
- package/dist/Utils/GitUtils.d.ts.map +1 -1
- package/dist/Utils/GitUtils.js +15 -0
- package/dist/Utils/GitUtils.js.map +1 -1
- package/dist/Utils/Paging.d.ts.map +1 -1
- package/dist/Utils/Paging.js +4 -4
- package/dist/Utils/Paging.js.map +1 -1
- package/dist/Utils/ResolveCommand.d.ts +7 -1
- package/dist/Utils/ResolveCommand.d.ts.map +1 -1
- package/dist/Utils/ResolveCommand.js +38 -20
- package/dist/Utils/ResolveCommand.js.map +1 -1
- package/dist/Utils/Spinner.d.ts +9 -1
- package/dist/Utils/Spinner.d.ts.map +1 -1
- package/dist/Utils/Spinner.js +25 -5
- package/dist/Utils/Spinner.js.map +1 -1
- package/dist/Verbs/AddAction.d.ts.map +1 -1
- package/dist/Verbs/AddAction.js +12 -41
- package/dist/Verbs/AddAction.js.map +1 -1
- package/dist/Verbs/AddConnector.d.ts +24 -0
- package/dist/Verbs/AddConnector.d.ts.map +1 -0
- package/dist/Verbs/AddConnector.js +156 -0
- package/dist/Verbs/AddConnector.js.map +1 -0
- package/dist/Verbs/AddConnectorFlows.d.ts +72 -0
- package/dist/Verbs/AddConnectorFlows.d.ts.map +1 -0
- package/dist/Verbs/AddConnectorFlows.js +198 -0
- package/dist/Verbs/AddConnectorFlows.js.map +1 -0
- package/dist/Verbs/AddDataSource.js +1 -1
- package/dist/Verbs/AddDataSource.js.map +1 -1
- package/dist/Verbs/AddTable.d.ts.map +1 -1
- package/dist/Verbs/AddTable.js +15 -100
- package/dist/Verbs/AddTable.js.map +1 -1
- package/dist/Verbs/AuthStatus.d.ts.map +1 -1
- package/dist/Verbs/AuthStatus.js +34 -6
- package/dist/Verbs/AuthStatus.js.map +1 -1
- package/dist/Verbs/AuthSwitch.d.ts +6 -0
- package/dist/Verbs/AuthSwitch.d.ts.map +1 -0
- package/dist/Verbs/AuthSwitch.js +67 -0
- package/dist/Verbs/AuthSwitch.js.map +1 -0
- package/dist/Verbs/BuildMaafApp.d.ts.map +1 -1
- package/dist/Verbs/BuildMaafApp.js +98 -22
- package/dist/Verbs/BuildMaafApp.js.map +1 -1
- package/dist/Verbs/ConnectorHelpers.d.ts +54 -1
- package/dist/Verbs/ConnectorHelpers.d.ts.map +1 -1
- package/dist/Verbs/ConnectorHelpers.js +217 -16
- package/dist/Verbs/ConnectorHelpers.js.map +1 -1
- package/dist/Verbs/CreateMaafApp.d.ts +75 -0
- package/dist/Verbs/CreateMaafApp.d.ts.map +1 -1
- package/dist/Verbs/CreateMaafApp.js +273 -75
- package/dist/Verbs/CreateMaafApp.js.map +1 -1
- package/dist/Verbs/DeployMaafApp.d.ts.map +1 -1
- package/dist/Verbs/DeployMaafApp.js +52 -20
- package/dist/Verbs/DeployMaafApp.js.map +1 -1
- package/dist/Verbs/Dev.js +5 -5
- package/dist/Verbs/Dev.js.map +1 -1
- package/dist/Verbs/GetMaafBuildStatus.d.ts.map +1 -1
- package/dist/Verbs/GetMaafBuildStatus.js +66 -17
- package/dist/Verbs/GetMaafBuildStatus.js.map +1 -1
- package/dist/Verbs/Init.d.ts.map +1 -1
- package/dist/Verbs/Init.js +170 -60
- package/dist/Verbs/Init.js.map +1 -1
- package/dist/Verbs/ListConnectors.d.ts.map +1 -1
- package/dist/Verbs/ListConnectors.js +4 -2
- package/dist/Verbs/ListConnectors.js.map +1 -1
- package/dist/Verbs/ListDatasets.d.ts.map +1 -1
- package/dist/Verbs/ListDatasets.js +5 -0
- package/dist/Verbs/ListDatasets.js.map +1 -1
- package/dist/Verbs/ListFlows.d.ts.map +1 -1
- package/dist/Verbs/ListFlows.js +1 -2
- package/dist/Verbs/ListFlows.js.map +1 -1
- package/dist/Verbs/ListSqlStoredProcedures.d.ts.map +1 -1
- package/dist/Verbs/ListSqlStoredProcedures.js +5 -0
- package/dist/Verbs/ListSqlStoredProcedures.js.map +1 -1
- package/dist/Verbs/ListTables.d.ts.map +1 -1
- package/dist/Verbs/ListTables.js +5 -0
- package/dist/Verbs/ListTables.js.map +1 -1
- package/dist/Verbs/Login.d.ts.map +1 -1
- package/dist/Verbs/Login.js +16 -13
- package/dist/Verbs/Login.js.map +1 -1
- package/dist/Verbs/Logout.d.ts.map +1 -1
- package/dist/Verbs/Logout.js +19 -13
- package/dist/Verbs/Logout.js.map +1 -1
- package/dist/Verbs/MaafAppPermissions.d.ts.map +1 -1
- package/dist/Verbs/MaafAppPermissions.js +4 -0
- package/dist/Verbs/MaafAppPermissions.js.map +1 -1
- package/dist/Verbs/Pack.d.ts +6 -6
- package/dist/Verbs/Pack.d.ts.map +1 -1
- package/dist/Verbs/Pack.js +80 -12
- package/dist/Verbs/Pack.js.map +1 -1
- package/dist/Verbs/PlayMaafApp.d.ts +22 -0
- package/dist/Verbs/PlayMaafApp.d.ts.map +1 -0
- package/dist/Verbs/PlayMaafApp.js +147 -0
- package/dist/Verbs/PlayMaafApp.js.map +1 -0
- package/dist/Verbs/RefreshDataSource.d.ts.map +1 -1
- package/dist/Verbs/RefreshDataSource.js.map +1 -1
- package/dist/Verbs/RefreshGitAuth.d.ts.map +1 -1
- package/dist/Verbs/RefreshGitAuth.js +1 -1
- package/dist/Verbs/RefreshGitAuth.js.map +1 -1
- package/dist/Verbs/ShareLinkCreate.d.ts +23 -0
- package/dist/Verbs/ShareLinkCreate.d.ts.map +1 -0
- package/dist/Verbs/ShareLinkCreate.js +73 -0
- package/dist/Verbs/ShareLinkCreate.js.map +1 -0
- package/dist/Verbs/ShareLinkList.d.ts +16 -0
- package/dist/Verbs/ShareLinkList.d.ts.map +1 -0
- package/dist/Verbs/ShareLinkList.js +84 -0
- package/dist/Verbs/ShareLinkList.js.map +1 -0
- package/dist/Verbs/ShareLinkRevoke.d.ts +22 -0
- package/dist/Verbs/ShareLinkRevoke.d.ts.map +1 -0
- package/dist/Verbs/ShareLinkRevoke.js +137 -0
- package/dist/Verbs/ShareLinkRevoke.js.map +1 -0
- package/dist/Verbs/VerbConstants.d.ts +151 -21
- package/dist/Verbs/VerbConstants.d.ts.map +1 -1
- package/dist/Verbs/VerbConstants.js +127 -21
- package/dist/Verbs/VerbConstants.js.map +1 -1
- package/dist/Verbs/index.d.ts +6 -0
- package/dist/Verbs/index.d.ts.map +1 -1
- package/dist/Verbs/index.js +6 -0
- package/dist/Verbs/index.js.map +1 -1
- package/package.json +8 -8
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import { CLI_BINARY_NAME } from '../Constants/CliConstants.js';
|
|
5
5
|
import { COMMAND_TREE } from '../Constants/CommandRegistry.js';
|
|
6
|
-
import { isTypedVerbDef } from '../Types/Command.types.js';
|
|
6
|
+
import { hasParentHandler, isTypedVerbDef } from '../Types/Command.types.js';
|
|
7
7
|
import { isKnownNoun } from './ResolveCommand.js';
|
|
8
8
|
/** Renders a two-column label/helpText table under a title heading. */
|
|
9
9
|
function appendTable(lines, title, entries) {
|
|
@@ -47,41 +47,97 @@ export function buildNounHelpText(noun) {
|
|
|
47
47
|
lines.push('');
|
|
48
48
|
lines.push(nounDef['@description']);
|
|
49
49
|
lines.push('');
|
|
50
|
-
|
|
51
|
-
|
|
50
|
+
// Hybrid typed verbs (those with their own handler, e.g. `app share`) show
|
|
51
|
+
// up in BOTH the direct-commands list AND the typed-subcommand list below.
|
|
52
|
+
const directEntries = [];
|
|
53
|
+
const typedEntries = [];
|
|
54
|
+
for (const [name, entry] of Object.entries(nounDef.commands)) {
|
|
55
|
+
if (isTypedVerbDef(entry)) {
|
|
56
|
+
if (hasParentHandler(entry)) {
|
|
57
|
+
directEntries.push([name, entry['@helpText']]);
|
|
58
|
+
}
|
|
59
|
+
typedEntries.push([name, entry]);
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
directEntries.push([name, entry['@helpText']]);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
52
65
|
if (directEntries.length > 0) {
|
|
53
|
-
appendTable(lines, 'Commands:', directEntries
|
|
66
|
+
appendTable(lines, 'Commands:', directEntries);
|
|
54
67
|
}
|
|
55
68
|
if (typedEntries.length > 0) {
|
|
56
69
|
lines.push('');
|
|
57
70
|
for (const [verb, typedVerbDef] of typedEntries) {
|
|
58
|
-
appendTable(lines, `${verb} <type>:`,
|
|
59
|
-
`${verb} ${type}`,
|
|
60
|
-
leafDef['@helpText'],
|
|
61
|
-
]));
|
|
71
|
+
appendTable(lines, `${verb} <type>:`, flattenTypedVerb(typedVerbDef, verb).map(([label, helpText]) => [label, helpText]));
|
|
62
72
|
}
|
|
63
73
|
}
|
|
64
74
|
lines.push('');
|
|
65
75
|
lines.push(`Run '${CLI_BINARY_NAME} ${noun} <command> --help' for command-specific flags.`);
|
|
66
76
|
return lines.join('\n');
|
|
67
77
|
}
|
|
78
|
+
/**
|
|
79
|
+
* Flattens a typed verb into a list of `<prefix> <type> [...nested]` labels
|
|
80
|
+
* paired with their leaf help text. Pass an empty `prefix` to get bare type
|
|
81
|
+
* paths (e.g. `link create`); pass a non-empty prefix to include it.
|
|
82
|
+
*/
|
|
83
|
+
function flattenTypedVerb(verbDef, prefix) {
|
|
84
|
+
const rows = [];
|
|
85
|
+
for (const [type, sub] of Object.entries(verbDef.commands)) {
|
|
86
|
+
const label = prefix ? `${prefix} ${type}` : type;
|
|
87
|
+
if (isTypedVerbDef(sub)) {
|
|
88
|
+
rows.push(...flattenTypedVerb(sub, label));
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
rows.push([label, sub['@helpText']]);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return rows;
|
|
95
|
+
}
|
|
68
96
|
/**
|
|
69
97
|
* Builds help text for a typed subcommand verb (e.g., `app add`).
|
|
70
|
-
* Lists the available types.
|
|
98
|
+
* Lists the available types — including nested typed verbs.
|
|
71
99
|
*/
|
|
72
100
|
export function buildTypedSubcommandHelpText(noun, verb) {
|
|
101
|
+
return buildPathTypedHelpText([noun, verb]) ?? '';
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Walks the command tree along `pathTokens` and, if the endpoint is a typed
|
|
105
|
+
* verb, returns its flattened subcommand help text. Returns `null` if any
|
|
106
|
+
* token fails to match or the endpoint is a leaf (in which case Commander
|
|
107
|
+
* handles `--help` on its own at the leaf level).
|
|
108
|
+
*
|
|
109
|
+
* Used to surface help for nested-typed paths the resolver cannot leaf-match,
|
|
110
|
+
* e.g. `ms app share link --help` → list `create | list | revoke`.
|
|
111
|
+
*/
|
|
112
|
+
export function buildPathTypedHelpText(pathTokens) {
|
|
113
|
+
if (pathTokens.length < 2)
|
|
114
|
+
return null;
|
|
115
|
+
const [noun, ...rest] = pathTokens;
|
|
73
116
|
if (!isKnownNoun(noun, COMMAND_TREE))
|
|
74
|
-
return
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
117
|
+
return null;
|
|
118
|
+
let commands = COMMAND_TREE[noun].commands;
|
|
119
|
+
let endpoint;
|
|
120
|
+
for (const token of rest) {
|
|
121
|
+
const entry = commands[token];
|
|
122
|
+
if (!entry)
|
|
123
|
+
return null;
|
|
124
|
+
endpoint = entry;
|
|
125
|
+
if (isTypedVerbDef(entry)) {
|
|
126
|
+
commands = entry.commands;
|
|
127
|
+
}
|
|
128
|
+
else {
|
|
129
|
+
return null; // Leaf — leaf-level `--help` is Commander's job, not ours.
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
if (!endpoint || !isTypedVerbDef(endpoint))
|
|
133
|
+
return null;
|
|
134
|
+
const labelPath = pathTokens.join(' ');
|
|
79
135
|
const lines = [];
|
|
80
|
-
lines.push(`Usage: ${CLI_BINARY_NAME} ${
|
|
136
|
+
lines.push(`Usage: ${CLI_BINARY_NAME} ${labelPath} <type> [flags]`);
|
|
81
137
|
lines.push('');
|
|
82
|
-
appendTable(lines, 'Types:',
|
|
138
|
+
appendTable(lines, 'Types:', flattenTypedVerb(endpoint, ''));
|
|
83
139
|
lines.push('');
|
|
84
|
-
lines.push(`Run '${CLI_BINARY_NAME} ${
|
|
140
|
+
lines.push(`Run '${CLI_BINARY_NAME} ${labelPath} <type> --help' for type-specific flags.`);
|
|
85
141
|
return lines.join('\n');
|
|
86
142
|
}
|
|
87
143
|
//# sourceMappingURL=BuildVerbDescriptionTable.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BuildVerbDescriptionTable.js","sourceRoot":"","sources":["../../src/Utils/BuildVerbDescriptionTable.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAE5D,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"BuildVerbDescriptionTable.js","sourceRoot":"","sources":["../../src/Utils/BuildVerbDescriptionTable.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ConsoleOutput.d.ts","sourceRoot":"","sources":["../../src/Utils/ConsoleOutput.ts"],"names":[],"mappings":"AAAA;;GAEG;AAWH,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,OAAO,EAAE,SAAS,EAAE,CAAC;IACrB,IAAI,EAAE,MAAM,EAAE,EAAE,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,GAAG,IAAI,CA8DP;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,OAAO,EAAE;IAC5C,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,CAAC,EAAE,CAAC;IACX,MAAM,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,MAAM,CAAA;KAAE,EAAE,CAAC;IACxD,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,GAAG,IAAI,CAyBP;AAED,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAElD;AAMD,KAAK,oBAAoB,GAAG;IAAE,OAAO,CAAC,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,EAAE,KAAK,CAAC;IAAC,YAAY,CAAC,EAAE,KAAK,CAAA;CAAE,CAAC;AAMxF,KAAK,QAAQ,CAAC,CAAC,IAAI,CAAC,SAAS,SAAS,OAAO,EAAE,GAAG,KAAK,GAAG,CAAC,CAAC;AAE5D;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,SAAS,MAAM,EAC/C,IAAI,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,oBAAoB,GACxC,IAAI,CAEN;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAElD;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,IAAI,CAExD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,CAAC,YAAY,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAE5E;AAED,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAE/C;AAED,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"ConsoleOutput.d.ts","sourceRoot":"","sources":["../../src/Utils/ConsoleOutput.ts"],"names":[],"mappings":"AAAA;;GAEG;AAWH,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,OAAO,EAAE,SAAS,EAAE,CAAC;IACrB,IAAI,EAAE,MAAM,EAAE,EAAE,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,GAAG,IAAI,CA8DP;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,OAAO,EAAE;IAC5C,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,CAAC,EAAE,CAAC;IACX,MAAM,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,MAAM,CAAA;KAAE,EAAE,CAAC;IACxD,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,GAAG,IAAI,CAyBP;AAED,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAElD;AAMD,KAAK,oBAAoB,GAAG;IAAE,OAAO,CAAC,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,EAAE,KAAK,CAAC;IAAC,YAAY,CAAC,EAAE,KAAK,CAAA;CAAE,CAAC;AAMxF,KAAK,QAAQ,CAAC,CAAC,IAAI,CAAC,SAAS,SAAS,OAAO,EAAE,GAAG,KAAK,GAAG,CAAC,CAAC;AAE5D;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,SAAS,MAAM,EAC/C,IAAI,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,oBAAoB,GACxC,IAAI,CAEN;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAElD;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,IAAI,CAExD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,CAAC,YAAY,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAE5E;AAED,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAE/C;AAED,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAIlD;AAED,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAGhD"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/*!
|
|
2
2
|
* Copyright (C) Microsoft Corporation. All rights reserved.
|
|
3
3
|
*/
|
|
4
|
-
import
|
|
4
|
+
import { styleText } from 'node:util';
|
|
5
5
|
// Suppress decorative separator lines when output is piped or redirected (non-interactive).
|
|
6
6
|
// This applies to both shell pipelines and LLM agents that invoke CLI commands programmatically —
|
|
7
7
|
// in both cases stdout is not a TTY, and box-drawing characters would pollute the parseable output.
|
|
@@ -14,14 +14,14 @@ function isTTY() {
|
|
|
14
14
|
*/
|
|
15
15
|
export function printTable(options) {
|
|
16
16
|
const { title, metadata, columns, rows, emptyMessage, totalLabel, width = 80 } = options;
|
|
17
|
-
const line = isTTY() ?
|
|
17
|
+
const line = isTTY() ? styleText('dim', '-'.repeat(width)) : null;
|
|
18
18
|
console.log('');
|
|
19
|
-
console.log(
|
|
19
|
+
console.log(styleText(['cyan', 'bold'], ` ${title}`));
|
|
20
20
|
if (metadata) {
|
|
21
21
|
if (line)
|
|
22
22
|
console.log(line);
|
|
23
23
|
for (const meta of metadata) {
|
|
24
|
-
console.log(
|
|
24
|
+
console.log(styleText('white', ` ${meta}`));
|
|
25
25
|
}
|
|
26
26
|
}
|
|
27
27
|
if (rows.length === 0) {
|
|
@@ -45,7 +45,7 @@ export function printTable(options) {
|
|
|
45
45
|
if (line)
|
|
46
46
|
console.log(line);
|
|
47
47
|
const headerParts = columns.map((col, i) => i === columns.length - 1 ? col.header : col.header.padEnd(colWidths[i]));
|
|
48
|
-
console.log(
|
|
48
|
+
console.log(styleText('cyan', ` ${headerParts.join(' ')}`));
|
|
49
49
|
if (line)
|
|
50
50
|
console.log(line);
|
|
51
51
|
for (const row of rows) {
|
|
@@ -66,7 +66,7 @@ export function printTable(options) {
|
|
|
66
66
|
if (line)
|
|
67
67
|
console.log(line);
|
|
68
68
|
if (totalLabel !== undefined) {
|
|
69
|
-
console.log(
|
|
69
|
+
console.log(styleText('dim', ` Total: ${rows.length} ${totalLabel}`));
|
|
70
70
|
}
|
|
71
71
|
}
|
|
72
72
|
/**
|
|
@@ -75,9 +75,9 @@ export function printTable(options) {
|
|
|
75
75
|
*/
|
|
76
76
|
export function printKeyValueList(options) {
|
|
77
77
|
const { title, items, fields, emptyMessage, width = 80 } = options;
|
|
78
|
-
const line = isTTY() ?
|
|
78
|
+
const line = isTTY() ? styleText('dim', '-'.repeat(width)) : null;
|
|
79
79
|
console.log('');
|
|
80
|
-
console.log(
|
|
80
|
+
console.log(styleText(['cyan', 'bold'], ` ${title}`));
|
|
81
81
|
if (line)
|
|
82
82
|
console.log(line);
|
|
83
83
|
if (items.length === 0) {
|
|
@@ -88,7 +88,7 @@ export function printKeyValueList(options) {
|
|
|
88
88
|
}
|
|
89
89
|
for (let i = 0; i < items.length; i++) {
|
|
90
90
|
for (const field of fields) {
|
|
91
|
-
console.log(` ${
|
|
91
|
+
console.log(` ${styleText('white', field.label)}: ${field.value(items[i])}`);
|
|
92
92
|
}
|
|
93
93
|
// Separator between items only — no trailing separator after the last item (intentional).
|
|
94
94
|
if (i < items.length - 1 && line) {
|
|
@@ -97,7 +97,7 @@ export function printKeyValueList(options) {
|
|
|
97
97
|
}
|
|
98
98
|
}
|
|
99
99
|
export function printSuccess(message) {
|
|
100
|
-
console.log(
|
|
100
|
+
console.log(styleText('green', message));
|
|
101
101
|
}
|
|
102
102
|
/**
|
|
103
103
|
* Emits a success JSON envelope `{ success: true, ...data }` to **stdout**.
|
|
@@ -151,9 +151,12 @@ export function printInfo(message) {
|
|
|
151
151
|
console.log(message);
|
|
152
152
|
}
|
|
153
153
|
export function printWarning(message) {
|
|
154
|
-
console.warn(
|
|
154
|
+
// console.warn writes to stderr, so evaluate hasColors() against stderr rather than the
|
|
155
|
+
// styleText default (process.stdout). Keeps warnings colored when only stdout is piped.
|
|
156
|
+
console.warn(styleText('yellow', message, { stream: process.stderr }));
|
|
155
157
|
}
|
|
156
158
|
export function printError(message) {
|
|
157
|
-
console.error
|
|
159
|
+
// console.error writes to stderr; see printWarning above.
|
|
160
|
+
console.error(styleText('red', message, { stream: process.stderr }));
|
|
158
161
|
}
|
|
159
162
|
//# sourceMappingURL=ConsoleOutput.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ConsoleOutput.js","sourceRoot":"","sources":["../../src/Utils/ConsoleOutput.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,
|
|
1
|
+
{"version":3,"file":"ConsoleOutput.js","sourceRoot":"","sources":["../../src/Utils/ConsoleOutput.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (C) Microsoft Corporation. All rights reserved.
|
|
3
|
+
*/
|
|
4
|
+
import type { RepoType } from '@microsoft/managed-apps-common/config';
|
|
5
|
+
/** Verbs that currently invoke the DCF catch-and-retry recovery flow. */
|
|
6
|
+
export type DcfRecoveryVerb = 'app create' | 'app init' | 'app build' | 'app deploy';
|
|
7
|
+
export interface DcfRecoveryOptions {
|
|
8
|
+
remoteUrl: string;
|
|
9
|
+
tenantId: string;
|
|
10
|
+
jsonMode: boolean;
|
|
11
|
+
openBrowser: boolean;
|
|
12
|
+
/** The CLI verb invoking the recovery — drives the telemetry event prefix and error context. */
|
|
13
|
+
verb: DcfRecoveryVerb;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Inline DCF recovery branch for the github catch-and-retry. SIGINT handling
|
|
17
|
+
* is scoped to this helper so Ctrl+C during the device-code polling loop
|
|
18
|
+
* doesn't leak a listener back to the verb's outer body. Server errors thrown
|
|
19
|
+
* by `authenticateForRepoAsync` are mapped through
|
|
20
|
+
* {@link mapGitHubServerErrorToCliError} before being rethrown so the verb's
|
|
21
|
+
* outer catch (and the single-retry contract) sees CLI-typed errors.
|
|
22
|
+
*
|
|
23
|
+
* Telemetry event prefix is derived from the verb (e.g. `'app create'` →
|
|
24
|
+
* `'Maaf.Create.GitHubDcfRecovery'`) — keeps the call site a one-liner that
|
|
25
|
+
* can't drift out of sync with the verb field.
|
|
26
|
+
*/
|
|
27
|
+
export declare function runDcfRecoveryAsync(options: DcfRecoveryOptions): Promise<void>;
|
|
28
|
+
export interface WithGitHubDcfRecoveryOptions {
|
|
29
|
+
/**
|
|
30
|
+
* The repo binding mode from `ms.config.json`. Non-`'github'` short-circuits:
|
|
31
|
+
* the attempt error is rethrown untouched and no DCF recovery is attempted.
|
|
32
|
+
* Accepts `undefined` so the legacy/native-only verb paths (where no
|
|
33
|
+
* `ms.config.json` is loaded yet) can flow through with the same call shape.
|
|
34
|
+
*/
|
|
35
|
+
repoType: RepoType | undefined;
|
|
36
|
+
/**
|
|
37
|
+
* The external repository URL the attempt was authenticating against.
|
|
38
|
+
* Required for `github` recovery — `undefined` triggers a verb-agnostic
|
|
39
|
+
* legacy guard that throws an actionable {@link AuthenticationError} before
|
|
40
|
+
* we'd otherwise crash inside DCF (which needs a URL to parse host/owner/repo).
|
|
41
|
+
*/
|
|
42
|
+
externalRepoUrl: string | undefined;
|
|
43
|
+
tenantId: string;
|
|
44
|
+
jsonMode: boolean;
|
|
45
|
+
openBrowser: boolean;
|
|
46
|
+
verb: DcfRecoveryVerb;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Higher-order wrapper that bolts the GitHub catch-and-retry DCF recovery
|
|
50
|
+
* branch onto a single async attempt. Encapsulates the
|
|
51
|
+
*
|
|
52
|
+
* try { attempt } catch { match → DCF → retry attempt → map-on-failure }
|
|
53
|
+
*
|
|
54
|
+
* pattern that `ms app create`, `ms app init`, `ms app build`, and `ms app deploy`
|
|
55
|
+
* all need, so the verbs stay focused on their own happy-path flow.
|
|
56
|
+
*
|
|
57
|
+
* Contract:
|
|
58
|
+
* - The attempt runs at most twice; DCF runs at most once. No looping.
|
|
59
|
+
* - The attempt callback receives `{ isRetry: false }` on the first call
|
|
60
|
+
* and `{ isRetry: true }` on the post-DCF retry so callers can
|
|
61
|
+
* conditionally alter their request (e.g. drop `forceReauth` on retry
|
|
62
|
+
* so the just-refreshed mapping isn't bypassed again).
|
|
63
|
+
* - `repoType !== 'github'` is a no-op around the attempt — the original
|
|
64
|
+
* error escapes untouched so native/none verbs behave identically to the
|
|
65
|
+
* un-wrapped call.
|
|
66
|
+
* - First-attempt errors that {@link matchGitHubAuthError} doesn't recognize
|
|
67
|
+
* are mapped via {@link mapGitHubServerErrorToCliError} (for
|
|
68
|
+
* {@link GrsServerError}) before being rethrown; everything else escapes
|
|
69
|
+
* as-is.
|
|
70
|
+
* - A matching first-attempt error with no `externalRepoUrl` throws a
|
|
71
|
+
* verb-agnostic {@link AuthenticationError} before DCF is invoked — DCF
|
|
72
|
+
* itself requires a URL to derive host/owner/repo.
|
|
73
|
+
* - Second-attempt (post-DCF) errors follow the same map-and-rethrow
|
|
74
|
+
* contract; a still-matching error after DCF surfaces through the
|
|
75
|
+
* friendly mapper rather than looping the device flow.
|
|
76
|
+
*
|
|
77
|
+
* `runDcfRecovery` is an optional dependency seam — defaults to the real
|
|
78
|
+
* {@link runDcfRecoveryAsync}; tests inject a stub so they don't have to
|
|
79
|
+
* spin up the device-code polling loop.
|
|
80
|
+
*/
|
|
81
|
+
export declare function withGitHubDcfRecoveryAsync<T>(attempt: (context: {
|
|
82
|
+
isRetry: boolean;
|
|
83
|
+
}) => Promise<T>, options: WithGitHubDcfRecoveryOptions, runDcfRecovery?: typeof runDcfRecoveryAsync): Promise<T>;
|
|
84
|
+
//# sourceMappingURL=DcfRecovery.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DcfRecovery.d.ts","sourceRoot":"","sources":["../../src/Utils/DcfRecovery.ts"],"names":[],"mappings":"AAAA;;GAEG;AAkBH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,uCAAuC,CAAC;AAStE,yEAAyE;AACzE,MAAM,MAAM,eAAe,GAAG,YAAY,GAAG,UAAU,GAAG,WAAW,GAAG,YAAY,CAAC;AAErF,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,OAAO,CAAC;IAClB,WAAW,EAAE,OAAO,CAAC;IACrB,gGAAgG;IAChG,IAAI,EAAE,eAAe,CAAC;CACvB;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CA+EpF;AAqDD,MAAM,WAAW,4BAA4B;IAC3C;;;;;OAKG;IACH,QAAQ,EAAE,QAAQ,GAAG,SAAS,CAAC;IAC/B;;;;;OAKG;IACH,eAAe,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,OAAO,CAAC;IAClB,WAAW,EAAE,OAAO,CAAC;IACrB,IAAI,EAAE,eAAe,CAAC;CACvB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,wBAAsB,0BAA0B,CAAC,CAAC,EAChD,OAAO,EAAE,CAAC,OAAO,EAAE;IAAE,OAAO,EAAE,OAAO,CAAA;CAAE,KAAK,OAAO,CAAC,CAAC,CAAC,EACtD,OAAO,EAAE,4BAA4B,EACrC,cAAc,GAAE,OAAO,mBAAyC,GAC/D,OAAO,CAAC,CAAC,CAAC,CA2EZ"}
|
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (C) Microsoft Corporation. All rights reserved.
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Shared inline Device Code Flow (DCF) recovery for the github catch-and-retry
|
|
6
|
+
* branch of `ms app create`, `ms app init`, `ms app build`, and `ms app deploy`.
|
|
7
|
+
* On a missing/expired/stale
|
|
8
|
+
* Entra↔GitHub identity mapping, the verb's outer catch calls this helper to
|
|
9
|
+
* prompt the user through the same device-code flow `ms git auth refresh` runs
|
|
10
|
+
* and then retries the failed action exactly once. SIGINT plumbing, telemetry,
|
|
11
|
+
* display selection, and error mapping all live here so the caller can stay
|
|
12
|
+
* focused on its own happy-path flow.
|
|
13
|
+
*/
|
|
14
|
+
import { authenticateForRepoAsync, GrsServerError, } from '@microsoft/managed-apps-actions';
|
|
15
|
+
import { getCliLogger } from '../CliSettings.js';
|
|
16
|
+
import { AuthenticationError } from '../Errors/CliError.js';
|
|
17
|
+
import { mapGitHubServerErrorToCliError, matchGitHubAuthError } from '../Errors/GitHubErrorMap.js';
|
|
18
|
+
import { printInfo } from './ConsoleOutput.js';
|
|
19
|
+
import { ConsoleGitHubDcfDisplay, JsonGitHubDcfDisplay } from './GitHubDcfFlow.js';
|
|
20
|
+
import { computeRepoHash, parseGitHubRepoUrl } from './RepoUrl.js';
|
|
21
|
+
/**
|
|
22
|
+
* Inline DCF recovery branch for the github catch-and-retry. SIGINT handling
|
|
23
|
+
* is scoped to this helper so Ctrl+C during the device-code polling loop
|
|
24
|
+
* doesn't leak a listener back to the verb's outer body. Server errors thrown
|
|
25
|
+
* by `authenticateForRepoAsync` are mapped through
|
|
26
|
+
* {@link mapGitHubServerErrorToCliError} before being rethrown so the verb's
|
|
27
|
+
* outer catch (and the single-retry contract) sees CLI-typed errors.
|
|
28
|
+
*
|
|
29
|
+
* Telemetry event prefix is derived from the verb (e.g. `'app create'` →
|
|
30
|
+
* `'Maaf.Create.GitHubDcfRecovery'`) — keeps the call site a one-liner that
|
|
31
|
+
* can't drift out of sync with the verb field.
|
|
32
|
+
*/
|
|
33
|
+
export async function runDcfRecoveryAsync(options) {
|
|
34
|
+
const { remoteUrl, tenantId, jsonMode, openBrowser, verb } = options;
|
|
35
|
+
const { host, owner, repo } = parseGitHubRepoUrl(remoteUrl);
|
|
36
|
+
const repoHash = computeRepoHash(owner, repo);
|
|
37
|
+
const logger = getCliLogger();
|
|
38
|
+
const eventPrefix = telemetryEventPrefixForVerb(verb);
|
|
39
|
+
// Telemetry: PII-safe — host is the parsed string, repoHash is a truncated
|
|
40
|
+
// SHA256. Emit Start at the top so a recovery that never reaches the retry
|
|
41
|
+
// (e.g. user denied auth) is still observable.
|
|
42
|
+
logger.trackActivityEvent(eventPrefix, {
|
|
43
|
+
repoHost: host,
|
|
44
|
+
repoHash,
|
|
45
|
+
});
|
|
46
|
+
if (!jsonMode) {
|
|
47
|
+
printInfo('GitHub authentication is required to bind this repository.');
|
|
48
|
+
}
|
|
49
|
+
const display = composeRecoveryDisplay({ isJson: jsonMode, openBrowser });
|
|
50
|
+
// SIGINT plumbing: a Ctrl+C during the (potentially 15-minute) polling
|
|
51
|
+
// loop drops us out cleanly rather than leaving a dangling promise.
|
|
52
|
+
const controller = new AbortController();
|
|
53
|
+
const onSigint = () => {
|
|
54
|
+
controller.abort();
|
|
55
|
+
};
|
|
56
|
+
process.once('SIGINT', onSigint);
|
|
57
|
+
try {
|
|
58
|
+
await authenticateForRepoAsync({
|
|
59
|
+
remoteUrl: `https://${host}/${owner}/${repo}`,
|
|
60
|
+
tenantId,
|
|
61
|
+
logger,
|
|
62
|
+
display,
|
|
63
|
+
// Browser launch is gated by the `display` object above: `composeRecoveryDisplay`
|
|
64
|
+
// returns a display whose `openVerificationUri` is undefined by default (no
|
|
65
|
+
// --open-browser flag). `skipBrowser` is the legacy lower-level kill-switch;
|
|
66
|
+
// hardcode to false so the display contract is the single source of truth.
|
|
67
|
+
skipBrowser: false,
|
|
68
|
+
signal: controller.signal,
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
catch (error) {
|
|
72
|
+
// Pair the Start event with a Failed event on every error path so a
|
|
73
|
+
// recovery that throws (DCF declined, server error, abort) still shows
|
|
74
|
+
// up as a closed pair in the activity stream rather than an orphaned Start.
|
|
75
|
+
logger.trackActivityEvent(`${eventPrefix}.Failed`, {
|
|
76
|
+
repoHost: host,
|
|
77
|
+
repoHash,
|
|
78
|
+
});
|
|
79
|
+
if (error instanceof GrsServerError) {
|
|
80
|
+
const mapped = mapGitHubServerErrorToCliError({
|
|
81
|
+
code: error.code,
|
|
82
|
+
message: error.message,
|
|
83
|
+
status: error.status,
|
|
84
|
+
details: error.details,
|
|
85
|
+
}, { repoUrl: remoteUrl, verb });
|
|
86
|
+
if (mapped)
|
|
87
|
+
throw mapped;
|
|
88
|
+
}
|
|
89
|
+
throw error;
|
|
90
|
+
}
|
|
91
|
+
finally {
|
|
92
|
+
process.removeListener('SIGINT', onSigint);
|
|
93
|
+
}
|
|
94
|
+
logger.trackActivityEvent(`${eventPrefix}.Complete`, {
|
|
95
|
+
repoHost: host,
|
|
96
|
+
repoHash,
|
|
97
|
+
});
|
|
98
|
+
if (!jsonMode) {
|
|
99
|
+
// Printed here (before the helper returns) rather than at the retry
|
|
100
|
+
// call site so it's adjacent to the DCF-completed telemetry event. If
|
|
101
|
+
// the subsequent verb retry hard-fails, the user sees this followed by the failure message.
|
|
102
|
+
// Still accurate: we DID resume; the resumed call is what failed.
|
|
103
|
+
printInfo(resumeMessageForVerb(verb));
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
/** Verb-specific "resuming X..." message shown after a successful DCF recovery. */
|
|
107
|
+
function resumeMessageForVerb(verb) {
|
|
108
|
+
switch (verb) {
|
|
109
|
+
case 'app create':
|
|
110
|
+
return 'Resuming create...';
|
|
111
|
+
case 'app init':
|
|
112
|
+
return 'Resuming init...';
|
|
113
|
+
case 'app build':
|
|
114
|
+
return 'Resuming build...';
|
|
115
|
+
case 'app deploy':
|
|
116
|
+
return 'Resuming deploy...';
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Build the right {@link GitHubDcfDisplay} for the recovery path:
|
|
121
|
+
* - JSON mode → NDJSON events, never opens a browser.
|
|
122
|
+
* - Default (no `--open-browser`) → console output, browser launch suppressed.
|
|
123
|
+
* - `--open-browser` → console output + best-effort browser launch (TTY-gated).
|
|
124
|
+
*/
|
|
125
|
+
function composeRecoveryDisplay(opts) {
|
|
126
|
+
if (opts.isJson) {
|
|
127
|
+
return new JsonGitHubDcfDisplay();
|
|
128
|
+
}
|
|
129
|
+
if (opts.openBrowser) {
|
|
130
|
+
return ConsoleGitHubDcfDisplay;
|
|
131
|
+
}
|
|
132
|
+
return {
|
|
133
|
+
...ConsoleGitHubDcfDisplay,
|
|
134
|
+
openVerificationUri: undefined,
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Map a verb name to its telemetry event prefix. Keeps the create and build
|
|
139
|
+
* events under their respective `Maaf.Create.*` / `Maaf.Build.*` namespaces
|
|
140
|
+
* so dashboards that filter by namespace continue to work.
|
|
141
|
+
*/
|
|
142
|
+
function telemetryEventPrefixForVerb(verb) {
|
|
143
|
+
switch (verb) {
|
|
144
|
+
case 'app create':
|
|
145
|
+
return 'Maaf.Create.GitHubDcfRecovery';
|
|
146
|
+
case 'app init':
|
|
147
|
+
return 'Maaf.Init.GitHubDcfRecovery';
|
|
148
|
+
case 'app build':
|
|
149
|
+
return 'Maaf.Build.GitHubDcfRecovery';
|
|
150
|
+
case 'app deploy':
|
|
151
|
+
return 'Maaf.Deploy.GitHubDcfRecovery';
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Higher-order wrapper that bolts the GitHub catch-and-retry DCF recovery
|
|
156
|
+
* branch onto a single async attempt. Encapsulates the
|
|
157
|
+
*
|
|
158
|
+
* try { attempt } catch { match → DCF → retry attempt → map-on-failure }
|
|
159
|
+
*
|
|
160
|
+
* pattern that `ms app create`, `ms app init`, `ms app build`, and `ms app deploy`
|
|
161
|
+
* all need, so the verbs stay focused on their own happy-path flow.
|
|
162
|
+
*
|
|
163
|
+
* Contract:
|
|
164
|
+
* - The attempt runs at most twice; DCF runs at most once. No looping.
|
|
165
|
+
* - The attempt callback receives `{ isRetry: false }` on the first call
|
|
166
|
+
* and `{ isRetry: true }` on the post-DCF retry so callers can
|
|
167
|
+
* conditionally alter their request (e.g. drop `forceReauth` on retry
|
|
168
|
+
* so the just-refreshed mapping isn't bypassed again).
|
|
169
|
+
* - `repoType !== 'github'` is a no-op around the attempt — the original
|
|
170
|
+
* error escapes untouched so native/none verbs behave identically to the
|
|
171
|
+
* un-wrapped call.
|
|
172
|
+
* - First-attempt errors that {@link matchGitHubAuthError} doesn't recognize
|
|
173
|
+
* are mapped via {@link mapGitHubServerErrorToCliError} (for
|
|
174
|
+
* {@link GrsServerError}) before being rethrown; everything else escapes
|
|
175
|
+
* as-is.
|
|
176
|
+
* - A matching first-attempt error with no `externalRepoUrl` throws a
|
|
177
|
+
* verb-agnostic {@link AuthenticationError} before DCF is invoked — DCF
|
|
178
|
+
* itself requires a URL to derive host/owner/repo.
|
|
179
|
+
* - Second-attempt (post-DCF) errors follow the same map-and-rethrow
|
|
180
|
+
* contract; a still-matching error after DCF surfaces through the
|
|
181
|
+
* friendly mapper rather than looping the device flow.
|
|
182
|
+
*
|
|
183
|
+
* `runDcfRecovery` is an optional dependency seam — defaults to the real
|
|
184
|
+
* {@link runDcfRecoveryAsync}; tests inject a stub so they don't have to
|
|
185
|
+
* spin up the device-code polling loop.
|
|
186
|
+
*/
|
|
187
|
+
export async function withGitHubDcfRecoveryAsync(attempt, options, runDcfRecovery = runDcfRecoveryAsync) {
|
|
188
|
+
const { repoType, externalRepoUrl, tenantId, jsonMode, openBrowser, verb } = options;
|
|
189
|
+
// Local helper: if `e` is a recognized GrsServerError, return the friendly
|
|
190
|
+
// CLI-typed error; otherwise null. Closes over `externalRepoUrl`/`verb` so
|
|
191
|
+
// the two non-matching call sites below stay one line each and can't drift.
|
|
192
|
+
const mapGrsError = (e) => {
|
|
193
|
+
if (!(e instanceof GrsServerError))
|
|
194
|
+
return null;
|
|
195
|
+
return mapGitHubServerErrorToCliError({ code: e.code, message: e.message, status: e.status, details: e.details }, { repoUrl: externalRepoUrl, verb });
|
|
196
|
+
};
|
|
197
|
+
try {
|
|
198
|
+
// Happy path: attempt succeeds on the first try, no DCF, no retry.
|
|
199
|
+
return await attempt({ isRetry: false });
|
|
200
|
+
}
|
|
201
|
+
catch (err) {
|
|
202
|
+
if (repoType !== 'github')
|
|
203
|
+
throw err;
|
|
204
|
+
const matched = matchGitHubAuthError(err);
|
|
205
|
+
if (!matched) {
|
|
206
|
+
// Non-matching first-attempt error: map known server errors to friendly
|
|
207
|
+
// CLI errors, otherwise rethrow untouched.
|
|
208
|
+
const mapped = mapGrsError(err);
|
|
209
|
+
if (mapped)
|
|
210
|
+
throw mapped;
|
|
211
|
+
throw err;
|
|
212
|
+
}
|
|
213
|
+
// Legacy guard: apps created before `externalRepoUrl` was persisted to
|
|
214
|
+
// ms.config.json hit this branch with no URL to authenticate against.
|
|
215
|
+
// Fail fast with an actionable message rather than crashing inside DCF
|
|
216
|
+
// recovery (which would also bypass the Start telemetry).
|
|
217
|
+
if (!externalRepoUrl) {
|
|
218
|
+
throw new AuthenticationError('GitHub authentication is required, but the app config does not record the external ' +
|
|
219
|
+
'repository URL needed to recover the identity mapping. This app may have been created ' +
|
|
220
|
+
'before the URL was persisted to `ms.config.json`. Either add ' +
|
|
221
|
+
'`externalRepoUrl: "<your repo url>"` to `ms.config.json`, or recreate the app with ' +
|
|
222
|
+
`\`ms app create --repo <your repo url>\`, then run \`ms ${verb}\` again.`);
|
|
223
|
+
}
|
|
224
|
+
await runDcfRecovery({
|
|
225
|
+
remoteUrl: externalRepoUrl,
|
|
226
|
+
tenantId,
|
|
227
|
+
jsonMode,
|
|
228
|
+
openBrowser,
|
|
229
|
+
verb,
|
|
230
|
+
});
|
|
231
|
+
try {
|
|
232
|
+
return await attempt({ isRetry: true });
|
|
233
|
+
}
|
|
234
|
+
catch (retryErr) {
|
|
235
|
+
const remapped = matchGitHubAuthError(retryErr);
|
|
236
|
+
if (remapped) {
|
|
237
|
+
// Single-retry contract: a still-matching error after DCF surfaces
|
|
238
|
+
// through the friendly verb-agnostic mapper so the user sees the
|
|
239
|
+
// same wording as on a first-attempt mapping failure. We deliberately
|
|
240
|
+
// do NOT loop DCF — repeated failures suggest the user can't complete
|
|
241
|
+
// the device-code flow and another loop would just hang. Fall through
|
|
242
|
+
// to `retryErr` if the mapper somehow returns null (defensive — the
|
|
243
|
+
// mapper recognizes every code matchGitHubAuthError matches on).
|
|
244
|
+
const mapped = mapGitHubServerErrorToCliError(remapped.payload, {
|
|
245
|
+
repoUrl: externalRepoUrl,
|
|
246
|
+
verb,
|
|
247
|
+
});
|
|
248
|
+
throw mapped ?? retryErr;
|
|
249
|
+
}
|
|
250
|
+
// Non-matching retry error: same map-or-rethrow shape as the first attempt.
|
|
251
|
+
const mapped = mapGrsError(retryErr);
|
|
252
|
+
if (mapped)
|
|
253
|
+
throw mapped;
|
|
254
|
+
throw retryErr;
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
//# sourceMappingURL=DcfRecovery.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DcfRecovery.js","sourceRoot":"","sources":["../../src/Utils/DcfRecovery.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EnhanceNetworkError.d.ts","sourceRoot":"","sources":["../../src/Utils/EnhanceNetworkError.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,KAAK,
|
|
1
|
+
{"version":3,"file":"EnhanceNetworkError.d.ts","sourceRoot":"","sources":["../../src/Utils/EnhanceNetworkError.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,KAAK,CAgDtF"}
|