Skip to content

Commit

Permalink
Convert Oauth, Polling, and Projects to TS (#1306)
Browse files Browse the repository at this point in the history
  • Loading branch information
camden11 authored Dec 18, 2024
1 parent 9422cfe commit b20ec8b
Show file tree
Hide file tree
Showing 44 changed files with 1,549 additions and 1,265 deletions.
10 changes: 5 additions & 5 deletions commands/project/__tests__/deploy.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,9 @@ const {
addUseEnvironmentOptions,
} = require('../../../lib/commonOpts');
const { loadAndValidateOptions } = require('../../../lib/validation');
const {
getProjectConfig,
pollDeployStatus,
getProjectDetailUrl,
} = require('../../../lib/projects');
const { getProjectConfig } = require('../../../lib/projects');
const { getProjectDetailUrl } = require('../../../lib/projects/urls');
const { pollDeployStatus } = require('../../../lib/projects/buildAndDeploy');
const { projectNamePrompt } = require('../../../lib/prompts/projectNamePrompt');
const { promptUser } = require('../../../lib/prompts/promptUtils');
const { trackCommandUsage } = require('../../../lib/usageTracking');
Expand All @@ -35,6 +33,8 @@ jest.mock('@hubspot/local-dev-lib/config');
jest.mock('../../../lib/commonOpts');
jest.mock('../../../lib/validation');
jest.mock('../../../lib/projects');
jest.mock('../../../lib/projects/urls');
jest.mock('../../../lib/projects/buildAndDeploy');
jest.mock('../../../lib/prompts/projectNamePrompt');
jest.mock('../../../lib/prompts/promptUtils');
jest.mock('../../../lib/usageTracking');
Expand Down
8 changes: 3 additions & 5 deletions commands/project/deploy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,9 @@ const {
fetchProject,
} = require('@hubspot/local-dev-lib/api/projects');
const { loadAndValidateOptions } = require('../../lib/validation');
const {
getProjectConfig,
pollDeployStatus,
getProjectDetailUrl,
} = require('../../lib/projects');
const { getProjectConfig } = require('../../lib/projects');
const { pollDeployStatus } = require('../../lib/projects/buildAndDeploy');
const { getProjectDetailUrl } = require('../../lib/projects/urls');
const { projectNamePrompt } = require('../../lib/prompts/projectNamePrompt');
const { promptUser } = require('../../lib/prompts/promptUtils');
const { i18n } = require('../../lib/lang');
Expand Down
2 changes: 1 addition & 1 deletion commands/project/dev.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ const {
findProjectComponents,
getProjectComponentTypes,
COMPONENT_TYPES,
} = require('../../lib/projectStructure');
} = require('../../lib/projects/structure');
const {
confirmDefaultAccountIsTarget,
suggestRecommendedNestedAccount,
Expand Down
2 changes: 1 addition & 1 deletion commands/project/listBuilds.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ const { uiBetaTag, uiLink } = require('../../lib/ui');
const { loadAndValidateOptions } = require('../../lib/validation');
const {
getProjectConfig,
getProjectDetailUrl,
validateProjectConfig,
} = require('../../lib/projects');
const { getProjectDetailUrl } = require('../../lib/projects/urls');
const moment = require('moment');
const { promptUser } = require('../../lib/prompts/promptUtils');
const { isHubSpotHttpError } = require('@hubspot/local-dev-lib/errors/index');
Expand Down
7 changes: 2 additions & 5 deletions commands/project/open.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,8 @@ const { trackCommandUsage } = require('../../lib/usageTracking');
const { loadAndValidateOptions } = require('../../lib/validation');
const { i18n } = require('../../lib/lang');
const { logger } = require('@hubspot/local-dev-lib/logger');
const {
getProjectConfig,
getProjectDetailUrl,
ensureProjectExists,
} = require('../../lib/projects');
const { getProjectConfig, ensureProjectExists } = require('../../lib/projects');
const { getProjectDetailUrl } = require('../../lib/projects/urls');
const { projectNamePrompt } = require('../../lib/prompts/projectNamePrompt');
const { uiBetaTag } = require('../../lib/ui');
const { EXIT_CODES } = require('../../lib/enums/exitCodes');
Expand Down
8 changes: 5 additions & 3 deletions commands/project/upload.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,14 @@ const { loadAndValidateOptions } = require('../../lib/validation');
const {
ensureProjectExists,
getProjectConfig,
handleProjectUpload,
logFeedbackMessage,
validateProjectConfig,
pollProjectBuildAndDeploy,
displayWarnLogs,
} = require('../../lib/projects');
const { handleProjectUpload } = require('../../lib/projects/upload');
const {
displayWarnLogs,
pollProjectBuildAndDeploy,
} = require('../../lib/projects/buildAndDeploy');
const { i18n } = require('../../lib/lang');
const { getAccountConfig } = require('@hubspot/local-dev-lib/config');
const { isSpecifiedError } = require('@hubspot/local-dev-lib/errors/index');
Expand Down
16 changes: 8 additions & 8 deletions commands/project/watch.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// @ts-nocheck
const { i18n } = require('../../lib/lang');
const { createWatcher } = require('../../lib/projectsWatch');
const { createWatcher } = require('../../lib/projects/watch');
const { logError, ApiErrorContext } = require('../../lib/errorHandlers/index');
const { logger } = require('@hubspot/local-dev-lib/logger');
const { PROJECT_ERROR_TYPES } = require('../../lib/constants');
Expand All @@ -14,12 +14,14 @@ const { uiBetaTag } = require('../../lib/ui');
const {
ensureProjectExists,
getProjectConfig,
handleProjectUpload,
pollBuildStatus,
pollDeployStatus,
validateProjectConfig,
logFeedbackMessage,
} = require('../../lib/projects');
const { handleProjectUpload } = require('../../lib/projects/upload');
const {
pollBuildStatus,
pollDeployStatus,
} = require('../../lib/projects/buildAndDeploy');
const {
cancelStagedBuild,
fetchProjectBuilds,
Expand All @@ -35,10 +37,8 @@ exports.command = 'watch';
exports.describe = uiBetaTag(i18n(`${i18nKey}.describe`), false);

const handleBuildStatus = async (accountId, projectName, buildId) => {
const {
isAutoDeployEnabled,
deployStatusTaskLocator,
} = await pollBuildStatus(accountId, projectName, buildId);
const { isAutoDeployEnabled, deployStatusTaskLocator } =
await pollBuildStatus(accountId, projectName, buildId);

if (isAutoDeployEnabled && deployStatusTaskLocator) {
await pollDeployStatus(
Expand Down
2 changes: 1 addition & 1 deletion commands/theme/preview.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ const { getProjectConfig } = require('../../lib/projects');
const {
findProjectComponents,
COMPONENT_TYPES,
} = require('../../lib/projectStructure');
} = require('../../lib/projects/structure');
const { preview } = require('@hubspot/theme-preview-dev-server');
const { hasFeature } = require('../../lib/hasFeature');
const i18nKey = 'commands.theme.subcommands.preview';
Expand Down
32 changes: 18 additions & 14 deletions lang/en.lyaml
Original file line number Diff line number Diff line change
Expand Up @@ -1094,16 +1094,6 @@ en:
checkIfParentAccountIsAuthed:
notAuthedError: "To develop this project locally, run {{ authCommand }} to authenticate the App Developer Account {{ accountId }} associated with {{ accountIdentifier }}."
projects:
uploadProjectFiles:
add: "Uploading {{#bold}}{{ projectName }}{{/bold}} project files to {{ accountIdentifier }}"
fail: "Failed to upload {{#bold}}{{ projectName }}{{/bold}} project files to {{ accountIdentifier }}"
succeed: "Uploaded {{#bold}}{{ projectName }}{{/bold}} project files to {{ accountIdentifier }}"
buildCreated: "Project \"{{ projectName }}\" uploaded and build #{{ buildId }} created"
handleProjectUpload:
emptySource: "Source directory \"{{ srcDir }}\" is empty. Add files to your project and rerun `{{#yellow}}hs project upload{{/yellow}}` to upload them to HubSpot."
compressed: "Project files compressed: {{ byteCount }} bytes"
compressing: "Compressing build files to \"{{ path }}\""
fileFiltered: "Ignore rule triggered for \"{{ filename }}\""
validateProjectConfig:
configNotFound: "Unable to locate a project configuration file. Try running again from a project directory, or run {{ createCommand }} to create a new project."
configMissingFields: "The project configuruation file is missing required fields."
Expand All @@ -1116,6 +1106,11 @@ en:
notFound: "Your project {{#bold}}{{ projectName }}{{/bold}} could not be found in {{#bold}}{{ accountIdentifier }}{{/bold}}."
pollFetchProject:
checkingProject: "Checking if project exists in {{ accountIdentifier }}"
unableToFindAutodeployStatus: "Unable to find the auto deploy for build #{{ buildId }}. This deploy may have been skipped. {{ viewDeploysLink }}."
logFeedbackMessage:
feedbackHeader: "We'd love to hear your feedback!"
feedbackMessage: "How are you liking the new projects and developer tools? \n > Run `{{#yellow}}hs feedback{{/yellow}}` to let us know what you think!\n"
projectBuildAndDeploy:
makePollTaskStatusFunc:
componentCountSingular: "Found 1 component in this project"
componentCount: "Found {{ numComponents }} components in this project"
Expand All @@ -1127,10 +1122,17 @@ en:
buildSucceededAutomaticallyDeploying: "Build #{{ buildId }} succeeded. {{#bold}}Automatically deploying{{/bold}} to {{ accountIdentifier }}\n"
cleanedUpTempFile: "Cleaned up temporary file {{ path }}"
viewDeploys: "View all deploys for this project in HubSpot"
unableToFindAutodeployStatus: "Unable to find the auto deploy for build #{{ buildId }}. This deploy may have been skipped. {{ viewDeploysLink }}."
logFeedbackMessage:
feedbackHeader: "We'd love to hear your feedback!"
feedbackMessage: "How are you liking the new projects and developer tools? \n > Run `{{#yellow}}hs feedback{{/yellow}}` to let us know what you think!\n"
projectUpload:
uploadProjectFiles:
add: "Uploading {{#bold}}{{ projectName }}{{/bold}} project files to {{ accountIdentifier }}"
fail: "Failed to upload {{#bold}}{{ projectName }}{{/bold}} project files to {{ accountIdentifier }}"
succeed: "Uploaded {{#bold}}{{ projectName }}{{/bold}} project files to {{ accountIdentifier }}"
buildCreated: "Project \"{{ projectName }}\" uploaded and build #{{ buildId }} created"
handleProjectUpload:
emptySource: "Source directory \"{{ srcDir }}\" is empty. Add files to your project and rerun `{{#yellow}}hs project upload{{/yellow}}` to upload them to HubSpot."
compressed: "Project files compressed: {{ byteCount }} bytes"
compressing: "Compressing build files to \"{{ path }}\""
fileFiltered: "Ignore rule triggered for \"{{ filename }}\""
ui:
betaTag: "{{#bold}}[BETA]{{/bold}}"
betaWarning:
Expand Down Expand Up @@ -1551,6 +1553,8 @@ en:
counts:
errors: '{{#bold}}Errors:{{/bold}} {{ count }}'
warnings: "{{#bold}}Warning:{{/bold}} {{ count }}"
oauth:
missingClientId: "Error building oauth URL: missing client ID."



2 changes: 1 addition & 1 deletion lib/DevServerManager.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// @ts-nocheck
const { logger } = require('@hubspot/local-dev-lib/logger');
const { COMPONENT_TYPES } = require('./projectStructure');
const { COMPONENT_TYPES } = require('./projects/structure');
const { i18n } = require('./lang');
const { promptUser } = require('./prompts/promptUtils');
const { DevModeInterface } = require('@hubspot/ui-extensions-dev-server');
Expand Down
4 changes: 2 additions & 2 deletions lib/LocalDevManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,13 @@ const { PROJECT_CONFIG_FILE } = require('./constants');
const SpinniesManager = require('./ui/SpinniesManager');
const DevServerManager = require('./DevServerManager');
const { EXIT_CODES } = require('./enums/exitCodes');
const { getProjectDetailUrl } = require('./projects');
const { getProjectDetailUrl } = require('./projects/urls');
const { getAccountHomeUrl } = require('./localDev');
const {
CONFIG_FILES,
COMPONENT_TYPES,
getAppCardConfigs,
} = require('./projectStructure');
} = require('./projects/structure');
const {
UI_COLORS,
uiCommandReference,
Expand Down
4 changes: 2 additions & 2 deletions lib/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,12 +61,12 @@ export const PROJECT_ERROR_TYPES = {
SUBDEPLOY_FAILED: 'DeployPipelineErrorType.DEPENDENT_SUBDEPLOY_FAILED',
} as const;

export const PROJECT_TASK_TYPES = {
export const PROJECT_TASK_TYPES: { [key: string]: string } = {
PRIVATE_APP: 'private app',
PUBLIC_APP: 'public app',
APP_FUNCTION: 'function',
CRM_CARD_V2: 'card',
} as const;
};

export const PROJECT_COMPONENT_TYPES = {
PROJECTS: 'projects',
Expand Down
12 changes: 8 additions & 4 deletions lib/doctor/DiagnosticInfoBuilder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,12 +87,14 @@ export class DiagnosticInfoBuilder {
}

async generateDiagnosticInfo(): Promise<DiagnosticInfo> {
// @ts-expect-error getProjectConfig not typed yet
this._projectConfig = await getProjectConfig();

if (this._projectConfig?.projectConfig) {
await this.fetchProjectDetails();
await this.fetchAccessToken();
}

if (this._projectConfig?.projectDir) {
await this.fetchProjectFilenames();
}

Expand Down Expand Up @@ -134,7 +136,8 @@ export class DiagnosticInfoBuilder {
try {
const { data } = await fetchProject(
this.accountId!,
this._projectConfig?.projectConfig?.name
// We check that config exists before running this function
this._projectConfig!.projectConfig!.name
);
this.projectDetails = data;
} catch (e) {
Expand All @@ -158,10 +161,11 @@ export class DiagnosticInfoBuilder {

private async fetchProjectFilenames(): Promise<void> {
try {
this.files = (await walk(this._projectConfig?.projectDir))
// We check that projectDir exists before running this function
this.files = (await walk(this._projectConfig!.projectDir!))
.filter(file => !path.dirname(file).includes('node_modules'))
.map(filename =>
path.relative(this._projectConfig?.projectDir, filename)
path.relative(this._projectConfig!.projectDir!, filename)
);
} catch (e) {
logger.debug(e);
Expand Down
10 changes: 7 additions & 3 deletions lib/doctor/Doctor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ export class Doctor {
text: i18n(`${i18nKey}.runningDiagnostics`),
});

this.diagnosticInfo = await this.diagnosticInfoBuilder.generateDiagnosticInfo();
this.diagnosticInfo =
await this.diagnosticInfoBuilder.generateDiagnosticInfo();

this.projectConfig = this.diagnosticInfo?.project.config;

Expand Down Expand Up @@ -279,7 +280,7 @@ export class Doctor {
const packageDirName = path.dirname(packageFile);
try {
const needsInstall = await hasMissingPackages(
path.join(this.projectConfig?.projectDir, packageDirName)
path.join(this.projectConfig?.projectDir || '', packageDirName)
);

if (needsInstall) {
Expand Down Expand Up @@ -343,7 +344,10 @@ export class Doctor {
private async checkProjectConfigJsonFiles(): Promise<void> {
let foundError = false;
for (const jsonFile of this.diagnosticInfo?.jsonFiles || []) {
const fileToCheck = path.join(this.projectConfig?.projectDir, jsonFile);
const fileToCheck = path.join(
this.projectConfig?.projectDir || '',
jsonFile
);
if (!(await this.isValidJsonFile(fileToCheck))) {
foundError = true;
this.diagnosis?.addProjectSection({
Expand Down
2 changes: 2 additions & 0 deletions lib/doctor/__tests__/Diagnosis.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ describe('lib/doctor/Diagnosis', () => {
projectDir: 'project-dir',
projectConfig: {
name: 'Super cool project',
srcDir: 'project-dir',
platformVersion: 'test',
},
},
},
Expand Down
14 changes: 8 additions & 6 deletions lib/doctor/__tests__/DiagnosticInfoBuilder.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import { AccessToken, CLIAccount } from '@hubspot/local-dev-lib/types/Accounts';
import { getProjectConfig as _getProjectConfig } from '../../projects';
import { fetchProject as _fetchProject } from '@hubspot/local-dev-lib/api/projects';
import { Project } from '@hubspot/local-dev-lib/types/Project';
import { AxiosPromise } from 'axios';
import { HubSpotPromise } from '@hubspot/local-dev-lib/types/Http';

const walk = _walk as jest.MockedFunction<typeof _walk>;
const getAccessToken = _getAccessToken as jest.MockedFunction<
Expand Down Expand Up @@ -124,6 +124,8 @@ describe('lib/doctor/DiagnosticInfo', () => {
projectDir,
projectConfig: {
name: 'My project',
srcDir: 'project-dir',
platformVersion: 'test',
},
};

Expand All @@ -133,7 +135,7 @@ describe('lib/doctor/DiagnosticInfo', () => {
deployedBuildId: 1,
id: 8989898,
isLocked: false,
name: projectConfig.projectConfig.name,
name: projectConfig!.projectConfig!.name,
portalId: accountId,
updatedAt: 12345,
};
Expand All @@ -143,16 +145,16 @@ describe('lib/doctor/DiagnosticInfo', () => {
accountType: 'STANDARD',
encodedOAuthRefreshToken: '',
expiresAt: '',
hubName: projectConfig.projectConfig.name,
hubName: projectConfig!.projectConfig!.name,
portalId: accountId,
scopeGroups: [],
enabledFeatures: {},
};

getProjectConfig.mockResolvedValue(projectConfig);
fetchProject.mockResolvedValue(({
fetchProject.mockResolvedValue({
data: projectDetails,
} as unknown) as AxiosPromise<Project>);
} as unknown as HubSpotPromise<Project>);
getAccessToken.mockResolvedValue(accessToken);
getConfigPath.mockReturnValue(configPath);
utilPromisify.mockReturnValue(jest.fn().mockResolvedValue(npmVersion));
Expand All @@ -166,7 +168,7 @@ describe('lib/doctor/DiagnosticInfo', () => {
expect(fetchProject).toHaveBeenCalledTimes(1);
expect(fetchProject).toHaveBeenCalledWith(
accountId,
projectConfig!.projectConfig.name
projectConfig!.projectConfig!.name
);

expect(getAccessToken).toHaveBeenCalledTimes(1);
Expand Down
Loading

0 comments on commit b20ec8b

Please sign in to comment.