@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
package/src/lib/transform.js
CHANGED
|
@@ -1,76 +1,80 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
};
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
exports.transform = transform;
|
|
10
|
-
exports.getIntermediateRepresentation = getIntermediateRepresentation;
|
|
11
|
-
exports.generateServerlessPackageComponent = generateServerlessPackageComponent;
|
|
12
|
-
const profiles_1 = require("./profiles");
|
|
13
|
-
const constants_1 = require("./constants");
|
|
14
|
-
const copy_1 = require("../lang/copy");
|
|
15
|
-
const path_1 = __importDefault(require("path"));
|
|
16
|
-
const fs_1 = __importDefault(require("fs"));
|
|
1
|
+
import path from 'path';
|
|
2
|
+
import fs from 'fs';
|
|
3
|
+
import { logger } from '@hubspot/local-dev-lib/logger';
|
|
4
|
+
import { applyHsProfileVariables, getHsProfileVariables } from './profiles.js';
|
|
5
|
+
import { APP_KEY, APP_OBJECT_KEY, Components, PROJECT_STRUCTURE, APP_FUNCTIONS_KEY, APP_FUNCTIONS_PACKAGE_KEY, USER_FACING_TO_INTERNAL_TYPE, INTERNAL_TYPE_TO_USER_FACING, PACKAGE_JSON, PACKAGE_LOCK_JSON, PROFILE_VARIABLE_TYPES, } from './constants.js';
|
|
6
|
+
import { errorMessages } from '../lang/copy.js';
|
|
7
|
+
import { getJavaNumberType } from './utils.js';
|
|
8
|
+
import { convertPathToPosixPath } from './files.js';
|
|
17
9
|
function calculateComponentDeps(fileValidationResult, parentComponents, appObjects, appFunctionsPackageUid) {
|
|
18
|
-
|
|
19
|
-
//
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
10
|
+
// Pass through any developer-authored dependencies declared in the hsmeta
|
|
11
|
+
// file. Framework-injected structural dependencies (app, allAppObjects,
|
|
12
|
+
// serverlessPackage) are layered on top below and take precedence over any
|
|
13
|
+
// authored value for those reserved keys.
|
|
14
|
+
const dependencies = {
|
|
15
|
+
...fileValidationResult.content?.dependencies,
|
|
16
|
+
};
|
|
23
17
|
const { type } = fileValidationResult.content;
|
|
24
18
|
// If the component is a child of the App component, add the app and appObjects as dependencies
|
|
25
|
-
if (
|
|
26
|
-
const parentUid = parentComponents[
|
|
19
|
+
if (Components[type]?.parentComponent === APP_KEY) {
|
|
20
|
+
const parentUid = parentComponents[APP_KEY];
|
|
27
21
|
if (parentUid) {
|
|
28
22
|
dependencies.app = parentUid;
|
|
29
23
|
}
|
|
30
|
-
|
|
24
|
+
else {
|
|
25
|
+
logger.debug(parentComponents);
|
|
26
|
+
return {
|
|
27
|
+
dependencies,
|
|
28
|
+
errors: [errorMessages.project.mustHaveAppComponent(type)],
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
if (type !== APP_OBJECT_KEY) {
|
|
31
32
|
dependencies.allAppObjects = appObjects;
|
|
32
33
|
}
|
|
33
|
-
if (type ===
|
|
34
|
+
if (type === APP_FUNCTIONS_KEY && appFunctionsPackageUid) {
|
|
34
35
|
dependencies.serverlessPackage = appFunctionsPackageUid;
|
|
35
36
|
}
|
|
36
37
|
}
|
|
37
|
-
return dependencies;
|
|
38
|
+
return { dependencies };
|
|
38
39
|
}
|
|
39
|
-
function mapToInternalType(type) {
|
|
40
|
-
const resolvedType =
|
|
40
|
+
export function mapToInternalType(type) {
|
|
41
|
+
const resolvedType = USER_FACING_TO_INTERNAL_TYPE[type] || type || '';
|
|
41
42
|
return resolvedType.toUpperCase().replace(/-/g, '_');
|
|
42
43
|
}
|
|
43
|
-
function mapToUserFacingType(type) {
|
|
44
|
-
return (
|
|
44
|
+
export function mapToUserFacingType(type) {
|
|
45
|
+
return (INTERNAL_TYPE_TO_USER_FACING[type] || type || '')
|
|
45
46
|
.toLowerCase()
|
|
46
47
|
.replace(/_/g, '-');
|
|
47
48
|
}
|
|
48
|
-
function mapToUserFriendlyName(internalType) {
|
|
49
|
-
return
|
|
49
|
+
export function mapToUserFriendlyName(internalType) {
|
|
50
|
+
return Components[mapToUserFacingType(internalType)]?.userFriendlyName || '';
|
|
51
|
+
}
|
|
52
|
+
export function findTransformationByUid(transformations, uid) {
|
|
53
|
+
return transformations.find(t => t.intermediateRepresentation?.uid === uid);
|
|
50
54
|
}
|
|
51
|
-
function transform(fileParseResults, translationContext, hsProfileContents) {
|
|
52
|
-
const parentTypes = Object.keys(
|
|
55
|
+
export function transform(fileParseResults, translationContext, hsProfileContents) {
|
|
56
|
+
const parentTypes = Object.keys(PROJECT_STRUCTURE);
|
|
53
57
|
const parentComponents = {};
|
|
54
58
|
const allAppObjects = [];
|
|
55
59
|
let appUid = '';
|
|
56
60
|
let appFunctionsDirectory;
|
|
57
61
|
// Apply the profile variable overrides to the config
|
|
58
62
|
if (hsProfileContents) {
|
|
59
|
-
fileParseResults =
|
|
63
|
+
fileParseResults = applyHsProfileVariables(fileParseResults, hsProfileContents);
|
|
60
64
|
}
|
|
61
65
|
// Compute the parent components, so we can add them as dependencies to the child components
|
|
62
66
|
fileParseResults.forEach(file => {
|
|
63
67
|
if (file.content?.type && parentTypes.includes(file.content.type)) {
|
|
64
|
-
if (file.content.type ===
|
|
68
|
+
if (file.content.type === APP_KEY) {
|
|
65
69
|
appUid = file.content.uid;
|
|
66
70
|
}
|
|
67
71
|
parentComponents[file.content.type] = file.content.uid;
|
|
68
72
|
}
|
|
69
|
-
if (file.content?.type ===
|
|
73
|
+
if (file.content?.type === APP_OBJECT_KEY) {
|
|
70
74
|
allAppObjects.push(file.content.uid);
|
|
71
75
|
}
|
|
72
|
-
if (file.content?.type ===
|
|
73
|
-
appFunctionsDirectory =
|
|
76
|
+
if (file.content?.type === APP_FUNCTIONS_KEY) {
|
|
77
|
+
appFunctionsDirectory = path.dirname(file.file);
|
|
74
78
|
}
|
|
75
79
|
});
|
|
76
80
|
const autoGeneratedComponents = [];
|
|
@@ -85,28 +89,35 @@ function transform(fileParseResults, translationContext, hsProfileContents) {
|
|
|
85
89
|
}
|
|
86
90
|
const transformations = fileParseResults.map((currentFile) => {
|
|
87
91
|
if (!currentFile.content) {
|
|
88
|
-
currentFile.errors?.
|
|
92
|
+
if (!currentFile.errors?.includes(errorMessages.validation.invalidJson)) {
|
|
93
|
+
currentFile.errors?.push(errorMessages.project.fileContentMissingFor(currentFile.file));
|
|
94
|
+
}
|
|
89
95
|
return {
|
|
90
96
|
intermediateRepresentation: null,
|
|
91
97
|
fileParseResult: currentFile,
|
|
92
98
|
};
|
|
93
99
|
}
|
|
94
|
-
const { config, uid, type } = currentFile.content;
|
|
100
|
+
const { config, uid, type, permissions } = currentFile.content;
|
|
101
|
+
const { dependencies, errors } = calculateComponentDeps(currentFile, parentComponents, allAppObjects, serverlessPackageUid);
|
|
102
|
+
if (errors) {
|
|
103
|
+
currentFile.errors?.push(...errors);
|
|
104
|
+
}
|
|
95
105
|
return {
|
|
96
106
|
intermediateRepresentation: {
|
|
97
107
|
uid,
|
|
98
108
|
config,
|
|
99
109
|
componentType: mapToInternalType(type),
|
|
100
|
-
componentDeps:
|
|
101
|
-
metaFilePath: currentFile.file,
|
|
110
|
+
componentDeps: dependencies,
|
|
111
|
+
metaFilePath: convertPathToPosixPath(currentFile.file),
|
|
102
112
|
files: {},
|
|
113
|
+
...(permissions ? { permissions } : {}),
|
|
103
114
|
},
|
|
104
115
|
fileParseResult: currentFile,
|
|
105
116
|
};
|
|
106
117
|
});
|
|
107
118
|
return [...autoGeneratedComponents, ...transformations];
|
|
108
119
|
}
|
|
109
|
-
function getIntermediateRepresentation(transformations, skipValidation) {
|
|
120
|
+
export function getIntermediateRepresentation(transformations, hsProfileContents, skipValidation) {
|
|
110
121
|
const nodes = transformations.reduce((acc, current) => {
|
|
111
122
|
if (!current.intermediateRepresentation) {
|
|
112
123
|
return acc;
|
|
@@ -116,15 +127,14 @@ function getIntermediateRepresentation(transformations, skipValidation) {
|
|
|
116
127
|
const duplicates = transformations
|
|
117
128
|
.filter(t => t.intermediateRepresentation?.uid === uid)
|
|
118
129
|
.map(t => t.fileParseResult.file);
|
|
119
|
-
throw new Error(
|
|
130
|
+
throw new Error(errorMessages.project.duplicateUid(uid, duplicates));
|
|
120
131
|
}
|
|
121
132
|
if (!skipValidation) {
|
|
122
133
|
return {
|
|
123
134
|
...acc,
|
|
124
135
|
// If the uid is not defined just make one up for the sake of indexing.
|
|
125
136
|
// It will still fail validation, but this prevents collisions so we validate all files.
|
|
126
|
-
[uid ||
|
|
127
|
-
`missing-${current.fileParseResult.file}`]: current.intermediateRepresentation,
|
|
137
|
+
[uid || `missing-${current.fileParseResult.file}`]: current.intermediateRepresentation,
|
|
128
138
|
};
|
|
129
139
|
}
|
|
130
140
|
return {
|
|
@@ -132,17 +142,55 @@ function getIntermediateRepresentation(transformations, skipValidation) {
|
|
|
132
142
|
[uid]: current.intermediateRepresentation,
|
|
133
143
|
};
|
|
134
144
|
}, {});
|
|
145
|
+
const profileData = getProfileData(hsProfileContents);
|
|
135
146
|
return {
|
|
136
147
|
intermediateNodesIndexedByUid: nodes,
|
|
148
|
+
profileData,
|
|
137
149
|
};
|
|
138
150
|
}
|
|
139
|
-
function
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
151
|
+
export function getParsingErrors(transformations) {
|
|
152
|
+
return transformations
|
|
153
|
+
.filter(t => t.fileParseResult.errors.length > 0)
|
|
154
|
+
.map(t => t.fileParseResult);
|
|
155
|
+
}
|
|
156
|
+
function getProfileData(hsProfileContents) {
|
|
157
|
+
const profileVariablesForBE = {};
|
|
158
|
+
if (hsProfileContents && hsProfileContents.variables) {
|
|
159
|
+
const profileVariables = getHsProfileVariables(hsProfileContents);
|
|
160
|
+
Object.keys(profileVariables).forEach(key => {
|
|
161
|
+
const profileVar = profileVariables[key];
|
|
162
|
+
let variableTypeForBE;
|
|
163
|
+
switch (typeof profileVar) {
|
|
164
|
+
case 'string':
|
|
165
|
+
variableTypeForBE = PROFILE_VARIABLE_TYPES.PROFILE_STRING;
|
|
166
|
+
break;
|
|
167
|
+
case 'number':
|
|
168
|
+
variableTypeForBE = getJavaNumberType(profileVar);
|
|
169
|
+
break;
|
|
170
|
+
case 'boolean':
|
|
171
|
+
variableTypeForBE = PROFILE_VARIABLE_TYPES.PROFILE_BOOLEAN;
|
|
172
|
+
break;
|
|
173
|
+
default:
|
|
174
|
+
break;
|
|
175
|
+
}
|
|
176
|
+
if (variableTypeForBE) {
|
|
177
|
+
profileVariablesForBE[key] = {
|
|
178
|
+
variableType: variableTypeForBE,
|
|
179
|
+
value: profileVar,
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
return { vars: { profileVariables: profileVariablesForBE } };
|
|
185
|
+
}
|
|
186
|
+
export function generateServerlessPackageComponent(appFunctionsDirectory, translationContext, componentDeps) {
|
|
187
|
+
const appFunctionsPosix = convertPathToPosixPath(appFunctionsDirectory);
|
|
188
|
+
const packageFilePosix = path.posix.join(appFunctionsPosix, PACKAGE_JSON);
|
|
189
|
+
const packageLockFilePosix = path.posix.join(appFunctionsPosix, PACKAGE_LOCK_JSON);
|
|
190
|
+
const projectSourceDirPosix = convertPathToPosixPath(translationContext.projectSourceDir);
|
|
191
|
+
const appFunctionsPackageFile = path.posix.join(projectSourceDirPosix, packageFilePosix);
|
|
192
|
+
if (!fs.existsSync(appFunctionsPackageFile)) {
|
|
193
|
+
throw new Error(errorMessages.project.noPackageJsonForServerless(appFunctionsPackageFile));
|
|
146
194
|
}
|
|
147
195
|
const uid = `hubspot-serverless-package-uid`;
|
|
148
196
|
return {
|
|
@@ -154,15 +202,17 @@ function generateServerlessPackageComponent(appFunctionsDirectory, translationCo
|
|
|
154
202
|
},
|
|
155
203
|
intermediateRepresentation: {
|
|
156
204
|
uid,
|
|
157
|
-
componentType: mapToInternalType(
|
|
205
|
+
componentType: mapToInternalType(APP_FUNCTIONS_PACKAGE_KEY),
|
|
158
206
|
config: {
|
|
159
|
-
packageFile,
|
|
160
|
-
packageLockfile:
|
|
161
|
-
|
|
207
|
+
packageFile: packageFilePosix,
|
|
208
|
+
packageLockfile: fs.existsSync(
|
|
209
|
+
// Don't use posix here because we are checking the file system
|
|
210
|
+
path.join(translationContext.projectSourceDir, path.join(appFunctionsDirectory, PACKAGE_LOCK_JSON)))
|
|
211
|
+
? packageLockFilePosix
|
|
162
212
|
: undefined,
|
|
163
213
|
},
|
|
164
214
|
componentDeps,
|
|
165
|
-
metaFilePath:
|
|
215
|
+
metaFilePath: packageFilePosix,
|
|
166
216
|
files: {},
|
|
167
217
|
},
|
|
168
218
|
},
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { IntermediateRepresentation, IntermediateRepresentationLocalDev, TranslationContext, TranslationOptions, TranslationOptionsLocalDev } from './types.js';
|
|
2
|
+
export interface TranslateResult {
|
|
3
|
+
intermediateRepresentation: IntermediateRepresentation;
|
|
4
|
+
skippedHsMetaFiles: string[];
|
|
5
|
+
}
|
|
6
|
+
export interface TranslateForLocalDevResult {
|
|
7
|
+
intermediateRepresentation: IntermediateRepresentationLocalDev;
|
|
8
|
+
skippedHsMetaFiles: string[];
|
|
9
|
+
}
|
|
10
|
+
export declare function translate(translationContext: TranslationContext, translationOptions?: TranslationOptions): Promise<TranslateResult>;
|
|
11
|
+
export declare function translateForLocalDev(translationContext: TranslationContext, translationOptions?: TranslationOptionsLocalDev): Promise<TranslateForLocalDevResult>;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { loadHsProfileFile, loadHsMetaFiles } from './files.js';
|
|
2
|
+
import { validateIntermediateRepresentation } from './validation.js';
|
|
3
|
+
import { getIntermediateRepresentation, getParsingErrors, transform, } from './transform.js';
|
|
4
|
+
import { errorMessages } from '../lang/copy.js';
|
|
5
|
+
import { getLocalDevProfileData, getLocalDevProjectNodes, getRemovedNodesAndNodesWithErrors, } from './localDev.js';
|
|
6
|
+
import { isKnownPlatformVersion } from './platformVersion.js';
|
|
7
|
+
const defaultOptions = {
|
|
8
|
+
skipValidation: false,
|
|
9
|
+
};
|
|
10
|
+
export async function translate(translationContext, translationOptions = defaultOptions) {
|
|
11
|
+
const { skipValidation, profile } = translationOptions;
|
|
12
|
+
if (!skipValidation &&
|
|
13
|
+
!isKnownPlatformVersion(translationContext.platformVersion)) {
|
|
14
|
+
throw new Error(errorMessages.project.unsupportedPlatformVersion(translationContext.platformVersion));
|
|
15
|
+
}
|
|
16
|
+
const { results: metafileContents, skippedFiles } = await loadHsMetaFiles(translationContext);
|
|
17
|
+
if (metafileContents.length === 0) {
|
|
18
|
+
throw new Error(errorMessages.project.noHsMetaFiles);
|
|
19
|
+
}
|
|
20
|
+
let hsProfileContents;
|
|
21
|
+
if (profile) {
|
|
22
|
+
hsProfileContents = loadHsProfileFile(translationContext.projectSourceDir, profile);
|
|
23
|
+
}
|
|
24
|
+
const transformations = transform(metafileContents, translationContext, hsProfileContents);
|
|
25
|
+
const intermediateRepresentation = getIntermediateRepresentation(transformations, hsProfileContents, skipValidation);
|
|
26
|
+
// Remove once extensions and serverless functions are supported
|
|
27
|
+
if (!skipValidation) {
|
|
28
|
+
await validateIntermediateRepresentation(intermediateRepresentation, transformations, translationContext);
|
|
29
|
+
}
|
|
30
|
+
return { intermediateRepresentation, skippedHsMetaFiles: skippedFiles };
|
|
31
|
+
}
|
|
32
|
+
export async function translateForLocalDev(translationContext, translationOptions) {
|
|
33
|
+
const { skipValidation, profile, projectNodesAtLastUpload } = translationOptions || {};
|
|
34
|
+
if (!skipValidation &&
|
|
35
|
+
!isKnownPlatformVersion(translationContext.platformVersion)) {
|
|
36
|
+
throw new Error(errorMessages.project.unsupportedPlatformVersion(translationContext.platformVersion));
|
|
37
|
+
}
|
|
38
|
+
const { results: metafileContents, skippedFiles } = await loadHsMetaFiles(translationContext);
|
|
39
|
+
if (metafileContents.length === 0) {
|
|
40
|
+
throw new Error(errorMessages.project.noHsMetaFiles);
|
|
41
|
+
}
|
|
42
|
+
let hsProfileContents;
|
|
43
|
+
if (profile) {
|
|
44
|
+
hsProfileContents = loadHsProfileFile(translationContext.projectSourceDir, profile);
|
|
45
|
+
}
|
|
46
|
+
const transformation = transform(metafileContents, translationContext, hsProfileContents);
|
|
47
|
+
const baseIntermediateRepresentation = getIntermediateRepresentation(transformation, hsProfileContents, true);
|
|
48
|
+
const parsingErrors = getParsingErrors(transformation);
|
|
49
|
+
const projectNodes = getLocalDevProjectNodes(baseIntermediateRepresentation.intermediateNodesIndexedByUid, translationContext.projectSourceDir, projectNodesAtLastUpload);
|
|
50
|
+
let projectNodesWithErrors = {};
|
|
51
|
+
if (projectNodesAtLastUpload) {
|
|
52
|
+
projectNodesWithErrors = getRemovedNodesAndNodesWithErrors(baseIntermediateRepresentation.intermediateNodesIndexedByUid, projectNodesAtLastUpload, parsingErrors);
|
|
53
|
+
}
|
|
54
|
+
const profileData = getLocalDevProfileData(baseIntermediateRepresentation.profileData?.vars.profileVariables);
|
|
55
|
+
return {
|
|
56
|
+
intermediateRepresentation: {
|
|
57
|
+
intermediateNodesIndexedByUid: {
|
|
58
|
+
...projectNodes,
|
|
59
|
+
...projectNodesWithErrors,
|
|
60
|
+
},
|
|
61
|
+
profileData,
|
|
62
|
+
},
|
|
63
|
+
skippedHsMetaFiles: skippedFiles,
|
|
64
|
+
};
|
|
65
|
+
}
|
package/src/lib/types.d.ts
CHANGED
|
@@ -1,10 +1,16 @@
|
|
|
1
|
-
import { ErrorObject } from 'ajv
|
|
1
|
+
import type { ErrorObject } from 'ajv';
|
|
2
2
|
export type Dependencies = Record<string, string | string[]>;
|
|
3
|
-
export interface
|
|
3
|
+
export interface ComponentPermissions {
|
|
4
|
+
requiredScopes?: string[];
|
|
5
|
+
optionalScopes?: string[];
|
|
6
|
+
conditionallyRequiredScopes?: string[];
|
|
7
|
+
}
|
|
8
|
+
export interface ComponentMeta {
|
|
4
9
|
uid: string;
|
|
5
10
|
type: string;
|
|
6
11
|
config: unknown;
|
|
7
12
|
dependencies?: Dependencies;
|
|
13
|
+
permissions?: ComponentPermissions;
|
|
8
14
|
}
|
|
9
15
|
export interface FileActionResult {
|
|
10
16
|
file: string;
|
|
@@ -15,7 +21,7 @@ export interface FileLoadResult extends FileActionResult {
|
|
|
15
21
|
content?: string;
|
|
16
22
|
}
|
|
17
23
|
export interface FileParseResult extends FileActionResult {
|
|
18
|
-
content?:
|
|
24
|
+
content?: ComponentMeta;
|
|
19
25
|
}
|
|
20
26
|
export interface IntermediateRepresentationNode {
|
|
21
27
|
componentType: string;
|
|
@@ -24,22 +30,39 @@ export interface IntermediateRepresentationNode {
|
|
|
24
30
|
uid: string;
|
|
25
31
|
config: unknown;
|
|
26
32
|
files: unknown;
|
|
33
|
+
permissions?: ComponentPermissions;
|
|
34
|
+
}
|
|
35
|
+
export type BEProfileVariableType = 'PROFILE_INT' | 'PROFILE_LONG' | 'PROFILE_STRING' | 'PROFILE_BOOLEAN';
|
|
36
|
+
export interface BEProfileVariables {
|
|
37
|
+
[key: string]: {
|
|
38
|
+
variableType: BEProfileVariableType;
|
|
39
|
+
value: HSProfileVariableType;
|
|
40
|
+
};
|
|
27
41
|
}
|
|
28
42
|
export interface IntermediateRepresentation {
|
|
29
43
|
intermediateNodesIndexedByUid: {
|
|
30
44
|
[key: string]: IntermediateRepresentationNode;
|
|
31
45
|
};
|
|
46
|
+
profileData?: {
|
|
47
|
+
vars: {
|
|
48
|
+
profileVariables: BEProfileVariables;
|
|
49
|
+
};
|
|
50
|
+
};
|
|
32
51
|
}
|
|
33
52
|
export interface IntermediateRepresentationNodeLocalDev extends IntermediateRepresentationNode {
|
|
34
53
|
localDev: {
|
|
35
54
|
componentRoot: string;
|
|
36
55
|
componentConfigPath: string;
|
|
56
|
+
configUpdatedSinceLastUpload: boolean;
|
|
57
|
+
removed: boolean;
|
|
58
|
+
parsingErrors: string[];
|
|
37
59
|
};
|
|
38
60
|
}
|
|
39
61
|
export interface IntermediateRepresentationLocalDev {
|
|
40
62
|
intermediateNodesIndexedByUid: {
|
|
41
63
|
[key: string]: IntermediateRepresentationNodeLocalDev;
|
|
42
64
|
};
|
|
65
|
+
profileData: HSProfileVariables;
|
|
43
66
|
}
|
|
44
67
|
export type Transformation = {
|
|
45
68
|
intermediateRepresentation?: IntermediateRepresentationNode | null;
|
|
@@ -49,6 +72,12 @@ export type Transformation = {
|
|
|
49
72
|
export type CompiledError = {
|
|
50
73
|
errors: string[];
|
|
51
74
|
};
|
|
75
|
+
export interface ProjectConfig {
|
|
76
|
+
name: string;
|
|
77
|
+
srcDir: string;
|
|
78
|
+
platformVersion: string;
|
|
79
|
+
[key: string]: unknown;
|
|
80
|
+
}
|
|
52
81
|
export interface TranslationContext {
|
|
53
82
|
projectSourceDir: string;
|
|
54
83
|
platformVersion: string;
|
|
@@ -58,9 +87,17 @@ export interface TranslationOptions {
|
|
|
58
87
|
skipValidation?: boolean;
|
|
59
88
|
profile?: string;
|
|
60
89
|
}
|
|
90
|
+
export interface TranslationOptionsLocalDev extends TranslationOptions {
|
|
91
|
+
projectNodesAtLastUpload?: {
|
|
92
|
+
[key: string]: IntermediateRepresentationNodeLocalDev;
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
type HSProfileVariableType = string | number | boolean;
|
|
96
|
+
export type HSProfileVariables = {
|
|
97
|
+
[key: string]: HSProfileVariableType;
|
|
98
|
+
};
|
|
61
99
|
export interface HsProfileFile {
|
|
62
100
|
accountId: number;
|
|
63
|
-
variables?:
|
|
64
|
-
[key: string]: string | number | boolean;
|
|
65
|
-
};
|
|
101
|
+
variables?: HSProfileVariables;
|
|
66
102
|
}
|
|
103
|
+
export {};
|
package/src/lib/types.js
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
1
|
+
export {};
|
package/src/lib/uid.d.ts
CHANGED
package/src/lib/uid.js
CHANGED
|
@@ -1,15 +1,20 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
const copy_1 = require("../lang/copy");
|
|
5
|
-
function validateUid(uid) {
|
|
1
|
+
import { errorMessages } from '../lang/copy.js';
|
|
2
|
+
export const MAX_UID_LENGTH = 64;
|
|
3
|
+
export function validateUid(uid) {
|
|
6
4
|
if (uid === '' || !uid) {
|
|
7
|
-
return
|
|
5
|
+
return errorMessages.validation.emptyUid;
|
|
8
6
|
}
|
|
9
|
-
if (uid.length >
|
|
10
|
-
return
|
|
7
|
+
if (uid.length > MAX_UID_LENGTH) {
|
|
8
|
+
return errorMessages.validation.uidTooLong;
|
|
11
9
|
}
|
|
12
10
|
if (!/^[a-zA-Z0-9_\-.]+$/.test(uid)) {
|
|
13
|
-
return
|
|
11
|
+
return errorMessages.validation.invalidUid;
|
|
14
12
|
}
|
|
15
13
|
}
|
|
14
|
+
export function coerceToValidUid(potentialUid) {
|
|
15
|
+
if (typeof potentialUid !== 'string') {
|
|
16
|
+
return undefined;
|
|
17
|
+
}
|
|
18
|
+
const newUid = potentialUid.replace(/[^a-zA-Z0-9_\-.]/g, '');
|
|
19
|
+
return newUid.length === 0 ? undefined : newUid.substring(0, MAX_UID_LENGTH);
|
|
20
|
+
}
|
package/src/lib/utils.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import { PROFILE_VARIABLE_TYPES } from './constants.js';
|
|
3
|
+
export function loadJsonFile(filename) {
|
|
4
|
+
return JSON.parse(fs.readFileSync(filename, {
|
|
5
|
+
encoding: 'utf-8',
|
|
6
|
+
}));
|
|
7
|
+
}
|
|
8
|
+
export function getJavaNumberType(value) {
|
|
9
|
+
const JAVA_INT_MIN = -2_147_483_648;
|
|
10
|
+
const JAVA_INT_MAX = 2_147_483_647;
|
|
11
|
+
// Check if the value fits in Java int range
|
|
12
|
+
if (value >= JAVA_INT_MIN && value <= JAVA_INT_MAX) {
|
|
13
|
+
return PROFILE_VARIABLE_TYPES.PROFILE_INT;
|
|
14
|
+
}
|
|
15
|
+
return PROFILE_VARIABLE_TYPES.PROFILE_LONG;
|
|
16
|
+
}
|
package/src/lib/validation.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { CompiledError, IntermediateRepresentation, Transformation, TranslationContext } from './types';
|
|
2
|
-
import
|
|
1
|
+
import { CompiledError, IntermediateRepresentation, Transformation, TranslationContext } from './types.js';
|
|
2
|
+
import { Ajv2020, ValidateFunction } from 'ajv/dist/2020.js';
|
|
3
3
|
export type ValidResult = {
|
|
4
4
|
valid: true;
|
|
5
5
|
errors?: null;
|
|
@@ -10,5 +10,5 @@ export type ValidationResults = {
|
|
|
10
10
|
errors?: CompiledError;
|
|
11
11
|
schemaValidationErrors?: ValidateFunction['errors'];
|
|
12
12
|
} | ValidResult;
|
|
13
|
-
export declare function createAjvInstance():
|
|
14
|
-
export declare function validateIntermediateRepresentation(intermediateRepresentation: IntermediateRepresentation,
|
|
13
|
+
export declare function createAjvInstance(): Ajv2020;
|
|
14
|
+
export declare function validateIntermediateRepresentation(intermediateRepresentation: IntermediateRepresentation, transformations: Transformation[], translationContext: TranslationContext): Promise<ValidResult>;
|