@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.
Files changed (207) hide show
  1. package/README.md +56 -10
  2. package/dist/ArgumentProvider.d.ts +21 -2
  3. package/dist/ArgumentProvider.d.ts.map +1 -1
  4. package/dist/ArgumentProvider.js +47 -3
  5. package/dist/ArgumentProvider.js.map +1 -1
  6. package/dist/Authentication/ActiveAccountStore.d.ts +24 -0
  7. package/dist/Authentication/ActiveAccountStore.d.ts.map +1 -0
  8. package/dist/Authentication/ActiveAccountStore.js +54 -0
  9. package/dist/Authentication/ActiveAccountStore.js.map +1 -0
  10. package/dist/Authentication/NodeMsalAuthenticationProvider.d.ts +57 -3
  11. package/dist/Authentication/NodeMsalAuthenticationProvider.d.ts.map +1 -1
  12. package/dist/Authentication/NodeMsalAuthenticationProvider.js +187 -27
  13. package/dist/Authentication/NodeMsalAuthenticationProvider.js.map +1 -1
  14. package/dist/Cli.d.ts.map +1 -1
  15. package/dist/Cli.js +8 -2
  16. package/dist/Cli.js.map +1 -1
  17. package/dist/CliSettings.d.ts.map +1 -1
  18. package/dist/CliSettings.js +1 -2
  19. package/dist/CliSettings.js.map +1 -1
  20. package/dist/CliUtils.d.ts +2 -1
  21. package/dist/CliUtils.d.ts.map +1 -1
  22. package/dist/CliUtils.js +4 -0
  23. package/dist/CliUtils.js.map +1 -1
  24. package/dist/Constants/CommandRegistry.d.ts.map +1 -1
  25. package/dist/Constants/CommandRegistry.js +44 -6
  26. package/dist/Constants/CommandRegistry.js.map +1 -1
  27. package/dist/Constants/HelpStrings.d.ts +75 -3
  28. package/dist/Constants/HelpStrings.d.ts.map +1 -1
  29. package/dist/Constants/HelpStrings.js +143 -41
  30. package/dist/Constants/HelpStrings.js.map +1 -1
  31. package/dist/Errors/GitHubErrorMap.d.ts +3 -3
  32. package/dist/Errors/GitHubErrorMap.d.ts.map +1 -1
  33. package/dist/Errors/GitHubErrorMap.js +12 -7
  34. package/dist/Errors/GitHubErrorMap.js.map +1 -1
  35. package/dist/FS/CliFs.d.ts.map +1 -1
  36. package/dist/FS/CliFs.js.map +1 -1
  37. package/dist/HttpClient/CliHttpClient.d.ts +17 -0
  38. package/dist/HttpClient/CliHttpClient.d.ts.map +1 -1
  39. package/dist/HttpClient/CliHttpClient.js +112 -1
  40. package/dist/HttpClient/CliHttpClient.js.map +1 -1
  41. package/dist/Logger/CliLogger.d.ts.map +1 -1
  42. package/dist/Logger/CliLogger.js +1 -1
  43. package/dist/Logger/CliLogger.js.map +1 -1
  44. package/dist/Logger/ConsoleWriter.d.ts.map +1 -1
  45. package/dist/Logger/ConsoleWriter.js +7 -7
  46. package/dist/Logger/ConsoleWriter.js.map +1 -1
  47. package/dist/Middletier/FunctionsBundler.d.ts +17 -0
  48. package/dist/Middletier/FunctionsBundler.d.ts.map +1 -0
  49. package/dist/Middletier/FunctionsBundler.js +165 -0
  50. package/dist/Middletier/FunctionsBundler.js.map +1 -0
  51. package/dist/Middletier/PackFunctions.d.ts +52 -0
  52. package/dist/Middletier/PackFunctions.d.ts.map +1 -0
  53. package/dist/Middletier/PackFunctions.js +122 -0
  54. package/dist/Middletier/PackFunctions.js.map +1 -0
  55. package/dist/Types/Cli.types.d.ts +42 -1
  56. package/dist/Types/Cli.types.d.ts.map +1 -1
  57. package/dist/Types/Command.types.d.ts +14 -3
  58. package/dist/Types/Command.types.d.ts.map +1 -1
  59. package/dist/Types/Command.types.js +4 -0
  60. package/dist/Types/Command.types.js.map +1 -1
  61. package/dist/Utils/BuildPolling.d.ts +18 -0
  62. package/dist/Utils/BuildPolling.d.ts.map +1 -0
  63. package/dist/Utils/BuildPolling.js +63 -0
  64. package/dist/Utils/BuildPolling.js.map +1 -0
  65. package/dist/Utils/BuildVerbDescriptionTable.d.ts +11 -1
  66. package/dist/Utils/BuildVerbDescriptionTable.d.ts.map +1 -1
  67. package/dist/Utils/BuildVerbDescriptionTable.js +73 -17
  68. package/dist/Utils/BuildVerbDescriptionTable.js.map +1 -1
  69. package/dist/Utils/ConsoleOutput.d.ts.map +1 -1
  70. package/dist/Utils/ConsoleOutput.js +15 -12
  71. package/dist/Utils/ConsoleOutput.js.map +1 -1
  72. package/dist/Utils/DcfRecovery.d.ts +84 -0
  73. package/dist/Utils/DcfRecovery.d.ts.map +1 -0
  74. package/dist/Utils/DcfRecovery.js +258 -0
  75. package/dist/Utils/DcfRecovery.js.map +1 -0
  76. package/dist/Utils/EnhanceNetworkError.d.ts.map +1 -1
  77. package/dist/Utils/EnhanceNetworkError.js +2 -0
  78. package/dist/Utils/EnhanceNetworkError.js.map +1 -1
  79. package/dist/Utils/EnvVars.d.ts +1 -1
  80. package/dist/Utils/EnvVars.d.ts.map +1 -1
  81. package/dist/Utils/EnvVars.js.map +1 -1
  82. package/dist/Utils/EnvironmentRoutingUtils.d.ts +8 -0
  83. package/dist/Utils/EnvironmentRoutingUtils.d.ts.map +1 -0
  84. package/dist/Utils/EnvironmentRoutingUtils.js +45 -0
  85. package/dist/Utils/EnvironmentRoutingUtils.js.map +1 -0
  86. package/dist/Utils/GitHubDcfFlow.d.ts +4 -5
  87. package/dist/Utils/GitHubDcfFlow.d.ts.map +1 -1
  88. package/dist/Utils/GitHubDcfFlow.js +4 -5
  89. package/dist/Utils/GitHubDcfFlow.js.map +1 -1
  90. package/dist/Utils/GitUtils.d.ts +5 -0
  91. package/dist/Utils/GitUtils.d.ts.map +1 -1
  92. package/dist/Utils/GitUtils.js +15 -0
  93. package/dist/Utils/GitUtils.js.map +1 -1
  94. package/dist/Utils/Paging.d.ts.map +1 -1
  95. package/dist/Utils/Paging.js +4 -4
  96. package/dist/Utils/Paging.js.map +1 -1
  97. package/dist/Utils/ResolveCommand.d.ts +7 -1
  98. package/dist/Utils/ResolveCommand.d.ts.map +1 -1
  99. package/dist/Utils/ResolveCommand.js +38 -20
  100. package/dist/Utils/ResolveCommand.js.map +1 -1
  101. package/dist/Utils/Spinner.d.ts +9 -1
  102. package/dist/Utils/Spinner.d.ts.map +1 -1
  103. package/dist/Utils/Spinner.js +25 -5
  104. package/dist/Utils/Spinner.js.map +1 -1
  105. package/dist/Verbs/AddAction.d.ts.map +1 -1
  106. package/dist/Verbs/AddAction.js +12 -41
  107. package/dist/Verbs/AddAction.js.map +1 -1
  108. package/dist/Verbs/AddConnector.d.ts +24 -0
  109. package/dist/Verbs/AddConnector.d.ts.map +1 -0
  110. package/dist/Verbs/AddConnector.js +156 -0
  111. package/dist/Verbs/AddConnector.js.map +1 -0
  112. package/dist/Verbs/AddConnectorFlows.d.ts +72 -0
  113. package/dist/Verbs/AddConnectorFlows.d.ts.map +1 -0
  114. package/dist/Verbs/AddConnectorFlows.js +198 -0
  115. package/dist/Verbs/AddConnectorFlows.js.map +1 -0
  116. package/dist/Verbs/AddDataSource.js +1 -1
  117. package/dist/Verbs/AddDataSource.js.map +1 -1
  118. package/dist/Verbs/AddTable.d.ts.map +1 -1
  119. package/dist/Verbs/AddTable.js +15 -100
  120. package/dist/Verbs/AddTable.js.map +1 -1
  121. package/dist/Verbs/AuthStatus.d.ts.map +1 -1
  122. package/dist/Verbs/AuthStatus.js +34 -6
  123. package/dist/Verbs/AuthStatus.js.map +1 -1
  124. package/dist/Verbs/AuthSwitch.d.ts +6 -0
  125. package/dist/Verbs/AuthSwitch.d.ts.map +1 -0
  126. package/dist/Verbs/AuthSwitch.js +67 -0
  127. package/dist/Verbs/AuthSwitch.js.map +1 -0
  128. package/dist/Verbs/BuildMaafApp.d.ts.map +1 -1
  129. package/dist/Verbs/BuildMaafApp.js +98 -22
  130. package/dist/Verbs/BuildMaafApp.js.map +1 -1
  131. package/dist/Verbs/ConnectorHelpers.d.ts +54 -1
  132. package/dist/Verbs/ConnectorHelpers.d.ts.map +1 -1
  133. package/dist/Verbs/ConnectorHelpers.js +217 -16
  134. package/dist/Verbs/ConnectorHelpers.js.map +1 -1
  135. package/dist/Verbs/CreateMaafApp.d.ts +75 -0
  136. package/dist/Verbs/CreateMaafApp.d.ts.map +1 -1
  137. package/dist/Verbs/CreateMaafApp.js +273 -75
  138. package/dist/Verbs/CreateMaafApp.js.map +1 -1
  139. package/dist/Verbs/DeployMaafApp.d.ts.map +1 -1
  140. package/dist/Verbs/DeployMaafApp.js +52 -20
  141. package/dist/Verbs/DeployMaafApp.js.map +1 -1
  142. package/dist/Verbs/Dev.js +5 -5
  143. package/dist/Verbs/Dev.js.map +1 -1
  144. package/dist/Verbs/GetMaafBuildStatus.d.ts.map +1 -1
  145. package/dist/Verbs/GetMaafBuildStatus.js +66 -17
  146. package/dist/Verbs/GetMaafBuildStatus.js.map +1 -1
  147. package/dist/Verbs/Init.d.ts.map +1 -1
  148. package/dist/Verbs/Init.js +170 -60
  149. package/dist/Verbs/Init.js.map +1 -1
  150. package/dist/Verbs/ListConnectors.d.ts.map +1 -1
  151. package/dist/Verbs/ListConnectors.js +4 -2
  152. package/dist/Verbs/ListConnectors.js.map +1 -1
  153. package/dist/Verbs/ListDatasets.d.ts.map +1 -1
  154. package/dist/Verbs/ListDatasets.js +5 -0
  155. package/dist/Verbs/ListDatasets.js.map +1 -1
  156. package/dist/Verbs/ListFlows.d.ts.map +1 -1
  157. package/dist/Verbs/ListFlows.js +1 -2
  158. package/dist/Verbs/ListFlows.js.map +1 -1
  159. package/dist/Verbs/ListSqlStoredProcedures.d.ts.map +1 -1
  160. package/dist/Verbs/ListSqlStoredProcedures.js +5 -0
  161. package/dist/Verbs/ListSqlStoredProcedures.js.map +1 -1
  162. package/dist/Verbs/ListTables.d.ts.map +1 -1
  163. package/dist/Verbs/ListTables.js +5 -0
  164. package/dist/Verbs/ListTables.js.map +1 -1
  165. package/dist/Verbs/Login.d.ts.map +1 -1
  166. package/dist/Verbs/Login.js +16 -13
  167. package/dist/Verbs/Login.js.map +1 -1
  168. package/dist/Verbs/Logout.d.ts.map +1 -1
  169. package/dist/Verbs/Logout.js +19 -13
  170. package/dist/Verbs/Logout.js.map +1 -1
  171. package/dist/Verbs/MaafAppPermissions.d.ts.map +1 -1
  172. package/dist/Verbs/MaafAppPermissions.js +4 -0
  173. package/dist/Verbs/MaafAppPermissions.js.map +1 -1
  174. package/dist/Verbs/Pack.d.ts +6 -6
  175. package/dist/Verbs/Pack.d.ts.map +1 -1
  176. package/dist/Verbs/Pack.js +80 -12
  177. package/dist/Verbs/Pack.js.map +1 -1
  178. package/dist/Verbs/PlayMaafApp.d.ts +22 -0
  179. package/dist/Verbs/PlayMaafApp.d.ts.map +1 -0
  180. package/dist/Verbs/PlayMaafApp.js +147 -0
  181. package/dist/Verbs/PlayMaafApp.js.map +1 -0
  182. package/dist/Verbs/RefreshDataSource.d.ts.map +1 -1
  183. package/dist/Verbs/RefreshDataSource.js.map +1 -1
  184. package/dist/Verbs/RefreshGitAuth.d.ts.map +1 -1
  185. package/dist/Verbs/RefreshGitAuth.js +1 -1
  186. package/dist/Verbs/RefreshGitAuth.js.map +1 -1
  187. package/dist/Verbs/ShareLinkCreate.d.ts +23 -0
  188. package/dist/Verbs/ShareLinkCreate.d.ts.map +1 -0
  189. package/dist/Verbs/ShareLinkCreate.js +73 -0
  190. package/dist/Verbs/ShareLinkCreate.js.map +1 -0
  191. package/dist/Verbs/ShareLinkList.d.ts +16 -0
  192. package/dist/Verbs/ShareLinkList.d.ts.map +1 -0
  193. package/dist/Verbs/ShareLinkList.js +84 -0
  194. package/dist/Verbs/ShareLinkList.js.map +1 -0
  195. package/dist/Verbs/ShareLinkRevoke.d.ts +22 -0
  196. package/dist/Verbs/ShareLinkRevoke.d.ts.map +1 -0
  197. package/dist/Verbs/ShareLinkRevoke.js +137 -0
  198. package/dist/Verbs/ShareLinkRevoke.js.map +1 -0
  199. package/dist/Verbs/VerbConstants.d.ts +151 -21
  200. package/dist/Verbs/VerbConstants.d.ts.map +1 -1
  201. package/dist/Verbs/VerbConstants.js +127 -21
  202. package/dist/Verbs/VerbConstants.js.map +1 -1
  203. package/dist/Verbs/index.d.ts +6 -0
  204. package/dist/Verbs/index.d.ts.map +1 -1
  205. package/dist/Verbs/index.js +6 -0
  206. package/dist/Verbs/index.js.map +1 -1
  207. package/package.json +8 -8
@@ -0,0 +1,165 @@
1
+ /*!
2
+ * Copyright (C) Microsoft Corporation. All rights reserved.
3
+ */
4
+ import * as path from 'node:path';
5
+ import { AppError } from '../Errors/CliError.js';
6
+ /**
7
+ * Maps the browser-SDK specifiers that generated/customer code imports to the
8
+ * workerd-SDK specifiers that survive into the bundled output. esbuild uses
9
+ * this map for two things:
10
+ * - `alias`: rewrites every key to its value during resolution.
11
+ * - `external`: marks every value as external so the import statement is
12
+ * left intact in the bundle and resolved at workerd instantiation time.
13
+ *
14
+ * The allowlist plugin also derives from this map (see {@link ALLOWED_PACKAGES}),
15
+ * so this is the single source of truth — the three derived uses stay in sync
16
+ * automatically.
17
+ */
18
+ const MIDDLETIER_PACKAGE_ALIAS_MAP = {
19
+ '@microsoft/managed-apps/data': '@microsoft/managed-apps-functions/data',
20
+ };
21
+ /**
22
+ * Specifier the externalized `generated/dataSources` import gets rewritten to.
23
+ * The functions-runtime registers a workerd `json` module under this name with
24
+ * the pack's `dataSources.json` as its content, so every customer bundle reads
25
+ * the data sources from a single shared file instead of inlining a per-bundle
26
+ * copy of the ~16KB config blob.
27
+ */
28
+ const DATA_SOURCES_MODULE = '@config/dataSources';
29
+ /**
30
+ * Bundles each discovered function entry point to ESM JavaScript using esbuild.
31
+ * Returns a Map keyed by the function's `relPath` (same key as
32
+ * {@link DiscoveredFunction.relPath}) with the bundled JS source as the value.
33
+ *
34
+ * esbuild is imported dynamically (`await import('esbuild')`) so the CLI can be
35
+ * shipped into environments that mark esbuild `--external` and supply their own.
36
+ */
37
+ export async function bundleFunctionsAsync(args) {
38
+ const { projectRoot, functions } = args;
39
+ if (functions.length === 0)
40
+ return new Map();
41
+ // `.catch` so a missing-esbuild error gets a clear, actionable message
42
+ // instead of the raw module-resolution failure surfacing to the user.
43
+ const esbuild = await import('esbuild').catch((err) => {
44
+ throw new AppError(`esbuild is required to pack functions but could not be loaded: ${err.message}`);
45
+ });
46
+ // esbuild's Go worker pool parallelises within a single `build()`, but
47
+ // running per-file builds in parallel still lets us overlap plugin
48
+ // callbacks and JS-side work. esbuild self-bounds concurrency internally,
49
+ // so we don't need our own semaphore.
50
+ const entries = await Promise.all(functions.map(async (fn) => {
51
+ const result = await esbuild.build({
52
+ entryPoints: [fn.absPath],
53
+ bundle: true,
54
+ write: false,
55
+ format: 'esm',
56
+ platform: 'neutral',
57
+ target: 'es2022',
58
+ external: [...Object.values(MIDDLETIER_PACKAGE_ALIAS_MAP), DATA_SOURCES_MODULE],
59
+ alias: MIDDLETIER_PACKAGE_ALIAS_MAP,
60
+ // Plugin order matters — `dataSourcesPlugin` returns first so the
61
+ // allowlist never sees the externalised `@config/dataSources` rewrite
62
+ // and the resolved-path lookup for `generated/dataSources.ts` short-
63
+ // circuits before the allowlist would have admitted it via the
64
+ // `generated/` rule.
65
+ plugins: [dataSourcesPlugin(projectRoot), allowlistPlugin(projectRoot)],
66
+ logLevel: 'silent',
67
+ });
68
+ const output = result.outputFiles?.[0];
69
+ if (!output) {
70
+ throw new AppError(`Failed to bundle function ${fn.relPath}: esbuild produced no output`);
71
+ }
72
+ return [fn.relPath, output.text];
73
+ }));
74
+ return new Map(entries);
75
+ }
76
+ /**
77
+ * esbuild `onResolve` plugin that intercepts the codegen-emitted
78
+ * `import dataSources from '../dataSources'` (or any path resolving to
79
+ * `<projectRoot>/generated/dataSources.<ext>`) and rewrites it to the
80
+ * canonical {@link DATA_SOURCES_MODULE} specifier, marked external. The
81
+ * functions-runtime supplies the resolved value at workerd config time as a
82
+ * `json` module embedded from the pack's `dataSources.json`, so a single
83
+ * shared copy is read by every function instead of the ~16KB config map
84
+ * being inlined into each bundle.
85
+ *
86
+ * Matching is by resolved file path (not import-specifier string) so codegen
87
+ * layout changes that move the file or alter the relative-path shape don't
88
+ * break the substitution.
89
+ */
90
+ function dataSourcesPlugin(projectRoot) {
91
+ // Codegen always emits `generated/dataSources.ts`; specifier is extensionless
92
+ // (`../dataSources`), so we resolve the relative path and tack on `.ts` to
93
+ // get the candidate filesystem location, then compare.
94
+ const target = path.resolve(projectRoot, 'generated/dataSources.ts');
95
+ return {
96
+ name: 'external-data-sources',
97
+ setup(build) {
98
+ build.onResolve({ filter: /(^|\/)dataSources$/ }, (args) => {
99
+ if (!args.path.startsWith('.'))
100
+ return null;
101
+ const resolved = path.resolve(path.dirname(args.importer), args.path) + '.ts';
102
+ if (resolved !== target)
103
+ return null;
104
+ return { path: DATA_SOURCES_MODULE, external: true };
105
+ });
106
+ },
107
+ };
108
+ }
109
+ /**
110
+ * esbuild `onResolve` plugin that fails the build when customer code imports
111
+ * anything outside the allowlist. Two categories pass:
112
+ *
113
+ * - Relative imports that resolve inside the project's `generated/` folder.
114
+ * - Bare specifiers exactly matching an entry in {@link ALLOWED_PACKAGES}.
115
+ *
116
+ * esbuild applies `alias` substitution *after* `onResolve` plugins run, so the
117
+ * incoming `args.path` is always the pre-alias specifier.
118
+ */
119
+ function allowlistPlugin(projectRoot) {
120
+ const generatedDir = path.resolve(projectRoot, 'generated');
121
+ return {
122
+ name: 'allowlist-imports',
123
+ setup(build) {
124
+ build.onResolve({ filter: /.*/ }, (args) => {
125
+ if (args.kind === 'entry-point')
126
+ return null;
127
+ if (args.path.startsWith('.')) {
128
+ const resolved = path.resolve(path.dirname(args.importer), args.path);
129
+ if (resolved.startsWith(generatedDir + path.sep)) {
130
+ return null;
131
+ }
132
+ return {
133
+ errors: [
134
+ {
135
+ text: `Relative import '${args.path}' is outside the allowed 'generated/' folder`,
136
+ },
137
+ ],
138
+ };
139
+ }
140
+ /**
141
+ * The exact module specifiers customer/generated code is allowed to import
142
+ * from outside the project's `generated/` folder. Anything else — arbitrary
143
+ * npm packages, `node:*` built-ins, other scopes, deeper subpaths — is a
144
+ * build error.
145
+ *
146
+ * esbuild applies `alias` substitution *after* `onResolve` plugins run, so the
147
+ * allowlist matches the pre-alias specifier (the map key), not the post-alias
148
+ * target.
149
+ */
150
+ if (MIDDLETIER_PACKAGE_ALIAS_MAP[args.path])
151
+ return null;
152
+ return {
153
+ errors: [
154
+ {
155
+ text: `Import '${args.path}' is not on the allowlist. Allowed: relative imports into 'generated/' and ${Object.keys(MIDDLETIER_PACKAGE_ALIAS_MAP)
156
+ .map((p) => `'${p}'`)
157
+ .join(', ')}.`,
158
+ },
159
+ ],
160
+ };
161
+ });
162
+ },
163
+ };
164
+ }
165
+ //# sourceMappingURL=FunctionsBundler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FunctionsBundler.js","sourceRoot":"","sources":["../../src/Middletier/FunctionsBundler.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAIlC,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAG9C;;;;;;;;;;;GAWG;AACH,MAAM,4BAA4B,GAA2B;IAC3D,8BAA8B,EAAE,wCAAwC;CACzE,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,mBAAmB,GAAG,qBAAqB,CAAC;AAElD;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,IAG1C;IACC,MAAM,EAAE,WAAW,EAAE,SAAS,EAAE,GAAG,IAAI,CAAC;IACxC,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,GAAG,EAAE,CAAC;IAE7C,uEAAuE;IACvE,sEAAsE;IACtE,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,CAAC,GAAU,EAAE,EAAE;QAC3D,MAAM,IAAI,QAAQ,CAChB,kEAAkE,GAAG,CAAC,OAAO,EAAE,CAChF,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,uEAAuE;IACvE,mEAAmE;IACnE,0EAA0E;IAC1E,sCAAsC;IACtC,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,GAAG,CAC/B,SAAS,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,EAAE,EAAE;QACzB,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC;YACjC,WAAW,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC;YACzB,MAAM,EAAE,IAAI;YACZ,KAAK,EAAE,KAAK;YACZ,MAAM,EAAE,KAAK;YACb,QAAQ,EAAE,SAAS;YACnB,MAAM,EAAE,QAAQ;YAChB,QAAQ,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,4BAA4B,CAAC,EAAE,mBAAmB,CAAC;YAC/E,KAAK,EAAE,4BAA4B;YACnC,kEAAkE;YAClE,sEAAsE;YACtE,qEAAqE;YACrE,+DAA+D;YAC/D,qBAAqB;YACrB,OAAO,EAAE,CAAC,iBAAiB,CAAC,WAAW,CAAC,EAAE,eAAe,CAAC,WAAW,CAAC,CAAC;YACvE,QAAQ,EAAE,QAAQ;SACnB,CAAC,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,CAAC;QACvC,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,IAAI,QAAQ,CAAC,6BAA6B,EAAE,CAAC,OAAO,8BAA8B,CAAC,CAAC;QAC5F,CAAC;QACD,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,IAAI,CAAU,CAAC;IAC5C,CAAC,CAAC,CACH,CAAC;IACF,OAAO,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC;AAC1B,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,SAAS,iBAAiB,CAAC,WAAmB;IAC5C,8EAA8E;IAC9E,2EAA2E;IAC3E,uDAAuD;IACvD,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,0BAA0B,CAAC,CAAC;IAErE,OAAO;QACL,IAAI,EAAE,uBAAuB;QAC7B,KAAK,CAAC,KAAkB;YACtB,KAAK,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,oBAAoB,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE;gBACzD,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;oBAAE,OAAO,IAAI,CAAC;gBAC5C,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC;gBAC9E,IAAI,QAAQ,KAAK,MAAM;oBAAE,OAAO,IAAI,CAAC;gBACrC,OAAO,EAAE,IAAI,EAAE,mBAAmB,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;YACvD,CAAC,CAAC,CAAC;QACL,CAAC;KACF,CAAC;AACJ,CAAC;AAED;;;;;;;;;GASG;AACH,SAAS,eAAe,CAAC,WAAmB;IAC1C,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;IAE5D,OAAO;QACL,IAAI,EAAE,mBAAmB;QACzB,KAAK,CAAC,KAAkB;YACtB,KAAK,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE;gBACzC,IAAI,IAAI,CAAC,IAAI,KAAK,aAAa;oBAAE,OAAO,IAAI,CAAC;gBAE7C,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;oBAC9B,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;oBACtE,IAAI,QAAQ,CAAC,UAAU,CAAC,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;wBACjD,OAAO,IAAI,CAAC;oBACd,CAAC;oBACD,OAAO;wBACL,MAAM,EAAE;4BACN;gCACE,IAAI,EAAE,oBAAoB,IAAI,CAAC,IAAI,8CAA8C;6BAClF;yBACF;qBACF,CAAC;gBACJ,CAAC;gBAED;;;;;;;;;mBASG;gBACH,IAAI,4BAA4B,CAAC,IAAI,CAAC,IAAI,CAAC;oBAAE,OAAO,IAAI,CAAC;gBAEzD,OAAO;oBACL,MAAM,EAAE;wBACN;4BACE,IAAI,EAAE,WACJ,IAAI,CAAC,IACP,8EAA8E,MAAM,CAAC,IAAI,CACvF,4BAA4B,CAC7B;iCACE,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC;iCACpB,IAAI,CAAC,IAAI,CAAC,GAAG;yBACjB;qBACF;iBACF,CAAC;YACJ,CAAC,CAAC,CAAC;QACL,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,52 @@
1
+ /*!
2
+ * Copyright (C) Microsoft Corporation. All rights reserved.
3
+ */
4
+ import type { FunctionRoute, FunctionsPackage } from '@microsoft/managed-apps-common/types';
5
+ /** Filename of the functions archive written next to manifest.json. */
6
+ export declare const FUNCTIONS_ARCHIVE_NAME = "functions.zip";
7
+ /** Archive format/compression embedded in the manifest. Standard zip uses DEFLATE. */
8
+ export declare const FUNCTIONS_ARCHIVE_DESCRIPTOR: Omit<FunctionsPackage, 'path'>;
9
+ /** A single `.ts` function discovered under `functions.baseDirectory`. */
10
+ export interface DiscoveredFunction {
11
+ /** Path relative to `functions.baseDirectory`, with forward slashes. Includes `.ts` suffix. */
12
+ relPath: string;
13
+ /** Absolute path to the source file on disk. */
14
+ absPath: string;
15
+ }
16
+ /**
17
+ * Recursively walks `baseDirectory` and returns every `.ts` file beneath it.
18
+ *
19
+ * The directory must exist; callers are expected to have validated this via
20
+ * {@link assertFunctionsDirectoryExists}. An existing directory containing no
21
+ * `.ts` files returns an empty array — that case maps to "skip packing" per the
22
+ * pack spec, not an error.
23
+ */
24
+ export declare function discoverFunctionsAsync(baseDirectory: string): Promise<DiscoveredFunction[]>;
25
+ export declare function assertFunctionsDirectoryExists(baseDirectory: string): Promise<void>;
26
+ /**
27
+ * Builds the `routes` entries for compiled functions. The key is the basename
28
+ * of `functions.baseDirectory` joined with the function's path relative to
29
+ * that directory (`.ts` stripped); `path` is the same string with `.js`. Both
30
+ * mirror the entry's location inside the archive.
31
+ */
32
+ export declare function buildFunctionRoutes(functions: readonly DiscoveredFunction[], baseDirName: string): Record<string, FunctionRoute>;
33
+ /**
34
+ * Builds a zip Buffer containing one bundled `.js` per discovered `.ts` source
35
+ * (mirroring the source layout under `<baseDirName>/`), plus the generated
36
+ * `manifest.json` and — when present — `dataSources.json`.
37
+ *
38
+ * `bundles` is a Map keyed by `DiscoveredFunction.relPath` whose value is the
39
+ * bundled JS source from {@link bundleFunctionsAsync}. Every discovered function
40
+ * must have a corresponding bundle; missing entries throw.
41
+ *
42
+ * Returning a `Buffer` (vs. streaming to disk) lets callers use `fsp.writeFile`,
43
+ * which keeps the implementation testable under memfs.
44
+ */
45
+ export declare function buildFunctionsArchiveAsync(args: {
46
+ baseDirName: string;
47
+ functions: readonly DiscoveredFunction[];
48
+ bundles: ReadonlyMap<string, string>;
49
+ manifestContent: string;
50
+ dataSourcesJson: string | undefined;
51
+ }): Promise<Buffer>;
52
+ //# sourceMappingURL=PackFunctions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PackFunctions.d.ts","sourceRoot":"","sources":["../../src/Middletier/PackFunctions.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,OAAO,KAAK,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,sCAAsC,CAAC;AAK5F,uEAAuE;AACvE,eAAO,MAAM,sBAAsB,kBAAkB,CAAC;AAEtD,sFAAsF;AACtF,eAAO,MAAM,4BAA4B,EAAE,IAAI,CAAC,gBAAgB,EAAE,MAAM,CAGvE,CAAC;AAEF,0EAA0E;AAC1E,MAAM,WAAW,kBAAkB;IACjC,+FAA+F;IAC/F,OAAO,EAAE,MAAM,CAAC;IAChB,gDAAgD;IAChD,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;GAOG;AACH,wBAAsB,sBAAsB,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAKjG;AA6BD,wBAAsB,8BAA8B,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAUzF;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CACjC,SAAS,EAAE,SAAS,kBAAkB,EAAE,EACxC,WAAW,EAAE,MAAM,GAClB,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAU/B;AAMD;;;;;;;;;;;GAWG;AACH,wBAAsB,0BAA0B,CAAC,IAAI,EAAE;IACrD,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,SAAS,kBAAkB,EAAE,CAAC;IACzC,OAAO,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,eAAe,EAAE,MAAM,CAAC;IACxB,eAAe,EAAE,MAAM,GAAG,SAAS,CAAC;CACrC,GAAG,OAAO,CAAC,MAAM,CAAC,CA8BlB"}
@@ -0,0 +1,122 @@
1
+ /*!
2
+ * Copyright (C) Microsoft Corporation. All rights reserved.
3
+ */
4
+ import * as fsp from 'node:fs/promises';
5
+ import * as path from 'node:path';
6
+ import archiver from 'archiver';
7
+ import { ConfigurationError } from '../Errors/CliError.js';
8
+ /** Filename of the functions archive written next to manifest.json. */
9
+ export const FUNCTIONS_ARCHIVE_NAME = 'functions.zip';
10
+ /** Archive format/compression embedded in the manifest. Standard zip uses DEFLATE. */
11
+ export const FUNCTIONS_ARCHIVE_DESCRIPTOR = {
12
+ archive: 'zip',
13
+ compression: 'deflate',
14
+ };
15
+ /**
16
+ * Recursively walks `baseDirectory` and returns every `.ts` file beneath it.
17
+ *
18
+ * The directory must exist; callers are expected to have validated this via
19
+ * {@link assertFunctionsDirectoryExists}. An existing directory containing no
20
+ * `.ts` files returns an empty array — that case maps to "skip packing" per the
21
+ * pack spec, not an error.
22
+ */
23
+ export async function discoverFunctionsAsync(baseDirectory) {
24
+ const results = [];
25
+ await walkAsync(baseDirectory, '', results);
26
+ results.sort((a, b) => a.relPath.localeCompare(b.relPath));
27
+ return results;
28
+ }
29
+ async function walkAsync(absDir, relDir, out) {
30
+ const entries = await fsp.readdir(absDir, { withFileTypes: true });
31
+ for (const entry of entries) {
32
+ const entryRel = relDir ? `${relDir}/${entry.name}` : entry.name;
33
+ const entryAbs = path.join(absDir, entry.name);
34
+ if (entry.isDirectory()) {
35
+ await walkAsync(entryAbs, entryRel, out);
36
+ }
37
+ else if (entry.isFile() && isFunctionSourceFile(entry.name)) {
38
+ out.push({ relPath: entryRel, absPath: entryAbs });
39
+ }
40
+ }
41
+ }
42
+ /**
43
+ * `.ts` files that are part of the function surface. Skips type declarations
44
+ * (`.d.ts` — no runtime) and unit-test files (`.test.ts` / `.spec.ts` — not
45
+ * functions, and the common JS ecosystem convention is to co-locate them).
46
+ */
47
+ function isFunctionSourceFile(name) {
48
+ return (name.endsWith('.ts') &&
49
+ !name.endsWith('.d.ts') &&
50
+ !name.endsWith('.test.ts') &&
51
+ !name.endsWith('.spec.ts'));
52
+ }
53
+ export async function assertFunctionsDirectoryExists(baseDirectory) {
54
+ let stat;
55
+ try {
56
+ stat = await fsp.stat(baseDirectory);
57
+ }
58
+ catch {
59
+ throw new ConfigurationError(`functions.baseDirectory does not exist: ${baseDirectory}`);
60
+ }
61
+ if (!stat.isDirectory()) {
62
+ throw new ConfigurationError(`functions.baseDirectory is not a directory: ${baseDirectory}`);
63
+ }
64
+ }
65
+ /**
66
+ * Builds the `routes` entries for compiled functions. The key is the basename
67
+ * of `functions.baseDirectory` joined with the function's path relative to
68
+ * that directory (`.ts` stripped); `path` is the same string with `.js`. Both
69
+ * mirror the entry's location inside the archive.
70
+ */
71
+ export function buildFunctionRoutes(functions, baseDirName) {
72
+ const routes = {};
73
+ for (const fn of functions) {
74
+ const routeKey = `${baseDirName}/${stripTsExtension(fn.relPath)}`;
75
+ routes[routeKey] = {
76
+ type: 'function',
77
+ path: `${routeKey}.js`,
78
+ };
79
+ }
80
+ return routes;
81
+ }
82
+ function stripTsExtension(relPath) {
83
+ return relPath.slice(0, -'.ts'.length);
84
+ }
85
+ /**
86
+ * Builds a zip Buffer containing one bundled `.js` per discovered `.ts` source
87
+ * (mirroring the source layout under `<baseDirName>/`), plus the generated
88
+ * `manifest.json` and — when present — `dataSources.json`.
89
+ *
90
+ * `bundles` is a Map keyed by `DiscoveredFunction.relPath` whose value is the
91
+ * bundled JS source from {@link bundleFunctionsAsync}. Every discovered function
92
+ * must have a corresponding bundle; missing entries throw.
93
+ *
94
+ * Returning a `Buffer` (vs. streaming to disk) lets callers use `fsp.writeFile`,
95
+ * which keeps the implementation testable under memfs.
96
+ */
97
+ export async function buildFunctionsArchiveAsync(args) {
98
+ const { baseDirName, functions, bundles, manifestContent, dataSourcesJson } = args;
99
+ return new Promise((resolve, reject) => {
100
+ const chunks = [];
101
+ const archive = archiver('zip', { zlib: { level: 9 } });
102
+ archive.on('data', (chunk) => chunks.push(chunk));
103
+ archive.on('warning', reject);
104
+ archive.on('error', reject);
105
+ archive.on('end', () => resolve(Buffer.concat(chunks)));
106
+ for (const fn of functions) {
107
+ const bundled = bundles.get(fn.relPath);
108
+ if (bundled === undefined) {
109
+ reject(new Error(`Missing bundled output for function ${fn.relPath}`));
110
+ return;
111
+ }
112
+ const routeKey = stripTsExtension(fn.relPath);
113
+ archive.append(bundled, { name: `${baseDirName}/${routeKey}.js` });
114
+ }
115
+ archive.append(manifestContent, { name: 'manifest.json' });
116
+ if (dataSourcesJson !== undefined) {
117
+ archive.append(dataSourcesJson, { name: 'dataSources.json' });
118
+ }
119
+ void archive.finalize();
120
+ });
121
+ }
122
+ //# sourceMappingURL=PackFunctions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PackFunctions.js","sourceRoot":"","sources":["../../src/Middletier/PackFunctions.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,GAAG,MAAM,kBAAkB,CAAC;AACxC,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAGlC,OAAO,QAAQ,MAAM,UAAU,CAAC;AAEhC,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAExD,uEAAuE;AACvE,MAAM,CAAC,MAAM,sBAAsB,GAAG,eAAe,CAAC;AAEtD,sFAAsF;AACtF,MAAM,CAAC,MAAM,4BAA4B,GAAmC;IAC1E,OAAO,EAAE,KAAK;IACd,WAAW,EAAE,SAAS;CACvB,CAAC;AAUF;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAAC,aAAqB;IAChE,MAAM,OAAO,GAAyB,EAAE,CAAC;IACzC,MAAM,SAAS,CAAC,aAAa,EAAE,EAAE,EAAE,OAAO,CAAC,CAAC;IAC5C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;IAC3D,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,KAAK,UAAU,SAAS,CAAC,MAAc,EAAE,MAAc,EAAE,GAAyB;IAChF,MAAM,OAAO,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;IACnE,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,MAAM,QAAQ,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC;QACjE,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QAC/C,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;YACxB,MAAM,SAAS,CAAC,QAAQ,EAAE,QAAQ,EAAE,GAAG,CAAC,CAAC;QAC3C,CAAC;aAAM,IAAI,KAAK,CAAC,MAAM,EAAE,IAAI,oBAAoB,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YAC9D,GAAG,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC,CAAC;QACrD,CAAC;IACH,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,SAAS,oBAAoB,CAAC,IAAY;IACxC,OAAO,CACL,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;QACpB,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC;QACvB,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC;QAC1B,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,CAC3B,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,8BAA8B,CAAC,aAAqB;IACxE,IAAI,IAAI,CAAC;IACT,IAAI,CAAC;QACH,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;IACvC,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,kBAAkB,CAAC,2CAA2C,aAAa,EAAE,CAAC,CAAC;IAC3F,CAAC;IACD,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;QACxB,MAAM,IAAI,kBAAkB,CAAC,+CAA+C,aAAa,EAAE,CAAC,CAAC;IAC/F,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,mBAAmB,CACjC,SAAwC,EACxC,WAAmB;IAEnB,MAAM,MAAM,GAAkC,EAAE,CAAC;IACjD,KAAK,MAAM,EAAE,IAAI,SAAS,EAAE,CAAC;QAC3B,MAAM,QAAQ,GAAG,GAAG,WAAW,IAAI,gBAAgB,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC;QAClE,MAAM,CAAC,QAAQ,CAAC,GAAG;YACjB,IAAI,EAAE,UAAU;YAChB,IAAI,EAAE,GAAG,QAAQ,KAAK;SACvB,CAAC;IACJ,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,gBAAgB,CAAC,OAAe;IACvC,OAAO,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;AACzC,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,KAAK,UAAU,0BAA0B,CAAC,IAMhD;IACC,MAAM,EAAE,WAAW,EAAE,SAAS,EAAE,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,GAAG,IAAI,CAAC;IAEnF,OAAO,IAAI,OAAO,CAAS,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QAC7C,MAAM,MAAM,GAAa,EAAE,CAAC;QAC5B,MAAM,OAAO,GAAG,QAAQ,CAAC,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;QAExD,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;QAC1D,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;QAC9B,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAC5B,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QAExD,KAAK,MAAM,EAAE,IAAI,SAAS,EAAE,CAAC;YAC3B,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC;YACxC,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;gBAC1B,MAAM,CAAC,IAAI,KAAK,CAAC,uCAAuC,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;gBACvE,OAAO;YACT,CAAC;YACD,MAAM,QAAQ,GAAG,gBAAgB,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC;YAC9C,OAAO,CAAC,MAAM,CAAC,OAAO,EAAE,EAAE,IAAI,EAAE,GAAG,WAAW,IAAI,QAAQ,KAAK,EAAE,CAAC,CAAC;QACrE,CAAC;QAED,OAAO,CAAC,MAAM,CAAC,eAAe,EAAE,EAAE,IAAI,EAAE,eAAe,EAAE,CAAC,CAAC;QAE3D,IAAI,eAAe,KAAK,SAAS,EAAE,CAAC;YAClC,OAAO,CAAC,MAAM,CAAC,eAAe,EAAE,EAAE,IAAI,EAAE,kBAAkB,EAAE,CAAC,CAAC;QAChE,CAAC;QAED,KAAK,OAAO,CAAC,QAAQ,EAAE,CAAC;IAC1B,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -4,13 +4,54 @@
4
4
  import type { AppConfig } from '@microsoft/managed-apps-common/config';
5
5
  import type { Region } from '@microsoft/managed-apps-common/services';
6
6
  import type { CliFS } from '../FS/CliFs.js';
7
+ export interface CachedAccount {
8
+ /** MSAL home account ID (`<oid>.<tid>`). Stable across email changes; the canonical key. */
9
+ homeAccountId: string;
10
+ /** UPN / email — what we show to the user. */
11
+ username: string;
12
+ /** True if this is the account currently used by silent token acquisition. */
13
+ isActive: boolean;
14
+ }
15
+ /**
16
+ * Acquires access tokens for authenticated CLI calls. Every auth mode (interactive MSAL,
17
+ * service principal, HTTP forward) implements this — it's the lowest common denominator.
18
+ */
7
19
  export interface IAuthenticationProvider {
8
20
  initAsync(region: Region): Promise<void>;
9
21
  getAccessTokenForResource(resource: string, loginHint?: string): Promise<string>;
10
22
  getUserTenantId(): string | undefined;
11
- /** Returns the cached account email without triggering interactive login. */
23
+ /** Returns the active cached account email without triggering interactive login. */
12
24
  getCachedAccountAsync(): Promise<string | undefined>;
13
25
  }
26
+ /**
27
+ * Manages the local cache of signed-in accounts: list, switch, remove, add. Only the
28
+ * interactive MSAL provider supports this. Service principal and HTTP forward modes don't
29
+ * have a "cached account" concept, so they don't implement this interface and the
30
+ * `auth login`/`logout`/`status`/`switch` verbs refuse to run in those modes.
31
+ */
32
+ export interface IAccountManager {
33
+ /** Returns every cached account, marking which one is currently active. */
34
+ listCachedAccountsAsync(): Promise<CachedAccount[]>;
35
+ /**
36
+ * Marks `accountKey` (a username or homeAccountId) as the active account.
37
+ * Throws if no cached account matches. Returns the resolved account.
38
+ */
39
+ setActiveAccountAsync(accountKey: string): Promise<CachedAccount>;
40
+ /**
41
+ * Forces an interactive browser sign-in for `resource`. Used by `auth login` so users
42
+ * can add a new account even when one is already cached. Writes the signed-in account
43
+ * as the active one.
44
+ */
45
+ loginInteractiveAsync(resource: string, loginHint?: string): Promise<CachedAccount>;
46
+ /**
47
+ * Removes every cached account and the active-account pointer. Backs `auth logout`.
48
+ * Routing through the account manager (rather than `fs.rmSync` directly in the verb)
49
+ * lets non-interactive auth modes refuse the call uniformly via the standard
50
+ * `getAccountManager()` UsageError. Returns `true` when something was cleared and
51
+ * `false` when no cached state existed.
52
+ */
53
+ clearCacheAsync(): Promise<boolean>;
54
+ }
14
55
  export type CliSettings = {
15
56
  source: 'pac-cli' | 'standalone';
16
57
  interactive: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"Cli.types.d.ts","sourceRoot":"","sources":["../../src/Types/Cli.types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uCAAuC,CAAC;AACvE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,yCAAyC,CAAC;AAEtE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAEzC,MAAM,WAAW,uBAAuB;IACtC,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACzC,yBAAyB,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACjF,eAAe,IAAI,MAAM,GAAG,SAAS,CAAC;IACtC,6EAA6E;IAC7E,qBAAqB,IAAI,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;CACtD;AAED,MAAM,MAAM,WAAW,GAAG;IACxB,MAAM,EAAE,SAAS,GAAG,YAAY,CAAC;IACjC,WAAW,EAAE,OAAO,CAAC;IACrB,UAAU,EAAE,cAAc,CAAC;IAC3B,KAAK,EAAE,KAAK,CAAC;IACb,SAAS,CAAC,EAAE,SAAS,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC3B,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAClC,6DAA6D;IAC7D,MAAM,EAAE,OAAO,CAAC;IAChB,0DAA0D;IAC1D,OAAO,EAAE,OAAO,CAAC;CAClB,CAAC"}
1
+ {"version":3,"file":"Cli.types.d.ts","sourceRoot":"","sources":["../../src/Types/Cli.types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uCAAuC,CAAC;AACvE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,yCAAyC,CAAC;AAEtE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAEzC,MAAM,WAAW,aAAa;IAC5B,4FAA4F;IAC5F,aAAa,EAAE,MAAM,CAAC;IACtB,8CAA8C;IAC9C,QAAQ,EAAE,MAAM,CAAC;IACjB,8EAA8E;IAC9E,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED;;;GAGG;AACH,MAAM,WAAW,uBAAuB;IACtC,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACzC,yBAAyB,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACjF,eAAe,IAAI,MAAM,GAAG,SAAS,CAAC;IACtC,oFAAoF;IACpF,qBAAqB,IAAI,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;CACtD;AAED;;;;;GAKG;AACH,MAAM,WAAW,eAAe;IAC9B,2EAA2E;IAC3E,uBAAuB,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC;IACpD;;;OAGG;IACH,qBAAqB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;IAClE;;;;OAIG;IACH,qBAAqB,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;IACpF;;;;;;OAMG;IACH,eAAe,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;CACrC;AAED,MAAM,MAAM,WAAW,GAAG;IACxB,MAAM,EAAE,SAAS,GAAG,YAAY,CAAC;IACjC,WAAW,EAAE,OAAO,CAAC;IACrB,UAAU,EAAE,cAAc,CAAC;IAC3B,KAAK,EAAE,KAAK,CAAC;IACb,SAAS,CAAC,EAAE,SAAS,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC3B,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAClC,6DAA6D;IAC7D,MAAM,EAAE,OAAO,CAAC;IAChB,0DAA0D;IAC1D,OAAO,EAAE,OAAO,CAAC;CAClB,CAAC"}
@@ -12,15 +12,26 @@ export interface LeafCommandDef {
12
12
  handler: CommandHandler;
13
13
  }
14
14
  /**
15
- * A typed verb group where the third token selects the subcommand type.
16
- * e.g. `app add table` 'add' is the verb, 'table' is the type.
15
+ * A typed verb group whose next token selects a subcommand. Commands within
16
+ * a typed verb may themselves be typed verbs, allowing arbitrarily deep
17
+ * nesting (e.g. `app share link create` — `share` is a typed verb, `link` is
18
+ * a nested typed verb, `create` is the leaf).
19
+ *
20
+ * A typed verb MAY also carry its own `handler` + `@helpText` to support
21
+ * "hybrid" verbs that accept a positional argument when the next token does
22
+ * not match a known subcommand. Example: `app share <principals>` (parent
23
+ * handler) coexisting with `app share link create` (nested subcommand).
17
24
  */
18
25
  export interface TypedVerbDef {
19
26
  typed: true;
20
- commands: Record<string, LeafCommandDef>;
27
+ '@helpText'?: string;
28
+ handler?: CommandHandler;
29
+ commands: Record<string, LeafCommandDef | TypedVerbDef>;
21
30
  }
22
31
  /** Type guard — narrows a verb entry to TypedVerbDef. */
23
32
  export declare function isTypedVerbDef(entry: LeafCommandDef | TypedVerbDef): entry is TypedVerbDef;
33
+ /** Narrows to a hybrid TypedVerbDef that also carries a parent handler. */
34
+ export declare function hasParentHandler(entry: TypedVerbDef): entry is TypedVerbDef & Required<Pick<TypedVerbDef, 'handler' | '@helpText'>>;
24
35
  /** A noun group with its description and command map. */
25
36
  export interface NounDef {
26
37
  '@description': string;
@@ -1 +1 @@
1
- {"version":3,"file":"Command.types.d.ts","sourceRoot":"","sources":["../../src/Types/Command.types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAE5D,yEAAyE;AACzE,MAAM,MAAM,cAAc,GAAG,CAAC,gBAAgB,EAAE,gBAAgB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;AAEnF,uEAAuE;AACvE,MAAM,MAAM,WAAW,GAAG,SAAS,MAAM,EAAE,CAAC;AAI5C,iDAAiD;AACjD,MAAM,WAAW,cAAc;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,cAAc,CAAC;CACzB;AAED;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,IAAI,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;CAC1C;AAED,yDAAyD;AACzD,wBAAgB,cAAc,CAAC,KAAK,EAAE,cAAc,GAAG,YAAY,GAAG,KAAK,IAAI,YAAY,CAE1F;AAED,yDAAyD;AACzD,MAAM,WAAW,OAAO;IACtB,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,GAAG,YAAY,CAAC,CAAC;CACzD;AAED;;;;;;GAMG;AACH,MAAM,MAAM,OAAO,GAAG,MAAM,GAAG,KAAK,GAAG,WAAW,GAAG,KAAK,GAAG,WAAW,CAAC;AAEzE;;;;GAIG;AACH,MAAM,MAAM,WAAW,GAAG,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;AAEnD,+DAA+D;AAC/D,MAAM,WAAW,eAAe;IAC9B,gFAAgF;IAChF,IAAI,EAAE,WAAW,CAAC;IAClB,qCAAqC;IACrC,OAAO,EAAE,cAAc,CAAC;IACxB,kEAAkE;IAClE,cAAc,EAAE,MAAM,CAAC;CACxB"}
1
+ {"version":3,"file":"Command.types.d.ts","sourceRoot":"","sources":["../../src/Types/Command.types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAE5D,yEAAyE;AACzE,MAAM,MAAM,cAAc,GAAG,CAAC,gBAAgB,EAAE,gBAAgB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;AAEnF,uEAAuE;AACvE,MAAM,MAAM,WAAW,GAAG,SAAS,MAAM,EAAE,CAAC;AAI5C,iDAAiD;AACjD,MAAM,WAAW,cAAc;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,cAAc,CAAC;CACzB;AAED;;;;;;;;;;GAUG;AACH,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,IAAI,CAAC;IACZ,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,cAAc,CAAC;IACzB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,GAAG,YAAY,CAAC,CAAC;CACzD;AAED,yDAAyD;AACzD,wBAAgB,cAAc,CAAC,KAAK,EAAE,cAAc,GAAG,YAAY,GAAG,KAAK,IAAI,YAAY,CAE1F;AAED,2EAA2E;AAC3E,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,YAAY,GAClB,KAAK,IAAI,YAAY,GAAG,QAAQ,CAAC,IAAI,CAAC,YAAY,EAAE,SAAS,GAAG,WAAW,CAAC,CAAC,CAE/E;AAED,yDAAyD;AACzD,MAAM,WAAW,OAAO;IACtB,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,GAAG,YAAY,CAAC,CAAC;CACzD;AAED;;;;;;GAMG;AACH,MAAM,MAAM,OAAO,GAAG,MAAM,GAAG,KAAK,GAAG,WAAW,GAAG,KAAK,GAAG,WAAW,CAAC;AAEzE;;;;GAIG;AACH,MAAM,MAAM,WAAW,GAAG,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;AAEnD,+DAA+D;AAC/D,MAAM,WAAW,eAAe;IAC9B,gFAAgF;IAChF,IAAI,EAAE,WAAW,CAAC;IAClB,qCAAqC;IACrC,OAAO,EAAE,cAAc,CAAC;IACxB,kEAAkE;IAClE,cAAc,EAAE,MAAM,CAAC;CACxB"}
@@ -5,4 +5,8 @@
5
5
  export function isTypedVerbDef(entry) {
6
6
  return entry.typed === true;
7
7
  }
8
+ /** Narrows to a hybrid TypedVerbDef that also carries a parent handler. */
9
+ export function hasParentHandler(entry) {
10
+ return typeof entry.handler === 'function';
11
+ }
8
12
  //# sourceMappingURL=Command.types.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Command.types.js","sourceRoot":"","sources":["../../src/Types/Command.types.ts"],"names":[],"mappings":"AAAA;;GAEG;AA2BH,yDAAyD;AACzD,MAAM,UAAU,cAAc,CAAC,KAAoC;IACjE,OAAQ,KAAsB,CAAC,KAAK,KAAK,IAAI,CAAC;AAChD,CAAC"}
1
+ {"version":3,"file":"Command.types.js","sourceRoot":"","sources":["../../src/Types/Command.types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAoCH,yDAAyD;AACzD,MAAM,UAAU,cAAc,CAAC,KAAoC;IACjE,OAAQ,KAAsB,CAAC,KAAK,KAAK,IAAI,CAAC;AAChD,CAAC;AAED,2EAA2E;AAC3E,MAAM,UAAU,gBAAgB,CAC9B,KAAmB;IAEnB,OAAO,OAAO,KAAK,CAAC,OAAO,KAAK,UAAU,CAAC;AAC7C,CAAC"}
@@ -0,0 +1,18 @@
1
+ /*!
2
+ * Copyright (C) Microsoft Corporation. All rights reserved.
3
+ */
4
+ import type { MaafBuildPollResult } from '@microsoft/managed-apps-actions';
5
+ export interface WaitForBuildStatusArgs {
6
+ appName: string;
7
+ commitSha: string;
8
+ initialWaitMs: number;
9
+ isJsonMode: boolean;
10
+ spinnerLabel?: string;
11
+ }
12
+ /**
13
+ * Polls `buildStatusAsync` for the given app + commit until the build reaches a
14
+ * terminal state. Shared between `ms app build` and `ms app play --mode preview`
15
+ * so both verbs surface identical waiting/error UX.
16
+ */
17
+ export declare function waitForBuildStatusAsync(args: WaitForBuildStatusArgs): Promise<MaafBuildPollResult>;
18
+ //# sourceMappingURL=BuildPolling.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BuildPolling.d.ts","sourceRoot":"","sources":["../../src/Utils/BuildPolling.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AAS3E,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,OAAO,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;;GAIG;AACH,wBAAsB,uBAAuB,CAC3C,IAAI,EAAE,sBAAsB,GAC3B,OAAO,CAAC,mBAAmB,CAAC,CAiC9B"}
@@ -0,0 +1,63 @@
1
+ /*!
2
+ * Copyright (C) Microsoft Corporation. All rights reserved.
3
+ */
4
+ import { buildStatusAsync } from '@microsoft/managed-apps-actions';
5
+ import { getCliLogger } from '../CliSettings.js';
6
+ import { AppError } from '../Errors/CliError.js';
7
+ import { CliSpinner } from './Spinner.js';
8
+ const MIN_POLL_INTERVAL_MS = 1000;
9
+ /**
10
+ * Polls `buildStatusAsync` for the given app + commit until the build reaches a
11
+ * terminal state. Shared between `ms app build` and `ms app play --mode preview`
12
+ * so both verbs surface identical waiting/error UX.
13
+ */
14
+ export async function waitForBuildStatusAsync(args) {
15
+ const logger = getCliLogger();
16
+ let waitMs = Math.max(MIN_POLL_INTERVAL_MS, args.initialWaitMs);
17
+ const spinner = args.isJsonMode ? null : new CliSpinner();
18
+ spinner?.start(args.spinnerLabel ?? 'Waiting for build status...');
19
+ try {
20
+ for (;;) {
21
+ await sleep(waitMs);
22
+ const status = await buildStatusAsync({
23
+ logger,
24
+ actionsParams: { appName: args.appName, commitSha: args.commitSha },
25
+ });
26
+ switch (status.status) {
27
+ case 'Succeeded':
28
+ return status;
29
+ case 'Failed':
30
+ case 'Canceled':
31
+ throw new AppError(`Build ${status.status.toLowerCase()}${formatStatusDetail(status.result)}.`);
32
+ case 'NotStarted':
33
+ case 'Running':
34
+ waitMs = Math.max(MIN_POLL_INTERVAL_MS, status.retryAfterMs ?? waitMs);
35
+ break;
36
+ default:
37
+ return status;
38
+ }
39
+ }
40
+ }
41
+ finally {
42
+ spinner?.stop();
43
+ }
44
+ }
45
+ function formatStatusDetail(result) {
46
+ if (typeof result === 'string' && result.trim()) {
47
+ return `: ${result}`;
48
+ }
49
+ if (result && typeof result === 'object') {
50
+ const parts = [];
51
+ if (typeof result.code === 'string' && result.code)
52
+ parts.push(result.code);
53
+ if (typeof result.message === 'string' && result.message)
54
+ parts.push(result.message);
55
+ if (parts.length > 0)
56
+ return `: ${parts.join(' - ')}`;
57
+ }
58
+ return '';
59
+ }
60
+ function sleep(ms) {
61
+ return new Promise((resolve) => setTimeout(resolve, ms));
62
+ }
63
+ //# sourceMappingURL=BuildPolling.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BuildPolling.js","sourceRoot":"","sources":["../../src/Utils/BuildPolling.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AAEnE,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAEvC,MAAM,oBAAoB,GAAG,IAAI,CAAC;AAUlC;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,IAA4B;IAE5B,MAAM,MAAM,GAAG,YAAY,EAAE,CAAC;IAC9B,IAAI,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,oBAAoB,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC;IAChE,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,UAAU,EAAE,CAAC;IAE1D,OAAO,EAAE,KAAK,CAAC,IAAI,CAAC,YAAY,IAAI,6BAA6B,CAAC,CAAC;IACnE,IAAI,CAAC;QACH,SAAS,CAAC;YACR,MAAM,KAAK,CAAC,MAAM,CAAC,CAAC;YACpB,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC;gBACpC,MAAM;gBACN,aAAa,EAAE,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE;aACpE,CAAC,CAAC;YAEH,QAAQ,MAAM,CAAC,MAAM,EAAE,CAAC;gBACtB,KAAK,WAAW;oBACd,OAAO,MAAM,CAAC;gBAChB,KAAK,QAAQ,CAAC;gBACd,KAAK,UAAU;oBACb,MAAM,IAAI,QAAQ,CAChB,SAAS,MAAM,CAAC,MAAM,CAAC,WAAW,EAAE,GAAG,kBAAkB,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAC5E,CAAC;gBACJ,KAAK,YAAY,CAAC;gBAClB,KAAK,SAAS;oBACZ,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,oBAAoB,EAAE,MAAM,CAAC,YAAY,IAAI,MAAM,CAAC,CAAC;oBACvE,MAAM;gBACR;oBACE,OAAO,MAAM,CAAC;YAClB,CAAC;QACH,CAAC;IACH,CAAC;YAAS,CAAC;QACT,OAAO,EAAE,IAAI,EAAE,CAAC;IAClB,CAAC;AACH,CAAC;AAED,SAAS,kBAAkB,CAAC,MAAqC;IAC/D,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC;QAChD,OAAO,KAAK,MAAM,EAAE,CAAC;IACvB,CAAC;IACD,IAAI,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;QACzC,MAAM,KAAK,GAAa,EAAE,CAAC;QAC3B,IAAI,OAAO,MAAM,CAAC,IAAI,KAAK,QAAQ,IAAI,MAAM,CAAC,IAAI;YAAE,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAC5E,IAAI,OAAO,MAAM,CAAC,OAAO,KAAK,QAAQ,IAAI,MAAM,CAAC,OAAO;YAAE,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACrF,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;YAAE,OAAO,KAAK,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;IACxD,CAAC;IACD,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,SAAS,KAAK,CAAC,EAAU;IACvB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;AAC3D,CAAC"}
@@ -13,7 +13,17 @@ export declare function buildVerbDescriptionTable(): string;
13
13
  export declare function buildNounHelpText(noun: string): string;
14
14
  /**
15
15
  * Builds help text for a typed subcommand verb (e.g., `app add`).
16
- * Lists the available types.
16
+ * Lists the available types — including nested typed verbs.
17
17
  */
18
18
  export declare function buildTypedSubcommandHelpText(noun: string, verb: string): string;
19
+ /**
20
+ * Walks the command tree along `pathTokens` and, if the endpoint is a typed
21
+ * verb, returns its flattened subcommand help text. Returns `null` if any
22
+ * token fails to match or the endpoint is a leaf (in which case Commander
23
+ * handles `--help` on its own at the leaf level).
24
+ *
25
+ * Used to surface help for nested-typed paths the resolver cannot leaf-match,
26
+ * e.g. `ms app share link --help` → list `create | list | revoke`.
27
+ */
28
+ export declare function buildPathTypedHelpText(pathTokens: readonly string[]): string | null;
19
29
  //# sourceMappingURL=BuildVerbDescriptionTable.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"BuildVerbDescriptionTable.d.ts","sourceRoot":"","sources":["../../src/Utils/BuildVerbDescriptionTable.ts"],"names":[],"mappings":"AAAA;;GAEG;AAkBH;;;GAGG;AACH,wBAAgB,yBAAyB,IAAI,MAAM,CAkBlD;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CA4CtD;AAED;;;GAGG;AACH,wBAAgB,4BAA4B,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAmB/E"}
1
+ {"version":3,"file":"BuildVerbDescriptionTable.d.ts","sourceRoot":"","sources":["../../src/Utils/BuildVerbDescriptionTable.ts"],"names":[],"mappings":"AAAA;;GAEG;AAkBH;;;GAGG;AACH,wBAAgB,yBAAyB,IAAI,MAAM,CAkBlD;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CA4CtD;AAoBD;;;GAGG;AACH,wBAAgB,4BAA4B,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAE/E;AAED;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,GAAG,IAAI,CA6BnF"}