@hubspot/local-dev-lib 0.7.5-experimental.0 → 0.7.6-experimental.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/api/projects.d.ts CHANGED
@@ -1,8 +1,8 @@
1
1
  import { HubSpotPromise, QueryParams } from '../types/Http.js';
2
- import { Project, FetchProjectResponse, UploadProjectResponse, ProjectSettings, FetchPlatformVersionResponse, WarnLogsResponse, UploadIRResponse, Release, FetchListReleasesResponse } from '../types/Project.js';
2
+ import { Project, FetchProjectResponse, UploadProjectResponse, ProjectSettings, FetchPlatformVersionResponse, WarnLogsResponse, UploadIRResponse } from '../types/Project.js';
3
3
  import { Build, FetchProjectBuildsResponse } from '../types/Build.js';
4
4
  import { ComponentStructureResponse, ProjectComponentsMetadata } from '../types/ComponentStructure.js';
5
- import { Deploy, ProjectDeployResponse, ProjectDeployResponseV1 } from '../types/Deploy.js';
5
+ import { Deploy, ProjectDeployResponse, ProjectDeployResponseV1, ProjectDeletionResponse } from '../types/Deploy.js';
6
6
  import { MigrateAppResponse, CloneAppResponse, PollAppResponse } from '../types/Migration.js';
7
7
  export declare function fetchProjects(accountId: number): HubSpotPromise<FetchProjectResponse>;
8
8
  export declare function createProject(accountId: number, name: string): HubSpotPromise<Project>;
@@ -11,6 +11,14 @@ export declare function fetchProject(accountId: number, projectName: string): Hu
11
11
  export declare function fetchProjectComponentsMetadata(accountId: number, projectId: number): HubSpotPromise<ProjectComponentsMetadata>;
12
12
  export declare function downloadProject(accountId: number, projectName: string, buildId: number): HubSpotPromise<Buffer>;
13
13
  export declare function deleteProject(accountId: number, projectName: string): HubSpotPromise<void>;
14
+ /**
15
+ * Stages the project for deletion. Returns a deployId that can be polled using getDeployStatus.
16
+ * This needs to be called first before `deleteProject` for unified projects
17
+ * @param accountId
18
+ * @param projectName - The name of the project to delete
19
+ * @param dryRun - Should this be a dry run of the deletion. If set to true, returns a list of the components that will be removed `componentsToRemove`
20
+ */
21
+ export declare function stageProjectForDeletion(accountId: number, projectName: string, dryRun: boolean): HubSpotPromise<ProjectDeletionResponse>;
14
22
  export declare function fetchPlatformVersions(accountId: number): HubSpotPromise<FetchPlatformVersionResponse>;
15
23
  export declare function fetchProjectBuilds(accountId: number, projectName: string, params?: QueryParams): HubSpotPromise<FetchProjectBuildsResponse>;
16
24
  export declare function getBuildStatus(accountId: number, projectName: string, buildId: number): HubSpotPromise<Build>;
@@ -31,9 +39,6 @@ export declare function deleteFileFromBuild(accountId: number, projectName: stri
31
39
  export declare function cancelStagedBuild(accountId: number, projectName: string): HubSpotPromise<void>;
32
40
  export declare function fetchBuildWarnLogs(accountId: number, projectName: string, buildId: number): HubSpotPromise<WarnLogsResponse>;
33
41
  export declare function fetchDeployWarnLogs(accountId: number, projectName: string, deployId: number): HubSpotPromise<WarnLogsResponse>;
34
- export declare function createRelease(accountId: number, projectName: string, buildId: number): HubSpotPromise<Release>;
35
- export declare function listReleases(accountId: number, projectName: string, params?: QueryParams): HubSpotPromise<FetchListReleasesResponse>;
36
- export declare function getReleaseInfo(accountId: number, projectName: string, releaseTag: string): HubSpotPromise<Release>;
37
42
  /**
38
43
  * @deprecated
39
44
  */
package/api/projects.js CHANGED
@@ -78,6 +78,19 @@ export function deleteProject(accountId, projectName) {
78
78
  url: `${DEVELOPER_PROJECTS_API_PATH}/${encodeURIComponent(projectName)}`,
79
79
  });
80
80
  }
81
+ /**
82
+ * Stages the project for deletion. Returns a deployId that can be polled using getDeployStatus.
83
+ * This needs to be called first before `deleteProject` for unified projects
84
+ * @param accountId
85
+ * @param projectName - The name of the project to delete
86
+ * @param dryRun - Should this be a dry run of the deletion. If set to true, returns a list of the components that will be removed `componentsToRemove`
87
+ */
88
+ export function stageProjectForDeletion(accountId, projectName, dryRun) {
89
+ return http.post(accountId, {
90
+ url: `${PROJECTS_DEPLOY_API_PATH_V3}/deploys/delete`,
91
+ data: { projectName, dryRun },
92
+ });
93
+ }
81
94
  export function fetchPlatformVersions(accountId) {
82
95
  return http.get(accountId, {
83
96
  url: `${DEVELOPER_PROJECTS_API_PATH}/platformVersion`,
@@ -202,23 +215,6 @@ export function fetchDeployWarnLogs(accountId, projectName, deployId) {
202
215
  url: `${PROJECTS_LOGS_API_PATH}/logs/projects/${encodeURIComponent(projectName)}/deploys/${deployId}/combined/warn`,
203
216
  });
204
217
  }
205
- export function createRelease(accountId, projectName, buildId) {
206
- return http.post(accountId, {
207
- url: `${PROJECTS_API_PATH}/${encodeURIComponent(projectName)}/releases`,
208
- data: { buildId },
209
- });
210
- }
211
- export function listReleases(accountId, projectName, params = {}) {
212
- return http.get(accountId, {
213
- url: `${PROJECTS_API_PATH}/${encodeURIComponent(projectName)}/releases`,
214
- params,
215
- });
216
- }
217
- export function getReleaseInfo(accountId, projectName, releaseTag) {
218
- return http.get(accountId, {
219
- url: `${PROJECTS_API_PATH}/${encodeURIComponent(projectName)}/releases/${encodeURIComponent(releaseTag)}`,
220
- });
221
- }
222
218
  /**
223
219
  * @deprecated
224
220
  */
@@ -1,3 +1,4 @@
1
1
  import { HubSpotConfigAccount } from '../types/Accounts.js';
2
2
  export declare function getDefaultAccountOverrideAccountId(accounts: Array<HubSpotConfigAccount>): number | null;
3
+ export declare function removeDefaultAccountOverrideFile(): void;
3
4
  export declare function getDefaultAccountOverrideFilePath(): string | null;
@@ -40,6 +40,21 @@ export function getDefaultAccountOverrideAccountId(accounts) {
40
40
  }
41
41
  return account.accountId;
42
42
  }
43
+ export function removeDefaultAccountOverrideFile() {
44
+ const filePath = getDefaultAccountOverrideFilePath();
45
+ if (!filePath) {
46
+ return;
47
+ }
48
+ try {
49
+ fs.unlinkSync(filePath);
50
+ }
51
+ catch (e) {
52
+ throw new FileSystemError({ cause: e }, {
53
+ filepath: filePath,
54
+ operation: 'write',
55
+ });
56
+ }
57
+ }
43
58
  export function getDefaultAccountOverrideFilePath() {
44
59
  return findup([DEFAULT_ACCOUNT_OVERRIDE_FILE_NAME], {
45
60
  cwd: getCwd(),
@@ -0,0 +1,4 @@
1
+ import { HsSettingsFile } from '../types/HsSettings.js';
2
+ export declare function getHsSettingsFilePath(): string | null;
3
+ export declare function getHsSettingsFileIfExists(): HsSettingsFile | null;
4
+ export declare function writeHsSettingsFile(settingsFile: HsSettingsFile): void;
@@ -0,0 +1,57 @@
1
+ import findupSync from 'findup-sync';
2
+ import fs from 'fs';
3
+ import path from 'path';
4
+ import { HS_FOLDER, HS_README_FILENAME, HS_SETTINGS_FILENAME, } from '../constants/config.js';
5
+ import { getCwd } from '../lib/path.js';
6
+ import { FileSystemError } from '../models/FileSystemError.js';
7
+ const HS_README_CONTENTS = `Why do I have a folder named ".hs" in my project?
8
+ The ".hs" folder is created when you link a directory to a HubSpot project.
9
+
10
+ What does the "settings.json" file contain?
11
+ The "settings.json" file contains:
12
+ - The ID(s) of the HubSpot account(s) that you linked ("accounts")
13
+ - The ID of the HubSpot account that you set as the default for this directory ("linkedDefaultAccount")
14
+
15
+ Should I commit the ".hs" folder?
16
+ No, the ".hs" folder should not be committed to version control. It is automatically added to your .gitignore file when the directory is linked.
17
+ `;
18
+ export function getHsSettingsFilePath() {
19
+ return findupSync([`${HS_FOLDER}/${HS_SETTINGS_FILENAME}`], {
20
+ cwd: getCwd(),
21
+ });
22
+ }
23
+ export function getHsSettingsFileIfExists() {
24
+ const hsSettingsFilePath = getHsSettingsFilePath();
25
+ if (!hsSettingsFilePath) {
26
+ return null;
27
+ }
28
+ let hsSettingsFile;
29
+ try {
30
+ hsSettingsFile = JSON.parse(fs.readFileSync(hsSettingsFilePath, 'utf-8'));
31
+ }
32
+ catch (e) {
33
+ throw new FileSystemError({ cause: e }, {
34
+ filepath: hsSettingsFilePath,
35
+ operation: 'read',
36
+ });
37
+ }
38
+ return hsSettingsFile;
39
+ }
40
+ export function writeHsSettingsFile(settingsFile) {
41
+ const dir = getCwd();
42
+ const hsFolderPath = path.join(dir, HS_FOLDER);
43
+ const isFirstScaffold = !fs.existsSync(hsFolderPath);
44
+ try {
45
+ fs.mkdirSync(hsFolderPath, { recursive: true });
46
+ fs.writeFileSync(path.join(dir, HS_FOLDER, HS_SETTINGS_FILENAME), JSON.stringify(settingsFile, null, 2), 'utf8');
47
+ if (isFirstScaffold) {
48
+ fs.writeFileSync(path.join(hsFolderPath, HS_README_FILENAME), HS_README_CONTENTS, 'utf8');
49
+ }
50
+ }
51
+ catch (err) {
52
+ throw new FileSystemError({ cause: err }, {
53
+ filepath: dir,
54
+ operation: 'write',
55
+ });
56
+ }
57
+ }
package/config/index.d.ts CHANGED
@@ -18,6 +18,7 @@ export declare function getConfigAccountIfExists(identifier: number | string): H
18
18
  export declare function getConfigDefaultAccount(): HubSpotConfigAccount;
19
19
  export declare function getConfigDefaultAccountIfExists(): HubSpotConfigAccount | undefined;
20
20
  export declare function getAllConfigAccounts(): HubSpotConfigAccount[];
21
+ export declare function getLinkedOrAllConfigAccounts(): HubSpotConfigAccount[];
21
22
  export declare function getConfigAccountEnvironment(identifier: number | string): Environment;
22
23
  export declare function addConfigAccount(accountToAdd: HubSpotConfigAccount): void;
23
24
  export declare function updateConfigAccount(updatedAccount: HubSpotConfigAccount): void;
package/config/index.js CHANGED
@@ -11,6 +11,7 @@ import { HubSpotConfigError } from '../models/HubSpotConfigError.js';
11
11
  import { HUBSPOT_CONFIG_ERROR_TYPES } from '../constants/config.js';
12
12
  import { isDeepEqual } from '../lib/isDeepEqual.js';
13
13
  import { getCwd } from '../lib/path.js';
14
+ import { getHsSettingsFileIfExists } from './hsSettings.js';
14
15
  const EMPTY_CONFIG = { accounts: [] };
15
16
  export function getGlobalConfigFilePath() {
16
17
  return GLOBAL_CONFIG_PATH;
@@ -152,11 +153,17 @@ export function getConfigAccountIfExists(identifier) {
152
153
  export function getConfigDefaultAccount() {
153
154
  const { accounts, defaultAccount } = getConfig();
154
155
  let defaultAccountToUse = defaultAccount;
155
- const currentConfigPath = getConfigFilePath();
156
- const globalConfigPath = getGlobalConfigFilePath();
157
- if (currentConfigPath === globalConfigPath && globalConfigFileExists()) {
158
- const defaultAccountOverrideAccountId = getDefaultAccountOverrideAccountId(accounts);
159
- defaultAccountToUse = defaultAccountOverrideAccountId || defaultAccount;
156
+ const hsSettingsFile = getHsSettingsFileIfExists();
157
+ if (hsSettingsFile && hsSettingsFile.localDefaultAccount) {
158
+ defaultAccountToUse = hsSettingsFile.localDefaultAccount;
159
+ }
160
+ else {
161
+ const currentConfigPath = getConfigFilePath();
162
+ const globalConfigPath = getGlobalConfigFilePath();
163
+ if (currentConfigPath === globalConfigPath && globalConfigFileExists()) {
164
+ const defaultAccountOverrideAccountId = getDefaultAccountOverrideAccountId(accounts);
165
+ defaultAccountToUse = defaultAccountOverrideAccountId || defaultAccount;
166
+ }
160
167
  }
161
168
  if (!defaultAccountToUse) {
162
169
  throw new HubSpotConfigError(i18n('config.getConfigDefaultAccount.fieldMissingError'), HUBSPOT_CONFIG_ERROR_TYPES.NO_DEFAULT_ACCOUNT, HUBSPOT_CONFIG_OPERATIONS.READ);
@@ -172,12 +179,17 @@ export function getConfigDefaultAccount() {
172
179
  export function getConfigDefaultAccountIfExists() {
173
180
  const { accounts, defaultAccount } = getConfig();
174
181
  let defaultAccountToUse = defaultAccount;
175
- // Only check for default account override if we're using the global config
176
- const currentConfigPath = getConfigFilePath();
177
- const globalConfigPath = getGlobalConfigFilePath();
178
- if (currentConfigPath === globalConfigPath && globalConfigFileExists()) {
179
- const defaultAccountOverrideAccountId = getDefaultAccountOverrideAccountId(accounts);
180
- defaultAccountToUse = defaultAccountOverrideAccountId || defaultAccount;
182
+ const hsSettingsFile = getHsSettingsFileIfExists();
183
+ if (hsSettingsFile && hsSettingsFile.localDefaultAccount) {
184
+ defaultAccountToUse = hsSettingsFile.localDefaultAccount;
185
+ }
186
+ else {
187
+ const currentConfigPath = getConfigFilePath();
188
+ const globalConfigPath = getGlobalConfigFilePath();
189
+ if (currentConfigPath === globalConfigPath && globalConfigFileExists()) {
190
+ const defaultAccountOverrideAccountId = getDefaultAccountOverrideAccountId(accounts);
191
+ defaultAccountToUse = defaultAccountOverrideAccountId || defaultAccount;
192
+ }
181
193
  }
182
194
  if (!defaultAccountToUse) {
183
195
  return;
@@ -189,6 +201,14 @@ export function getAllConfigAccounts() {
189
201
  const { accounts } = getConfig();
190
202
  return accounts;
191
203
  }
204
+ export function getLinkedOrAllConfigAccounts() {
205
+ const { accounts } = getConfig();
206
+ const hsSettingsFile = getHsSettingsFileIfExists();
207
+ if (!hsSettingsFile || hsSettingsFile.accounts.length === 0) {
208
+ return accounts;
209
+ }
210
+ return accounts.filter(a => hsSettingsFile.accounts.includes(a.accountId));
211
+ }
192
212
  export function getConfigAccountEnvironment(identifier) {
193
213
  const config = getConfig();
194
214
  const account = getConfigAccountByInferredIdentifier(config.accounts, identifier);
@@ -102,3 +102,7 @@ export declare const HUBSPOT_CONFIG_OPERATIONS: {
102
102
  readonly WRITE: "WRITE";
103
103
  readonly DELETE: "DELETE";
104
104
  };
105
+ export declare const HS_FOLDER = ".hs";
106
+ export declare const HS_SETTINGS_FILENAME = "settings.json";
107
+ export declare const HS_README_FILENAME = "README.txt";
108
+ export declare const DEFAULT_HS_SETTINGS_PATH = ".hs/settings.json";
@@ -105,3 +105,7 @@ export const HUBSPOT_CONFIG_OPERATIONS = {
105
105
  WRITE: 'WRITE',
106
106
  DELETE: 'DELETE',
107
107
  };
108
+ export const HS_FOLDER = '.hs';
109
+ export const HS_SETTINGS_FILENAME = 'settings.json';
110
+ export const HS_README_FILENAME = 'README.txt';
111
+ export const DEFAULT_HS_SETTINGS_PATH = `${HS_FOLDER}/${HS_SETTINGS_FILENAME}`;
package/enums/build.d.ts CHANGED
@@ -7,6 +7,7 @@ export declare const BUILD_STATUS: {
7
7
  };
8
8
  export declare const SUBBUILD_TYPES: {
9
9
  readonly APP: "APP";
10
+ readonly APPLICATION: "APPLICATION";
10
11
  readonly PRIVATE_APP: "PRIVATE_APP";
11
12
  readonly THEME: "THEME";
12
13
  readonly REACT_THEME: "REACT_THEME";
package/enums/build.js CHANGED
@@ -7,6 +7,7 @@ export const BUILD_STATUS = {
7
7
  };
8
8
  export const SUBBUILD_TYPES = {
9
9
  APP: 'APP',
10
+ APPLICATION: 'APPLICATION',
10
11
  PRIVATE_APP: 'PRIVATE_APP',
11
12
  THEME: 'THEME',
12
13
  REACT_THEME: 'REACT_THEME',
@@ -1,3 +1,4 @@
1
1
  import { GitInclusionResult } from '../types/Config.js';
2
2
  export declare function checkAndAddConfigToGitignore(configPath: string): void;
3
+ export declare function checkAndAddHsFolderToGitignore(settingsPath: string): void;
3
4
  export declare function checkGitInclusion(configPath: string): GitInclusionResult;
package/lib/gitignore.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import fs from 'fs-extra';
2
2
  import path from 'path';
3
3
  import { isConfigPathInGitRepo, getGitignoreFiles, configFilenameIsIgnoredByGitignore, } from '../utils/git.js';
4
- import { DEFAULT_HUBSPOT_CONFIG_YAML_FILE_NAME } from '../constants/config.js';
4
+ import { DEFAULT_HUBSPOT_CONFIG_YAML_FILE_NAME, HS_FOLDER, } from '../constants/config.js';
5
5
  import { i18n } from '../utils/lang.js';
6
6
  const i18nKey = 'lib.gitignore';
7
7
  const GITIGNORE_FILE = '.gitignore';
@@ -23,6 +23,27 @@ export function checkAndAddConfigToGitignore(configPath) {
23
23
  throw new Error(i18n(`${i18nKey}.errors.configIgnore`), { cause: e });
24
24
  }
25
25
  }
26
+ export function checkAndAddHsFolderToGitignore(settingsPath) {
27
+ try {
28
+ const hsDirPath = path.resolve(path.dirname(settingsPath));
29
+ const { configIgnored, gitignoreFiles } = checkGitInclusion(hsDirPath);
30
+ if (configIgnored)
31
+ return;
32
+ let gitignoreFilePath = gitignoreFiles && gitignoreFiles.length ? gitignoreFiles[0] : null;
33
+ if (!gitignoreFilePath) {
34
+ gitignoreFilePath = path.join(path.dirname(hsDirPath), GITIGNORE_FILE);
35
+ fs.writeFileSync(gitignoreFilePath, '');
36
+ }
37
+ const gitignoreContents = fs.readFileSync(gitignoreFilePath).toString();
38
+ if (gitignoreContents.includes(HS_FOLDER))
39
+ return;
40
+ const updatedContents = `${gitignoreContents.trim()}\n\n# HubSpot link folder\n${HS_FOLDER}\n`;
41
+ fs.writeFileSync(gitignoreFilePath, updatedContents);
42
+ }
43
+ catch (e) {
44
+ throw new Error(i18n(`${i18nKey}.errors.configIgnore`), { cause: e });
45
+ }
46
+ }
26
47
  export function checkGitInclusion(configPath) {
27
48
  const result = {
28
49
  inGit: false,
package/package.json CHANGED
@@ -1,8 +1,12 @@
1
1
  {
2
2
  "name": "@hubspot/local-dev-lib",
3
- "version": "0.7.5-experimental.0",
3
+ "version": "0.7.6-experimental.1",
4
4
  "type": "module",
5
5
  "description": "Provides library functionality for HubSpot local development tooling, including the HubSpot CLI",
6
+ "files": [
7
+ "**/*",
8
+ "!**/__tests__/**"
9
+ ],
6
10
  "repository": {
7
11
  "type": "git",
8
12
  "url": "https://github.com/HubSpot/hubspot-local-dev-lib"
@@ -55,6 +59,7 @@
55
59
  "./config/defaultAccountOverride": "./config/defaultAccountOverride.js",
56
60
  "./config/migrate": "./config/migrate.js",
57
61
  "./config/state": "./config/state.js",
62
+ "./config/hsSettings": "./config/hsSettings.js",
58
63
  "./config": "./config/index.js",
59
64
  "./constants/*": "./constants/*.js",
60
65
  "./enums/*": "./enums/*.js",
package/types/Apps.d.ts CHANGED
@@ -71,6 +71,8 @@ export type PublicApp = {
71
71
  };
72
72
  allowedExternalUrls: Array<string>;
73
73
  preventProjectMigrations?: boolean;
74
+ authType: string;
75
+ distributionType: string;
74
76
  };
75
77
  export type FetchPublicAppsForPortalResponse = {
76
78
  results: Array<PublicApp>;
package/types/Deploy.d.ts CHANGED
@@ -55,3 +55,12 @@ export type ProjectDeployResponseV1 = {
55
55
  id: string;
56
56
  links: DeployResponseLinks;
57
57
  };
58
+ export type DeployedComponentInfo = {
59
+ componentType: string;
60
+ componentId: string;
61
+ };
62
+ export type ProjectDeletionResponse = {
63
+ deployId?: number;
64
+ componentsToRemove: DeployedComponentInfo[];
65
+ hasDeployedComponents: boolean;
66
+ };
@@ -0,0 +1,4 @@
1
+ export type HsSettingsFile = {
2
+ localDefaultAccount: number | undefined;
3
+ accounts: number[];
4
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -1,8 +1,6 @@
1
1
  import type { Build } from './Build.js';
2
2
  import { GithubSourceData } from './Github.js';
3
3
  import { ProjectLog } from './ProjectLog.js';
4
- import { ValueOf } from './Utils.js';
5
- import { SUBBUILD_TYPES } from '../enums/build.js';
6
4
  export type Project = {
7
5
  createdAt: number;
8
6
  deletedAt: number;
@@ -50,22 +48,3 @@ export type FetchPlatformVersionResponse = {
50
48
  export type WarnLogsResponse = {
51
49
  logs: Array<ProjectLog>;
52
50
  };
53
- export type Release = {
54
- releaseTag: string;
55
- buildId: number;
56
- createdAt: string;
57
- components?: Array<{
58
- buildType: ValueOf<typeof SUBBUILD_TYPES>;
59
- buildName?: string;
60
- rootPath?: string;
61
- id?: string;
62
- }>;
63
- };
64
- export type FetchListReleasesResponse = {
65
- results: Array<Release>;
66
- paging: {
67
- next: {
68
- after: string;
69
- };
70
- };
71
- };