4264741281
## Summary - After a successful `uninstall`, clear all app registration config (`appRegistrationId`, `appRegistrationClientId`, `appAccessToken`, `appRefreshToken`) so the next `dev` run doesn't hit "app not found" errors from leftover credentials - On app re-registration (`ensureAppRegistration`), clear stale `appAccessToken`/`appRefreshToken` that belonged to the previous registration - On OAuth token refresh failure, only clear config when the server returns `invalid_client` (registration was deleted), not on transient failures like network issues - Extract a shared `parse-server-error` utility for consistently parsing both GraphQL error codes (`extensions.code`/`subCode`) and OAuth error responses (`error`/`error_description`)
66 lines
1.7 KiB
TypeScript
66 lines
1.7 KiB
TypeScript
import { ApiService } from '@/cli/utilities/api/api-service';
|
|
import { readManifestFromFile } from '@/cli/utilities/build/manifest/manifest-reader';
|
|
import { ConfigService } from '@/cli/utilities/config/config-service';
|
|
import { runSafe } from '@/cli/utilities/run-safe';
|
|
import { APP_ERROR_CODES, type CommandResult } from '@/cli/types';
|
|
|
|
export type AppUninstallOptions = {
|
|
appPath: string;
|
|
remote?: string;
|
|
};
|
|
|
|
const innerAppUninstall = async (
|
|
options: AppUninstallOptions,
|
|
): Promise<CommandResult> => {
|
|
if (options.remote) {
|
|
ConfigService.setActiveRemote(options.remote);
|
|
}
|
|
|
|
const configService = new ConfigService();
|
|
const apiService = new ApiService();
|
|
const manifest = await readManifestFromFile(options.appPath);
|
|
|
|
if (!manifest) {
|
|
return {
|
|
success: false,
|
|
error: {
|
|
code: APP_ERROR_CODES.MANIFEST_NOT_FOUND,
|
|
message: 'Manifest not found. Run `build` or `dev` first.',
|
|
},
|
|
};
|
|
}
|
|
|
|
const result = await apiService.uninstallApplication(
|
|
manifest.application.universalIdentifier,
|
|
);
|
|
|
|
if (!result.success) {
|
|
const errorMessage =
|
|
result.error instanceof Error
|
|
? result.error.message
|
|
: String(result.error ?? 'Unknown error');
|
|
|
|
return {
|
|
success: false,
|
|
error: {
|
|
code: APP_ERROR_CODES.UNINSTALL_FAILED,
|
|
message: errorMessage,
|
|
},
|
|
};
|
|
}
|
|
|
|
await configService.setConfig({
|
|
appRegistrationId: undefined,
|
|
appRegistrationClientId: undefined,
|
|
appAccessToken: undefined,
|
|
appRefreshToken: undefined,
|
|
});
|
|
|
|
return { success: true, data: undefined };
|
|
};
|
|
|
|
export const appUninstall = (
|
|
options: AppUninstallOptions,
|
|
): Promise<CommandResult> =>
|
|
runSafe(() => innerAppUninstall(options), APP_ERROR_CODES.UNINSTALL_FAILED);
|