@hubspot/cli 8.15.0-beta.0 → 8.15.0-beta.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/commands/getStarted.js +1 -1
- package/commands/project/create.js +4 -1
- package/commands/project/download.d.ts +3 -2
- package/commands/project/download.js +15 -2
- package/commands/project/migrate.js +0 -7
- package/commands/project/validate.d.ts +3 -2
- package/commands/project/validate.js +68 -15
- package/lang/en.d.ts +2 -1
- package/lang/en.js +2 -1
- package/lib/constants.d.ts +0 -1
- package/lib/constants.js +0 -1
- package/lib/filesystem.d.ts +6 -0
- package/lib/filesystem.js +9 -0
- package/lib/jsonOutput/download.d.ts +7 -0
- package/lib/jsonOutput/download.js +6 -0
- package/lib/jsonOutput/validate.d.ts +36 -0
- package/lib/jsonOutput/validate.js +20 -0
- package/lib/projects/projectProfiles.d.ts +1 -0
- package/lib/projects/projectProfiles.js +8 -0
- package/lib/projects/uieLinting.d.ts +2 -0
- package/lib/projects/uieLinting.js +13 -8
- package/lib/projects/upload.d.ts +5 -1
- package/lib/projects/upload.js +6 -1
- package/lib/projects/validate.d.ts +10 -1
- package/lib/projects/validate.js +76 -30
- package/lib/projects/validateLintConfigOnUpload.js +6 -5
- package/lib/projects/workspaces.js +6 -13
- package/mcp-server/tools/project/AddFeatureToProjectTool.d.ts +1 -1
- package/mcp-server/tools/project/CreateProjectTool.d.ts +1 -1
- package/mcp-server/tools/project/constants.d.ts +1 -1
- package/package.json +1 -1
package/commands/getStarted.js
CHANGED
|
@@ -117,7 +117,7 @@ async function handler(args) {
|
|
|
117
117
|
// 4. Clone the project template from GitHub
|
|
118
118
|
try {
|
|
119
119
|
await cloneGithubRepo(HUBSPOT_PROJECT_COMPONENTS_GITHUB_PATH, projectDest, {
|
|
120
|
-
sourceDir: '2026.
|
|
120
|
+
sourceDir: '2026.09/private-app-get-started-template',
|
|
121
121
|
hideLogs: true,
|
|
122
122
|
});
|
|
123
123
|
await trackCommandMetadataUsage('get-started', {
|
|
@@ -22,6 +22,7 @@ import { showMcpPromotionNudge } from '../../lib/mcp/promotion.js';
|
|
|
22
22
|
const command = ['create', 'init'];
|
|
23
23
|
const describe = commands.project.create.describe;
|
|
24
24
|
const BETA_VERSIONS = [
|
|
25
|
+
PLATFORM_VERSIONS.v2027_03_BETA,
|
|
25
26
|
PLATFORM_VERSIONS.v2026_09_BETA,
|
|
26
27
|
PLATFORM_VERSIONS.v2026_03_BETA,
|
|
27
28
|
];
|
|
@@ -151,8 +152,10 @@ function projectCreateBuilder(yargs) {
|
|
|
151
152
|
PLATFORM_VERSIONS.v2026_03_BETA,
|
|
152
153
|
PLATFORM_VERSIONS.v2026_03,
|
|
153
154
|
PLATFORM_VERSIONS.v2026_09_BETA,
|
|
155
|
+
PLATFORM_VERSIONS.v2026_09,
|
|
156
|
+
PLATFORM_VERSIONS.v2027_03_BETA,
|
|
154
157
|
],
|
|
155
|
-
default: PLATFORM_VERSIONS.
|
|
158
|
+
default: PLATFORM_VERSIONS.v2026_09,
|
|
156
159
|
},
|
|
157
160
|
'project-base': {
|
|
158
161
|
describe: commands.project.create.options.projectBase.describe,
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { CommonArgs, ConfigArgs, AccountArgs, EnvironmentArgs, YargsCommandModule } from '../../types/Yargs.js';
|
|
2
|
-
|
|
1
|
+
import { CommonArgs, ConfigArgs, AccountArgs, EnvironmentArgs, JSONOutputArgs, YargsCommandModule } from '../../types/Yargs.js';
|
|
2
|
+
import { DownloadJsonOutput } from '../../lib/jsonOutput/download.js';
|
|
3
|
+
export type ProjectDownloadArgs = CommonArgs & ConfigArgs & AccountArgs & EnvironmentArgs & JSONOutputArgs<DownloadJsonOutput> & {
|
|
3
4
|
project?: string;
|
|
4
5
|
dest?: string;
|
|
5
6
|
build?: number;
|
|
@@ -11,10 +11,11 @@ import { uiLogger } from '../../lib/ui/logger.js';
|
|
|
11
11
|
import { EXIT_CODES } from '../../lib/enums/exitCodes.js';
|
|
12
12
|
import { makeWrappedYargsHandler } from '../../lib/yargs/makeWrappedYargsHandler.js';
|
|
13
13
|
import { makeYargsBuilder } from '../../lib/yargsUtils.js';
|
|
14
|
+
import { DownloadSchema, } from '../../lib/jsonOutput/download.js';
|
|
14
15
|
const command = 'download';
|
|
15
16
|
const describe = commands.project.download.describe;
|
|
16
17
|
async function handler(args) {
|
|
17
|
-
const { dest, build, derivedAccountId, exit } = args;
|
|
18
|
+
const { dest, build, derivedAccountId, exit, addJsonOutput } = args;
|
|
18
19
|
const isInProjectDir = getIsInProject();
|
|
19
20
|
if (isInProjectDir) {
|
|
20
21
|
uiLogger.error(commands.project.download.warnings.cannotDownloadWithinProject);
|
|
@@ -41,6 +42,11 @@ async function handler(args) {
|
|
|
41
42
|
: path.resolve(getCwd(), sanitizedProjectName);
|
|
42
43
|
const { data: zippedProject } = await downloadProject(derivedAccountId, projectName, buildNumberToDownload);
|
|
43
44
|
await extractZipArchive(zippedProject, sanitizeFileName(projectName), path.resolve(absoluteDestPath));
|
|
45
|
+
addJsonOutput({
|
|
46
|
+
projectName,
|
|
47
|
+
buildId: buildNumberToDownload,
|
|
48
|
+
dest: absoluteDestPath,
|
|
49
|
+
});
|
|
44
50
|
uiLogger.log(commands.project.download.logs.downloadSucceeded(buildNumberToDownload, projectName));
|
|
45
51
|
return exit(EXIT_CODES.SUCCESS);
|
|
46
52
|
}
|
|
@@ -76,6 +82,10 @@ function projectDownloadBuilder(yargs) {
|
|
|
76
82
|
'$0 project download --project=myProject --dest=myProjectFolder',
|
|
77
83
|
commands.project.download.examples.default,
|
|
78
84
|
],
|
|
85
|
+
[
|
|
86
|
+
'$0 project download --project=myProject --json',
|
|
87
|
+
commands.project.download.examples.json,
|
|
88
|
+
],
|
|
79
89
|
]);
|
|
80
90
|
return yargs;
|
|
81
91
|
}
|
|
@@ -84,11 +94,14 @@ const builder = makeYargsBuilder(projectDownloadBuilder, command, describe, {
|
|
|
84
94
|
useConfigOptions: true,
|
|
85
95
|
useAccountOptions: true,
|
|
86
96
|
useEnvironmentOptions: true,
|
|
97
|
+
useJSONOutputOptions: true,
|
|
87
98
|
});
|
|
88
99
|
const projectDownloadCommand = {
|
|
89
100
|
command,
|
|
90
101
|
describe,
|
|
91
|
-
handler: makeWrappedYargsHandler('project-download', handler
|
|
102
|
+
handler: makeWrappedYargsHandler('project-download', handler, {
|
|
103
|
+
jsonOutputSchema: DownloadSchema,
|
|
104
|
+
}),
|
|
92
105
|
builder,
|
|
93
106
|
};
|
|
94
107
|
export default projectDownloadCommand;
|
|
@@ -11,8 +11,6 @@ import { uiLogger } from '../../lib/ui/logger.js';
|
|
|
11
11
|
import { renderInline } from '../../ui/render.js';
|
|
12
12
|
import { getWarningBox } from '../../ui/components/StatusMessageBoxes.js';
|
|
13
13
|
import { getHasMigratableThemes, migrateThemesV2, } from '../../lib/theme/migrate.js';
|
|
14
|
-
import { hasFeature } from '../../lib/hasFeature.js';
|
|
15
|
-
import { FEATURES } from '../../lib/constants.js';
|
|
16
14
|
import { trackCommandMetadataUsage } from '../../lib/usageTracking.js';
|
|
17
15
|
const { v2025_2, v2026_03_BETA, v2026_03 } = PLATFORM_VERSIONS;
|
|
18
16
|
const command = 'migrate';
|
|
@@ -35,11 +33,6 @@ async function handler(args) {
|
|
|
35
33
|
try {
|
|
36
34
|
const { hasMigratableThemes, migratableThemesCount } = await getHasMigratableThemes({ projectConfig, projectDir });
|
|
37
35
|
if (hasMigratableThemes) {
|
|
38
|
-
const hasThemeMigrationAccess = await hasFeature(derivedAccountId, FEATURES.THEME_MIGRATION_2025_2);
|
|
39
|
-
if (!hasThemeMigrationAccess) {
|
|
40
|
-
uiLogger.error(commands.project.migrate.errors.noThemeMigrationAccess(derivedAccountId));
|
|
41
|
-
return exit(EXIT_CODES.ERROR);
|
|
42
|
-
}
|
|
43
36
|
await migrateThemesV2(derivedAccountId, {
|
|
44
37
|
...args,
|
|
45
38
|
platformVersion: unstable
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { CommonArgs, YargsCommandModule } from '../../types/Yargs.js';
|
|
2
|
-
|
|
1
|
+
import { CommonArgs, JSONOutputArgs, YargsCommandModule } from '../../types/Yargs.js';
|
|
2
|
+
import { ValidateJsonOutput } from '../../lib/jsonOutput/validate.js';
|
|
3
|
+
export type ProjectValidateArgs = CommonArgs & JSONOutputArgs<ValidateJsonOutput> & {
|
|
3
4
|
profile?: string;
|
|
4
5
|
};
|
|
5
6
|
declare const projectValidateCommand: YargsCommandModule<unknown, ProjectValidateArgs>;
|
|
@@ -7,34 +7,83 @@ import { makeWrappedYargsHandler } from '../../lib/yargs/makeWrappedYargsHandler
|
|
|
7
7
|
import { makeYargsBuilder } from '../../lib/yargsUtils.js';
|
|
8
8
|
import { commands } from '../../lang/en.js';
|
|
9
9
|
import { logError } from '../../lib/errorHandlers/index.js';
|
|
10
|
-
import { validateProject } from '../../lib/projects/validate.js';
|
|
10
|
+
import { validateProject, toIssue, } from '../../lib/projects/validate.js';
|
|
11
|
+
import { ValidateSchema, } from '../../lib/jsonOutput/validate.js';
|
|
11
12
|
const command = 'validate';
|
|
12
13
|
const describe = commands.project.validate.describe;
|
|
14
|
+
function generateJson({ result, projectConfig, profile, }) {
|
|
15
|
+
const { valid, errors, warnings, profiles } = result;
|
|
16
|
+
const output = { valid, errors, warnings };
|
|
17
|
+
if (projectConfig) {
|
|
18
|
+
output.projectName = projectConfig.name;
|
|
19
|
+
output.platformVersion = projectConfig.platformVersion;
|
|
20
|
+
}
|
|
21
|
+
if (profile) {
|
|
22
|
+
output.profile = profile;
|
|
23
|
+
}
|
|
24
|
+
if (profiles.length > 0) {
|
|
25
|
+
output.profiles = profiles;
|
|
26
|
+
}
|
|
27
|
+
return output;
|
|
28
|
+
}
|
|
13
29
|
async function handler(args) {
|
|
14
|
-
const { derivedAccountId, profile, exit, addUsageMetadata } = args;
|
|
15
|
-
const accountConfig = getConfigAccountById(derivedAccountId);
|
|
16
|
-
const accountType = accountConfig && accountConfig.accountType;
|
|
17
|
-
addUsageMetadata({ type: accountType });
|
|
30
|
+
const { derivedAccountId, profile, exit, addUsageMetadata, formatOutputAsJson, addJsonOutput, } = args;
|
|
18
31
|
let projectConfig;
|
|
19
32
|
let projectDir;
|
|
33
|
+
function outputError(error) {
|
|
34
|
+
logError(error);
|
|
35
|
+
addJsonOutput(generateJson({
|
|
36
|
+
result: {
|
|
37
|
+
valid: false,
|
|
38
|
+
errors: [toIssue(error)],
|
|
39
|
+
warnings: [],
|
|
40
|
+
profiles: [],
|
|
41
|
+
},
|
|
42
|
+
projectConfig,
|
|
43
|
+
profile,
|
|
44
|
+
}));
|
|
45
|
+
}
|
|
20
46
|
try {
|
|
47
|
+
const accountConfig = getConfigAccountById(derivedAccountId);
|
|
48
|
+
const accountType = accountConfig && accountConfig.accountType;
|
|
49
|
+
addUsageMetadata({ type: accountType });
|
|
21
50
|
({ projectConfig, projectDir } = getProjectConfig());
|
|
22
51
|
}
|
|
23
52
|
catch (error) {
|
|
24
|
-
|
|
53
|
+
outputError(error);
|
|
25
54
|
return exit(EXIT_CODES.ERROR);
|
|
26
55
|
}
|
|
27
56
|
if (isLegacyProject(projectConfig.platformVersion)) {
|
|
28
|
-
|
|
57
|
+
const message = commands.project.validate.badVersion;
|
|
58
|
+
uiLogger.error(message);
|
|
59
|
+
addJsonOutput(generateJson({
|
|
60
|
+
result: {
|
|
61
|
+
valid: false,
|
|
62
|
+
errors: [{ message }],
|
|
63
|
+
warnings: [],
|
|
64
|
+
profiles: [],
|
|
65
|
+
},
|
|
66
|
+
projectConfig,
|
|
67
|
+
profile,
|
|
68
|
+
}));
|
|
29
69
|
return exit(EXIT_CODES.ERROR);
|
|
30
70
|
}
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
71
|
+
let result;
|
|
72
|
+
try {
|
|
73
|
+
result = await validateProject({
|
|
74
|
+
projectConfig,
|
|
75
|
+
projectDir,
|
|
76
|
+
derivedAccountId,
|
|
77
|
+
profile,
|
|
78
|
+
formatOutputAsJson,
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
catch (error) {
|
|
82
|
+
outputError(error);
|
|
83
|
+
return exit(EXIT_CODES.ERROR);
|
|
84
|
+
}
|
|
85
|
+
addJsonOutput(generateJson({ result, projectConfig, profile }));
|
|
86
|
+
if (!result.valid) {
|
|
38
87
|
return exit(EXIT_CODES.ERROR);
|
|
39
88
|
}
|
|
40
89
|
uiLogger.success(commands.project.validate.success(projectConfig.name));
|
|
@@ -55,6 +104,7 @@ function projectValidateBuilder(yargs) {
|
|
|
55
104
|
'$0 project validate --profile=profileName',
|
|
56
105
|
commands.project.validate.examples.withProfile,
|
|
57
106
|
],
|
|
107
|
+
['$0 project validate --json', commands.project.validate.examples.json],
|
|
58
108
|
]);
|
|
59
109
|
return yargs;
|
|
60
110
|
}
|
|
@@ -63,11 +113,14 @@ const builder = makeYargsBuilder(projectValidateBuilder, command, describe, {
|
|
|
63
113
|
useConfigOptions: true,
|
|
64
114
|
useAccountOptions: true,
|
|
65
115
|
useEnvironmentOptions: true,
|
|
116
|
+
useJSONOutputOptions: true,
|
|
66
117
|
});
|
|
67
118
|
const projectValidateCommand = {
|
|
68
119
|
command,
|
|
69
120
|
describe,
|
|
70
|
-
handler: makeWrappedYargsHandler('project-validate', handler
|
|
121
|
+
handler: makeWrappedYargsHandler('project-validate', handler, {
|
|
122
|
+
jsonOutputSchema: ValidateSchema,
|
|
123
|
+
}),
|
|
71
124
|
builder,
|
|
72
125
|
};
|
|
73
126
|
export default projectValidateCommand;
|
package/lang/en.d.ts
CHANGED
|
@@ -1646,7 +1646,6 @@ export declare const commands: {
|
|
|
1646
1646
|
describe: string;
|
|
1647
1647
|
errors: {
|
|
1648
1648
|
noProjectConfig: (command: string) => string;
|
|
1649
|
-
noThemeMigrationAccess: (accountId?: number) => string;
|
|
1650
1649
|
};
|
|
1651
1650
|
examples: {
|
|
1652
1651
|
default: string;
|
|
@@ -1986,6 +1985,7 @@ export declare const commands: {
|
|
|
1986
1985
|
describe: string;
|
|
1987
1986
|
examples: {
|
|
1988
1987
|
default: string;
|
|
1988
|
+
json: string;
|
|
1989
1989
|
};
|
|
1990
1990
|
logs: {
|
|
1991
1991
|
downloadCancelled: string;
|
|
@@ -2097,6 +2097,7 @@ export declare const commands: {
|
|
|
2097
2097
|
examples: {
|
|
2098
2098
|
default: string;
|
|
2099
2099
|
withProfile: string;
|
|
2100
|
+
json: string;
|
|
2100
2101
|
};
|
|
2101
2102
|
success: (projectName: string) => string;
|
|
2102
2103
|
failure: (projectName: string, profileName?: string) => string;
|
package/lang/en.js
CHANGED
|
@@ -1662,7 +1662,6 @@ export const commands = {
|
|
|
1662
1662
|
describe: 'Migrate an existing project to the new version of the projects framework.',
|
|
1663
1663
|
errors: {
|
|
1664
1664
|
noProjectConfig: (command) => `No project detected. Please run this command again from a project directory. If you are trying to migrate an app, run ${command}`,
|
|
1665
|
-
noThemeMigrationAccess: (accountId) => `This project contains a CMS theme. You must opt in to theme migration beta to continue updating it on ${uiAccountDescription(accountId)}. Try again with a different account or ${uiLink('join the beta now', getProductUpdatesUrl('253920', accountId))}`,
|
|
1666
1665
|
},
|
|
1667
1666
|
examples: {
|
|
1668
1667
|
default: 'Migrate an existing project to the new version of the projects framework.',
|
|
@@ -2002,6 +2001,7 @@ export const commands = {
|
|
|
2002
2001
|
describe: 'Download your project files from HubSpot.',
|
|
2003
2002
|
examples: {
|
|
2004
2003
|
default: 'Download the project myProject into myProjectFolder folder',
|
|
2004
|
+
json: 'Output the download result as JSON for scripting',
|
|
2005
2005
|
},
|
|
2006
2006
|
logs: {
|
|
2007
2007
|
downloadCancelled: 'Cancelling project download',
|
|
@@ -2125,6 +2125,7 @@ export const commands = {
|
|
|
2125
2125
|
examples: {
|
|
2126
2126
|
default: 'Validate the project before uploading',
|
|
2127
2127
|
withProfile: 'Validate the project with a profile before uploading.',
|
|
2128
|
+
json: 'Output validation results as JSON for scripting',
|
|
2128
2129
|
},
|
|
2129
2130
|
success: (projectName) => `Project ${projectName} is valid and ready to upload`,
|
|
2130
2131
|
failure: (projectName, profileName) => `Project ${projectName} is invalid${profileName ? ` with profile "${profileName}" applied` : ''}`,
|
package/lib/constants.d.ts
CHANGED
|
@@ -80,7 +80,6 @@ export declare const APP_AUTH_TYPES: {
|
|
|
80
80
|
export declare const FEATURES: {
|
|
81
81
|
readonly UNIFIED_APPS: "Developers:UnifiedApps:PrivateBeta";
|
|
82
82
|
readonly APP_EVENTS: "Developers:UnifiedApps:AppEventsAccess";
|
|
83
|
-
readonly THEME_MIGRATION_2025_2: "Developers:ProjectThemeMigrations:2025.2";
|
|
84
83
|
readonly AGENT_TOOLS: "ThirdPartyAgentTools";
|
|
85
84
|
readonly APP_ACTIONS: "Developers:AppActions";
|
|
86
85
|
};
|
package/lib/constants.js
CHANGED
|
@@ -72,7 +72,6 @@ export const APP_AUTH_TYPES = {
|
|
|
72
72
|
export const FEATURES = {
|
|
73
73
|
UNIFIED_APPS: 'Developers:UnifiedApps:PrivateBeta',
|
|
74
74
|
APP_EVENTS: 'Developers:UnifiedApps:AppEventsAccess',
|
|
75
|
-
THEME_MIGRATION_2025_2: 'Developers:ProjectThemeMigrations:2025.2',
|
|
76
75
|
AGENT_TOOLS: 'ThirdPartyAgentTools',
|
|
77
76
|
APP_ACTIONS: 'Developers:AppActions',
|
|
78
77
|
};
|
package/lib/filesystem.d.ts
CHANGED
|
@@ -1,2 +1,8 @@
|
|
|
1
1
|
export declare function resolveLocalPath(filepath?: string): string;
|
|
2
|
+
/**
|
|
3
|
+
* Returns true if childPath is parentDirectory itself or a descendant of it.
|
|
4
|
+
* Compares resolved paths segment by segment, so sibling directories with a
|
|
5
|
+
* shared name prefix (foo-backup vs. foo) are not treated as descendants.
|
|
6
|
+
*/
|
|
7
|
+
export declare function isPathInsideDirectory(childPath: string, parentDirectory: string): boolean;
|
|
2
8
|
export declare function isPathFolder(path: string): boolean;
|
package/lib/filesystem.js
CHANGED
|
@@ -7,6 +7,15 @@ export function resolveLocalPath(filepath) {
|
|
|
7
7
|
: // Use CWD if optional filepath is not passed.
|
|
8
8
|
getCwd();
|
|
9
9
|
}
|
|
10
|
+
/**
|
|
11
|
+
* Returns true if childPath is parentDirectory itself or a descendant of it.
|
|
12
|
+
* Compares resolved paths segment by segment, so sibling directories with a
|
|
13
|
+
* shared name prefix (foo-backup vs. foo) are not treated as descendants.
|
|
14
|
+
*/
|
|
15
|
+
export function isPathInsideDirectory(childPath, parentDirectory) {
|
|
16
|
+
const relativePath = path.relative(path.resolve(parentDirectory), path.resolve(childPath));
|
|
17
|
+
return !relativePath.startsWith('..') && !path.isAbsolute(relativePath);
|
|
18
|
+
}
|
|
10
19
|
export function isPathFolder(path) {
|
|
11
20
|
const splitPath = path.split('/');
|
|
12
21
|
const fileOrFolderName = splitPath[splitPath.length - 1];
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
declare const ValidationIssueSchema: z.ZodObject<{
|
|
3
|
+
message: z.ZodString;
|
|
4
|
+
file: z.ZodOptional<z.ZodString>;
|
|
5
|
+
profile: z.ZodOptional<z.ZodString>;
|
|
6
|
+
}, z.core.$strip>;
|
|
7
|
+
declare const ProfileValidationSchema: z.ZodObject<{
|
|
8
|
+
name: z.ZodString;
|
|
9
|
+
accountId: z.ZodOptional<z.ZodNumber>;
|
|
10
|
+
valid: z.ZodBoolean;
|
|
11
|
+
}, z.core.$strip>;
|
|
12
|
+
export declare const ValidateSchema: z.ZodObject<{
|
|
13
|
+
valid: z.ZodBoolean;
|
|
14
|
+
projectName: z.ZodOptional<z.ZodString>;
|
|
15
|
+
platformVersion: z.ZodOptional<z.ZodString>;
|
|
16
|
+
profile: z.ZodOptional<z.ZodString>;
|
|
17
|
+
errors: z.ZodArray<z.ZodObject<{
|
|
18
|
+
message: z.ZodString;
|
|
19
|
+
file: z.ZodOptional<z.ZodString>;
|
|
20
|
+
profile: z.ZodOptional<z.ZodString>;
|
|
21
|
+
}, z.core.$strip>>;
|
|
22
|
+
warnings: z.ZodArray<z.ZodObject<{
|
|
23
|
+
message: z.ZodString;
|
|
24
|
+
file: z.ZodOptional<z.ZodString>;
|
|
25
|
+
profile: z.ZodOptional<z.ZodString>;
|
|
26
|
+
}, z.core.$strip>>;
|
|
27
|
+
profiles: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
28
|
+
name: z.ZodString;
|
|
29
|
+
accountId: z.ZodOptional<z.ZodNumber>;
|
|
30
|
+
valid: z.ZodBoolean;
|
|
31
|
+
}, z.core.$strip>>>;
|
|
32
|
+
}, z.core.$strip>;
|
|
33
|
+
export type ValidationIssueJsonOutput = z.infer<typeof ValidationIssueSchema>;
|
|
34
|
+
export type ProfileValidationJsonOutput = z.infer<typeof ProfileValidationSchema>;
|
|
35
|
+
export type ValidateJsonOutput = z.infer<typeof ValidateSchema>;
|
|
36
|
+
export {};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
const ValidationIssueSchema = z.object({
|
|
3
|
+
message: z.string(),
|
|
4
|
+
file: z.string().optional(),
|
|
5
|
+
profile: z.string().optional(),
|
|
6
|
+
});
|
|
7
|
+
const ProfileValidationSchema = z.object({
|
|
8
|
+
name: z.string(),
|
|
9
|
+
accountId: z.number().optional(),
|
|
10
|
+
valid: z.boolean(),
|
|
11
|
+
});
|
|
12
|
+
export const ValidateSchema = z.object({
|
|
13
|
+
valid: z.boolean(),
|
|
14
|
+
projectName: z.string().optional(),
|
|
15
|
+
platformVersion: z.string().optional(),
|
|
16
|
+
profile: z.string().optional(),
|
|
17
|
+
errors: z.array(ValidationIssueSchema),
|
|
18
|
+
warnings: z.array(ValidationIssueSchema),
|
|
19
|
+
profiles: z.array(ProfileValidationSchema).optional(),
|
|
20
|
+
});
|
|
@@ -3,6 +3,7 @@ import { ProjectConfig } from '../../types/Projects.js';
|
|
|
3
3
|
export declare function logProfileHeader(profileName: string): void;
|
|
4
4
|
export declare function logProfileFooter(profile: HsProfileFile, includeVariables?: boolean): void;
|
|
5
5
|
export declare function loadProfile(projectConfig: ProjectConfig, projectDir: string, profileName: string): HsProfileFile | never;
|
|
6
|
+
export declare function getProfileAccountId(projectConfig: ProjectConfig, projectDir: string, profileName: string): number | undefined;
|
|
6
7
|
export declare function loadAndValidateProfile(projectConfig: ProjectConfig, projectDir: string, profileName: string, silent?: boolean): Promise<HsProfileFile | never>;
|
|
7
8
|
type ValidateProjectForProfileOptions = {
|
|
8
9
|
projectConfig: ProjectConfig;
|
|
@@ -48,6 +48,14 @@ export function loadProfile(projectConfig, projectDir, profileName) {
|
|
|
48
48
|
}
|
|
49
49
|
return profile;
|
|
50
50
|
}
|
|
51
|
+
export function getProfileAccountId(projectConfig, projectDir, profileName) {
|
|
52
|
+
try {
|
|
53
|
+
return loadProfile(projectConfig, projectDir, profileName).accountId;
|
|
54
|
+
}
|
|
55
|
+
catch (_e) {
|
|
56
|
+
return undefined;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
51
59
|
export async function loadAndValidateProfile(projectConfig, projectDir, profileName, silent = false) {
|
|
52
60
|
if (!silent) {
|
|
53
61
|
logProfileHeader(profileName);
|
|
@@ -24,6 +24,8 @@ export declare function hasEslintConfig(directory: string): boolean;
|
|
|
24
24
|
export declare function hasDeprecatedEslintConfig(directory: string): boolean;
|
|
25
25
|
export declare function getDeprecatedEslintConfigFiles(directory: string): string[];
|
|
26
26
|
export declare function createEslintConfig(directory: string, platformVersion?: string | null): Promise<string>;
|
|
27
|
+
export declare function getUieComponentDirPrefixes(srcDir: string): string[];
|
|
28
|
+
export declare function isUieComponentDirectory(directory: string, srcDir: string): boolean;
|
|
27
29
|
export declare function getUieLintablePackageJsonLocations(projectConfig: LoadedProjectConfig): Promise<string[]>;
|
|
28
30
|
export declare const HUBSPOT_UI_EXTENSIONS_RULE_PREFIX = "@hubspot/ui-extensions/";
|
|
29
31
|
export declare function isHubSpotEslintConfigActive(directory: string): Promise<boolean>;
|
|
@@ -9,9 +9,10 @@ import { commands } from '../../lang/en.js';
|
|
|
9
9
|
import { uiLogger } from '../ui/logger.js';
|
|
10
10
|
import { clearPackageJsonCache, safeGetPackageJsonCached, } from '../npm/packageJson.js';
|
|
11
11
|
import { debugError } from '../errorHandlers/index.js';
|
|
12
|
+
import { isPathInsideDirectory } from '../filesystem.js';
|
|
12
13
|
import { isLegacyProject } from '@hubspot/project-parsing-lib/projects';
|
|
13
14
|
import { DEFAULT_PROJECT_TEMPLATE_BRANCH, HUBSPOT_PROJECT_COMPONENTS_GITHUB_PATH, } from '../constants.js';
|
|
14
|
-
import { CARDS_KEY, Components, PAGES_KEY, SETTINGS_KEY, } from '@hubspot/project-parsing-lib/constants';
|
|
15
|
+
import { ACTIONS_KEY, CARDS_KEY, Components, PAGES_KEY, SETTINGS_KEY, } from '@hubspot/project-parsing-lib/constants';
|
|
15
16
|
export const REQUIRED_PACKAGES_AND_MIN_VERSIONS = {
|
|
16
17
|
eslint: '9.0.0',
|
|
17
18
|
'@eslint/js': '9.0.0',
|
|
@@ -42,6 +43,7 @@ const DEPRECATED_ESLINT_CONFIG_FILES = [
|
|
|
42
43
|
'.eslintrc',
|
|
43
44
|
];
|
|
44
45
|
const UIE_COMPONENTS = [
|
|
46
|
+
Components[ACTIONS_KEY],
|
|
45
47
|
Components[CARDS_KEY],
|
|
46
48
|
Components[SETTINGS_KEY],
|
|
47
49
|
Components[PAGES_KEY],
|
|
@@ -169,16 +171,19 @@ export async function createEslintConfig(directory, platformVersion) {
|
|
|
169
171
|
throw error;
|
|
170
172
|
}
|
|
171
173
|
}
|
|
172
|
-
export
|
|
173
|
-
const srcDirAbsolute = path.resolve(
|
|
174
|
-
|
|
174
|
+
export function getUieComponentDirPrefixes(srcDir) {
|
|
175
|
+
const srcDirAbsolute = path.resolve(srcDir);
|
|
176
|
+
return UIE_COMPONENTS.map(component => path.join(srcDirAbsolute, component.parentComponent
|
|
175
177
|
? Components[component.parentComponent].dir
|
|
176
178
|
: '', component.dir));
|
|
179
|
+
}
|
|
180
|
+
export function isUieComponentDirectory(directory, srcDir) {
|
|
181
|
+
return getUieComponentDirPrefixes(srcDir).some(componentDir => isPathInsideDirectory(directory, componentDir));
|
|
182
|
+
}
|
|
183
|
+
export async function getUieLintablePackageJsonLocations(projectConfig) {
|
|
184
|
+
const srcDirAbsolute = path.resolve(projectConfig.projectDir, projectConfig.projectConfig.srcDir);
|
|
177
185
|
const allLocations = await getProjectPackageJsonLocations(projectConfig.projectDir);
|
|
178
|
-
return allLocations.filter(location =>
|
|
179
|
-
const resolvedLocation = path.resolve(location);
|
|
180
|
-
return uiePackageDirPrefixes.some(prefix => resolvedLocation.startsWith(prefix));
|
|
181
|
-
});
|
|
186
|
+
return allLocations.filter(location => isUieComponentDirectory(location, srcDirAbsolute));
|
|
182
187
|
}
|
|
183
188
|
export const HUBSPOT_UI_EXTENSIONS_RULE_PREFIX = '@hubspot/ui-extensions/';
|
|
184
189
|
function getEnvironmentWithoutNpmConfig() {
|
package/lib/projects/upload.d.ts
CHANGED
|
@@ -25,7 +25,11 @@ type HandleProjectUploadArg<T> = {
|
|
|
25
25
|
force?: boolean;
|
|
26
26
|
};
|
|
27
27
|
export declare function handleProjectUpload<T>({ accountId, projectConfig, projectDir, callbackFunc, profile, uploadMessage, forceCreate, isUploadCommand, sendIR, skipValidation, skipNpmAudit, skipAutoDeploy, force, }: HandleProjectUploadArg<T>): Promise<ProjectUploadResult<T>>;
|
|
28
|
-
export
|
|
28
|
+
export type SourceDirectoryWarning = {
|
|
29
|
+
message: string;
|
|
30
|
+
file: string;
|
|
31
|
+
};
|
|
32
|
+
export declare function validateSourceDirectory(srcDir: string, projectConfig: ProjectConfig, projectDir: string): Promise<SourceDirectoryWarning[]>;
|
|
29
33
|
export declare function validateNoHSMetaMismatch(srcDir: string, projectConfig: ProjectConfig): Promise<void>;
|
|
30
34
|
type HandleTranslateArg = {
|
|
31
35
|
projectDir: string;
|
package/lib/projects/upload.js
CHANGED
|
@@ -159,14 +159,19 @@ export async function validateSourceDirectory(srcDir, projectConfig, projectDir)
|
|
|
159
159
|
if (!projectFilePaths || projectFilePaths.length === 0) {
|
|
160
160
|
throw new ProjectValidationError(lib.projectUpload.handleProjectUpload.emptySource(projectConfig.srcDir));
|
|
161
161
|
}
|
|
162
|
+
const warnings = [];
|
|
162
163
|
if (!isLegacyProject(projectConfig.platformVersion)) {
|
|
163
164
|
projectFilePaths.forEach(filePath => {
|
|
164
165
|
const filename = path.basename(filePath);
|
|
165
166
|
if (LEGACY_CONFIG_FILES.includes(filename)) {
|
|
166
|
-
|
|
167
|
+
const relativePath = path.relative(projectDir, filePath);
|
|
168
|
+
const message = lib.projectUpload.handleProjectUpload.legacyFileDetected(relativePath, projectConfig.platformVersion);
|
|
169
|
+
warnings.push({ message, file: relativePath });
|
|
170
|
+
uiLogger.warn(message);
|
|
167
171
|
}
|
|
168
172
|
});
|
|
169
173
|
}
|
|
174
|
+
return warnings;
|
|
170
175
|
}
|
|
171
176
|
export async function validateNoHSMetaMismatch(srcDir, projectConfig) {
|
|
172
177
|
const hasHsMetaFiles = await projectContainsHsMetaFiles(srcDir);
|
|
@@ -1,9 +1,18 @@
|
|
|
1
1
|
import { ProjectConfig } from '../../types/Projects.js';
|
|
2
|
+
import { ProfileValidationJsonOutput, ValidationIssueJsonOutput } from '../jsonOutput/validate.js';
|
|
3
|
+
export type ProjectValidationResult = {
|
|
4
|
+
valid: boolean;
|
|
5
|
+
errors: ValidationIssueJsonOutput[];
|
|
6
|
+
warnings: ValidationIssueJsonOutput[];
|
|
7
|
+
profiles: ProfileValidationJsonOutput[];
|
|
8
|
+
};
|
|
2
9
|
type ValidateProjectArgs = {
|
|
3
10
|
projectConfig: ProjectConfig;
|
|
4
11
|
projectDir: string;
|
|
5
12
|
derivedAccountId: number;
|
|
6
13
|
profile?: string;
|
|
14
|
+
formatOutputAsJson?: boolean;
|
|
7
15
|
};
|
|
8
|
-
export declare function
|
|
16
|
+
export declare function toIssue(error: unknown, profile?: string): ValidationIssueJsonOutput;
|
|
17
|
+
export declare function validateProject({ projectConfig, projectDir, derivedAccountId, profile, formatOutputAsJson, }: ValidateProjectArgs): Promise<ProjectValidationResult>;
|
|
9
18
|
export {};
|
package/lib/projects/validate.js
CHANGED
|
@@ -1,11 +1,21 @@
|
|
|
1
1
|
import path from 'path';
|
|
2
|
+
import stripAnsi from 'strip-ansi';
|
|
2
3
|
import { getAllHsProfiles } from '@hubspot/project-parsing-lib/profiles';
|
|
3
4
|
import { uiLogger } from '../ui/logger.js';
|
|
4
5
|
import SpinniesManager from '../ui/SpinniesManager.js';
|
|
5
|
-
import { logError } from '../errorHandlers/index.js';
|
|
6
|
+
import { logError, getErrorMessage } from '../errorHandlers/index.js';
|
|
6
7
|
import { commands } from '../../lang/en.js';
|
|
7
|
-
import { validateProjectForProfile } from './projectProfiles.js';
|
|
8
|
+
import { getProfileAccountId, validateProjectForProfile, } from './projectProfiles.js';
|
|
8
9
|
import { handleTranslate, validateSourceDirectory } from './upload.js';
|
|
10
|
+
export function toIssue(error, profile) {
|
|
11
|
+
const issue = {
|
|
12
|
+
message: stripAnsi(getErrorMessage(error)).trim(),
|
|
13
|
+
};
|
|
14
|
+
if (profile) {
|
|
15
|
+
issue.profile = profile;
|
|
16
|
+
}
|
|
17
|
+
return issue;
|
|
18
|
+
}
|
|
9
19
|
function logValidationErrors(validationErrors) {
|
|
10
20
|
uiLogger.log('');
|
|
11
21
|
validationErrors.forEach(error => {
|
|
@@ -17,41 +27,73 @@ function logValidationErrors(validationErrors) {
|
|
|
17
27
|
}
|
|
18
28
|
});
|
|
19
29
|
}
|
|
20
|
-
|
|
30
|
+
async function validateProfile({ projectConfig, projectDir, derivedAccountId, profileName, formatOutputAsJson, indentSpinners, }) {
|
|
31
|
+
const rawErrors = await validateProjectForProfile({
|
|
32
|
+
projectConfig,
|
|
33
|
+
projectDir,
|
|
34
|
+
profileName,
|
|
35
|
+
derivedAccountId,
|
|
36
|
+
...(indentSpinners ? { indentSpinners: true } : {}),
|
|
37
|
+
});
|
|
38
|
+
const accountId = formatOutputAsJson
|
|
39
|
+
? getProfileAccountId(projectConfig, projectDir, profileName)
|
|
40
|
+
: undefined;
|
|
41
|
+
const profile = {
|
|
42
|
+
name: profileName,
|
|
43
|
+
valid: rawErrors.length === 0,
|
|
44
|
+
};
|
|
45
|
+
if (accountId !== undefined) {
|
|
46
|
+
profile.accountId = accountId;
|
|
47
|
+
}
|
|
48
|
+
return {
|
|
49
|
+
profile,
|
|
50
|
+
errors: rawErrors.map(e => toIssue(e, profileName)),
|
|
51
|
+
rawErrors,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
export async function validateProject({ projectConfig, projectDir, derivedAccountId, profile, formatOutputAsJson, }) {
|
|
55
|
+
const errors = [];
|
|
56
|
+
const warnings = [];
|
|
57
|
+
const profiles = [];
|
|
21
58
|
let valid = true;
|
|
22
59
|
const srcDir = path.resolve(projectDir, projectConfig.srcDir);
|
|
23
|
-
const
|
|
24
|
-
// If a profile is specified, only validate that profile
|
|
60
|
+
const projectProfiles = await getAllHsProfiles(path.join(projectDir, projectConfig.srcDir));
|
|
25
61
|
if (profile) {
|
|
26
|
-
const
|
|
62
|
+
const result = await validateProfile({
|
|
27
63
|
projectConfig,
|
|
28
64
|
projectDir,
|
|
29
|
-
profileName: profile,
|
|
30
65
|
derivedAccountId,
|
|
66
|
+
profileName: profile,
|
|
67
|
+
formatOutputAsJson,
|
|
68
|
+
indentSpinners: false,
|
|
31
69
|
});
|
|
32
|
-
|
|
33
|
-
|
|
70
|
+
profiles.push(result.profile);
|
|
71
|
+
if (result.rawErrors.length) {
|
|
34
72
|
valid = false;
|
|
73
|
+
errors.push(...result.errors);
|
|
74
|
+
logValidationErrors(result.rawErrors);
|
|
35
75
|
}
|
|
36
76
|
}
|
|
37
|
-
else if (
|
|
38
|
-
// If no profile was specified and the project has profiles, validate all of them
|
|
77
|
+
else if (projectProfiles.length > 0) {
|
|
39
78
|
SpinniesManager.add('validatingAllProfiles', {
|
|
40
79
|
text: commands.project.validate.spinners.validatingAllProfiles,
|
|
41
80
|
});
|
|
42
|
-
const
|
|
43
|
-
for (const profileName of
|
|
44
|
-
const
|
|
81
|
+
const rawErrors = [];
|
|
82
|
+
for (const profileName of projectProfiles) {
|
|
83
|
+
const result = await validateProfile({
|
|
45
84
|
projectConfig,
|
|
46
85
|
projectDir,
|
|
47
|
-
profileName,
|
|
48
86
|
derivedAccountId,
|
|
87
|
+
profileName,
|
|
88
|
+
formatOutputAsJson,
|
|
49
89
|
indentSpinners: true,
|
|
50
90
|
});
|
|
51
|
-
|
|
52
|
-
|
|
91
|
+
profiles.push(result.profile);
|
|
92
|
+
if (result.rawErrors.length) {
|
|
53
93
|
valid = false;
|
|
94
|
+
errors.push(...result.errors);
|
|
54
95
|
}
|
|
96
|
+
rawErrors.push(...result.rawErrors);
|
|
55
97
|
}
|
|
56
98
|
if (valid) {
|
|
57
99
|
SpinniesManager.succeed('validatingAllProfiles', {
|
|
@@ -63,10 +105,9 @@ export async function validateProject({ projectConfig, projectDir, derivedAccoun
|
|
|
63
105
|
text: commands.project.validate.spinners.allProfilesValidationFailed,
|
|
64
106
|
});
|
|
65
107
|
}
|
|
66
|
-
logValidationErrors(
|
|
108
|
+
logValidationErrors(rawErrors);
|
|
67
109
|
}
|
|
68
110
|
else {
|
|
69
|
-
// If the project has no profiles, validate the project without a profile
|
|
70
111
|
try {
|
|
71
112
|
await handleTranslate({
|
|
72
113
|
projectDir,
|
|
@@ -76,21 +117,26 @@ export async function validateProject({ projectConfig, projectDir, derivedAccoun
|
|
|
76
117
|
});
|
|
77
118
|
}
|
|
78
119
|
catch (e) {
|
|
120
|
+
valid = false;
|
|
121
|
+
errors.push(toIssue(e));
|
|
79
122
|
uiLogger.error(commands.project.validate.failure(projectConfig.name));
|
|
80
123
|
logError(e);
|
|
81
|
-
valid = false;
|
|
82
124
|
uiLogger.log('');
|
|
83
125
|
}
|
|
84
126
|
}
|
|
85
|
-
if (
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
127
|
+
if (valid) {
|
|
128
|
+
try {
|
|
129
|
+
const sourceWarnings = await validateSourceDirectory(srcDir, projectConfig, projectDir);
|
|
130
|
+
warnings.push(...sourceWarnings.map(warning => ({
|
|
131
|
+
message: stripAnsi(warning.message).trim(),
|
|
132
|
+
file: warning.file,
|
|
133
|
+
})));
|
|
134
|
+
}
|
|
135
|
+
catch (e) {
|
|
136
|
+
valid = false;
|
|
137
|
+
errors.push(toIssue(e));
|
|
138
|
+
logError(e);
|
|
139
|
+
}
|
|
94
140
|
}
|
|
95
|
-
return
|
|
141
|
+
return { valid, errors, warnings, profiles };
|
|
96
142
|
}
|
|
@@ -1,18 +1,19 @@
|
|
|
1
1
|
import path from 'path';
|
|
2
2
|
import { lib } from '../../lang/en.js';
|
|
3
3
|
import { uiLogger } from '../ui/logger.js';
|
|
4
|
-
import { areAllLintPackagesInstalled, hasEslintConfig, isHubSpotEslintConfigActive, } from './uieLinting.js';
|
|
4
|
+
import { areAllLintPackagesInstalled, hasEslintConfig, isHubSpotEslintConfigActive, isUieComponentDirectory, } from './uieLinting.js';
|
|
5
5
|
export async function validateLintConfigOnUpload({ srcDir, projectDir, parsedPackageJsons, isLegacyPlatform, }) {
|
|
6
6
|
const lintRoots = new Set();
|
|
7
7
|
if (isLegacyPlatform) {
|
|
8
8
|
lintRoots.add(srcDir);
|
|
9
9
|
}
|
|
10
10
|
else {
|
|
11
|
+
// Only check the directories that `hs project lint` actually covers,
|
|
12
|
+
// otherwise these warnings can never be resolved.
|
|
11
13
|
for (const { dir } of parsedPackageJsons) {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
lintRoots.add(srcDir);
|
|
14
|
+
if (isUieComponentDirectory(dir, srcDir)) {
|
|
15
|
+
lintRoots.add(dir);
|
|
16
|
+
}
|
|
16
17
|
}
|
|
17
18
|
}
|
|
18
19
|
let hasAnyOutput = false;
|
|
@@ -4,6 +4,7 @@ import crypto from 'crypto';
|
|
|
4
4
|
import { shouldIgnoreFile } from '@hubspot/local-dev-lib/ignoreRules';
|
|
5
5
|
import { getPackableFiles, } from '@hubspot/project-parsing-lib/workspaces';
|
|
6
6
|
import { uiLogger } from '../ui/logger.js';
|
|
7
|
+
import { isPathInsideDirectory } from '../filesystem.js';
|
|
7
8
|
import { lib } from '../../lang/en.js';
|
|
8
9
|
const FILE_PROTOCOL_PREFIX = 'file:';
|
|
9
10
|
const LINK_PROTOCOL_PREFIX = 'link:';
|
|
@@ -62,14 +63,6 @@ export function computeExternalArchivePath(absolutePath, kind = KIND_DIRECTORY)
|
|
|
62
63
|
}
|
|
63
64
|
return path.posix.join('_workspaces', `${name}-${shortHash(resolved)}`);
|
|
64
65
|
}
|
|
65
|
-
/**
|
|
66
|
-
* Returns true if dir is inside srcDir (i.e. it will already be included
|
|
67
|
-
* in the archive from the srcDir walk and must not be copied again).
|
|
68
|
-
*/
|
|
69
|
-
function isInsideSrcDir(dir, srcDir) {
|
|
70
|
-
const rel = path.relative(path.resolve(srcDir), path.resolve(dir));
|
|
71
|
-
return !rel.startsWith('..') && !path.isAbsolute(rel);
|
|
72
|
-
}
|
|
73
66
|
/**
|
|
74
67
|
* Creates a file filter function for workspace archiving.
|
|
75
68
|
* Filters files based on packable files list and ignore rules.
|
|
@@ -108,7 +101,7 @@ async function archiveWorkspaceDirectories(archive, srcDir, workspaceMappings) {
|
|
|
108
101
|
if (!packageWorkspaceEntries.has(sourcePackageJsonPath)) {
|
|
109
102
|
packageWorkspaceEntries.set(sourcePackageJsonPath, []);
|
|
110
103
|
}
|
|
111
|
-
if (
|
|
104
|
+
if (isPathInsideDirectory(workspaceDir, srcDir)) {
|
|
112
105
|
// Internal: already in archive from srcDir walk.
|
|
113
106
|
// Store the relative path from the package.json directory so npm can resolve it.
|
|
114
107
|
const relPath = toPosixPath(path.relative(path.dirname(sourcePackageJsonPath), path.resolve(workspaceDir)));
|
|
@@ -161,7 +154,7 @@ async function archiveFileDependencies(archive, srcDir, fileDependencyMappings,
|
|
|
161
154
|
const toArchive = [];
|
|
162
155
|
for (const mapping of fileDependencyMappings) {
|
|
163
156
|
const { packageName, localPath, sourcePackageJsonPath, kind, protocol } = mapping;
|
|
164
|
-
if (
|
|
157
|
+
if (isPathInsideDirectory(localPath, srcDir)) {
|
|
165
158
|
continue;
|
|
166
159
|
}
|
|
167
160
|
const archivePath = computeExternalArchivePath(localPath, kind);
|
|
@@ -325,7 +318,7 @@ export function getPackageJsonPathsToUpdate(srcDir, workspaceMappings, fileDepen
|
|
|
325
318
|
paths.add(toPosixPath(path.relative(srcDir, sourcePackageJsonPath)));
|
|
326
319
|
}
|
|
327
320
|
for (const { localPath, sourcePackageJsonPath } of fileDependencyMappings) {
|
|
328
|
-
if (!
|
|
321
|
+
if (!isPathInsideDirectory(localPath, srcDir)) {
|
|
329
322
|
paths.add(toPosixPath(path.relative(srcDir, sourcePackageJsonPath)));
|
|
330
323
|
}
|
|
331
324
|
}
|
|
@@ -334,12 +327,12 @@ export function getPackageJsonPathsToUpdate(srcDir, workspaceMappings, fileDepen
|
|
|
334
327
|
function getDirsWithExternalDeps(srcDir, workspaceMappings, fileDependencyMappings) {
|
|
335
328
|
const dirs = new Set();
|
|
336
329
|
for (const { workspaceDir, sourcePackageJsonPath } of workspaceMappings) {
|
|
337
|
-
if (!
|
|
330
|
+
if (!isPathInsideDirectory(workspaceDir, srcDir)) {
|
|
338
331
|
dirs.add(path.dirname(sourcePackageJsonPath));
|
|
339
332
|
}
|
|
340
333
|
}
|
|
341
334
|
for (const { localPath, sourcePackageJsonPath } of fileDependencyMappings) {
|
|
342
|
-
if (!
|
|
335
|
+
if (!isPathInsideDirectory(localPath, srcDir)) {
|
|
343
336
|
dirs.add(path.dirname(sourcePackageJsonPath));
|
|
344
337
|
}
|
|
345
338
|
}
|
|
@@ -18,9 +18,9 @@ declare const inputSchemaZodObject: z.ZodObject<{
|
|
|
18
18
|
features: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
19
19
|
card: "card";
|
|
20
20
|
settings: "settings";
|
|
21
|
+
"crm-bulk-action": "crm-bulk-action";
|
|
21
22
|
"app-event": "app-event";
|
|
22
23
|
"workflow-action-tool": "workflow-action-tool";
|
|
23
|
-
"crm-bulk-action": "crm-bulk-action";
|
|
24
24
|
page: "page";
|
|
25
25
|
webhooks: "webhooks";
|
|
26
26
|
"app-function": "app-function";
|
|
@@ -22,9 +22,9 @@ declare const inputSchemaZodObject: z.ZodObject<{
|
|
|
22
22
|
features: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
23
23
|
card: "card";
|
|
24
24
|
settings: "settings";
|
|
25
|
+
"crm-bulk-action": "crm-bulk-action";
|
|
25
26
|
"app-event": "app-event";
|
|
26
27
|
"workflow-action-tool": "workflow-action-tool";
|
|
27
|
-
"crm-bulk-action": "crm-bulk-action";
|
|
28
28
|
page: "page";
|
|
29
29
|
webhooks: "webhooks";
|
|
30
30
|
"app-function": "app-function";
|
|
@@ -4,9 +4,9 @@ export declare const absoluteCurrentWorkingDirectory: z.ZodString;
|
|
|
4
4
|
export declare const features: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
5
5
|
card: "card";
|
|
6
6
|
settings: "settings";
|
|
7
|
+
"crm-bulk-action": "crm-bulk-action";
|
|
7
8
|
"app-event": "app-event";
|
|
8
9
|
"workflow-action-tool": "workflow-action-tool";
|
|
9
|
-
"crm-bulk-action": "crm-bulk-action";
|
|
10
10
|
page: "page";
|
|
11
11
|
webhooks: "webhooks";
|
|
12
12
|
"app-function": "app-function";
|