@hubspot/project-parsing-lib 0.2.2-experimental.3 → 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 +5 -0
- package/package.json +8 -6
- package/src/exports/projects.d.ts +4 -3
- package/src/exports/projects.js +2 -2
- package/src/lang/copy.d.ts +8 -0
- package/src/lang/copy.js +9 -1
- package/src/lib/constants.d.ts +10 -8
- package/src/lib/constants.js +6 -3
- package/src/lib/platformVersion.d.ts +7 -3
- package/src/lib/platformVersion.js +62 -18
- package/src/lib/profiles.js +6 -3
- package/src/lib/project.d.ts +6 -0
- package/src/lib/project.js +52 -1
- package/src/lib/translate.js +3 -3
- package/src/lib/types.d.ts +6 -0
- package/src/lib/validation.js +3 -3
package/README.md
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
# @hubspot/project-parsing-lib
|
|
2
2
|
|
|
3
|
+
[](https://www.npmjs.com/package/@hubspot/project-parsing-lib)
|
|
4
|
+
[](https://www.npmjs.com/package/@hubspot/project-parsing-lib)
|
|
5
|
+
[](https://www.npmjs.com/package/@hubspot/project-parsing-lib)
|
|
6
|
+
[](https://www.npmjs.com/package/@hubspot/project-parsing-lib)
|
|
7
|
+
|
|
3
8
|
A parsing library for converting HubSpot project directory structures to their intermediate representation (IR).
|
|
4
9
|
|
|
5
10
|
## Description
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hubspot/project-parsing-lib",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0-experimental.0",
|
|
4
4
|
"description": "Parsing library for converting projects directory structures to their intermediate representation",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|
|
@@ -107,7 +107,7 @@
|
|
|
107
107
|
}
|
|
108
108
|
},
|
|
109
109
|
"devDependencies": {
|
|
110
|
-
"@hubspot/npm-scripts": "0.3.
|
|
110
|
+
"@hubspot/npm-scripts": "0.3.1",
|
|
111
111
|
"@inquirer/prompts": "^7.1.0",
|
|
112
112
|
"@types/node": "^24.9.0",
|
|
113
113
|
"@types/npm-packlist": "7.0.3",
|
|
@@ -123,10 +123,10 @@
|
|
|
123
123
|
"semver": "^7.6.3",
|
|
124
124
|
"tsx": "^4.20.5",
|
|
125
125
|
"typescript": "^5.6.2",
|
|
126
|
-
"vitest": "^2.
|
|
126
|
+
"vitest": "^3.2.7"
|
|
127
127
|
},
|
|
128
128
|
"dependencies": {
|
|
129
|
-
"@hubspot/local-dev-lib": "
|
|
129
|
+
"@hubspot/local-dev-lib": "5.10.1",
|
|
130
130
|
"@npmcli/map-workspaces": "4.0.2",
|
|
131
131
|
"ajv": "8.18.0",
|
|
132
132
|
"ajv-formats": "3.0.1",
|
|
@@ -134,12 +134,14 @@
|
|
|
134
134
|
"npm-packlist": "8.0.1"
|
|
135
135
|
},
|
|
136
136
|
"resolutions": {
|
|
137
|
-
"ajv-formats/ajv": "8.18.0"
|
|
137
|
+
"ajv-formats/ajv": "8.18.0",
|
|
138
|
+
"vite": "^6.0.0"
|
|
138
139
|
},
|
|
139
140
|
"overrides": {
|
|
140
141
|
"ajv-formats": {
|
|
141
142
|
"ajv": "8.18.0"
|
|
142
|
-
}
|
|
143
|
+
},
|
|
144
|
+
"vite": "^6.0.0"
|
|
143
145
|
},
|
|
144
146
|
"scripts": {
|
|
145
147
|
"build": "tsx ./scripts/build.ts",
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
export { getProjectMetadata } from '../lib/project.js';
|
|
2
|
-
export { projectContainsHsMetaFiles } from '../lib/files.js';
|
|
1
|
+
export { getProjectMetadata, parseProjectConfig, validateProjectConfig, ProjectConfigValidationError, } from '../lib/project.js';
|
|
3
2
|
export type { ProjectMetadata } from '../lib/project.js';
|
|
4
|
-
export {
|
|
3
|
+
export { projectContainsHsMetaFiles } from '../lib/files.js';
|
|
4
|
+
export type { ProjectConfig } from '../lib/types.js';
|
|
5
|
+
export { LATEST_SUPPORTED_PLATFORM_VERSION, isKnownPlatformVersion, isLegacyProject, meetsMinimumPlatformVersion, } from '../lib/platformVersion.js';
|
package/src/exports/projects.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { getProjectMetadata } from '../lib/project.js';
|
|
1
|
+
export { getProjectMetadata, parseProjectConfig, validateProjectConfig, ProjectConfigValidationError, } from '../lib/project.js';
|
|
2
2
|
export { projectContainsHsMetaFiles } from '../lib/files.js';
|
|
3
|
-
export { LATEST_SUPPORTED_PLATFORM_VERSION,
|
|
3
|
+
export { LATEST_SUPPORTED_PLATFORM_VERSION, isKnownPlatformVersion, isLegacyProject, meetsMinimumPlatformVersion, } from '../lib/platformVersion.js';
|
package/src/lang/copy.d.ts
CHANGED
|
@@ -37,6 +37,14 @@ export declare const errorMessages: {
|
|
|
37
37
|
unexpectedToplevelFields: (unexpectedFields: string) => string;
|
|
38
38
|
wrongDirectoryForComponent: (directory: string, componentType: string, componentMetadata: ComponentMetadata, correctDir: string) => string;
|
|
39
39
|
};
|
|
40
|
+
projectConfig: {
|
|
41
|
+
couldNotRead: (projectDir: string) => string;
|
|
42
|
+
invalidJson: string;
|
|
43
|
+
mustBeJsonObject: string;
|
|
44
|
+
missingRequiredFields: (fields: string[]) => string;
|
|
45
|
+
srcDirOutsideProject: string;
|
|
46
|
+
srcDirNotFound: (srcDir: string) => string;
|
|
47
|
+
};
|
|
40
48
|
migrateThemes: {
|
|
41
49
|
rootReactThemeNotSupported: string;
|
|
42
50
|
};
|
package/src/lang/copy.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { APP_FUNCTIONS_KEY, APP_KEY, Components, PACKAGE_JSON, } from '../lib/constants.js';
|
|
1
|
+
import { APP_FUNCTIONS_KEY, APP_KEY, Components, HS_PROJECT_JSON_FILENAME, PACKAGE_JSON, } from '../lib/constants.js';
|
|
2
2
|
import { mapToUserFacingType } from '../lib/transform.js';
|
|
3
3
|
export const errorMessages = {
|
|
4
4
|
api: {
|
|
@@ -38,6 +38,14 @@ export const errorMessages = {
|
|
|
38
38
|
unexpectedToplevelFields: (unexpectedFields) => `Unexpected top-level properties found: ${unexpectedFields}`,
|
|
39
39
|
wrongDirectoryForComponent: (directory, componentType, componentMetadata, correctDir) => `The directory '${directory}' is incorrect for type '${componentType}'. ${componentMetadata.userFriendlyName} ${componentMetadata.userFriendlyTypePlural} should only be placed in the '${correctDir}' directory`,
|
|
40
40
|
},
|
|
41
|
+
projectConfig: {
|
|
42
|
+
couldNotRead: (projectDir) => `Could not read ${HS_PROJECT_JSON_FILENAME} in ${projectDir}`,
|
|
43
|
+
invalidJson: `Failed to parse ${HS_PROJECT_JSON_FILENAME}: invalid JSON`,
|
|
44
|
+
mustBeJsonObject: `${HS_PROJECT_JSON_FILENAME} must be a JSON object`,
|
|
45
|
+
missingRequiredFields: (fields) => `${HS_PROJECT_JSON_FILENAME} is missing required field(s): ${fields.join(', ')}`,
|
|
46
|
+
srcDirOutsideProject: `"srcDir" in ${HS_PROJECT_JSON_FILENAME} must be within the project directory`,
|
|
47
|
+
srcDirNotFound: (srcDir) => `The "srcDir" specified in ${HS_PROJECT_JSON_FILENAME} does not exist: ${srcDir}`,
|
|
48
|
+
},
|
|
41
49
|
migrateThemes: {
|
|
42
50
|
rootReactThemeNotSupported: 'Migrating themes that live at the root of the project src directory is not supported. Please move the theme to a subdirectory.',
|
|
43
51
|
},
|
package/src/lib/constants.d.ts
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
|
+
export declare const DEPRECATED_PLATFORM_VERSIONS: {
|
|
2
|
+
readonly v2025_1: "2025.1";
|
|
3
|
+
};
|
|
1
4
|
export declare const PLATFORM_VERSIONS: {
|
|
2
|
-
v2023_2:
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
UNSTABLE: string;
|
|
5
|
+
readonly v2023_2: "2023.2";
|
|
6
|
+
readonly v2025_2: "2025.2";
|
|
7
|
+
readonly v2026_03_BETA: "2026.03-beta";
|
|
8
|
+
readonly v2026_03: "2026.03";
|
|
9
|
+
readonly v2026_09_BETA: "2026.09-beta";
|
|
10
|
+
readonly UNSTABLE: "unstable";
|
|
9
11
|
};
|
|
10
12
|
import { ComponentMeta as ComponentsTopLevel } from './types.js';
|
|
11
13
|
export declare const APP_KEY = "app";
|
|
@@ -29,7 +31,7 @@ export declare const VIDEO_CONFERENCING_KEY = "video-conferencing";
|
|
|
29
31
|
export declare const WEBHOOKS_KEY = "webhooks";
|
|
30
32
|
export declare const WEBHOOKS_JOURNAL_KEY = "webhooks-journal";
|
|
31
33
|
export declare const WORKFLOW_ACTIONS_KEY = "workflow-action";
|
|
32
|
-
export declare const ACTIONS_KEY = "action";
|
|
34
|
+
export declare const ACTIONS_KEY = "crm-bulk-action";
|
|
33
35
|
export declare const APP_FUNCTIONS_PACKAGE_KEY = "serverless-package";
|
|
34
36
|
export declare const AUTO_GENERATED_COMPONENT_TYPES: string[];
|
|
35
37
|
export interface ComponentMetadata {
|
package/src/lib/constants.js
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
|
-
// Project Platform Versions
|
|
1
|
+
// Previously supported Project Platform Versions
|
|
2
|
+
export const DEPRECATED_PLATFORM_VERSIONS = {
|
|
3
|
+
v2025_1: '2025.1',
|
|
4
|
+
};
|
|
5
|
+
// Supported Project Platform Versions
|
|
2
6
|
export const PLATFORM_VERSIONS = {
|
|
3
7
|
v2023_2: '2023.2',
|
|
4
|
-
v2025_1: '2025.1',
|
|
5
8
|
v2025_2: '2025.2',
|
|
6
9
|
v2026_03_BETA: '2026.03-beta',
|
|
7
10
|
v2026_03: '2026.03',
|
|
@@ -33,7 +36,7 @@ export const VIDEO_CONFERENCING_KEY = 'video-conferencing';
|
|
|
33
36
|
export const WEBHOOKS_KEY = 'webhooks';
|
|
34
37
|
export const WEBHOOKS_JOURNAL_KEY = 'webhooks-journal';
|
|
35
38
|
export const WORKFLOW_ACTIONS_KEY = 'workflow-action';
|
|
36
|
-
export const ACTIONS_KEY = 'action';
|
|
39
|
+
export const ACTIONS_KEY = 'crm-bulk-action';
|
|
37
40
|
// Auto-generated component types
|
|
38
41
|
export const APP_FUNCTIONS_PACKAGE_KEY = 'serverless-package';
|
|
39
42
|
export const AUTO_GENERATED_COMPONENT_TYPES = [APP_FUNCTIONS_PACKAGE_KEY];
|
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
export declare const LATEST_SUPPORTED_PLATFORM_VERSION:
|
|
2
|
-
export declare function
|
|
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;
|
|
3
8
|
export declare function isLegacyProject(platformVersion?: string | null): boolean;
|
|
4
|
-
export declare function supportsComponentPermissions(platformVersion: string): boolean;
|
|
@@ -1,30 +1,74 @@
|
|
|
1
|
-
import { PLATFORM_VERSIONS } from './constants.js';
|
|
1
|
+
import { PLATFORM_VERSIONS, DEPRECATED_PLATFORM_VERSIONS, } from './constants.js';
|
|
2
2
|
// Used for logging suggestions to users whenever we encouter an unknown version
|
|
3
3
|
export const LATEST_SUPPORTED_PLATFORM_VERSION = PLATFORM_VERSIONS.v2026_03;
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
if (!platformVersion || typeof platformVersion !== 'string') {
|
|
4
|
+
export function isKnownPlatformVersion(platformVersion) {
|
|
5
|
+
if (!platformVersion) {
|
|
7
6
|
return false;
|
|
8
7
|
}
|
|
9
8
|
if (process.env.HUBSPOT_PROJECT_INTERNAL_TEST === 'true')
|
|
10
9
|
return true;
|
|
11
|
-
const
|
|
12
|
-
|
|
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;
|
|
13
67
|
}
|
|
14
68
|
export function isLegacyProject(platformVersion) {
|
|
15
|
-
if (!platformVersion)
|
|
69
|
+
if (!platformVersion || typeof platformVersion !== 'string')
|
|
16
70
|
return false;
|
|
17
71
|
if (process.env.HUBSPOT_PROJECT_INTERNAL_TEST === 'true')
|
|
18
72
|
return false;
|
|
19
|
-
return
|
|
20
|
-
}
|
|
21
|
-
const PRE_PERMISSIONS_VERSIONS = new Set([
|
|
22
|
-
PLATFORM_VERSIONS.v2023_2,
|
|
23
|
-
PLATFORM_VERSIONS.v2025_1,
|
|
24
|
-
PLATFORM_VERSIONS.v2025_2,
|
|
25
|
-
PLATFORM_VERSIONS.v2026_03_BETA,
|
|
26
|
-
PLATFORM_VERSIONS.v2026_03,
|
|
27
|
-
]);
|
|
28
|
-
export function supportsComponentPermissions(platformVersion) {
|
|
29
|
-
return !PRE_PERMISSIONS_VERSIONS.has(platformVersion);
|
|
73
|
+
return !meetsMinimumPlatformVersion(platformVersion, PLATFORM_VERSIONS.v2025_2);
|
|
30
74
|
}
|
package/src/lib/profiles.js
CHANGED
|
@@ -95,15 +95,18 @@ export function applyHsProfileVariables(fileParseResults, hsProfileContents) {
|
|
|
95
95
|
const profileVariables = getHsProfileVariables(hsProfileContents);
|
|
96
96
|
return fileParseResults.map(fileParseResult => {
|
|
97
97
|
const { content, file } = fileParseResult;
|
|
98
|
-
|
|
99
|
-
if (!content?.config) {
|
|
98
|
+
if (!content) {
|
|
100
99
|
return fileParseResult;
|
|
101
100
|
}
|
|
102
|
-
const
|
|
101
|
+
const uidWithVariablesReplaced = interpolate(file, content.uid, profileVariables);
|
|
102
|
+
const configWithVariablesReplaced = content.config
|
|
103
|
+
? replaceVariablesInValue(content.config, file, profileVariables)
|
|
104
|
+
: content.config;
|
|
103
105
|
return {
|
|
104
106
|
...fileParseResult,
|
|
105
107
|
content: {
|
|
106
108
|
...content,
|
|
109
|
+
uid: uidWithVariablesReplaced,
|
|
107
110
|
config: configWithVariablesReplaced,
|
|
108
111
|
},
|
|
109
112
|
};
|
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,7 +1,58 @@
|
|
|
1
|
-
import { Components } from './constants.js';
|
|
1
|
+
import { Components, HS_PROJECT_JSON_FILENAME } from './constants.js';
|
|
2
2
|
import { locateHsMetaFiles } from './files.js';
|
|
3
|
+
import { errorMessages } from '../lang/copy.js';
|
|
3
4
|
import path from 'path';
|
|
4
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
|
+
}
|
|
5
56
|
export async function getProjectMetadata(projectSrcDir) {
|
|
6
57
|
const hsMetaFiles = [];
|
|
7
58
|
const components = {};
|
package/src/lib/translate.js
CHANGED
|
@@ -3,14 +3,14 @@ import { validateIntermediateRepresentation } from './validation.js';
|
|
|
3
3
|
import { getIntermediateRepresentation, getParsingErrors, transform, } from './transform.js';
|
|
4
4
|
import { errorMessages } from '../lang/copy.js';
|
|
5
5
|
import { getLocalDevProfileData, getLocalDevProjectNodes, getRemovedNodesAndNodesWithErrors, } from './localDev.js';
|
|
6
|
-
import {
|
|
6
|
+
import { isKnownPlatformVersion } from './platformVersion.js';
|
|
7
7
|
const defaultOptions = {
|
|
8
8
|
skipValidation: false,
|
|
9
9
|
};
|
|
10
10
|
export async function translate(translationContext, translationOptions = defaultOptions) {
|
|
11
11
|
const { skipValidation, profile } = translationOptions;
|
|
12
12
|
if (!skipValidation &&
|
|
13
|
-
!
|
|
13
|
+
!isKnownPlatformVersion(translationContext.platformVersion)) {
|
|
14
14
|
throw new Error(errorMessages.project.unsupportedPlatformVersion(translationContext.platformVersion));
|
|
15
15
|
}
|
|
16
16
|
const { results: metafileContents, skippedFiles } = await loadHsMetaFiles(translationContext);
|
|
@@ -32,7 +32,7 @@ export async function translate(translationContext, translationOptions = default
|
|
|
32
32
|
export async function translateForLocalDev(translationContext, translationOptions) {
|
|
33
33
|
const { skipValidation, profile, projectNodesAtLastUpload } = translationOptions || {};
|
|
34
34
|
if (!skipValidation &&
|
|
35
|
-
!
|
|
35
|
+
!isKnownPlatformVersion(translationContext.platformVersion)) {
|
|
36
36
|
throw new Error(errorMessages.project.unsupportedPlatformVersion(translationContext.platformVersion));
|
|
37
37
|
}
|
|
38
38
|
const { results: metafileContents, skippedFiles } = await loadHsMetaFiles(translationContext);
|
package/src/lib/types.d.ts
CHANGED
|
@@ -72,6 +72,12 @@ export type Transformation = {
|
|
|
72
72
|
export type CompiledError = {
|
|
73
73
|
errors: string[];
|
|
74
74
|
};
|
|
75
|
+
export interface ProjectConfig {
|
|
76
|
+
name: string;
|
|
77
|
+
srcDir: string;
|
|
78
|
+
platformVersion: string;
|
|
79
|
+
[key: string]: unknown;
|
|
80
|
+
}
|
|
75
81
|
export interface TranslationContext {
|
|
76
82
|
projectSourceDir: string;
|
|
77
83
|
platformVersion: string;
|
package/src/lib/validation.js
CHANGED
|
@@ -2,10 +2,10 @@ import { getIntermediateRepresentationSchema } from './schemas.js';
|
|
|
2
2
|
import { Ajv2020, } from 'ajv/dist/2020.js';
|
|
3
3
|
import { compileError, TranslationError } from './errors.js';
|
|
4
4
|
import { errorMessages } from '../lang/copy.js';
|
|
5
|
-
import { AUTO_GENERATED_COMPONENT_TYPES, Components } from './constants.js';
|
|
5
|
+
import { AUTO_GENERATED_COMPONENT_TYPES, Components, PLATFORM_VERSIONS, } from './constants.js';
|
|
6
6
|
import path from 'path';
|
|
7
7
|
import { findTransformationByUid, mapToUserFacingType } from './transform.js';
|
|
8
|
-
import {
|
|
8
|
+
import { meetsMinimumPlatformVersion } from './platformVersion.js';
|
|
9
9
|
import { validateUid } from './uid.js';
|
|
10
10
|
// ajv-formats does not play nicely with ESM and TS
|
|
11
11
|
import addFormatsModule from 'ajv-formats';
|
|
@@ -49,7 +49,7 @@ function validateIntermediateRepresentationNode(schema, transformation, irNode,
|
|
|
49
49
|
shouldSkipValidation = true;
|
|
50
50
|
}
|
|
51
51
|
if (irNode.permissions &&
|
|
52
|
-
!
|
|
52
|
+
!meetsMinimumPlatformVersion(translationContext.platformVersion, PLATFORM_VERSIONS.v2026_09_BETA)) {
|
|
53
53
|
transformation.fileParseResult.errors.push(errorMessages.validation.permissionsNotSupported(translationContext.platformVersion));
|
|
54
54
|
}
|
|
55
55
|
if (!schema[irNode.componentType]) {
|