@hubspot/ui-extensions-dev-server 0.0.1-prealpha.3 → 0.0.1-prealpha.4
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/build.js +16 -10
- package/cli.js +3 -1
- package/config.js +27 -10
- package/package.json +13 -2
- package/remoteBuild.js +19 -10
- package/run.js +7 -1
- package/tests/testBuild.js +33 -24
- package/utils.js +4 -3
package/build.js
CHANGED
|
@@ -6,21 +6,23 @@ async function buildAllExtensions(config, outputDir) {
|
|
|
6
6
|
for (let i = 0; i < extensionKeys.length; ++i) {
|
|
7
7
|
const { data } = config[extensionKeys[i]];
|
|
8
8
|
|
|
9
|
-
await buildSingleExtension(
|
|
10
|
-
data?.module.file,
|
|
11
|
-
data?.output,
|
|
9
|
+
await buildSingleExtension({
|
|
10
|
+
file: data?.module.file,
|
|
11
|
+
outputFileName: data?.output,
|
|
12
12
|
outputDir,
|
|
13
|
-
i === 0
|
|
14
|
-
);
|
|
13
|
+
emptyOutDir: i === 0,
|
|
14
|
+
});
|
|
15
15
|
}
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
async function buildSingleExtension(
|
|
18
|
+
async function buildSingleExtension({
|
|
19
19
|
file,
|
|
20
20
|
outputFileName,
|
|
21
21
|
outputDir,
|
|
22
|
-
emptyOutDir = true
|
|
23
|
-
|
|
22
|
+
emptyOutDir = true,
|
|
23
|
+
plugins = { rollup: [], vite: [] },
|
|
24
|
+
minify = false,
|
|
25
|
+
}) {
|
|
24
26
|
await build({
|
|
25
27
|
build: {
|
|
26
28
|
lib: {
|
|
@@ -29,10 +31,14 @@ async function buildSingleExtension(
|
|
|
29
31
|
formats: ['iife'],
|
|
30
32
|
fileName: () => outputFileName,
|
|
31
33
|
},
|
|
32
|
-
rollupOptions:
|
|
34
|
+
rollupOptions: {
|
|
35
|
+
...ROLLUP_OPTIONS,
|
|
36
|
+
plugins: [...(ROLLUP_OPTIONS.plugins || []), ...plugins?.rollup],
|
|
37
|
+
},
|
|
33
38
|
outDir: outputDir,
|
|
34
39
|
emptyOutDir,
|
|
35
|
-
minify
|
|
40
|
+
minify,
|
|
41
|
+
plugins: plugins?.vite,
|
|
36
42
|
},
|
|
37
43
|
});
|
|
38
44
|
}
|
package/cli.js
CHANGED
|
@@ -43,12 +43,14 @@ function showHelp(OUTPUT_DIR) {
|
|
|
43
43
|
optionList: [
|
|
44
44
|
{
|
|
45
45
|
name: 'extension',
|
|
46
|
+
alias: 'e',
|
|
46
47
|
typeLabel: '{underline file}',
|
|
47
48
|
description:
|
|
48
|
-
'The extension entrypoint file build or start local development for',
|
|
49
|
+
'The extension entrypoint file to build or start local development for',
|
|
49
50
|
},
|
|
50
51
|
{
|
|
51
52
|
name: 'help',
|
|
53
|
+
alias: 'h',
|
|
52
54
|
description: 'Print this usage guide.',
|
|
53
55
|
},
|
|
54
56
|
],
|
package/config.js
CHANGED
|
@@ -71,30 +71,47 @@ function loadConfig() {
|
|
|
71
71
|
|
|
72
72
|
const mainAppConfig = _loadRequiredConfigFile(configPath);
|
|
73
73
|
|
|
74
|
-
|
|
74
|
+
const crmCardsSubConfigFiles = mainAppConfig?.extensions?.crm?.cards;
|
|
75
|
+
if (!crmCardsSubConfigFiles) {
|
|
75
76
|
logger.error(
|
|
76
|
-
`"extensions.crm.cards"
|
|
77
|
+
`The "extensions.crm.cards" array in ${configPath} is missing, it is a required configuration property`
|
|
78
|
+
);
|
|
79
|
+
process.exit(1);
|
|
80
|
+
} else if (crmCardsSubConfigFiles.length === 0) {
|
|
81
|
+
logger.error(
|
|
82
|
+
`The "extensions.crm.cards" array in ${configPath} is empty, it is a required configuration property.`
|
|
77
83
|
);
|
|
78
84
|
process.exit(1);
|
|
79
85
|
}
|
|
80
86
|
|
|
81
87
|
const outputConfig = {};
|
|
82
88
|
|
|
83
|
-
|
|
89
|
+
crmCardsSubConfigFiles.forEach(card => {
|
|
84
90
|
const extensionsRemoved = card.file.replace('extensions/', '');
|
|
85
|
-
const
|
|
91
|
+
const cardConfigPath = path.join(process.cwd(), extensionsRemoved);
|
|
92
|
+
// Get the path to the config file relative to the extensions directory
|
|
93
|
+
const configPathRelativeToExtensions = path.parse(extensionsRemoved)?.dir;
|
|
94
|
+
|
|
86
95
|
try {
|
|
87
|
-
const cardConfig = require(
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
96
|
+
const cardConfig = require(cardConfigPath);
|
|
97
|
+
|
|
98
|
+
// Join the two relative paths
|
|
99
|
+
const entryPointPath = path.join(
|
|
100
|
+
configPathRelativeToExtensions,
|
|
91
101
|
cardConfig.data?.module?.file
|
|
92
102
|
);
|
|
93
|
-
|
|
103
|
+
|
|
104
|
+
cardConfig.data.module.file = entryPointPath;
|
|
105
|
+
|
|
106
|
+
outputConfig[entryPointPath] = cardConfig;
|
|
107
|
+
outputConfig[entryPointPath].data.output = getUrlSafeFileName(
|
|
108
|
+
entryPointPath
|
|
109
|
+
);
|
|
110
|
+
outputConfig[entryPointPath].data.appName = projectConfig.name;
|
|
94
111
|
} catch (e) {
|
|
95
112
|
let errorMessage = e?.message;
|
|
96
113
|
if (e?.code === 'MODULE_NOT_FOUND') {
|
|
97
|
-
errorMessage = `Unable to load "${
|
|
114
|
+
errorMessage = `Unable to load "${cardConfigPath}" file. \nPlease make sure you are running the command from the src/app/extensions directory and that your card JSON config exists within it.`;
|
|
98
115
|
}
|
|
99
116
|
|
|
100
117
|
logger.error(errorMessage);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hubspot/ui-extensions-dev-server",
|
|
3
|
-
"version": "0.0.1-prealpha.
|
|
3
|
+
"version": "0.0.1-prealpha.4",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -45,5 +45,16 @@
|
|
|
45
45
|
"node": true
|
|
46
46
|
}
|
|
47
47
|
},
|
|
48
|
-
"
|
|
48
|
+
"engines": {
|
|
49
|
+
"node": ">=16"
|
|
50
|
+
},
|
|
51
|
+
"peerDependencies": {
|
|
52
|
+
"typescript": "^5.0.4"
|
|
53
|
+
},
|
|
54
|
+
"peerDependenciesMeta": {
|
|
55
|
+
"typescript": {
|
|
56
|
+
"optional": true
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
"gitHead": "d3ed42de0f9675a2f599416ba1886ba379ecfcd0"
|
|
49
60
|
}
|
package/remoteBuild.js
CHANGED
|
@@ -2,20 +2,29 @@
|
|
|
2
2
|
const { OUTPUT_DIR } = require('./constants');
|
|
3
3
|
const { getUrlSafeFileName } = require('./utils');
|
|
4
4
|
const { buildSingleExtension } = require('./build');
|
|
5
|
+
const path = require('path');
|
|
6
|
+
const manifestPlugin = require('./plugins/manifestPlugin');
|
|
5
7
|
|
|
6
|
-
|
|
7
|
-
const entryPointRegex = new RegExp(/.*\.(ts|js)[x]?$/);
|
|
8
|
+
const entryPoint = process.argv[process.argv.length - 1];
|
|
8
9
|
|
|
9
|
-
|
|
10
|
+
const allowedExtensions = ['.js', '.ts', '.tsx', '.jsx'];
|
|
10
11
|
|
|
11
|
-
|
|
12
|
+
const fileInfo = path.parse(entryPoint);
|
|
13
|
+
|
|
14
|
+
if (!allowedExtensions.includes(fileInfo.ext)) {
|
|
12
15
|
throw new Error(
|
|
13
|
-
|
|
16
|
+
`The last argument should be the filename you wish to build. Supported file extensions are [${allowedExtensions.join(
|
|
17
|
+
', '
|
|
18
|
+
)}]`
|
|
14
19
|
);
|
|
15
20
|
}
|
|
16
21
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
+
buildSingleExtension({
|
|
23
|
+
file: entryPoint,
|
|
24
|
+
outputFileName: getUrlSafeFileName(entryPoint),
|
|
25
|
+
outputDir: OUTPUT_DIR,
|
|
26
|
+
plugins: {
|
|
27
|
+
rollup: [manifestPlugin({ minify: true })],
|
|
28
|
+
},
|
|
29
|
+
minify: true,
|
|
30
|
+
});
|
package/run.js
CHANGED
|
@@ -6,6 +6,7 @@ const { buildAllExtensions, buildSingleExtension } = require('./build');
|
|
|
6
6
|
const { VITE_DEFAULT_PORT, OUTPUT_DIR } = require('./constants');
|
|
7
7
|
const { parseArgs, showHelp } = require('./cli');
|
|
8
8
|
const { getUrlSafeFileName } = require('./utils');
|
|
9
|
+
const manifestPlugin = require('./plugins/manifestPlugin');
|
|
9
10
|
|
|
10
11
|
const { DEV_MODE, BUILD_MODE, port, extension, help } = parseArgs();
|
|
11
12
|
const PORT = port || VITE_DEFAULT_PORT;
|
|
@@ -18,7 +19,12 @@ if (DEV_MODE) {
|
|
|
18
19
|
startDevMode(loadConfig(), OUTPUT_DIR, PORT, extension);
|
|
19
20
|
} else if (BUILD_MODE) {
|
|
20
21
|
if (extension) {
|
|
21
|
-
buildSingleExtension(
|
|
22
|
+
buildSingleExtension({
|
|
23
|
+
file: extension,
|
|
24
|
+
outputFileName: getUrlSafeFileName(extension),
|
|
25
|
+
outputDir: OUTPUT_DIR,
|
|
26
|
+
plugins: { rollup: [manifestPlugin()] },
|
|
27
|
+
});
|
|
22
28
|
} else {
|
|
23
29
|
buildAllExtensions(loadConfig(), OUTPUT_DIR);
|
|
24
30
|
}
|
package/tests/testBuild.js
CHANGED
|
@@ -14,19 +14,37 @@ function _testHelper(command, outputDirFiles) {
|
|
|
14
14
|
// Spot check the file contents to make sure they seem ok
|
|
15
15
|
filesInOutputDir.forEach(file => {
|
|
16
16
|
const fileContents = fs.readFileSync(path.join(distDir, file)).toString();
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
17
|
+
if (file === 'manifest.json') {
|
|
18
|
+
const manifest = JSON.parse(fileContents);
|
|
19
|
+
assert(manifest.entry);
|
|
20
|
+
assert(manifest.modules);
|
|
21
|
+
assert(manifest.modules.internal);
|
|
22
|
+
manifest.modules.internal.forEach(mod => {
|
|
23
|
+
assert(mod.module);
|
|
24
|
+
assert(mod.renderedExports);
|
|
25
|
+
});
|
|
26
|
+
assert(manifest.modules.external);
|
|
27
|
+
manifest.modules.external.forEach(mod => {
|
|
28
|
+
assert(mod.module);
|
|
29
|
+
assert(mod.renderedExports);
|
|
30
|
+
});
|
|
31
|
+
assert(manifest.package);
|
|
32
|
+
assert(manifest.package.packages);
|
|
33
|
+
} else {
|
|
34
|
+
const stringsToSpotCheck = [
|
|
35
|
+
'.createRemoteReactComponent',
|
|
36
|
+
'.createElement',
|
|
37
|
+
'hubspot.extend',
|
|
38
|
+
'React',
|
|
39
|
+
'RemoteUI',
|
|
40
|
+
];
|
|
41
|
+
stringsToSpotCheck.forEach(stringToCheck => {
|
|
42
|
+
assert(
|
|
43
|
+
fileContents.includes(stringToCheck),
|
|
44
|
+
`File ${file} contents should contain: "${stringToCheck}"`
|
|
45
|
+
);
|
|
46
|
+
});
|
|
47
|
+
}
|
|
30
48
|
});
|
|
31
49
|
}
|
|
32
50
|
|
|
@@ -43,7 +61,7 @@ function testBuildWithExtensionFlag(logger) {
|
|
|
43
61
|
logger.warn('- Test build with flags started 🤞');
|
|
44
62
|
_testHelper(
|
|
45
63
|
'hs-ui-extensions-dev-server build --extension ProgressBarApp.tsx',
|
|
46
|
-
['ProgressBarApp.js']
|
|
64
|
+
['ProgressBarApp.js', 'manifest.json']
|
|
47
65
|
);
|
|
48
66
|
logger.info('- Test build with flags passed 🚀');
|
|
49
67
|
}
|
|
@@ -52,19 +70,11 @@ function testDefInfraBuildFileName(logger) {
|
|
|
52
70
|
logger.warn('- Test build with entrypoint as arg 🤞');
|
|
53
71
|
_testHelper('hs-ui-extensions-remote-build ProgressBarApp.tsx', [
|
|
54
72
|
'ProgressBarApp.js',
|
|
73
|
+
'manifest.json',
|
|
55
74
|
]);
|
|
56
75
|
logger.info('- Test build with entrypoint as arg 🚀');
|
|
57
76
|
}
|
|
58
77
|
|
|
59
|
-
function testDevInfraBuildFileNameWithPathPrefix(logger) {
|
|
60
|
-
logger.warn('- Test build with config file as arg 🤞');
|
|
61
|
-
_testHelper(
|
|
62
|
-
'hs-ui-extensions-remote-build some/super/long/file/path/to/the/extensions/PhoneLines.tsx',
|
|
63
|
-
['PhoneLines.js']
|
|
64
|
-
);
|
|
65
|
-
logger.info('- Test build with config file as arg 🚀');
|
|
66
|
-
}
|
|
67
|
-
|
|
68
78
|
function testBuild(logger) {
|
|
69
79
|
logger.warn('\nBuild Tests started - External Devs 🤞');
|
|
70
80
|
testDefaultBuildPath(logger);
|
|
@@ -73,7 +83,6 @@ function testBuild(logger) {
|
|
|
73
83
|
|
|
74
84
|
logger.warn('\nBuild Tests started - Dev Infra 🤞');
|
|
75
85
|
testDefInfraBuildFileName(logger);
|
|
76
|
-
testDevInfraBuildFileNameWithPathPrefix(logger);
|
|
77
86
|
logger.info('Build Tests passed - Dev Infra 🚀');
|
|
78
87
|
}
|
|
79
88
|
|
package/utils.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
const path = require('path');
|
|
2
|
+
|
|
1
3
|
function getUrlSafeFileName(filePath) {
|
|
2
|
-
const
|
|
3
|
-
|
|
4
|
-
return encodeURIComponent(fileNameWithJsExtension);
|
|
4
|
+
const { name } = path.parse(filePath);
|
|
5
|
+
return encodeURIComponent(`${name}.js`);
|
|
5
6
|
}
|
|
6
7
|
|
|
7
8
|
module.exports = {
|