@hubspot/project-parsing-lib 0.2.0-beta.1 → 0.2.0-experimental.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/README.md +4 -35
- package/package.json +54 -19
- package/src/exports/constants.d.ts +1 -0
- package/src/exports/constants.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 +3 -0
- package/src/exports/projects.js +2 -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 +3 -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/lang/copy.d.ts +7 -1
- package/src/lang/copy.js +29 -33
- package/src/lib/constants.d.ts +45 -28
- package/src/lib/constants.js +160 -121
- package/src/lib/errors.d.ts +4 -3
- package/src/lib/errors.js +62 -38
- package/src/lib/files.d.ts +10 -1
- package/src/lib/files.js +51 -40
- package/src/lib/localDev.d.ts +4 -0
- package/src/lib/localDev.js +72 -0
- package/src/lib/migrate.js +32 -42
- package/src/lib/migrateThemes.d.ts +25 -0
- package/src/lib/migrateThemes.js +120 -0
- package/src/lib/profiles.d.ts +6 -1
- package/src/lib/profiles.js +95 -40
- package/src/lib/project.d.ts +13 -0
- package/src/lib/project.js +29 -0
- 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 +100 -53
- package/src/lib/translate.d.ts +3 -0
- package/src/lib/translate.js +52 -0
- package/src/lib/types.d.ts +28 -4
- 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 +61 -53
- package/src/index.d.ts +0 -18
- package/src/index.js +0 -86
package/src/lib/constants.js
CHANGED
|
@@ -1,183 +1,222 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.allowedSubComponentDirectories = exports.allowedComponentDirectories = exports.ProjectStructure = exports.allowedThemeSubComponentsDirs = exports.allowedAppSubComponentsDirs = exports.packageLockJson = exports.packageJson = exports.hsProjectJsonFilename = exports.profileFilePrefix = exports.metafileExtension = exports.internalTypeToUserFacing = exports.userFacingToInternalType = exports.Components = exports.AutoGeneratedComponentTypes = exports.AppFunctionsPackageKey = exports.WorkflowActionsKey = exports.WebhooksKey = exports.VideoConferencingKey = exports.TimelineEventsKey = exports.MediaBridgeKey = exports.MarketingEventsKey = exports.SettingsKey = exports.CardsKey = exports.CallingKey = exports.AppObjectAssociationKey = exports.AppObjectKey = exports.AppFunctionsKey = exports.ThemeKey = exports.AppKey = void 0;
|
|
37
1
|
// Top Level Component types
|
|
38
|
-
|
|
2
|
+
import * as path from 'path';
|
|
39
3
|
// Component types
|
|
40
|
-
|
|
41
|
-
|
|
4
|
+
export const APP_KEY = 'app';
|
|
5
|
+
export const THEME_KEY = 'theme';
|
|
6
|
+
export const CMS_ASSETS_KEY = 'cms-assets';
|
|
42
7
|
// Sub-Component types
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
8
|
+
export const APP_EVENTS_KEY = 'app-event';
|
|
9
|
+
export const APP_FUNCTIONS_KEY = 'app-function';
|
|
10
|
+
export const PAGE_KEY = 'page';
|
|
11
|
+
export const PAGES_KEY = 'pages';
|
|
12
|
+
export const APP_OBJECT_KEY = 'app-object';
|
|
13
|
+
export const APP_OBJECT_ASSOCIATION_KEY = 'app-object-association';
|
|
14
|
+
export const CALLING_KEY = 'calling';
|
|
15
|
+
export const CARDS_KEY = 'card';
|
|
16
|
+
export const SCIM_KEY = 'scim';
|
|
17
|
+
export const MARKETING_EVENTS_KEY = 'marketing-event';
|
|
18
|
+
export const MCP_REGISTRY_KEY = 'mcp-registry';
|
|
19
|
+
export const MEDIA_BRIDGE_KEY = 'media-bridge';
|
|
20
|
+
export const SETTINGS_KEY = 'settings';
|
|
21
|
+
export const TELEMETRY_KEY = 'telemetry';
|
|
22
|
+
export const VIDEO_CONFERENCING_KEY = 'video-conferencing';
|
|
23
|
+
export const WEBHOOKS_KEY = 'webhooks';
|
|
24
|
+
export const WEBHOOKS_JOURNAL_KEY = 'webhooks-journal';
|
|
25
|
+
export const WORKFLOW_ACTIONS_KEY = 'workflow-action';
|
|
55
26
|
// Auto-generated component types
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
const
|
|
27
|
+
export const APP_FUNCTIONS_PACKAGE_KEY = 'serverless-package';
|
|
28
|
+
export const AUTO_GENERATED_COMPONENT_TYPES = [APP_FUNCTIONS_PACKAGE_KEY];
|
|
29
|
+
const TOP_LEVEL_COMPONENT_FIELDS = {
|
|
59
30
|
isToplevel: true,
|
|
60
31
|
userFriendlyType: 'component',
|
|
61
32
|
userFriendlyTypePlural: 'components',
|
|
62
33
|
};
|
|
63
|
-
const
|
|
34
|
+
const SUB_COMPONENT_FIELDS = {
|
|
64
35
|
isToplevel: false,
|
|
65
36
|
userFriendlyType: 'feature',
|
|
66
37
|
userFriendlyTypePlural: 'features',
|
|
67
38
|
};
|
|
68
|
-
|
|
69
|
-
[
|
|
70
|
-
dir:
|
|
39
|
+
export const Components = {
|
|
40
|
+
[APP_KEY]: {
|
|
41
|
+
dir: APP_KEY,
|
|
71
42
|
userFriendlyName: 'App',
|
|
72
|
-
...
|
|
43
|
+
...TOP_LEVEL_COMPONENT_FIELDS,
|
|
73
44
|
singularComponent: true,
|
|
74
45
|
},
|
|
75
|
-
[
|
|
46
|
+
[APP_OBJECT_KEY]: {
|
|
76
47
|
dir: 'app-objects',
|
|
77
|
-
parentComponent:
|
|
78
|
-
...
|
|
48
|
+
parentComponent: APP_KEY,
|
|
49
|
+
...SUB_COMPONENT_FIELDS,
|
|
79
50
|
userFriendlyName: 'App Object',
|
|
80
51
|
},
|
|
81
|
-
[
|
|
52
|
+
[APP_OBJECT_ASSOCIATION_KEY]: {
|
|
82
53
|
dir: 'app-object-associations',
|
|
83
|
-
parentComponent:
|
|
84
|
-
...
|
|
54
|
+
parentComponent: APP_KEY,
|
|
55
|
+
...SUB_COMPONENT_FIELDS,
|
|
85
56
|
userFriendlyName: 'App Object Association',
|
|
86
57
|
},
|
|
87
|
-
[
|
|
88
|
-
dir:
|
|
58
|
+
[PAGE_KEY]: {
|
|
59
|
+
dir: 'pages',
|
|
60
|
+
parentComponent: APP_KEY,
|
|
61
|
+
...SUB_COMPONENT_FIELDS,
|
|
62
|
+
userFriendlyName: 'Page',
|
|
63
|
+
singularComponent: true,
|
|
64
|
+
},
|
|
65
|
+
[PAGES_KEY]: {
|
|
66
|
+
dir: 'pages',
|
|
67
|
+
parentComponent: APP_KEY,
|
|
68
|
+
...SUB_COMPONENT_FIELDS,
|
|
69
|
+
userFriendlyName: 'Pages',
|
|
70
|
+
singularComponent: true,
|
|
71
|
+
},
|
|
72
|
+
[THEME_KEY]: {
|
|
73
|
+
dir: THEME_KEY,
|
|
89
74
|
userFriendlyName: 'Theme',
|
|
90
|
-
...
|
|
75
|
+
...TOP_LEVEL_COMPONENT_FIELDS,
|
|
91
76
|
},
|
|
92
|
-
[
|
|
93
|
-
dir:
|
|
94
|
-
|
|
77
|
+
[CMS_ASSETS_KEY]: {
|
|
78
|
+
dir: CMS_ASSETS_KEY,
|
|
79
|
+
userFriendlyName: 'CMS Asset',
|
|
80
|
+
...TOP_LEVEL_COMPONENT_FIELDS,
|
|
81
|
+
},
|
|
82
|
+
[CALLING_KEY]: {
|
|
83
|
+
dir: CALLING_KEY,
|
|
84
|
+
parentComponent: APP_KEY,
|
|
95
85
|
userFriendlyName: 'Calling',
|
|
96
|
-
...
|
|
86
|
+
...SUB_COMPONENT_FIELDS,
|
|
97
87
|
singularComponent: true,
|
|
98
88
|
},
|
|
99
|
-
[
|
|
89
|
+
[CARDS_KEY]: {
|
|
100
90
|
dir: 'cards',
|
|
101
|
-
parentComponent:
|
|
91
|
+
parentComponent: APP_KEY,
|
|
102
92
|
userFriendlyName: 'Card',
|
|
103
|
-
...
|
|
93
|
+
...SUB_COMPONENT_FIELDS,
|
|
104
94
|
},
|
|
105
|
-
[
|
|
95
|
+
[APP_FUNCTIONS_KEY]: {
|
|
106
96
|
dir: 'functions',
|
|
107
|
-
parentComponent:
|
|
97
|
+
parentComponent: APP_KEY,
|
|
108
98
|
userFriendlyName: 'App Function',
|
|
109
|
-
...
|
|
99
|
+
...SUB_COMPONENT_FIELDS,
|
|
100
|
+
},
|
|
101
|
+
[SCIM_KEY]: {
|
|
102
|
+
dir: SCIM_KEY,
|
|
103
|
+
parentComponent: APP_KEY,
|
|
104
|
+
userFriendlyName: 'SCIM',
|
|
105
|
+
singularComponent: true,
|
|
106
|
+
...SUB_COMPONENT_FIELDS,
|
|
110
107
|
},
|
|
111
|
-
[
|
|
108
|
+
[SETTINGS_KEY]: {
|
|
112
109
|
dir: 'settings',
|
|
113
|
-
parentComponent:
|
|
110
|
+
parentComponent: APP_KEY,
|
|
114
111
|
userFriendlyName: 'Settings Extension',
|
|
115
|
-
...
|
|
112
|
+
...SUB_COMPONENT_FIELDS,
|
|
116
113
|
singularComponent: true,
|
|
117
114
|
},
|
|
118
|
-
[
|
|
115
|
+
[MARKETING_EVENTS_KEY]: {
|
|
119
116
|
dir: 'marketing-events',
|
|
120
|
-
parentComponent:
|
|
117
|
+
parentComponent: APP_KEY,
|
|
121
118
|
userFriendlyName: 'Marketing Event',
|
|
122
|
-
...
|
|
119
|
+
...SUB_COMPONENT_FIELDS,
|
|
123
120
|
},
|
|
124
|
-
|
|
125
|
-
dir:
|
|
126
|
-
parentComponent:
|
|
121
|
+
[MEDIA_BRIDGE_KEY]: {
|
|
122
|
+
dir: MEDIA_BRIDGE_KEY,
|
|
123
|
+
parentComponent: APP_KEY,
|
|
127
124
|
userFriendlyName: 'Media Bridge',
|
|
128
|
-
...
|
|
125
|
+
...SUB_COMPONENT_FIELDS,
|
|
129
126
|
},
|
|
130
|
-
[
|
|
131
|
-
dir: '
|
|
132
|
-
parentComponent:
|
|
133
|
-
userFriendlyName: '
|
|
134
|
-
...
|
|
127
|
+
[APP_EVENTS_KEY]: {
|
|
128
|
+
dir: 'app-events',
|
|
129
|
+
parentComponent: APP_KEY,
|
|
130
|
+
userFriendlyName: 'App Event',
|
|
131
|
+
...SUB_COMPONENT_FIELDS,
|
|
135
132
|
},
|
|
136
|
-
[
|
|
137
|
-
dir:
|
|
138
|
-
parentComponent:
|
|
133
|
+
[VIDEO_CONFERENCING_KEY]: {
|
|
134
|
+
dir: VIDEO_CONFERENCING_KEY,
|
|
135
|
+
parentComponent: APP_KEY,
|
|
139
136
|
userFriendlyName: 'Video Conferencing',
|
|
140
|
-
...
|
|
137
|
+
...SUB_COMPONENT_FIELDS,
|
|
141
138
|
},
|
|
142
|
-
[
|
|
143
|
-
dir:
|
|
144
|
-
parentComponent:
|
|
139
|
+
[WEBHOOKS_KEY]: {
|
|
140
|
+
dir: WEBHOOKS_KEY,
|
|
141
|
+
parentComponent: APP_KEY,
|
|
145
142
|
userFriendlyName: 'Webhooks',
|
|
146
|
-
...
|
|
143
|
+
...SUB_COMPONENT_FIELDS,
|
|
147
144
|
singularComponent: true,
|
|
148
145
|
},
|
|
149
|
-
[
|
|
146
|
+
[WEBHOOKS_JOURNAL_KEY]: {
|
|
147
|
+
dir: WEBHOOKS_JOURNAL_KEY,
|
|
148
|
+
parentComponent: APP_KEY,
|
|
149
|
+
userFriendlyName: 'Webhooks Journal',
|
|
150
|
+
...SUB_COMPONENT_FIELDS,
|
|
151
|
+
singularComponent: true,
|
|
152
|
+
},
|
|
153
|
+
[WORKFLOW_ACTIONS_KEY]: {
|
|
150
154
|
dir: 'workflow-actions',
|
|
151
|
-
parentComponent:
|
|
155
|
+
parentComponent: APP_KEY,
|
|
152
156
|
userFriendlyName: 'Workflow Action',
|
|
153
|
-
...
|
|
157
|
+
...SUB_COMPONENT_FIELDS,
|
|
158
|
+
},
|
|
159
|
+
[TELEMETRY_KEY]: {
|
|
160
|
+
dir: TELEMETRY_KEY,
|
|
161
|
+
parentComponent: APP_KEY,
|
|
162
|
+
userFriendlyName: 'Telemetry',
|
|
163
|
+
singularComponent: true,
|
|
164
|
+
...SUB_COMPONENT_FIELDS,
|
|
165
|
+
},
|
|
166
|
+
[MCP_REGISTRY_KEY]: {
|
|
167
|
+
dir: MCP_REGISTRY_KEY,
|
|
168
|
+
parentComponent: APP_KEY,
|
|
169
|
+
userFriendlyName: 'MCP Registry',
|
|
170
|
+
singularComponent: true,
|
|
171
|
+
...SUB_COMPONENT_FIELDS,
|
|
154
172
|
},
|
|
155
173
|
};
|
|
156
|
-
const
|
|
157
|
-
|
|
158
|
-
[
|
|
174
|
+
export const USER_FACING_TO_INTERNAL_TYPE = {
|
|
175
|
+
[APP_KEY]: 'APPLICATION',
|
|
176
|
+
[SCIM_KEY]: 'SCIM_INTEGRATION',
|
|
177
|
+
[TELEMETRY_KEY]: 'TELEMETRY_CONFIG',
|
|
178
|
+
[CMS_ASSETS_KEY]: 'REACT_THEME',
|
|
179
|
+
[PAGES_KEY]: 'PAGE',
|
|
159
180
|
};
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
181
|
+
export const INTERNAL_TYPE_TO_USER_FACING = Object.fromEntries(Object.entries(USER_FACING_TO_INTERNAL_TYPE).map(([key, value]) => [
|
|
182
|
+
value,
|
|
183
|
+
key,
|
|
184
|
+
]));
|
|
185
|
+
export const METAFILE_EXTENSION = '-hsmeta.json';
|
|
186
|
+
export const PROFILE_FILE_PREFIX = 'hsprofile';
|
|
187
|
+
export const HS_PROJECT_JSON_FILENAME = 'hsproject.json';
|
|
188
|
+
export const PACKAGE_JSON = 'package.json';
|
|
189
|
+
export const PACKAGE_LOCK_JSON = 'package-lock.json';
|
|
166
190
|
function getSubComponentDirsForParentType(parentComponent) {
|
|
167
|
-
return Object.values(
|
|
191
|
+
return Object.values(Components).reduce((acc, item) => {
|
|
168
192
|
if (item.parentComponent === parentComponent) {
|
|
169
193
|
acc.push(item.dir);
|
|
170
194
|
}
|
|
171
195
|
return acc;
|
|
172
196
|
}, []);
|
|
173
197
|
}
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
[
|
|
198
|
+
export const ALLOWED_APP_SUB_COMPONENTS_DIRS = getSubComponentDirsForParentType(APP_KEY);
|
|
199
|
+
export const ALLOWED_THEME_SUB_COMPONENTS_DIRS = getSubComponentDirsForParentType(THEME_KEY);
|
|
200
|
+
export const ALLOWED_CMS_ASSET_SUB_COMPONENT_DIRS = getSubComponentDirsForParentType(CMS_ASSETS_KEY);
|
|
201
|
+
export const PROJECT_STRUCTURE = {
|
|
202
|
+
[APP_KEY]: ALLOWED_APP_SUB_COMPONENTS_DIRS,
|
|
203
|
+
[THEME_KEY]: ALLOWED_THEME_SUB_COMPONENTS_DIRS,
|
|
204
|
+
[CMS_ASSETS_KEY]: ALLOWED_CMS_ASSET_SUB_COMPONENT_DIRS,
|
|
179
205
|
};
|
|
180
|
-
|
|
181
|
-
|
|
206
|
+
export const ALLOWED_COMPONENT_DIRECTORIES = Object.keys(PROJECT_STRUCTURE);
|
|
207
|
+
export const ALLOWED_SUB_COMPONENT_DIRECTORIES = Object.entries(PROJECT_STRUCTURE)
|
|
182
208
|
.map(([key, value]) => value.map((value) => path.join(key, value)))
|
|
183
209
|
.flat();
|
|
210
|
+
// Profile variable types
|
|
211
|
+
export const PROFILE_VARIABLE_TYPES = {
|
|
212
|
+
PROFILE_INT: 'PROFILE_INT',
|
|
213
|
+
PROFILE_LONG: 'PROFILE_LONG',
|
|
214
|
+
PROFILE_STRING: 'PROFILE_STRING',
|
|
215
|
+
PROFILE_BOOLEAN: 'PROFILE_BOOLEAN',
|
|
216
|
+
};
|
|
217
|
+
export const ALLOWED_TOP_LEVEL_FIELDS = new Set([
|
|
218
|
+
'uid',
|
|
219
|
+
'type',
|
|
220
|
+
'config',
|
|
221
|
+
'dependencies',
|
|
222
|
+
]);
|
package/src/lib/errors.d.ts
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
|
-
import { CompiledError, Transformation, TranslationContext } from './types';
|
|
2
|
-
import { ErrorObject } from 'ajv
|
|
1
|
+
import { CompiledError, Transformation, TranslationContext } from './types.js';
|
|
2
|
+
import type { ErrorObject } from 'ajv';
|
|
3
3
|
export declare function isTranslationError(error: unknown): error is TranslationError;
|
|
4
4
|
export declare function compileError(validatedTransformation: Transformation): CompiledError;
|
|
5
5
|
export declare class TranslationError extends Error {
|
|
6
6
|
private errors;
|
|
7
7
|
private translationContext;
|
|
8
8
|
constructor(message: string, transformations: Transformation[], errors: (ErrorObject[] | null | undefined)[], translationContext: TranslationContext);
|
|
9
|
-
toString(): string;
|
|
9
|
+
toString(includeMessage?: boolean): string;
|
|
10
10
|
}
|
|
11
|
+
export declare function extractDotNotationValueFromTransformation(dotNotation: string, transformation: Transformation): unknown;
|
|
11
12
|
export declare const AjvErrorKeyword: {
|
|
12
13
|
AdditionalItems: string;
|
|
13
14
|
AdditionalProperties: string;
|
package/src/lib/errors.js
CHANGED
|
@@ -1,24 +1,17 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.AjvErrorKeyword = exports.TranslationError = void 0;
|
|
7
|
-
exports.isTranslationError = isTranslationError;
|
|
8
|
-
exports.compileError = compileError;
|
|
9
|
-
const copy_1 = require("../lang/copy");
|
|
10
|
-
const path_1 = __importDefault(require("path"));
|
|
11
|
-
function isTranslationError(error) {
|
|
1
|
+
import { errorMessages } from '../lang/copy.js';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { logger } from '@hubspot/local-dev-lib/logger';
|
|
4
|
+
export function isTranslationError(error) {
|
|
12
5
|
return error instanceof TranslationError;
|
|
13
6
|
}
|
|
14
|
-
function compileError(validatedTransformation) {
|
|
7
|
+
export function compileError(validatedTransformation) {
|
|
15
8
|
const { fileParseResult } = validatedTransformation;
|
|
16
9
|
const { errors } = fileParseResult;
|
|
17
10
|
return {
|
|
18
11
|
errors,
|
|
19
12
|
};
|
|
20
13
|
}
|
|
21
|
-
class TranslationError extends Error {
|
|
14
|
+
export class TranslationError extends Error {
|
|
22
15
|
errors = [];
|
|
23
16
|
translationContext;
|
|
24
17
|
constructor(message, transformations, errors, translationContext) {
|
|
@@ -28,19 +21,22 @@ class TranslationError extends Error {
|
|
|
28
21
|
this.errors = transformations.map((transformation, index) => compileTranslationErrors(transformation, errors[index]));
|
|
29
22
|
}
|
|
30
23
|
// Returns a formatted string for all the errors in all the files
|
|
31
|
-
toString() {
|
|
24
|
+
toString(includeMessage = true) {
|
|
32
25
|
const listOfErrors = this.errors.map(({ file, errors }) => {
|
|
33
26
|
if (errors.length === 0) {
|
|
34
27
|
return null;
|
|
35
28
|
}
|
|
36
|
-
|
|
29
|
+
const projectRoot = path.dirname(path.dirname(this.translationContext.projectSourceDir));
|
|
30
|
+
const relativePath = path.relative(projectRoot, path.join(this.translationContext.projectSourceDir, file));
|
|
31
|
+
return errorMessages.validation.errorWithFileHeader(relativePath, errors);
|
|
37
32
|
});
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
.
|
|
33
|
+
const errorString = listOfErrors.filter(error => error !== null).join('');
|
|
34
|
+
if (includeMessage) {
|
|
35
|
+
return `${this.message}:${errorString}`;
|
|
36
|
+
}
|
|
37
|
+
return errorString.trimStart();
|
|
41
38
|
}
|
|
42
39
|
}
|
|
43
|
-
exports.TranslationError = TranslationError;
|
|
44
40
|
function generateDotNotationPath(error) {
|
|
45
41
|
const { instancePath } = error;
|
|
46
42
|
const errorPath = instancePath
|
|
@@ -61,16 +57,16 @@ function compileTranslationErrors(transformation, schemaErrors) {
|
|
|
61
57
|
// If there is a one of error, we need to preprocess the errors to group them by instancePath and keyword
|
|
62
58
|
// This allows us to group data from the errors that correspond to the same field
|
|
63
59
|
if (hasOneOfErrors) {
|
|
64
|
-
errors.push(...preprocessSpecialErrors(schemaErrors));
|
|
60
|
+
errors.push(...preprocessSpecialErrors(schemaErrors, transformation));
|
|
65
61
|
}
|
|
66
62
|
else {
|
|
67
63
|
schemaErrors?.forEach(error => {
|
|
68
|
-
errors.push(generateErrorMessage(error));
|
|
64
|
+
errors.push(generateErrorMessage(error, transformation));
|
|
69
65
|
});
|
|
70
66
|
}
|
|
71
67
|
return { file, errors };
|
|
72
68
|
}
|
|
73
|
-
function preprocessSpecialErrors(schemaErrors) {
|
|
69
|
+
function preprocessSpecialErrors(schemaErrors, transformation) {
|
|
74
70
|
const errors = [];
|
|
75
71
|
const preprocessedErrors = {};
|
|
76
72
|
schemaErrors?.forEach(error => {
|
|
@@ -94,13 +90,13 @@ function preprocessSpecialErrors(schemaErrors) {
|
|
|
94
90
|
}
|
|
95
91
|
return cur;
|
|
96
92
|
});
|
|
97
|
-
errors.push(generateErrorMessage(newValue));
|
|
93
|
+
errors.push(generateErrorMessage(newValue, transformation));
|
|
98
94
|
});
|
|
99
95
|
return errors;
|
|
100
96
|
}
|
|
101
|
-
function generateErrorMessage(error) {
|
|
97
|
+
function generateErrorMessage(error, transformation) {
|
|
102
98
|
const errorPath = generateDotNotationPath(error);
|
|
103
|
-
const errorMessage =
|
|
99
|
+
const errorMessage = errorMessages.validation.errorWithField(errorPath, error.message);
|
|
104
100
|
const params = Object.entries(error.params);
|
|
105
101
|
if (params.length === 0) {
|
|
106
102
|
return errorMessage;
|
|
@@ -109,10 +105,14 @@ function generateErrorMessage(error) {
|
|
|
109
105
|
.filter(([_, value]) => value)
|
|
110
106
|
.map(([key, value]) => `${key}: ${Array.isArray(value) ? value.join(', ') : value}`);
|
|
111
107
|
if (isRequiredError(error)) {
|
|
112
|
-
return
|
|
108
|
+
return errorMessages.validation.missingRequiredField(`${errorPath}.${error.params.missingProperty}`);
|
|
113
109
|
}
|
|
114
110
|
else if (isTypeError(error)) {
|
|
115
|
-
|
|
111
|
+
const dotNotationPath = generateDotNotationPath(error);
|
|
112
|
+
const value = extractDotNotationValueFromTransformation(dotNotationPath, transformation);
|
|
113
|
+
return errorMessages.validation.errorWithField(value !== undefined
|
|
114
|
+
? `Value (${value}) in ${dotNotationPath}`
|
|
115
|
+
: dotNotationPath, error.message);
|
|
116
116
|
}
|
|
117
117
|
// Default case, it is not an error we know how to deal with
|
|
118
118
|
return `${errorMessage} ${additionalContext.length > 0
|
|
@@ -134,25 +134,49 @@ function mergeEnumErrors(cur, next) {
|
|
|
134
134
|
},
|
|
135
135
|
};
|
|
136
136
|
}
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
}
|
|
137
|
+
export function extractDotNotationValueFromTransformation(dotNotation, transformation) {
|
|
138
|
+
try {
|
|
139
|
+
const parts = dotNotation.split('.');
|
|
140
|
+
if (!transformation?.fileParseResult?.content || parts.length === 0) {
|
|
141
|
+
return undefined;
|
|
142
|
+
}
|
|
143
|
+
let value = transformation.fileParseResult.content;
|
|
144
|
+
// Traverse the nested objects and lists to get the end value
|
|
145
|
+
parts.forEach(item => {
|
|
146
|
+
// @ts-expect-error value is unknown since it is user generated config
|
|
147
|
+
const newValue = value[item];
|
|
148
|
+
if (newValue &&
|
|
149
|
+
typeof newValue === 'object' &&
|
|
150
|
+
!Array.isArray(newValue)) {
|
|
151
|
+
value = Object.assign(Object.create(null), newValue);
|
|
152
|
+
}
|
|
153
|
+
else {
|
|
154
|
+
value = newValue;
|
|
155
|
+
}
|
|
156
|
+
});
|
|
157
|
+
// If the value is an object/array, stringify the value so it doesn't log as [object Object] or '' for array
|
|
158
|
+
if (typeof value === 'object' && !!value) {
|
|
159
|
+
return JSON.stringify(value);
|
|
160
|
+
}
|
|
161
|
+
return value;
|
|
162
|
+
}
|
|
163
|
+
catch (e) {
|
|
164
|
+
logger.debug('Unable to parse dot notation path to located value', e);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
143
167
|
function isOneOfError(error) {
|
|
144
|
-
return error.keyword ===
|
|
168
|
+
return error.keyword === AjvErrorKeyword.OneOf;
|
|
145
169
|
}
|
|
146
170
|
function isRequiredError(error) {
|
|
147
|
-
return error.keyword ===
|
|
171
|
+
return error.keyword === AjvErrorKeyword.Required;
|
|
148
172
|
}
|
|
149
173
|
function isEnumError(error) {
|
|
150
|
-
return error.keyword ===
|
|
174
|
+
return error.keyword === AjvErrorKeyword.Enum;
|
|
151
175
|
}
|
|
152
176
|
function isTypeError(error) {
|
|
153
|
-
return error.keyword ===
|
|
177
|
+
return error.keyword === AjvErrorKeyword.Type;
|
|
154
178
|
}
|
|
155
|
-
|
|
179
|
+
export const AjvErrorKeyword = {
|
|
156
180
|
AdditionalItems: 'additionalItems',
|
|
157
181
|
AdditionalProperties: 'additionalProperties',
|
|
158
182
|
Dependencies: 'dependencies',
|
package/src/lib/files.d.ts
CHANGED
|
@@ -1,4 +1,13 @@
|
|
|
1
|
-
import { FileParseResult, TranslationContext, HsProfileFile } from './types';
|
|
1
|
+
import { FileParseResult, TranslationContext, HsProfileFile } from './types.js';
|
|
2
|
+
export type MetaFileLocation = {
|
|
3
|
+
file: string;
|
|
4
|
+
parentDirectory?: string;
|
|
5
|
+
};
|
|
2
6
|
export declare function loadHsProfileFile(projectSourceDir: string, profile: string): HsProfileFile;
|
|
3
7
|
export declare function getAllHsProfiles(projectSourceDir: string): Promise<string[]>;
|
|
4
8
|
export declare function loadHsMetaFiles(translationContext: TranslationContext): Promise<FileParseResult[]>;
|
|
9
|
+
export declare function locateHsMetaFiles(projectSourceDir: string, options?: {
|
|
10
|
+
silent: boolean;
|
|
11
|
+
}): Promise<MetaFileLocation[]>;
|
|
12
|
+
export declare function projectContainsHsMetaFiles(projectSourceDir: string): Promise<boolean>;
|
|
13
|
+
export declare function convertPathToPosixPath(filepath: string): string;
|