@hubspot/project-parsing-lib 0.2.2 → 0.3.0-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/README.md +9 -35
- package/package.json +135 -22
- package/src/exports/constants.d.ts +1 -0
- package/src/exports/constants.js +1 -0
- package/src/exports/lang.d.ts +1 -0
- package/src/exports/lang.js +1 -0
- package/src/exports/migrate.d.ts +1 -0
- package/src/exports/migrate.js +1 -0
- package/src/exports/profiles.d.ts +3 -0
- package/src/exports/profiles.js +2 -0
- package/src/exports/projects.d.ts +5 -0
- package/src/exports/projects.js +3 -0
- package/src/exports/schema.d.ts +2 -0
- package/src/exports/schema.js +1 -0
- package/src/exports/themes.d.ts +2 -0
- package/src/exports/themes.js +1 -0
- package/src/exports/transform.d.ts +2 -0
- package/src/exports/transform.js +1 -0
- package/src/exports/translate.d.ts +4 -0
- package/src/exports/translate.js +2 -0
- package/src/exports/uid.d.ts +1 -0
- package/src/exports/uid.js +1 -0
- package/src/exports/validation.d.ts +3 -0
- package/src/exports/validation.js +2 -0
- package/src/exports/workspaces.d.ts +2 -0
- package/src/exports/workspaces.js +1 -0
- package/src/lang/copy.d.ts +19 -3
- package/src/lang/copy.js +40 -34
- package/src/lib/constants.d.ts +57 -29
- package/src/lib/constants.js +173 -126
- package/src/lib/errors.d.ts +3 -3
- package/src/lib/errors.js +25 -33
- package/src/lib/files.d.ts +13 -7
- package/src/lib/files.js +56 -49
- package/src/lib/localDev.d.ts +4 -0
- package/src/lib/localDev.js +72 -0
- package/src/lib/migrate.d.ts +1 -0
- package/src/lib/migrate.js +43 -45
- package/src/lib/migrateThemes.d.ts +25 -0
- package/src/lib/migrateThemes.js +120 -0
- package/src/lib/minimalArboristTree.d.ts +118 -0
- package/src/lib/minimalArboristTree.js +32 -0
- package/src/lib/platformVersion.d.ts +8 -0
- package/src/lib/platformVersion.js +74 -0
- package/src/lib/profiles.d.ts +6 -1
- package/src/lib/profiles.js +98 -40
- package/src/lib/project.d.ts +6 -0
- package/src/lib/project.js +73 -17
- package/src/lib/schemas.d.ts +2 -2
- package/src/lib/schemas.js +11 -11
- package/src/lib/transform.d.ts +4 -2
- package/src/lib/transform.js +109 -59
- package/src/lib/translate.d.ts +11 -0
- package/src/lib/translate.js +65 -0
- package/src/lib/types.d.ts +43 -6
- package/src/lib/types.js +1 -2
- package/src/lib/uid.d.ts +2 -0
- package/src/lib/uid.js +14 -9
- package/src/lib/utils.d.ts +3 -0
- package/src/lib/utils.js +16 -0
- package/src/lib/validation.d.ts +4 -4
- package/src/lib/validation.js +66 -53
- package/src/lib/workspaces.d.ts +113 -0
- package/src/lib/workspaces.js +403 -0
- package/src/index.d.ts +0 -18
- package/src/index.js +0 -87
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
/**
|
|
4
|
+
* Creates a minimal tree object that satisfies npm-packlist's requirements
|
|
5
|
+
* without importing the heavy @npmcli/arborist package.
|
|
6
|
+
*
|
|
7
|
+
* @param dir - Directory containing the package
|
|
8
|
+
* @returns Minimal tree object compatible with npm-packlist
|
|
9
|
+
*/
|
|
10
|
+
export function createMinimalTree(dir) {
|
|
11
|
+
let pkgJson = {};
|
|
12
|
+
try {
|
|
13
|
+
const content = fs.readFileSync(path.join(dir, 'package.json'), 'utf8');
|
|
14
|
+
pkgJson = JSON.parse(content);
|
|
15
|
+
}
|
|
16
|
+
catch {
|
|
17
|
+
// Use empty package.json if not found or invalid
|
|
18
|
+
// npm-packlist handles this gracefully
|
|
19
|
+
}
|
|
20
|
+
return {
|
|
21
|
+
path: dir,
|
|
22
|
+
package: pkgJson,
|
|
23
|
+
// Set to null to skip workspace-aware filtering
|
|
24
|
+
// (we process each workspace independently)
|
|
25
|
+
workspaces: null,
|
|
26
|
+
// Set to false to skip bundled dependency handling
|
|
27
|
+
// (not needed for workspace file collection)
|
|
28
|
+
isProjectRoot: false,
|
|
29
|
+
// Empty map - only accessed when isProjectRoot is true
|
|
30
|
+
edgesOut: new Map(),
|
|
31
|
+
};
|
|
32
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export declare const LATEST_SUPPORTED_PLATFORM_VERSION: "2026.03";
|
|
2
|
+
export declare function isKnownPlatformVersion(platformVersion?: string | null): boolean;
|
|
3
|
+
/**
|
|
4
|
+
* Returns true if platformVersion meets or exceeds minimumVersion.
|
|
5
|
+
* Versions that do not match the expected format are treated as newer than all known versions.
|
|
6
|
+
*/
|
|
7
|
+
export declare function meetsMinimumPlatformVersion(platformVersion: string, minimumVersion: string): boolean;
|
|
8
|
+
export declare function isLegacyProject(platformVersion?: string | null): boolean;
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { PLATFORM_VERSIONS, DEPRECATED_PLATFORM_VERSIONS, } from './constants.js';
|
|
2
|
+
// Used for logging suggestions to users whenever we encouter an unknown version
|
|
3
|
+
export const LATEST_SUPPORTED_PLATFORM_VERSION = PLATFORM_VERSIONS.v2026_03;
|
|
4
|
+
export function isKnownPlatformVersion(platformVersion) {
|
|
5
|
+
if (!platformVersion) {
|
|
6
|
+
return false;
|
|
7
|
+
}
|
|
8
|
+
if (process.env.HUBSPOT_PROJECT_INTERNAL_TEST === 'true')
|
|
9
|
+
return true;
|
|
10
|
+
const knownVersions = [
|
|
11
|
+
...Object.values(PLATFORM_VERSIONS),
|
|
12
|
+
...Object.values(DEPRECATED_PLATFORM_VERSIONS),
|
|
13
|
+
];
|
|
14
|
+
return knownVersions.includes(platformVersion);
|
|
15
|
+
}
|
|
16
|
+
function parseVersion(version) {
|
|
17
|
+
if (version === PLATFORM_VERSIONS.UNSTABLE)
|
|
18
|
+
return { type: PLATFORM_VERSIONS.UNSTABLE };
|
|
19
|
+
const match = version.match(/^(\d{4})\.(\d{1,2})(-beta)?$/);
|
|
20
|
+
if (!match)
|
|
21
|
+
return { type: 'unknown' };
|
|
22
|
+
return {
|
|
23
|
+
type: 'dated',
|
|
24
|
+
year: parseInt(match[1], 10),
|
|
25
|
+
month: parseInt(match[2], 10),
|
|
26
|
+
beta: !!match[3],
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
function compareVersions(a, b) {
|
|
30
|
+
if (b.type === 'unknown') {
|
|
31
|
+
throw new Error(`platformVersion: thresholdVersion could not be parsed as a known version format`);
|
|
32
|
+
}
|
|
33
|
+
// "Unstable" is always the most recent version
|
|
34
|
+
if (a.type === PLATFORM_VERSIONS.UNSTABLE &&
|
|
35
|
+
b.type === PLATFORM_VERSIONS.UNSTABLE) {
|
|
36
|
+
return 0;
|
|
37
|
+
}
|
|
38
|
+
if (a.type === PLATFORM_VERSIONS.UNSTABLE)
|
|
39
|
+
return 1;
|
|
40
|
+
if (b.type === PLATFORM_VERSIONS.UNSTABLE)
|
|
41
|
+
return -1;
|
|
42
|
+
if (a.type !== 'dated') {
|
|
43
|
+
throw new Error(`platformVersion: thresholdVersion could not be parsed as a known version format`);
|
|
44
|
+
}
|
|
45
|
+
if (a.year !== b.year)
|
|
46
|
+
return a.year - b.year;
|
|
47
|
+
if (a.month !== b.month)
|
|
48
|
+
return a.month - b.month;
|
|
49
|
+
// Look for beta tags if all else is equal
|
|
50
|
+
if (a.beta === b.beta)
|
|
51
|
+
return 0;
|
|
52
|
+
return a.beta ? -1 : 1;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Returns true if platformVersion meets or exceeds minimumVersion.
|
|
56
|
+
* Versions that do not match the expected format are treated as newer than all known versions.
|
|
57
|
+
*/
|
|
58
|
+
export function meetsMinimumPlatformVersion(platformVersion, minimumVersion) {
|
|
59
|
+
const parsedMinimum = parseVersion(minimumVersion);
|
|
60
|
+
if (parsedMinimum.type === 'unknown') {
|
|
61
|
+
throw new Error(`platformVersion: minimumVersion could not be parsed as a known version format`);
|
|
62
|
+
}
|
|
63
|
+
const parsed = parseVersion(platformVersion);
|
|
64
|
+
if (parsed.type === 'unknown')
|
|
65
|
+
return true;
|
|
66
|
+
return compareVersions(parsed, parsedMinimum) >= 0;
|
|
67
|
+
}
|
|
68
|
+
export function isLegacyProject(platformVersion) {
|
|
69
|
+
if (!platformVersion || typeof platformVersion !== 'string')
|
|
70
|
+
return false;
|
|
71
|
+
if (process.env.HUBSPOT_PROJECT_INTERNAL_TEST === 'true')
|
|
72
|
+
return false;
|
|
73
|
+
return !meetsMinimumPlatformVersion(platformVersion, PLATFORM_VERSIONS.v2025_2);
|
|
74
|
+
}
|
package/src/lib/profiles.d.ts
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
|
-
import { FileParseResult, HsProfileFile } from './types';
|
|
1
|
+
import { FileParseResult, HsProfileFile, HSProfileVariables } from './types.js';
|
|
2
2
|
export declare function getIsProfileFile(filename: string): boolean;
|
|
3
3
|
export declare function getHsProfileFilename(profileName: string): string;
|
|
4
4
|
export declare function getHsProfileName(profileFilename: string): string;
|
|
5
|
+
export declare function getHsProfileVariables(hsProfileContents: HsProfileFile): HSProfileVariables;
|
|
6
|
+
export declare function validateProfileVariables(profileVariables: HSProfileVariables, filename: string): {
|
|
7
|
+
success: boolean;
|
|
8
|
+
errors: string[];
|
|
9
|
+
};
|
|
5
10
|
export declare function applyHsProfileVariables(fileParseResults: FileParseResult[], hsProfileContents: HsProfileFile): FileParseResult[];
|
package/src/lib/profiles.js
CHANGED
|
@@ -1,56 +1,114 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
exports.getHsProfileName = getHsProfileName;
|
|
6
|
-
exports.applyHsProfileVariables = applyHsProfileVariables;
|
|
7
|
-
const constants_1 = require("./constants");
|
|
8
|
-
const copy_1 = require("../lang/copy");
|
|
9
|
-
const profileFilenameRegex = new RegExp(`^${constants_1.profileFilePrefix}\\.([^.]+)\\.json$`);
|
|
1
|
+
import { PROFILE_FILE_PREFIX } from './constants.js';
|
|
2
|
+
import { errorMessages } from '../lang/copy.js';
|
|
3
|
+
const profileFilenameRegex = new RegExp(`^${PROFILE_FILE_PREFIX}\\.([^.]+)\\.json$`);
|
|
4
|
+
// Regex to match variable placeholders like ${variableName}
|
|
10
5
|
const profileInsertRegex = /\${(.*?)}/g;
|
|
11
|
-
|
|
6
|
+
// Helper to check if string is a single variable reference (e.g., "${port}" but not "http://${port}")
|
|
7
|
+
// Returns the variable key if it matches, null otherwise
|
|
8
|
+
function isSingleVariableReference(str) {
|
|
9
|
+
const match = str.match(/^\${([^}]+)}$/);
|
|
10
|
+
return match ? match[1] : null;
|
|
11
|
+
}
|
|
12
|
+
export function getIsProfileFile(filename) {
|
|
12
13
|
return profileFilenameRegex.test(filename);
|
|
13
14
|
}
|
|
14
|
-
function getHsProfileFilename(profileName) {
|
|
15
|
-
return `${
|
|
15
|
+
export function getHsProfileFilename(profileName) {
|
|
16
|
+
return `${PROFILE_FILE_PREFIX}.${profileName}.json`;
|
|
16
17
|
}
|
|
17
|
-
function getHsProfileName(profileFilename) {
|
|
18
|
+
export function getHsProfileName(profileFilename) {
|
|
18
19
|
const match = profileFilename.match(profileFilenameRegex);
|
|
19
20
|
return match ? match[1] : '';
|
|
20
21
|
}
|
|
21
|
-
function
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
22
|
+
export function getHsProfileVariables(hsProfileContents) {
|
|
23
|
+
const profileVariablesAreValid = hsProfileContents?.variables &&
|
|
24
|
+
typeof hsProfileContents.variables === 'object' &&
|
|
25
|
+
!Array.isArray(hsProfileContents.variables);
|
|
26
|
+
return profileVariablesAreValid ? hsProfileContents.variables : {};
|
|
27
|
+
}
|
|
28
|
+
export function validateProfileVariables(profileVariables, filename) {
|
|
29
|
+
const errors = [];
|
|
30
|
+
for (const [variableKey, variableValue] of Object.entries(profileVariables)) {
|
|
31
|
+
try {
|
|
32
|
+
const variableType = typeof variableValue;
|
|
33
|
+
validateProfileVariable(variableType, variableKey, filename);
|
|
26
34
|
}
|
|
27
|
-
|
|
28
|
-
|
|
35
|
+
catch (error) {
|
|
36
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
37
|
+
errors.push(errorMessage);
|
|
29
38
|
}
|
|
30
|
-
|
|
39
|
+
}
|
|
40
|
+
return {
|
|
41
|
+
success: errors.length === 0,
|
|
42
|
+
errors,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
function validateProfileVariable(variableType, variableKey, filename) {
|
|
46
|
+
const allowedTypes = ['string', 'number', 'boolean'];
|
|
47
|
+
if (variableType === 'undefined') {
|
|
48
|
+
throw new Error(errorMessages.profile.missingValue(variableKey, filename));
|
|
49
|
+
}
|
|
50
|
+
if (!allowedTypes.includes(variableType)) {
|
|
51
|
+
throw new Error(errorMessages.profile.invalidValue(variableKey));
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
function interpolate(file, template, profileVariables) {
|
|
55
|
+
return template.replace(profileInsertRegex, (_fullMatch, variableKey) => {
|
|
56
|
+
const variableValue = profileVariables[variableKey];
|
|
57
|
+
const variableType = typeof variableValue;
|
|
58
|
+
validateProfileVariable(variableType, variableKey, file);
|
|
59
|
+
return String(variableValue);
|
|
31
60
|
});
|
|
32
61
|
}
|
|
33
|
-
function
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
62
|
+
function replaceVariablesInValue(value, file, profileVariables) {
|
|
63
|
+
// Handle string values with variable substitution
|
|
64
|
+
if (typeof value === 'string') {
|
|
65
|
+
// If the entire value is a single variable (e.g., "${port}"),
|
|
66
|
+
// return the typed value to preserve number/boolean types
|
|
67
|
+
const variableKey = isSingleVariableReference(value);
|
|
68
|
+
if (variableKey) {
|
|
69
|
+
const variableValue = profileVariables[variableKey];
|
|
70
|
+
const variableType = typeof variableValue;
|
|
71
|
+
validateProfileVariable(variableType, variableKey, file);
|
|
72
|
+
return variableValue;
|
|
73
|
+
}
|
|
74
|
+
// Otherwise, perform string interpolation (no-op if no variables found)
|
|
75
|
+
// For strings with multiple variables (e.g., "http://${host}:${port}"),
|
|
76
|
+
// this converts all values to strings
|
|
77
|
+
return interpolate(file, value, profileVariables);
|
|
78
|
+
}
|
|
79
|
+
// Recursively handle arrays
|
|
80
|
+
if (Array.isArray(value)) {
|
|
81
|
+
return value.map(item => replaceVariablesInValue(item, file, profileVariables));
|
|
82
|
+
}
|
|
83
|
+
// Recursively handle objects
|
|
84
|
+
if (value !== null && typeof value === 'object') {
|
|
85
|
+
const result = {};
|
|
86
|
+
for (const [key, val] of Object.entries(value)) {
|
|
87
|
+
result[key] = replaceVariablesInValue(val, file, profileVariables);
|
|
88
|
+
}
|
|
89
|
+
return result;
|
|
90
|
+
}
|
|
91
|
+
// Return primitive values as-is
|
|
92
|
+
return value;
|
|
93
|
+
}
|
|
94
|
+
export function applyHsProfileVariables(fileParseResults, hsProfileContents) {
|
|
95
|
+
const profileVariables = getHsProfileVariables(hsProfileContents);
|
|
39
96
|
return fileParseResults.map(fileParseResult => {
|
|
40
97
|
const { content, file } = fileParseResult;
|
|
41
|
-
if (content
|
|
42
|
-
|
|
43
|
-
interpolatedConfig = JSON.parse(interpolate(file, JSON.stringify(content.config), profileVariables));
|
|
44
|
-
if (interpolatedConfig) {
|
|
45
|
-
return {
|
|
46
|
-
...fileParseResult,
|
|
47
|
-
content: {
|
|
48
|
-
...content,
|
|
49
|
-
config: interpolatedConfig,
|
|
50
|
-
},
|
|
51
|
-
};
|
|
52
|
-
}
|
|
98
|
+
if (!content) {
|
|
99
|
+
return fileParseResult;
|
|
53
100
|
}
|
|
54
|
-
|
|
101
|
+
const uidWithVariablesReplaced = interpolate(file, content.uid, profileVariables);
|
|
102
|
+
const configWithVariablesReplaced = content.config
|
|
103
|
+
? replaceVariablesInValue(content.config, file, profileVariables)
|
|
104
|
+
: content.config;
|
|
105
|
+
return {
|
|
106
|
+
...fileParseResult,
|
|
107
|
+
content: {
|
|
108
|
+
...content,
|
|
109
|
+
uid: uidWithVariablesReplaced,
|
|
110
|
+
config: configWithVariablesReplaced,
|
|
111
|
+
},
|
|
112
|
+
};
|
|
55
113
|
});
|
|
56
114
|
}
|
package/src/lib/project.d.ts
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
import { ProjectConfig } from './types.js';
|
|
2
|
+
export declare class ProjectConfigValidationError extends Error {
|
|
3
|
+
constructor(message: string);
|
|
4
|
+
}
|
|
5
|
+
export declare function parseProjectConfig(projectDir: string): ProjectConfig;
|
|
6
|
+
export declare function validateProjectConfig(config: unknown, projectDir: string): asserts config is ProjectConfig;
|
|
1
7
|
export interface ComponentMetadata {
|
|
2
8
|
count: number;
|
|
3
9
|
maxCount: number;
|
package/src/lib/project.js
CHANGED
|
@@ -1,28 +1,84 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
1
|
+
import { Components, HS_PROJECT_JSON_FILENAME } from './constants.js';
|
|
2
|
+
import { locateHsMetaFiles } from './files.js';
|
|
3
|
+
import { errorMessages } from '../lang/copy.js';
|
|
4
|
+
import path from 'path';
|
|
5
|
+
import fs from 'fs';
|
|
6
|
+
export class ProjectConfigValidationError extends Error {
|
|
7
|
+
constructor(message) {
|
|
8
|
+
super(message);
|
|
9
|
+
this.name = 'ProjectConfigValidationError';
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
export function parseProjectConfig(projectDir) {
|
|
13
|
+
const configPath = path.join(projectDir, HS_PROJECT_JSON_FILENAME);
|
|
14
|
+
let rawConfig;
|
|
15
|
+
try {
|
|
16
|
+
rawConfig = fs.readFileSync(configPath, 'utf-8');
|
|
17
|
+
}
|
|
18
|
+
catch {
|
|
19
|
+
throw new ProjectConfigValidationError(errorMessages.projectConfig.couldNotRead(projectDir));
|
|
20
|
+
}
|
|
21
|
+
let config;
|
|
22
|
+
try {
|
|
23
|
+
config = JSON.parse(rawConfig);
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
throw new ProjectConfigValidationError(errorMessages.projectConfig.invalidJson);
|
|
27
|
+
}
|
|
28
|
+
validateProjectConfig(config, projectDir);
|
|
29
|
+
return config;
|
|
30
|
+
}
|
|
31
|
+
export function validateProjectConfig(config, projectDir) {
|
|
32
|
+
if (!config || typeof config !== 'object') {
|
|
33
|
+
throw new ProjectConfigValidationError(errorMessages.projectConfig.mustBeJsonObject);
|
|
34
|
+
}
|
|
35
|
+
const c = config;
|
|
36
|
+
const missingFields = [];
|
|
37
|
+
if (!c['name'])
|
|
38
|
+
missingFields.push('name');
|
|
39
|
+
if (!c['srcDir'])
|
|
40
|
+
missingFields.push('srcDir');
|
|
41
|
+
if (!c['platformVersion'])
|
|
42
|
+
missingFields.push('platformVersion');
|
|
43
|
+
if (missingFields.length > 0) {
|
|
44
|
+
throw new ProjectConfigValidationError(errorMessages.projectConfig.missingRequiredFields(missingFields));
|
|
45
|
+
}
|
|
46
|
+
const srcDirResolved = path.resolve(projectDir, c['srcDir']);
|
|
47
|
+
const projectDirNormalized = path.resolve(projectDir);
|
|
48
|
+
if (srcDirResolved !== projectDirNormalized &&
|
|
49
|
+
!srcDirResolved.startsWith(projectDirNormalized + path.sep)) {
|
|
50
|
+
throw new ProjectConfigValidationError(errorMessages.projectConfig.srcDirOutsideProject);
|
|
51
|
+
}
|
|
52
|
+
if (!fs.existsSync(srcDirResolved)) {
|
|
53
|
+
throw new ProjectConfigValidationError(errorMessages.projectConfig.srcDirNotFound(c['srcDir']));
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
export async function getProjectMetadata(projectSrcDir) {
|
|
11
57
|
const hsMetaFiles = [];
|
|
12
58
|
const components = {};
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
59
|
+
let metafiles = [];
|
|
60
|
+
if (fs.existsSync(projectSrcDir)) {
|
|
61
|
+
({ metaFiles: metafiles } = await locateHsMetaFiles(projectSrcDir));
|
|
62
|
+
}
|
|
63
|
+
const seenComponentPaths = new Map();
|
|
64
|
+
Object.keys(Components).forEach(componentType => {
|
|
65
|
+
const { parentComponent, singularComponent, dir } = Components[componentType];
|
|
66
|
+
const componentPath = path.join(projectSrcDir, parentComponent ? path.join(parentComponent, dir) : dir);
|
|
67
|
+
if (seenComponentPaths.has(componentPath)) {
|
|
68
|
+
components[componentType] = seenComponentPaths.get(componentPath);
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
17
71
|
const metaFilesByType = metafiles
|
|
18
|
-
.filter(metafile =>
|
|
72
|
+
.filter(metafile => path.parse(metafile.file).dir === componentPath)
|
|
19
73
|
.map(metaFile => metaFile.file);
|
|
20
|
-
|
|
21
|
-
components[componentType] = {
|
|
74
|
+
const metadata = {
|
|
22
75
|
hsMetaFiles: metaFilesByType,
|
|
23
76
|
count: metaFilesByType.length,
|
|
24
77
|
maxCount: singularComponent ? 1 : Infinity,
|
|
25
78
|
};
|
|
79
|
+
hsMetaFiles.push(...metaFilesByType);
|
|
80
|
+
seenComponentPaths.set(componentPath, metadata);
|
|
81
|
+
components[componentType] = metadata;
|
|
26
82
|
});
|
|
27
83
|
return {
|
|
28
84
|
hsMetaFiles,
|
package/src/lib/schemas.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { AnySchema } from 'ajv
|
|
2
|
-
import { TranslationContext } from './types';
|
|
1
|
+
import type { AnySchema } from 'ajv';
|
|
2
|
+
import { TranslationContext } from './types.js';
|
|
3
3
|
export declare function getIntermediateRepresentationSchema(translationContext: TranslationContext): Promise<Record<string, AnySchema>>;
|
package/src/lib/schemas.js
CHANGED
|
@@ -1,24 +1,24 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
const index_1 = require("@hubspot/local-dev-lib/errors/index");
|
|
6
|
-
const copy_1 = require("../lang/copy");
|
|
7
|
-
async function getIntermediateRepresentationSchema(translationContext) {
|
|
1
|
+
import { http } from '@hubspot/local-dev-lib/http';
|
|
2
|
+
import { isHubSpotHttpError, isSpecifiedError, } from '@hubspot/local-dev-lib/errors/index';
|
|
3
|
+
import { errorMessages } from '../lang/copy.js';
|
|
4
|
+
export async function getIntermediateRepresentationSchema(translationContext) {
|
|
8
5
|
if (!translationContext.accountId) {
|
|
9
|
-
throw new Error(
|
|
6
|
+
throw new Error(errorMessages.api.accountIdIsRequiredToFetchSchemas);
|
|
10
7
|
}
|
|
11
8
|
try {
|
|
12
9
|
const { accountId, platformVersion } = translationContext;
|
|
13
|
-
const { data } = await
|
|
10
|
+
const { data } = await http.get(accountId, {
|
|
14
11
|
url: `project-components-external/project-schemas/v3/${platformVersion}`,
|
|
15
12
|
});
|
|
16
13
|
return data;
|
|
17
14
|
}
|
|
18
15
|
catch (e) {
|
|
19
|
-
if ((
|
|
16
|
+
if (isSpecifiedError(e, { statusCode: 403 })) {
|
|
17
|
+
throw new Error(errorMessages.api.failedToFetchSchemas403, { cause: e });
|
|
18
|
+
}
|
|
19
|
+
if (isHubSpotHttpError(e)) {
|
|
20
20
|
throw e;
|
|
21
21
|
}
|
|
22
|
-
throw new Error(
|
|
22
|
+
throw new Error(errorMessages.api.failedToFetchSchemas, { cause: e });
|
|
23
23
|
}
|
|
24
24
|
}
|
package/src/lib/transform.d.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
import { Dependencies, FileParseResult, HsProfileFile, IntermediateRepresentation, Transformation, TranslationContext } from './types';
|
|
1
|
+
import { Dependencies, FileParseResult, HsProfileFile, IntermediateRepresentation, Transformation, TranslationContext } from './types.js';
|
|
2
2
|
export declare function mapToInternalType(type: string): string;
|
|
3
3
|
export declare function mapToUserFacingType(type: string): string;
|
|
4
4
|
export declare function mapToUserFriendlyName(internalType: string): string;
|
|
5
|
+
export declare function findTransformationByUid(transformations: Transformation[], uid: string): Transformation | undefined;
|
|
5
6
|
export declare function transform(fileParseResults: FileParseResult[], translationContext: TranslationContext, hsProfileContents?: HsProfileFile): Transformation[];
|
|
6
|
-
export declare function getIntermediateRepresentation(transformations: Transformation[], skipValidation
|
|
7
|
+
export declare function getIntermediateRepresentation(transformations: Transformation[], hsProfileContents?: HsProfileFile, skipValidation?: boolean): IntermediateRepresentation;
|
|
8
|
+
export declare function getParsingErrors(transformations: Transformation[]): FileParseResult[];
|
|
7
9
|
export declare function generateServerlessPackageComponent(appFunctionsDirectory: string, translationContext: TranslationContext, componentDeps: Dependencies): {
|
|
8
10
|
uid: string;
|
|
9
11
|
transformation: Transformation;
|