@pacaf/wizard-ux 3.3.10 → 3.4.1
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pacaf/wizard-ux",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.4.1",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "Browser-based setup wizard for Power Apps Code Apps (parallel to @pacaf/wizard CLI).",
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"react-dom": "^19.0.0",
|
|
39
39
|
"react-resizable-panels": "^2.1.7",
|
|
40
40
|
"react-router-dom": "^7.1.0",
|
|
41
|
-
"@pacaf/wizard": "3.
|
|
41
|
+
"@pacaf/wizard": "3.4.1"
|
|
42
42
|
},
|
|
43
43
|
"devDependencies": {
|
|
44
44
|
"@types/react": "^19.0.0",
|
|
@@ -105,44 +105,41 @@ function verifyUserProfile(pac, projectDir, state, credentialValues) {
|
|
|
105
105
|
});
|
|
106
106
|
}
|
|
107
107
|
|
|
108
|
-
//
|
|
108
|
+
// Ensure the deployed Code App is a component of the selected solution.
|
|
109
109
|
//
|
|
110
|
-
//
|
|
111
|
-
//
|
|
112
|
-
//
|
|
113
|
-
// was first pushed bare
|
|
114
|
-
//
|
|
115
|
-
//
|
|
116
|
-
//
|
|
117
|
-
// recovery instead of pretending to repair.
|
|
110
|
+
// `pac code push -s <UNIQUE name>` associates the app on the FIRST push (the
|
|
111
|
+
// CREATE). But several real-world paths leave it OUTSIDE the chosen solution:
|
|
112
|
+
// a unique-name mismatch makes pac fall back to the env's preferred/default
|
|
113
|
+
// solution, or the app was first pushed bare and a later -s re-push (an UPDATE)
|
|
114
|
+
// is ignored. The earlier #81 design treated that as unrecoverable and told the
|
|
115
|
+
// user to delete + recreate. That is wrong: appId === canvasappid, so the
|
|
116
|
+
// app can be added to the solution after the fact.
|
|
118
117
|
//
|
|
119
|
-
//
|
|
120
|
-
//
|
|
121
|
-
//
|
|
122
|
-
//
|
|
123
|
-
|
|
118
|
+
// READ + REPAIR (auth-agnostic, via the shared lib):
|
|
119
|
+
// • READ — `pac org fetch` on solutioncomponent (componenttype 300) under
|
|
120
|
+
// the active profile (user OR SPN), so no client secret is needed.
|
|
121
|
+
// • REPAIR — `pac solution add-solution-component --component <appId>
|
|
122
|
+
// --componentType 300 --solutionUniqueName <name>` when absent.
|
|
123
|
+
// The old `pac solution export --managed false` + type-300 count read was
|
|
124
|
+
// malformed and produced false negatives; the old `pac solution list` check
|
|
125
|
+
// was a false positive (it only proved the solution exists). Both are gone.
|
|
126
|
+
async function ensureAppInSolution(log, pac, projectDir, appId, solutionUniqueName, { appDisplayName } = {}) {
|
|
124
127
|
if (!solutionUniqueName) return { status: 'unknown' };
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
if (membership.status === 'member') {
|
|
129
|
-
log.ok(`Confirmed: the app is a component of solution "${solutionUniqueName}" (${membership.canvasComponentCount} Canvas App component(s)).`);
|
|
130
|
-
return membership;
|
|
128
|
+
if (!appId) {
|
|
129
|
+
log.warn(`No appId found in power.config.json — cannot confirm membership in "${solutionUniqueName}". Verify in the Maker Portal.`);
|
|
130
|
+
return { status: 'unknown' };
|
|
131
131
|
}
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
log.warn(`${hint} If it is missing in the Maker Portal, add it with: Solutions → ${solutionUniqueName} → Add existing → App → Code app.`);
|
|
142
|
-
return membership;
|
|
132
|
+
log.info(`Confirming the app is in solution "${solutionUniqueName}" (and adding it if missing)...`);
|
|
133
|
+
const runCapture = (file, args, opts) => runFileCapture(log, file, args, opts);
|
|
134
|
+
const result = await SOLUTION_MEMBERSHIP.ensureAppInSolution({
|
|
135
|
+
pac, projectDir, appId, solutionUniqueName, runCapture, log,
|
|
136
|
+
});
|
|
137
|
+
if (result.status !== 'member' && result.status === 'absent') {
|
|
138
|
+
for (const line of SOLUTION_MEMBERSHIP.manualSolutionAddSteps(solutionUniqueName, appDisplayName || 'this Code App', appId)) {
|
|
139
|
+
log.warn(line);
|
|
140
|
+
}
|
|
143
141
|
}
|
|
144
|
-
|
|
145
|
-
return membership;
|
|
142
|
+
return result;
|
|
146
143
|
}
|
|
147
144
|
|
|
148
145
|
export default {
|
|
@@ -218,17 +215,14 @@ export default {
|
|
|
218
215
|
throw new Error('No solution unique name (SOLUTION_UNIQUE_NAME) is available. Refusing to run a bare `pac code push`, which would create the Code App outside any solution (a silent failure a later -s re-push cannot fix). Re-run the wizard solution step so the unique name is captured before deploying.');
|
|
219
216
|
}
|
|
220
217
|
|
|
221
|
-
// PRE-PUSH
|
|
222
|
-
//
|
|
223
|
-
//
|
|
224
|
-
//
|
|
225
|
-
// Catch that here and hard-stop with recovery instructions instead of
|
|
226
|
-
// wasting an update that silently leaves the app orphaned.
|
|
218
|
+
// PRE-PUSH NOTE. On an UPDATE push (appId already present) `-s` is ignored,
|
|
219
|
+
// but that is no longer a dead-end: after the push we read membership from
|
|
220
|
+
// Dataverse and add the app to the solution if needed (appId === canvasappid),
|
|
221
|
+
// which works regardless of whether this was a CREATE or an UPDATE.
|
|
227
222
|
const preInfo = PAC_TARGET.loadPowerConfigInfo(powerConfigPath);
|
|
228
223
|
const isFirstPush = !preInfo.appId;
|
|
229
|
-
if (!isFirstPush
|
|
230
|
-
log.info(`Existing appId detected (${preInfo.appId}) — this push is an UPDATE.
|
|
231
|
-
await verifyAppInSolution(log, pac, projectDir, solutionUniqueName, { phase: 'pre-push', appDisplayName });
|
|
224
|
+
if (!isFirstPush) {
|
|
225
|
+
log.info(`Existing appId detected (${preInfo.appId}) — this push is an UPDATE. Solution membership will be confirmed (and repaired if needed) after the push.`);
|
|
232
226
|
}
|
|
233
227
|
|
|
234
228
|
const pushResult = await runFileCapture(log, pac, pushArgs, { cwd: projectDir });
|
|
@@ -252,13 +246,14 @@ export default {
|
|
|
252
246
|
log.warn('Could not detect deployed app URL in pac output. Open the app from Power Apps Maker Portal.');
|
|
253
247
|
}
|
|
254
248
|
|
|
255
|
-
// POST-
|
|
256
|
-
//
|
|
257
|
-
// solution
|
|
258
|
-
//
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
249
|
+
// POST-PUSH MEMBERSHIP ENSURE. Read the appId the push wrote into
|
|
250
|
+
// power.config.json, confirm the app is a component of the selected
|
|
251
|
+
// solution via a Dataverse read, and add it automatically if it is not.
|
|
252
|
+
// This covers BOTH a CREATE that silently fell back to the preferred/default
|
|
253
|
+
// solution AND an UPDATE of an app that was first pushed bare (issue #81),
|
|
254
|
+
// without ever deleting or recreating the app.
|
|
255
|
+
const postInfo = PAC_TARGET.loadPowerConfigInfo(powerConfigPath);
|
|
256
|
+
await ensureAppInSolution(log, pac, projectDir, postInfo.appId, solutionUniqueName, { appDisplayName });
|
|
262
257
|
|
|
263
258
|
return { stateUpdate, completedStep: 9 };
|
|
264
259
|
},
|