@hubspot/cli 7.4.2-experimental.0 → 7.4.4-experimental.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/api/migrate.d.ts +61 -0
- package/api/migrate.js +44 -0
- package/commands/app/migrate.js +5 -4
- package/lang/en.lyaml +1 -0
- package/lib/app/migrate.d.ts +0 -2
- package/lib/app/migrate.js +40 -166
- package/lib/app/migrate_legacy.d.ts +4 -0
- package/lib/app/migrate_legacy.js +129 -0
- package/package.json +2 -2
package/api/migrate.d.ts
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { HubSpotPromise } from '@hubspot/local-dev-lib/types/Http';
|
|
2
|
+
import { UNMIGRATABLE_REASONS } from '@hubspot/local-dev-lib/constants/projects';
|
|
3
|
+
import { MIGRATION_STATUS } from '@hubspot/local-dev-lib/types/Migration';
|
|
4
|
+
interface BaseMigrationApp {
|
|
5
|
+
appId: number;
|
|
6
|
+
appName: string;
|
|
7
|
+
isMigratable: boolean;
|
|
8
|
+
migrationComponents: ListAppsMigrationComponent[];
|
|
9
|
+
projectName?: string;
|
|
10
|
+
}
|
|
11
|
+
export interface MigratableApp extends BaseMigrationApp {
|
|
12
|
+
isMigratable: true;
|
|
13
|
+
}
|
|
14
|
+
export interface UnmigratableApp extends BaseMigrationApp {
|
|
15
|
+
isMigratable: false;
|
|
16
|
+
unmigratableReason: keyof typeof UNMIGRATABLE_REASONS;
|
|
17
|
+
}
|
|
18
|
+
export type MigrationApp = MigratableApp | UnmigratableApp;
|
|
19
|
+
export interface ListAppsResponse {
|
|
20
|
+
migratableApps: MigratableApp[];
|
|
21
|
+
unmigratableApps: UnmigratableApp[];
|
|
22
|
+
}
|
|
23
|
+
export interface InitializeMigrationResponse {
|
|
24
|
+
migrationId: number;
|
|
25
|
+
}
|
|
26
|
+
export interface ListAppsMigrationComponent {
|
|
27
|
+
id: string;
|
|
28
|
+
componentType: string;
|
|
29
|
+
isSupported: boolean;
|
|
30
|
+
}
|
|
31
|
+
export type ContinueMigrationResponse = {
|
|
32
|
+
migrationId: number;
|
|
33
|
+
};
|
|
34
|
+
export interface MigrationBaseStatus {
|
|
35
|
+
id: number;
|
|
36
|
+
}
|
|
37
|
+
export interface MigrationInProgress extends MigrationBaseStatus {
|
|
38
|
+
status: typeof MIGRATION_STATUS.IN_PROGRESS;
|
|
39
|
+
}
|
|
40
|
+
export interface MigrationInputRequired extends MigrationBaseStatus {
|
|
41
|
+
status: typeof MIGRATION_STATUS.INPUT_REQUIRED;
|
|
42
|
+
componentsRequiringUids: Record<string, {
|
|
43
|
+
componentType: string;
|
|
44
|
+
componentHint: string;
|
|
45
|
+
}>;
|
|
46
|
+
}
|
|
47
|
+
export interface MigrationSuccess extends MigrationBaseStatus {
|
|
48
|
+
status: typeof MIGRATION_STATUS.SUCCESS;
|
|
49
|
+
buildId: number;
|
|
50
|
+
}
|
|
51
|
+
export interface MigrationFailed extends MigrationBaseStatus {
|
|
52
|
+
status: typeof MIGRATION_STATUS.FAILURE;
|
|
53
|
+
projectErrorsDetail?: string;
|
|
54
|
+
componentErrorDetails: Record<string, string>;
|
|
55
|
+
}
|
|
56
|
+
export type MigrationStatus = MigrationInProgress | MigrationInputRequired | MigrationSuccess | MigrationFailed;
|
|
57
|
+
export declare function listAppsForMigration(accountId: number): HubSpotPromise<ListAppsResponse>;
|
|
58
|
+
export declare function initializeMigration(accountId: number, applicationId: number, platformVersion: string): HubSpotPromise<InitializeMigrationResponse>;
|
|
59
|
+
export declare function continueMigration(portalId: number, migrationId: number, componentUids: Record<string, string>, projectName: string): HubSpotPromise<ContinueMigrationResponse>;
|
|
60
|
+
export declare function checkMigrationStatusV2(accountId: number, id: number): HubSpotPromise<MigrationStatus>;
|
|
61
|
+
export {};
|
package/api/migrate.js
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.listAppsForMigration = listAppsForMigration;
|
|
4
|
+
exports.initializeMigration = initializeMigration;
|
|
5
|
+
exports.continueMigration = continueMigration;
|
|
6
|
+
exports.checkMigrationStatusV2 = checkMigrationStatusV2;
|
|
7
|
+
const projects_1 = require("@hubspot/local-dev-lib/constants/projects");
|
|
8
|
+
const http_1 = require("@hubspot/local-dev-lib/http");
|
|
9
|
+
const MIGRATIONS_API_PATH_V2 = 'dfs/migrations/v2';
|
|
10
|
+
async function listAppsForMigration(accountId) {
|
|
11
|
+
return http_1.http.get(accountId, {
|
|
12
|
+
url: `${MIGRATIONS_API_PATH_V2}/list-apps`,
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
function mapPlatformVersionToEnum(platformVersion) {
|
|
16
|
+
if (platformVersion === projects_1.PLATFORM_VERSIONS.unstable) {
|
|
17
|
+
return projects_1.PLATFORM_VERSIONS.unstable.toUpperCase();
|
|
18
|
+
}
|
|
19
|
+
return `V${platformVersion.replace('.', '_')}`;
|
|
20
|
+
}
|
|
21
|
+
async function initializeMigration(accountId, applicationId, platformVersion) {
|
|
22
|
+
return http_1.http.post(accountId, {
|
|
23
|
+
url: `${MIGRATIONS_API_PATH_V2}/migrations`,
|
|
24
|
+
data: {
|
|
25
|
+
applicationId,
|
|
26
|
+
platformVersion: mapPlatformVersionToEnum(platformVersion),
|
|
27
|
+
},
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
async function continueMigration(portalId, migrationId, componentUids, projectName) {
|
|
31
|
+
return http_1.http.post(portalId, {
|
|
32
|
+
url: `${MIGRATIONS_API_PATH_V2}/migrations/continue`,
|
|
33
|
+
data: {
|
|
34
|
+
migrationId,
|
|
35
|
+
projectName,
|
|
36
|
+
componentUids,
|
|
37
|
+
},
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
function checkMigrationStatusV2(accountId, id) {
|
|
41
|
+
return http_1.http.get(accountId, {
|
|
42
|
+
url: `${MIGRATIONS_API_PATH_V2}/migrations/${id}/status`,
|
|
43
|
+
});
|
|
44
|
+
}
|
package/commands/app/migrate.js
CHANGED
|
@@ -3,16 +3,17 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.validMigrationTargets = void 0;
|
|
4
4
|
exports.handler = handler;
|
|
5
5
|
exports.builder = builder;
|
|
6
|
+
const logger_1 = require("@hubspot/local-dev-lib/logger");
|
|
7
|
+
const config_1 = require("@hubspot/local-dev-lib/config");
|
|
8
|
+
const projects_1 = require("@hubspot/local-dev-lib/constants/projects");
|
|
6
9
|
const commonOpts_1 = require("../../lib/commonOpts");
|
|
7
10
|
const usageTracking_1 = require("../../lib/usageTracking");
|
|
8
11
|
const lang_1 = require("../../lib/lang");
|
|
9
12
|
const errorHandlers_1 = require("../../lib/errorHandlers");
|
|
10
13
|
const exitCodes_1 = require("../../lib/enums/exitCodes");
|
|
11
|
-
const config_1 = require("@hubspot/local-dev-lib/config");
|
|
12
14
|
const migrate_1 = require("../../lib/app/migrate");
|
|
13
|
-
const projects_1 = require("@hubspot/local-dev-lib/constants/projects");
|
|
14
|
-
const logger_1 = require("@hubspot/local-dev-lib/logger");
|
|
15
15
|
const ui_1 = require("../../lib/ui");
|
|
16
|
+
const migrate_legacy_1 = require("../../lib/app/migrate_legacy");
|
|
16
17
|
const { v2023_2, v2025_2, unstable } = projects_1.PLATFORM_VERSIONS;
|
|
17
18
|
exports.validMigrationTargets = [v2023_2, v2025_2, unstable];
|
|
18
19
|
const command = 'migrate';
|
|
@@ -34,7 +35,7 @@ async function handler(options) {
|
|
|
34
35
|
await (0, migrate_1.migrateApp2025_2)(derivedAccountId, options);
|
|
35
36
|
}
|
|
36
37
|
else {
|
|
37
|
-
await (0,
|
|
38
|
+
await (0, migrate_legacy_1.migrateApp2023_2)(derivedAccountId, options, accountConfig);
|
|
38
39
|
}
|
|
39
40
|
}
|
|
40
41
|
catch (error) {
|
package/lang/en.lyaml
CHANGED
|
@@ -597,6 +597,7 @@ en:
|
|
|
597
597
|
projectAlreadyExists: "A project with name {{ projectName }} already exists. Please choose another name."
|
|
598
598
|
invalidApp: "Could not migrate appId {{ appId }}. This app cannot be migrated at this time. Please choose another public app."
|
|
599
599
|
appWithAppIdNotFound: "Could not find an app with the id {{ appId }} "
|
|
600
|
+
migrationFailed: 'Migration Failed'
|
|
600
601
|
prompt:
|
|
601
602
|
chooseApp: 'Which app would you like to migrate?'
|
|
602
603
|
inputName: '[--name] What would you like to name the project?'
|
package/lib/app/migrate.d.ts
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
import { CLIAccount } from '@hubspot/local-dev-lib/types/Accounts';
|
|
2
1
|
import { ArgumentsCamelCase } from 'yargs';
|
|
3
2
|
import { MigrateAppOptions } from '../../types/Yargs';
|
|
4
3
|
export declare function downloadProjectFiles(derivedAccountId: number, projectName: string, buildId: number, projectDest: string): Promise<void>;
|
|
5
4
|
export declare function migrateApp2025_2(derivedAccountId: number, options: ArgumentsCamelCase<MigrateAppOptions>): Promise<void>;
|
|
6
5
|
export declare function logInvalidAccountError(i18nKey: string): void;
|
|
7
|
-
export declare function migrateApp2023_2(derivedAccountId: number, options: ArgumentsCamelCase<MigrateAppOptions>, accountConfig: CLIAccount): Promise<void>;
|
package/lib/app/migrate.js
CHANGED
|
@@ -6,39 +6,30 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.downloadProjectFiles = downloadProjectFiles;
|
|
7
7
|
exports.migrateApp2025_2 = migrateApp2025_2;
|
|
8
8
|
exports.logInvalidAccountError = logInvalidAccountError;
|
|
9
|
-
exports.migrateApp2023_2 = migrateApp2023_2;
|
|
10
|
-
const promptUtils_1 = require("../prompts/promptUtils");
|
|
11
|
-
const errorHandlers_1 = require("../errorHandlers");
|
|
12
|
-
const exitCodes_1 = require("../enums/exitCodes");
|
|
13
9
|
const logger_1 = require("@hubspot/local-dev-lib/logger");
|
|
14
|
-
const ui_1 = require("../ui");
|
|
15
|
-
const lang_1 = require("../lang");
|
|
16
|
-
const accountTypes_1 = require("../accountTypes");
|
|
17
|
-
const selectPublicAppPrompt_1 = require("../prompts/selectPublicAppPrompt");
|
|
18
|
-
const appsDev_1 = require("@hubspot/local-dev-lib/api/appsDev");
|
|
19
|
-
const createProjectPrompt_1 = require("../prompts/createProjectPrompt");
|
|
20
|
-
const projects_1 = require("../projects");
|
|
21
|
-
const usageTracking_1 = require("../usageTracking");
|
|
22
|
-
const SpinniesManager_1 = __importDefault(require("../ui/SpinniesManager"));
|
|
23
|
-
const process_1 = require("../process");
|
|
24
|
-
const projects_2 = require("@hubspot/local-dev-lib/api/projects");
|
|
25
|
-
const polling_1 = require("../polling");
|
|
26
10
|
const path_1 = __importDefault(require("path"));
|
|
27
11
|
const path_2 = require("@hubspot/local-dev-lib/path");
|
|
28
|
-
const urls_1 = require("@hubspot/local-dev-lib/urls");
|
|
29
12
|
const archive_1 = require("@hubspot/local-dev-lib/archive");
|
|
30
13
|
const chalk_1 = __importDefault(require("chalk"));
|
|
31
14
|
const project_parsing_lib_1 = require("@hubspot/project-parsing-lib");
|
|
32
|
-
const
|
|
15
|
+
const projects_1 = require("@hubspot/local-dev-lib/constants/projects");
|
|
33
16
|
const transform_1 = require("@hubspot/project-parsing-lib/src/lib/transform");
|
|
34
|
-
const
|
|
17
|
+
const Migration_1 = require("@hubspot/local-dev-lib/types/Migration");
|
|
18
|
+
const projects_2 = require("@hubspot/local-dev-lib/api/projects");
|
|
19
|
+
const promptUtils_1 = require("../prompts/promptUtils");
|
|
20
|
+
const ui_1 = require("../ui");
|
|
21
|
+
const lang_1 = require("../lang");
|
|
22
|
+
const projects_3 = require("../projects");
|
|
23
|
+
const SpinniesManager_1 = __importDefault(require("../ui/SpinniesManager"));
|
|
24
|
+
const polling_1 = require("../polling");
|
|
25
|
+
const migrate_1 = require("../../api/migrate");
|
|
35
26
|
function getUnmigratableReason(reasonCode) {
|
|
36
27
|
switch (reasonCode) {
|
|
37
|
-
case
|
|
28
|
+
case projects_1.UNMIGRATABLE_REASONS.UP_TO_DATE:
|
|
38
29
|
return (0, lang_1.i18n)('commands.project.subcommands.migrateApp.unmigratableReasons.upToDate');
|
|
39
|
-
case
|
|
30
|
+
case projects_1.UNMIGRATABLE_REASONS.IS_A_PRIVATE_APP:
|
|
40
31
|
return (0, lang_1.i18n)('commands.project.subcommands.migrateApp.unmigratableReasons.isPrivateApp');
|
|
41
|
-
case
|
|
32
|
+
case projects_1.UNMIGRATABLE_REASONS.LISTED_IN_MARKETPLACE:
|
|
42
33
|
return (0, lang_1.i18n)('commands.project.subcommands.migrateApp.unmigratableReasons.listedInMarketplace');
|
|
43
34
|
default:
|
|
44
35
|
return (0, lang_1.i18n)('commands.project.subcommands.migrateApp.unmigratableReasons.generic', {
|
|
@@ -48,7 +39,7 @@ function getUnmigratableReason(reasonCode) {
|
|
|
48
39
|
}
|
|
49
40
|
async function handleMigrationSetup(derivedAccountId, options) {
|
|
50
41
|
const { name, dest, appId } = options;
|
|
51
|
-
const { data } = await (0,
|
|
42
|
+
const { data } = await (0, migrate_1.listAppsForMigration)(derivedAccountId);
|
|
52
43
|
const { migratableApps, unmigratableApps } = data;
|
|
53
44
|
const allApps = [...migratableApps, ...unmigratableApps].filter(app => !app.projectName);
|
|
54
45
|
if (allApps.length === 0) {
|
|
@@ -114,7 +105,7 @@ async function handleMigrationSetup(derivedAccountId, options) {
|
|
|
114
105
|
}
|
|
115
106
|
const projectName = name ||
|
|
116
107
|
(await (0, promptUtils_1.inputPrompt)((0, lang_1.i18n)('commands.project.subcommands.migrateApp.prompt.inputName')));
|
|
117
|
-
const { projectExists } = await (0,
|
|
108
|
+
const { projectExists } = await (0, projects_3.ensureProjectExists)(derivedAccountId, projectName, { allowCreate: false, noLogs: true });
|
|
118
109
|
if (projectExists) {
|
|
119
110
|
throw new Error((0, lang_1.i18n)('commands.project.subcommands.migrateApp.errors.projectAlreadyExists', {
|
|
120
111
|
projectName,
|
|
@@ -131,10 +122,10 @@ async function beginMigration(derivedAccountId, appId, platformVersion) {
|
|
|
131
122
|
text: (0, lang_1.i18n)('commands.project.subcommands.migrateApp.spinners.beginningMigration'),
|
|
132
123
|
});
|
|
133
124
|
const uidMap = {};
|
|
134
|
-
const { data } = await (0,
|
|
125
|
+
const { data } = await (0, migrate_1.initializeMigration)(derivedAccountId, appId, platformVersion);
|
|
135
126
|
const { migrationId } = data;
|
|
136
|
-
const pollResponse = await pollMigrationStatus(derivedAccountId, migrationId, [
|
|
137
|
-
if (pollResponse.status !==
|
|
127
|
+
const pollResponse = await pollMigrationStatus(derivedAccountId, migrationId, [Migration_1.MIGRATION_STATUS.INPUT_REQUIRED]);
|
|
128
|
+
if (pollResponse.status !== Migration_1.MIGRATION_STATUS.INPUT_REQUIRED) {
|
|
138
129
|
SpinniesManager_1.default.fail('beginningMigration', {
|
|
139
130
|
text: (0, lang_1.i18n)('commands.project.subcommands.migrateApp.spinners.unableToStartMigration'),
|
|
140
131
|
});
|
|
@@ -159,31 +150,21 @@ async function beginMigration(derivedAccountId, appId, platformVersion) {
|
|
|
159
150
|
return { migrationId, uidMap };
|
|
160
151
|
}
|
|
161
152
|
async function pollMigrationStatus(derivedAccountId, migrationId, successStates = []) {
|
|
162
|
-
return (0, polling_1.poll)(() => (0,
|
|
153
|
+
return (0, polling_1.poll)(() => (0, migrate_1.checkMigrationStatusV2)(derivedAccountId, migrationId), {
|
|
163
154
|
successStates: [...successStates],
|
|
164
155
|
errorStates: [...polling_1.DEFAULT_POLLING_STATUS_LOOKUP.errorStates],
|
|
165
156
|
});
|
|
166
157
|
}
|
|
167
158
|
async function finalizeMigration(derivedAccountId, migrationId, uidMap, projectName) {
|
|
168
|
-
let
|
|
159
|
+
let pollResponse;
|
|
169
160
|
try {
|
|
170
161
|
SpinniesManager_1.default.add('finishingMigration', {
|
|
171
162
|
text: (0, lang_1.i18n)(`commands.project.subcommands.migrateApp.spinners.finishingMigration`),
|
|
172
163
|
});
|
|
173
|
-
await (0,
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
SpinniesManager_1.default.succeed('finishingMigration', {
|
|
178
|
-
text: (0, lang_1.i18n)(`commands.project.subcommands.migrateApp.spinners.migrationComplete`),
|
|
179
|
-
});
|
|
180
|
-
}
|
|
181
|
-
else {
|
|
182
|
-
SpinniesManager_1.default.fail('finishingMigration', {
|
|
183
|
-
text: (0, lang_1.i18n)(`commands.project.subcommands.migrateApp.spinners.migrationFailed`),
|
|
184
|
-
});
|
|
185
|
-
}
|
|
186
|
-
return buildId;
|
|
164
|
+
await (0, migrate_1.continueMigration)(derivedAccountId, migrationId, uidMap, projectName);
|
|
165
|
+
pollResponse = await pollMigrationStatus(derivedAccountId, migrationId, [
|
|
166
|
+
Migration_1.MIGRATION_STATUS.SUCCESS,
|
|
167
|
+
]);
|
|
187
168
|
}
|
|
188
169
|
catch (error) {
|
|
189
170
|
SpinniesManager_1.default.fail('finishingMigration', {
|
|
@@ -191,6 +172,22 @@ async function finalizeMigration(derivedAccountId, migrationId, uidMap, projectN
|
|
|
191
172
|
});
|
|
192
173
|
throw error;
|
|
193
174
|
}
|
|
175
|
+
if (pollResponse.status === Migration_1.MIGRATION_STATUS.SUCCESS) {
|
|
176
|
+
SpinniesManager_1.default.succeed('finishingMigration', {
|
|
177
|
+
text: (0, lang_1.i18n)(`commands.project.subcommands.migrateApp.spinners.migrationComplete`),
|
|
178
|
+
});
|
|
179
|
+
return pollResponse.buildId;
|
|
180
|
+
}
|
|
181
|
+
else {
|
|
182
|
+
SpinniesManager_1.default.fail('finishingMigration', {
|
|
183
|
+
text: (0, lang_1.i18n)(`commands.project.subcommands.migrateApp.spinners.migrationFailed`),
|
|
184
|
+
});
|
|
185
|
+
if (pollResponse.status === Migration_1.MIGRATION_STATUS.FAILURE) {
|
|
186
|
+
logger_1.logger.error(pollResponse.componentErrorDetails);
|
|
187
|
+
throw new Error(pollResponse.projectErrorsDetail);
|
|
188
|
+
}
|
|
189
|
+
throw new Error((0, lang_1.i18n)('commands.project.subcommands.migrateApp.errors.migrationFailed'));
|
|
190
|
+
}
|
|
194
191
|
}
|
|
195
192
|
async function downloadProjectFiles(derivedAccountId, projectName, buildId, projectDest) {
|
|
196
193
|
try {
|
|
@@ -229,9 +226,6 @@ async function migrateApp2025_2(derivedAccountId, options) {
|
|
|
229
226
|
}
|
|
230
227
|
const { migrationId, uidMap } = migrationInProgress;
|
|
231
228
|
const buildId = await finalizeMigration(derivedAccountId, migrationId, uidMap, projectName);
|
|
232
|
-
if (!buildId) {
|
|
233
|
-
throw new Error('Migration Failed');
|
|
234
|
-
}
|
|
235
229
|
await downloadProjectFiles(derivedAccountId, projectName, buildId, projectDest);
|
|
236
230
|
}
|
|
237
231
|
function logInvalidAccountError(i18nKey) {
|
|
@@ -243,123 +237,3 @@ function logInvalidAccountError(i18nKey) {
|
|
|
243
237
|
}));
|
|
244
238
|
(0, ui_1.uiLine)();
|
|
245
239
|
}
|
|
246
|
-
async function migrateApp2023_2(derivedAccountId, options, accountConfig) {
|
|
247
|
-
const i18nKey = 'commands.project.subcommands.migrateApp';
|
|
248
|
-
const accountName = (0, ui_1.uiAccountDescription)(derivedAccountId);
|
|
249
|
-
if (!(0, accountTypes_1.isAppDeveloperAccount)(accountConfig)) {
|
|
250
|
-
logInvalidAccountError(i18nKey);
|
|
251
|
-
process.exit(exitCodes_1.EXIT_CODES.SUCCESS);
|
|
252
|
-
}
|
|
253
|
-
const { appId } = 'appId' in options
|
|
254
|
-
? options
|
|
255
|
-
: await (0, selectPublicAppPrompt_1.selectPublicAppPrompt)({
|
|
256
|
-
accountId: derivedAccountId,
|
|
257
|
-
accountName,
|
|
258
|
-
isMigratingApp: true,
|
|
259
|
-
});
|
|
260
|
-
try {
|
|
261
|
-
const { data: selectedApp } = await (0, appsDev_1.fetchPublicAppMetadata)(appId, derivedAccountId);
|
|
262
|
-
// preventProjectMigrations returns true if we have not added app to allowlist config.
|
|
263
|
-
// listingInfo will only exist for marketplace apps
|
|
264
|
-
const preventProjectMigrations = selectedApp.preventProjectMigrations;
|
|
265
|
-
const listingInfo = selectedApp.listingInfo;
|
|
266
|
-
if (preventProjectMigrations && listingInfo) {
|
|
267
|
-
logger_1.logger.error((0, lang_1.i18n)(`${i18nKey}.errors.invalidApp`, { appId }));
|
|
268
|
-
process.exit(exitCodes_1.EXIT_CODES.ERROR);
|
|
269
|
-
}
|
|
270
|
-
}
|
|
271
|
-
catch (error) {
|
|
272
|
-
(0, errorHandlers_1.logError)(error, new errorHandlers_1.ApiErrorContext({ accountId: derivedAccountId }));
|
|
273
|
-
process.exit(exitCodes_1.EXIT_CODES.ERROR);
|
|
274
|
-
}
|
|
275
|
-
const createProjectPromptResponse = await (0, createProjectPrompt_1.createProjectPrompt)(options);
|
|
276
|
-
const { name: projectName, dest: projectDest } = createProjectPromptResponse;
|
|
277
|
-
try {
|
|
278
|
-
await (0, projects_2.fetchProject)(derivedAccountId, projectName);
|
|
279
|
-
throw new Error((0, lang_1.i18n)(`${i18nKey}.errors.projectAlreadyExists`, {
|
|
280
|
-
projectName,
|
|
281
|
-
}));
|
|
282
|
-
}
|
|
283
|
-
catch (error) {
|
|
284
|
-
if (!(0, index_1.isSpecifiedError)(error, { statusCode: 404 })) {
|
|
285
|
-
(0, errorHandlers_1.logError)(error, new errorHandlers_1.ApiErrorContext({ accountId: derivedAccountId }));
|
|
286
|
-
return process.exit(exitCodes_1.EXIT_CODES.ERROR);
|
|
287
|
-
}
|
|
288
|
-
}
|
|
289
|
-
// const { projectExists } = await ensureProjectExists(
|
|
290
|
-
// derivedAccountId,
|
|
291
|
-
// projectName,
|
|
292
|
-
// {
|
|
293
|
-
// allowCreate: false,
|
|
294
|
-
// noLogs: true,
|
|
295
|
-
// }
|
|
296
|
-
// );
|
|
297
|
-
//
|
|
298
|
-
// if (projectExists) {
|
|
299
|
-
// throw new Error(
|
|
300
|
-
// i18n(`${i18nKey}.errors.projectAlreadyExists`, {
|
|
301
|
-
// projectName,
|
|
302
|
-
// })
|
|
303
|
-
// );
|
|
304
|
-
// }
|
|
305
|
-
await (0, usageTracking_1.trackCommandMetadataUsage)('migrate-app', { step: 'STARTED' }, derivedAccountId);
|
|
306
|
-
logger_1.logger.log('');
|
|
307
|
-
(0, ui_1.uiLine)();
|
|
308
|
-
logger_1.logger.warn(`${(0, lang_1.i18n)(`${i18nKey}.warning.title`)}\n`);
|
|
309
|
-
logger_1.logger.log((0, lang_1.i18n)(`${i18nKey}.warning.projectConversion`));
|
|
310
|
-
logger_1.logger.log(`${(0, lang_1.i18n)(`${i18nKey}.warning.appConfig`)}\n`);
|
|
311
|
-
logger_1.logger.log(`${(0, lang_1.i18n)(`${i18nKey}.warning.buildAndDeploy`)}\n`);
|
|
312
|
-
logger_1.logger.log(`${(0, lang_1.i18n)(`${i18nKey}.warning.existingApps`)}\n`);
|
|
313
|
-
logger_1.logger.log((0, lang_1.i18n)(`${i18nKey}.warning.copyApp`));
|
|
314
|
-
(0, ui_1.uiLine)();
|
|
315
|
-
const { shouldCreateApp } = await (0, promptUtils_1.promptUser)({
|
|
316
|
-
name: 'shouldCreateApp',
|
|
317
|
-
type: 'confirm',
|
|
318
|
-
message: (0, lang_1.i18n)(`${i18nKey}.createAppPrompt`),
|
|
319
|
-
});
|
|
320
|
-
process.stdin.resume();
|
|
321
|
-
if (!shouldCreateApp) {
|
|
322
|
-
process.exit(exitCodes_1.EXIT_CODES.SUCCESS);
|
|
323
|
-
}
|
|
324
|
-
try {
|
|
325
|
-
SpinniesManager_1.default.init();
|
|
326
|
-
SpinniesManager_1.default.add('migrateApp', {
|
|
327
|
-
text: (0, lang_1.i18n)(`${i18nKey}.migrationStatus.inProgress`),
|
|
328
|
-
});
|
|
329
|
-
(0, process_1.handleKeypress)(async (key) => {
|
|
330
|
-
if ((key.ctrl && key.name === 'c') || key.name === 'q') {
|
|
331
|
-
SpinniesManager_1.default.remove('migrateApp');
|
|
332
|
-
logger_1.logger.log((0, lang_1.i18n)(`${i18nKey}.migrationInterrupted`));
|
|
333
|
-
process.exit(exitCodes_1.EXIT_CODES.SUCCESS);
|
|
334
|
-
}
|
|
335
|
-
});
|
|
336
|
-
const { data: migrateResponse } = await (0, projects_2.migrateApp)(derivedAccountId, appId, projectName);
|
|
337
|
-
const { id } = migrateResponse;
|
|
338
|
-
const pollResponse = await (0, polling_1.poll)(() => (0, projects_2.checkMigrationStatus)(derivedAccountId, id));
|
|
339
|
-
const { status, project } = pollResponse;
|
|
340
|
-
if (status === 'SUCCESS') {
|
|
341
|
-
const absoluteDestPath = path_1.default.resolve((0, path_2.getCwd)(), projectDest);
|
|
342
|
-
const { env } = accountConfig;
|
|
343
|
-
const baseUrl = (0, urls_1.getHubSpotWebsiteOrigin)(env);
|
|
344
|
-
const { data: zippedProject } = await (0, projects_2.downloadProject)(derivedAccountId, projectName, 1);
|
|
345
|
-
await (0, archive_1.extractZipArchive)(zippedProject, (0, path_2.sanitizeFileName)(projectName), path_1.default.resolve(absoluteDestPath), { includesRootDir: true, hideLogs: true });
|
|
346
|
-
SpinniesManager_1.default.succeed('migrateApp', {
|
|
347
|
-
text: (0, lang_1.i18n)(`${i18nKey}.migrationStatus.done`),
|
|
348
|
-
succeedColor: 'white',
|
|
349
|
-
});
|
|
350
|
-
logger_1.logger.log('');
|
|
351
|
-
(0, ui_1.uiLine)();
|
|
352
|
-
logger_1.logger.success((0, lang_1.i18n)(`${i18nKey}.migrationStatus.success`));
|
|
353
|
-
logger_1.logger.log('');
|
|
354
|
-
logger_1.logger.log((0, ui_1.uiLink)((0, lang_1.i18n)(`${i18nKey}.projectDetailsLink`), `${baseUrl}/developer-projects/${derivedAccountId}/project/${encodeURIComponent(project.name)}`));
|
|
355
|
-
process.exit(exitCodes_1.EXIT_CODES.SUCCESS);
|
|
356
|
-
}
|
|
357
|
-
}
|
|
358
|
-
catch (error) {
|
|
359
|
-
SpinniesManager_1.default.fail('migrateApp', {
|
|
360
|
-
text: (0, lang_1.i18n)(`${i18nKey}.migrationStatus.failure`),
|
|
361
|
-
failColor: 'white',
|
|
362
|
-
});
|
|
363
|
-
throw error;
|
|
364
|
-
}
|
|
365
|
-
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { CLIAccount } from '@hubspot/local-dev-lib/types/Accounts';
|
|
2
|
+
import { ArgumentsCamelCase } from 'yargs';
|
|
3
|
+
import { MigrateAppOptions } from '../../types/Yargs';
|
|
4
|
+
export declare function migrateApp2023_2(derivedAccountId: number, options: ArgumentsCamelCase<MigrateAppOptions>, accountConfig: CLIAccount): Promise<void>;
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.migrateApp2023_2 = migrateApp2023_2;
|
|
7
|
+
const appsDev_1 = require("@hubspot/local-dev-lib/api/appsDev");
|
|
8
|
+
const logger_1 = require("@hubspot/local-dev-lib/logger");
|
|
9
|
+
const projects_1 = require("@hubspot/local-dev-lib/api/projects");
|
|
10
|
+
const path_1 = __importDefault(require("path"));
|
|
11
|
+
const path_2 = require("@hubspot/local-dev-lib/path");
|
|
12
|
+
const urls_1 = require("@hubspot/local-dev-lib/urls");
|
|
13
|
+
const archive_1 = require("@hubspot/local-dev-lib/archive");
|
|
14
|
+
const promptUtils_1 = require("../prompts/promptUtils");
|
|
15
|
+
const errorHandlers_1 = require("../errorHandlers");
|
|
16
|
+
const exitCodes_1 = require("../enums/exitCodes");
|
|
17
|
+
const ui_1 = require("../ui");
|
|
18
|
+
const lang_1 = require("../lang");
|
|
19
|
+
const accountTypes_1 = require("../accountTypes");
|
|
20
|
+
const selectPublicAppPrompt_1 = require("../prompts/selectPublicAppPrompt");
|
|
21
|
+
const createProjectPrompt_1 = require("../prompts/createProjectPrompt");
|
|
22
|
+
const projects_2 = require("../projects");
|
|
23
|
+
const usageTracking_1 = require("../usageTracking");
|
|
24
|
+
const SpinniesManager_1 = __importDefault(require("../ui/SpinniesManager"));
|
|
25
|
+
const process_1 = require("../process");
|
|
26
|
+
const polling_1 = require("../polling");
|
|
27
|
+
const migrate_1 = require("./migrate");
|
|
28
|
+
async function migrateApp2023_2(derivedAccountId, options, accountConfig) {
|
|
29
|
+
const accountName = (0, ui_1.uiAccountDescription)(derivedAccountId);
|
|
30
|
+
if (!(0, accountTypes_1.isAppDeveloperAccount)(accountConfig)) {
|
|
31
|
+
(0, migrate_1.logInvalidAccountError)('commands.project.subcommands.migrateApp');
|
|
32
|
+
process.exit(exitCodes_1.EXIT_CODES.SUCCESS);
|
|
33
|
+
}
|
|
34
|
+
const { appId } = 'appId' in options
|
|
35
|
+
? options
|
|
36
|
+
: await (0, selectPublicAppPrompt_1.selectPublicAppPrompt)({
|
|
37
|
+
accountId: derivedAccountId,
|
|
38
|
+
accountName,
|
|
39
|
+
isMigratingApp: true,
|
|
40
|
+
});
|
|
41
|
+
try {
|
|
42
|
+
const { data: selectedApp } = await (0, appsDev_1.fetchPublicAppMetadata)(appId, derivedAccountId);
|
|
43
|
+
// preventProjectMigrations returns true if we have not added app to allowlist config.
|
|
44
|
+
// listingInfo will only exist for marketplace apps
|
|
45
|
+
const preventProjectMigrations = selectedApp.preventProjectMigrations;
|
|
46
|
+
const listingInfo = selectedApp.listingInfo;
|
|
47
|
+
if (preventProjectMigrations && listingInfo) {
|
|
48
|
+
logger_1.logger.error((0, lang_1.i18n)(`commands.project.subcommands.migrateApp.errors.invalidApp`, {
|
|
49
|
+
appId,
|
|
50
|
+
}));
|
|
51
|
+
process.exit(exitCodes_1.EXIT_CODES.ERROR);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
catch (error) {
|
|
55
|
+
(0, errorHandlers_1.logError)(error, new errorHandlers_1.ApiErrorContext({ accountId: derivedAccountId }));
|
|
56
|
+
process.exit(exitCodes_1.EXIT_CODES.ERROR);
|
|
57
|
+
}
|
|
58
|
+
const createProjectPromptResponse = await (0, createProjectPrompt_1.createProjectPrompt)(options);
|
|
59
|
+
const { name: projectName, dest: projectDest } = createProjectPromptResponse;
|
|
60
|
+
const { projectExists } = await (0, projects_2.ensureProjectExists)(derivedAccountId, projectName, {
|
|
61
|
+
allowCreate: false,
|
|
62
|
+
noLogs: true,
|
|
63
|
+
});
|
|
64
|
+
if (projectExists) {
|
|
65
|
+
throw new Error((0, lang_1.i18n)(`commands.project.subcommands.migrateApp.errors.projectAlreadyExists`, {
|
|
66
|
+
projectName,
|
|
67
|
+
}));
|
|
68
|
+
}
|
|
69
|
+
await (0, usageTracking_1.trackCommandMetadataUsage)('migrate-app', { step: 'STARTED' }, derivedAccountId);
|
|
70
|
+
logger_1.logger.log('');
|
|
71
|
+
(0, ui_1.uiLine)();
|
|
72
|
+
logger_1.logger.warn(`${(0, lang_1.i18n)(`commands.project.subcommands.migrateApp.warning.title`)}\n`);
|
|
73
|
+
logger_1.logger.log((0, lang_1.i18n)(`commands.project.subcommands.migrateApp.warning.projectConversion`));
|
|
74
|
+
logger_1.logger.log(`${(0, lang_1.i18n)(`commands.project.subcommands.migrateApp.warning.appConfig`)}\n`);
|
|
75
|
+
logger_1.logger.log(`${(0, lang_1.i18n)(`commands.project.subcommands.migrateApp.warning.buildAndDeploy`)}\n`);
|
|
76
|
+
logger_1.logger.log(`${(0, lang_1.i18n)(`commands.project.subcommands.migrateApp.warning.existingApps`)}\n`);
|
|
77
|
+
logger_1.logger.log((0, lang_1.i18n)(`commands.project.subcommands.migrateApp.warning.copyApp`));
|
|
78
|
+
(0, ui_1.uiLine)();
|
|
79
|
+
const { shouldCreateApp } = await (0, promptUtils_1.promptUser)({
|
|
80
|
+
name: 'shouldCreateApp',
|
|
81
|
+
type: 'confirm',
|
|
82
|
+
message: (0, lang_1.i18n)(`commands.project.subcommands.migrateApp.createAppPrompt`),
|
|
83
|
+
});
|
|
84
|
+
process.stdin.resume();
|
|
85
|
+
if (!shouldCreateApp) {
|
|
86
|
+
process.exit(exitCodes_1.EXIT_CODES.SUCCESS);
|
|
87
|
+
}
|
|
88
|
+
try {
|
|
89
|
+
SpinniesManager_1.default.init();
|
|
90
|
+
SpinniesManager_1.default.add('migrateApp', {
|
|
91
|
+
text: (0, lang_1.i18n)(`commands.project.subcommands.migrateApp.migrationStatus.inProgress`),
|
|
92
|
+
});
|
|
93
|
+
(0, process_1.handleKeypress)(async (key) => {
|
|
94
|
+
if ((key.ctrl && key.name === 'c') || key.name === 'q') {
|
|
95
|
+
SpinniesManager_1.default.remove('migrateApp');
|
|
96
|
+
logger_1.logger.log((0, lang_1.i18n)(`commands.project.subcommands.migrateApp.migrationInterrupted`));
|
|
97
|
+
process.exit(exitCodes_1.EXIT_CODES.SUCCESS);
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
const { data: migrateResponse } = await (0, projects_1.migrateApp)(derivedAccountId, appId, projectName);
|
|
101
|
+
const { id } = migrateResponse;
|
|
102
|
+
const pollResponse = await (0, polling_1.poll)(() => (0, projects_1.checkMigrationStatus)(derivedAccountId, id));
|
|
103
|
+
const { status, project } = pollResponse;
|
|
104
|
+
if (status === 'SUCCESS') {
|
|
105
|
+
const absoluteDestPath = path_1.default.resolve((0, path_2.getCwd)(), projectDest);
|
|
106
|
+
const { env } = accountConfig;
|
|
107
|
+
const baseUrl = (0, urls_1.getHubSpotWebsiteOrigin)(env);
|
|
108
|
+
const { data: zippedProject } = await (0, projects_1.downloadProject)(derivedAccountId, projectName, 1);
|
|
109
|
+
await (0, archive_1.extractZipArchive)(zippedProject, (0, path_2.sanitizeFileName)(projectName), path_1.default.resolve(absoluteDestPath), { includesRootDir: true, hideLogs: true });
|
|
110
|
+
SpinniesManager_1.default.succeed('migrateApp', {
|
|
111
|
+
text: (0, lang_1.i18n)(`commands.project.subcommands.migrateApp.migrationStatus.done`),
|
|
112
|
+
succeedColor: 'white',
|
|
113
|
+
});
|
|
114
|
+
logger_1.logger.log('');
|
|
115
|
+
(0, ui_1.uiLine)();
|
|
116
|
+
logger_1.logger.success((0, lang_1.i18n)(`commands.project.subcommands.migrateApp.migrationStatus.success`));
|
|
117
|
+
logger_1.logger.log('');
|
|
118
|
+
logger_1.logger.log((0, ui_1.uiLink)((0, lang_1.i18n)(`commands.project.subcommands.migrateApp.projectDetailsLink`), `${baseUrl}/developer-projects/${derivedAccountId}/project/${encodeURIComponent(project.name)}`));
|
|
119
|
+
process.exit(exitCodes_1.EXIT_CODES.SUCCESS);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
catch (error) {
|
|
123
|
+
SpinniesManager_1.default.fail('migrateApp', {
|
|
124
|
+
text: (0, lang_1.i18n)(`commands.project.subcommands.migrateApp.migrationStatus.failure`),
|
|
125
|
+
failColor: 'white',
|
|
126
|
+
});
|
|
127
|
+
throw error;
|
|
128
|
+
}
|
|
129
|
+
}
|
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hubspot/cli",
|
|
3
|
-
"version": "7.4.
|
|
3
|
+
"version": "7.4.4-experimental.0",
|
|
4
4
|
"description": "The official CLI for developing on HubSpot",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": "https://github.com/HubSpot/hubspot-cli",
|
|
7
7
|
"dependencies": {
|
|
8
|
-
"@hubspot/local-dev-lib": "
|
|
8
|
+
"@hubspot/local-dev-lib": "3.5.1-beta.0",
|
|
9
9
|
"@hubspot/project-parsing-lib": "0.1.5",
|
|
10
10
|
"@hubspot/serverless-dev-runtime": "7.0.2",
|
|
11
11
|
"@hubspot/theme-preview-dev-server": "0.0.10",
|