@hubspot/ui-extensions-dev-server 0.7.3 → 0.8.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/dist/cli/config.d.ts +9 -0
- package/dist/cli/config.js +79 -0
- package/dist/cli/run.d.ts +2 -0
- package/dist/cli/run.js +75 -0
- package/dist/cli/utils.d.ts +3 -0
- package/dist/cli/utils.js +65 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +14 -0
- package/dist/lib/DevModeInterface.d.ts +35 -0
- package/dist/lib/DevModeInterface.js +121 -0
- package/dist/lib/build.d.ts +14 -0
- package/dist/lib/build.js +80 -0
- package/dist/lib/constants.d.ts +19 -0
- package/dist/lib/constants.js +35 -0
- package/dist/lib/dev.d.ts +13 -0
- package/dist/lib/dev.js +109 -0
- package/dist/lib/extensionsService.d.ts +12 -0
- package/dist/lib/extensionsService.js +39 -0
- package/dist/lib/plugins/codeCheckingPlugin.d.ts +7 -0
- package/dist/lib/plugins/codeCheckingPlugin.js +27 -0
- package/dist/lib/plugins/codeInjectionPlugin.d.ts +8 -0
- package/dist/lib/plugins/codeInjectionPlugin.js +30 -0
- package/dist/lib/plugins/devBuildPlugin.d.ts +11 -0
- package/dist/lib/plugins/devBuildPlugin.js +139 -0
- package/dist/lib/plugins/friendlyLoggingPlugin.d.ts +11 -0
- package/dist/lib/plugins/friendlyLoggingPlugin.js +44 -0
- package/dist/lib/plugins/manifestPlugin.d.ts +8 -0
- package/dist/lib/plugins/manifestPlugin.js +95 -0
- package/dist/lib/self.d.ts +0 -0
- package/{lib → dist/lib}/self.js +1 -1
- package/dist/lib/server.d.ts +13 -0
- package/dist/lib/server.js +68 -0
- package/dist/lib/types.d.ts +48 -0
- package/dist/lib/types.js +2 -0
- package/dist/lib/utils.d.ts +4 -0
- package/dist/lib/utils.js +35 -0
- package/package.json +20 -23
- package/cli/config.js +0 -111
- package/cli/run.js +0 -62
- package/cli/utils.js +0 -67
- package/index.js +0 -14
- package/lib/DevModeInterface.js +0 -131
- package/lib/build.js +0 -86
- package/lib/constants.js +0 -39
- package/lib/dev.js +0 -98
- package/lib/extensionsService.js +0 -54
- package/lib/plugins/codeCheckingPlugin.js +0 -26
- package/lib/plugins/codeInjectionPlugin.js +0 -30
- package/lib/plugins/devBuildPlugin.js +0 -153
- package/lib/plugins/manifestPlugin.js +0 -109
- package/lib/server.js +0 -57
- package/lib/utils.js +0 -36
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { AppConfig, ExtensionConfigMap } from '../lib/types';
|
|
2
|
+
declare function loadConfigByPath(configPath: string): any;
|
|
3
|
+
declare function loadExtensionConfig(appConfig: AppConfig, appPath: string): ExtensionConfigMap;
|
|
4
|
+
/**
|
|
5
|
+
* @deprecated Will be removed after integration with hubspot-cli is complete
|
|
6
|
+
* This version of load config makes assumptions about the location it is being ran from where the others do not
|
|
7
|
+
*/
|
|
8
|
+
declare function loadConfig(): ExtensionConfigMap;
|
|
9
|
+
export { loadConfigByPath, loadExtensionConfig, loadConfig };
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.loadConfig = exports.loadExtensionConfig = exports.loadConfigByPath = void 0;
|
|
7
|
+
const fs_1 = __importDefault(require("fs"));
|
|
8
|
+
const path_1 = __importDefault(require("path"));
|
|
9
|
+
const utils_1 = require("../lib/utils");
|
|
10
|
+
const constants_1 = require("../lib/constants");
|
|
11
|
+
function loadConfigByPath(configPath) {
|
|
12
|
+
const source = fs_1.default.readFileSync(configPath).toString();
|
|
13
|
+
return JSON.parse(source);
|
|
14
|
+
}
|
|
15
|
+
exports.loadConfigByPath = loadConfigByPath;
|
|
16
|
+
function loadExtensionConfig(appConfig, appPath) {
|
|
17
|
+
var _a, _b;
|
|
18
|
+
const crmCardsSubConfigFiles = (_b = (_a = appConfig === null || appConfig === void 0 ? void 0 : appConfig.extensions) === null || _a === void 0 ? void 0 : _a.crm) === null || _b === void 0 ? void 0 : _b.cards;
|
|
19
|
+
const outputConfig = {};
|
|
20
|
+
crmCardsSubConfigFiles.forEach(card => {
|
|
21
|
+
var _a, _b;
|
|
22
|
+
const cardConfigPath = path_1.default.join(appPath, card.file);
|
|
23
|
+
try {
|
|
24
|
+
const cardConfig = loadConfigByPath(cardConfigPath);
|
|
25
|
+
if (cardConfig && cardConfig.data) {
|
|
26
|
+
const cardConfigDir = path_1.default.parse(cardConfigPath).dir;
|
|
27
|
+
const entryPointPath = path_1.default.join(cardConfigDir, (_b = (_a = cardConfig.data) === null || _a === void 0 ? void 0 : _a.module) === null || _b === void 0 ? void 0 : _b.file);
|
|
28
|
+
cardConfig.data.module.file = entryPointPath;
|
|
29
|
+
outputConfig[entryPointPath] = Object.assign(Object.assign({}, cardConfig), { output: (0, utils_1.getUrlSafeFileName)(entryPointPath), path: appPath, extensionPath: path_1.default.parse(entryPointPath).dir, data: Object.assign(Object.assign({}, cardConfig.data), { appName: appConfig.name }) });
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
catch (e) {
|
|
33
|
+
throw new Error(`Unable to load ${cardConfigPath}`);
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
return outputConfig;
|
|
37
|
+
}
|
|
38
|
+
exports.loadExtensionConfig = loadExtensionConfig;
|
|
39
|
+
/**
|
|
40
|
+
* @deprecated Will be removed after integration with hubspot-cli is complete
|
|
41
|
+
* This version of load config makes assumptions about the location it is being ran from where the others do not
|
|
42
|
+
*/
|
|
43
|
+
function loadConfig() {
|
|
44
|
+
var _a, _b;
|
|
45
|
+
// app.json is one level up from the extensions directory, which is where these commands
|
|
46
|
+
// will need to be ran from, the extensions directory
|
|
47
|
+
const configPath = path_1.default.join(process.cwd(), '..', constants_1.MAIN_APP_CONFIG);
|
|
48
|
+
const mainAppConfig = loadConfigByPath(configPath);
|
|
49
|
+
const crmCardsSubConfigFiles = (_b = (_a = mainAppConfig === null || mainAppConfig === void 0 ? void 0 : mainAppConfig.extensions) === null || _a === void 0 ? void 0 : _a.crm) === null || _b === void 0 ? void 0 : _b.cards;
|
|
50
|
+
if (!crmCardsSubConfigFiles || crmCardsSubConfigFiles.length === 0) {
|
|
51
|
+
throw new Error(`The "extensions.crm.cards" array in ${configPath} is missing or empty, it is a required configuration property`);
|
|
52
|
+
}
|
|
53
|
+
const outputConfig = {};
|
|
54
|
+
crmCardsSubConfigFiles.forEach(card => {
|
|
55
|
+
const cardConfigPath = path_1.default.join(process.cwd(), '..', card.file);
|
|
56
|
+
try {
|
|
57
|
+
const cardConfig = loadConfigByPath(cardConfigPath);
|
|
58
|
+
if (!cardConfig.data) {
|
|
59
|
+
throw new Error(`Invalid config file at path ${cardConfigPath}, data is a required config property`);
|
|
60
|
+
}
|
|
61
|
+
if (!cardConfig.data.module) {
|
|
62
|
+
throw new Error(`Invalid config file at path ${cardConfigPath}, data.module is a require property`);
|
|
63
|
+
}
|
|
64
|
+
// Path.join with a single argument will strip off any relative prefixing such as './'
|
|
65
|
+
const entryPointPath = path_1.default.join(cardConfig.data.module.file);
|
|
66
|
+
cardConfig.data.module.file = entryPointPath;
|
|
67
|
+
outputConfig[entryPointPath] = cardConfig;
|
|
68
|
+
outputConfig[entryPointPath].data.appName = mainAppConfig.name;
|
|
69
|
+
}
|
|
70
|
+
catch (e) {
|
|
71
|
+
if ((e === null || e === void 0 ? void 0 : e.code) === 'MODULE_NOT_FOUND') {
|
|
72
|
+
throw new Error(`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.`);
|
|
73
|
+
}
|
|
74
|
+
throw e;
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
return outputConfig;
|
|
78
|
+
}
|
|
79
|
+
exports.loadConfig = loadConfig;
|
package/dist/cli/run.js
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
4
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
5
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
6
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
7
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
8
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
9
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
10
|
+
});
|
|
11
|
+
};
|
|
12
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
13
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
14
|
+
};
|
|
15
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
+
const utils_1 = require("../cli/utils");
|
|
17
|
+
const index_1 = require("../index");
|
|
18
|
+
const console_log_colors_1 = require("console-log-colors");
|
|
19
|
+
const path_1 = __importDefault(require("path"));
|
|
20
|
+
const constants_1 = require("../lib/constants");
|
|
21
|
+
const inquirer_1 = __importDefault(require("inquirer"));
|
|
22
|
+
const config_1 = require("./config");
|
|
23
|
+
// eslint-disable-next-line no-floating-promise/no-floating-promise
|
|
24
|
+
(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
25
|
+
const { DEV_MODE, BUILD_MODE, extension, help, force } = (0, utils_1.parseArgs)();
|
|
26
|
+
if (!force) {
|
|
27
|
+
console.warn((0, console_log_colors_1.yellow)(`"hs-ui-extensions-dev-server" is deprecated, please use "hs project dev" for local development.
|
|
28
|
+
\nSee our Getting Started guide for detailed instructions: https://app.hubspot.com/l/docs/doc/platform/create-a-project-for-ui-extensions\n`));
|
|
29
|
+
process.exit(0);
|
|
30
|
+
}
|
|
31
|
+
if (help || !(DEV_MODE || BUILD_MODE)) {
|
|
32
|
+
(0, utils_1.showHelp)(constants_1.OUTPUT_DIR);
|
|
33
|
+
}
|
|
34
|
+
else if (DEV_MODE) {
|
|
35
|
+
const extensionPath = process.cwd(); // Assumed to be /path/to/src/app/extensions
|
|
36
|
+
const appPath = path_1.default.join(extensionPath, '..');
|
|
37
|
+
const appConfig = (0, config_1.loadConfigByPath)(path_1.default.join(appPath, constants_1.MAIN_APP_CONFIG));
|
|
38
|
+
let extensionConfig;
|
|
39
|
+
if (extension) {
|
|
40
|
+
const allExtensionsConfig = (0, config_1.loadExtensionConfig)(appConfig, appPath);
|
|
41
|
+
extensionConfig =
|
|
42
|
+
allExtensionsConfig[path_1.default.join(extensionPath, extension)];
|
|
43
|
+
}
|
|
44
|
+
yield index_1.DevModeInterface.setup({
|
|
45
|
+
promptUser: inquirer_1.default.createPromptModule(),
|
|
46
|
+
components: {
|
|
47
|
+
[appConfig.name]: {
|
|
48
|
+
config: appConfig,
|
|
49
|
+
path: path_1.default.join(extensionPath, '..'),
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
extensionConfig,
|
|
53
|
+
});
|
|
54
|
+
yield index_1.DevModeInterface.start({});
|
|
55
|
+
}
|
|
56
|
+
else if (BUILD_MODE) {
|
|
57
|
+
if (extension) {
|
|
58
|
+
(0, index_1.buildSingleExtension)({
|
|
59
|
+
file: extension,
|
|
60
|
+
outputDir: constants_1.OUTPUT_DIR,
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
(0, index_1.buildAllExtensions)({ outputDir: constants_1.OUTPUT_DIR });
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}))();
|
|
68
|
+
function shutdown() {
|
|
69
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
70
|
+
yield index_1.DevModeInterface.cleanup();
|
|
71
|
+
process.exit(0);
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
process.on('SIGINT', shutdown);
|
|
75
|
+
process.on('SIGTERM', shutdown);
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.showHelp = exports.parseArgs = void 0;
|
|
7
|
+
// @ts-expect-error no type defs
|
|
8
|
+
const logger_1 = require("@hubspot/cli-lib/logger");
|
|
9
|
+
// @ts-expect-error no type defs
|
|
10
|
+
const command_line_args_1 = __importDefault(require("command-line-args"));
|
|
11
|
+
// @ts-expect-error no type defs
|
|
12
|
+
const command_line_usage_1 = __importDefault(require("command-line-usage"));
|
|
13
|
+
function parseArgs() {
|
|
14
|
+
const mainDefinitions = [{ name: 'command', defaultOption: true }];
|
|
15
|
+
const mainOptions = (0, command_line_args_1.default)(mainDefinitions, {
|
|
16
|
+
stopAtFirstUnknown: true,
|
|
17
|
+
});
|
|
18
|
+
const argv = mainOptions._unknown || [];
|
|
19
|
+
const DEV_MODE = mainOptions.command === 'dev';
|
|
20
|
+
const BUILD_MODE = mainOptions.command === 'build';
|
|
21
|
+
const optionDefinitions = [
|
|
22
|
+
{ name: 'port', alias: 'p', type: Number },
|
|
23
|
+
{ name: 'extension', alias: 'e', type: String },
|
|
24
|
+
{ name: 'help', alias: 'h', type: Boolean },
|
|
25
|
+
{ name: 'force', alias: 'f', type: Boolean },
|
|
26
|
+
];
|
|
27
|
+
const options = (0, command_line_args_1.default)(optionDefinitions, DEV_MODE || BUILD_MODE ? { argv } : {});
|
|
28
|
+
return Object.assign({ DEV_MODE, BUILD_MODE }, options);
|
|
29
|
+
}
|
|
30
|
+
exports.parseArgs = parseArgs;
|
|
31
|
+
function showHelp(OUTPUT_DIR) {
|
|
32
|
+
const sections = [
|
|
33
|
+
{
|
|
34
|
+
header: 'HubSpot UI Extensions Local Dev Server',
|
|
35
|
+
content: `Used for local development of HubSpot extensions. Built assets can be found in the ${OUTPUT_DIR} directory`,
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
header: 'Available Commands',
|
|
39
|
+
content: [
|
|
40
|
+
{ name: 'dev', summary: 'starts the local development server' },
|
|
41
|
+
{ name: 'build', summary: 'runs a build of your extensions' },
|
|
42
|
+
],
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
header: 'Options',
|
|
46
|
+
optionList: [
|
|
47
|
+
{
|
|
48
|
+
name: 'extension',
|
|
49
|
+
alias: 'e',
|
|
50
|
+
typeLabel: '{underline file}',
|
|
51
|
+
description: 'The extension entrypoint file to build or start local development for',
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
name: 'help',
|
|
55
|
+
alias: 'h',
|
|
56
|
+
description: 'Print this usage guide.',
|
|
57
|
+
},
|
|
58
|
+
],
|
|
59
|
+
},
|
|
60
|
+
];
|
|
61
|
+
const usage = (0, command_line_usage_1.default)(sections);
|
|
62
|
+
logger_1.logger.info(usage);
|
|
63
|
+
process.exit(0);
|
|
64
|
+
}
|
|
65
|
+
exports.showHelp = showHelp;
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
3
|
+
// @ts-nocheck We aren't ready to type check these files yet
|
|
4
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
5
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
6
|
+
};
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.DevModeInterface = exports.buildSingleExtension = exports.buildAllExtensions = exports.remoteBuild = void 0;
|
|
9
|
+
const build_1 = require("./lib/build");
|
|
10
|
+
Object.defineProperty(exports, "remoteBuild", { enumerable: true, get: function () { return build_1.remoteBuild; } });
|
|
11
|
+
Object.defineProperty(exports, "buildAllExtensions", { enumerable: true, get: function () { return build_1.buildAllExtensions; } });
|
|
12
|
+
Object.defineProperty(exports, "buildSingleExtension", { enumerable: true, get: function () { return build_1.buildSingleExtension; } });
|
|
13
|
+
const DevModeInterface_1 = __importDefault(require("./lib/DevModeInterface"));
|
|
14
|
+
exports.DevModeInterface = DevModeInterface_1.default;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { ExtensionConfig, ProjectComponentMap } from './types';
|
|
2
|
+
import { ServiceConfiguration } from '@hubspot/app-functions-dev-server/dist/types';
|
|
3
|
+
import { PromptModule } from 'inquirer';
|
|
4
|
+
interface SetupArguments {
|
|
5
|
+
components: ProjectComponentMap;
|
|
6
|
+
debug?: boolean;
|
|
7
|
+
extensionConfig?: ExtensionConfig;
|
|
8
|
+
onUploadRequired?: VoidFunction;
|
|
9
|
+
promptUser: PromptModule;
|
|
10
|
+
}
|
|
11
|
+
interface StartArguments {
|
|
12
|
+
accountId?: number;
|
|
13
|
+
debug?: boolean;
|
|
14
|
+
httpClient?: ServiceConfiguration['httpClient'];
|
|
15
|
+
}
|
|
16
|
+
interface AppExtensionMapping {
|
|
17
|
+
name: string;
|
|
18
|
+
value: ExtensionConfig;
|
|
19
|
+
}
|
|
20
|
+
declare class DevModeInterface {
|
|
21
|
+
config?: ExtensionConfig;
|
|
22
|
+
appName?: string;
|
|
23
|
+
title?: string;
|
|
24
|
+
cardConfigs?: string[];
|
|
25
|
+
onUploadRequired?: VoidFunction;
|
|
26
|
+
shutdown?: () => Promise<void>;
|
|
27
|
+
_setDataFromExtensionConfig(extensionConfig: ExtensionConfig): void;
|
|
28
|
+
_generateAppExtensionMappings(components: ProjectComponentMap): AppExtensionMapping[];
|
|
29
|
+
setup({ components, debug, extensionConfig, onUploadRequired, promptUser, }: SetupArguments): Promise<void>;
|
|
30
|
+
fileChange(filePath: string, __event: unknown): Promise<void>;
|
|
31
|
+
start({ accountId, debug, httpClient }: StartArguments): Promise<void>;
|
|
32
|
+
cleanup(): Promise<void>;
|
|
33
|
+
}
|
|
34
|
+
declare const _default: DevModeInterface;
|
|
35
|
+
export default _default;
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
const dev_1 = require("./dev");
|
|
16
|
+
const path_1 = __importDefault(require("path"));
|
|
17
|
+
const constants_1 = require("./constants");
|
|
18
|
+
const config_1 = require("../cli/config");
|
|
19
|
+
// @ts-expect-error no type defs
|
|
20
|
+
const logger_1 = require("@hubspot/cli-lib/logger");
|
|
21
|
+
class DevModeInterface {
|
|
22
|
+
_setDataFromExtensionConfig(extensionConfig) {
|
|
23
|
+
this.config = extensionConfig;
|
|
24
|
+
this.appName = extensionConfig.data.appName;
|
|
25
|
+
this.title = extensionConfig.data.title;
|
|
26
|
+
}
|
|
27
|
+
_generateAppExtensionMappings(components) {
|
|
28
|
+
// Loop over all of the app configs that are passed in
|
|
29
|
+
const allComponentNames = Object.keys(components);
|
|
30
|
+
return allComponentNames.reduce((appExtensionMappings, componentName) => {
|
|
31
|
+
var _a, _b;
|
|
32
|
+
const component = components[componentName];
|
|
33
|
+
if (!((_b = (_a = component.config.extensions) === null || _a === void 0 ? void 0 : _a.crm) === null || _b === void 0 ? void 0 : _b.cards)) {
|
|
34
|
+
return appExtensionMappings; // It's not an app
|
|
35
|
+
}
|
|
36
|
+
this.cardConfigs = component.config.extensions.crm.cards.map(card => path_1.default.join(component.path, card.file));
|
|
37
|
+
// Load all of the extension configs for a particular app.json file
|
|
38
|
+
const extensionsConfigForApp = (0, config_1.loadExtensionConfig)(component.config, component.path);
|
|
39
|
+
const extensionFilePaths = Object.keys(extensionsConfigForApp);
|
|
40
|
+
// Loop over the loaded extension configs and generate the list of choices to use to prompt the user for input
|
|
41
|
+
extensionFilePaths.forEach(extensionPath => {
|
|
42
|
+
const extensionConfig = extensionsConfigForApp[extensionPath];
|
|
43
|
+
appExtensionMappings.push({
|
|
44
|
+
name: `${componentName}/${extensionConfig.data.title}`,
|
|
45
|
+
value: extensionConfig,
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
return appExtensionMappings;
|
|
49
|
+
}, []);
|
|
50
|
+
}
|
|
51
|
+
setup({ components, debug = false, extensionConfig, onUploadRequired, promptUser, }) {
|
|
52
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
53
|
+
(0, logger_1.setLogLevel)(debug ? logger_1.LOG_LEVEL.DEBUG : logger_1.LOG_LEVEL.LOG);
|
|
54
|
+
this.onUploadRequired = onUploadRequired;
|
|
55
|
+
if (extensionConfig) {
|
|
56
|
+
this._setDataFromExtensionConfig(extensionConfig);
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
const choices = this._generateAppExtensionMappings(components);
|
|
60
|
+
if (choices.length === 0) {
|
|
61
|
+
throw new Error('No extensions to run');
|
|
62
|
+
}
|
|
63
|
+
else if (choices.length === 1) {
|
|
64
|
+
this._setDataFromExtensionConfig(choices[0].value);
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
const answers = yield promptUser({
|
|
68
|
+
type: 'list',
|
|
69
|
+
name: 'extension',
|
|
70
|
+
message: 'Which extension would you like to run?',
|
|
71
|
+
choices,
|
|
72
|
+
});
|
|
73
|
+
this._setDataFromExtensionConfig(answers.extension);
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
// The contract is for this to be async, so eslint can chill
|
|
78
|
+
// eslint-disable-next-line require-await
|
|
79
|
+
fileChange(filePath, __event) {
|
|
80
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
81
|
+
if (this.cardConfigs &&
|
|
82
|
+
this.cardConfigs.includes(filePath) &&
|
|
83
|
+
this.onUploadRequired) {
|
|
84
|
+
this.onUploadRequired();
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
start({ accountId, debug, httpClient }) {
|
|
89
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
90
|
+
if (debug !== undefined) {
|
|
91
|
+
(0, logger_1.setLogLevel)(debug ? logger_1.LOG_LEVEL.DEBUG : logger_1.LOG_LEVEL.LOG);
|
|
92
|
+
}
|
|
93
|
+
if (!this.config || !this.config.path) {
|
|
94
|
+
throw new Error('Unable to load the required extension configuration files');
|
|
95
|
+
}
|
|
96
|
+
const appPath = this.config.path;
|
|
97
|
+
// Pass options from the CLI for running app functions locally
|
|
98
|
+
const functionsConfig = {
|
|
99
|
+
app: { path: appPath },
|
|
100
|
+
accountId,
|
|
101
|
+
httpClient,
|
|
102
|
+
};
|
|
103
|
+
this.shutdown = yield (0, dev_1.startDevMode)({
|
|
104
|
+
extensionConfig: this.config,
|
|
105
|
+
outputDir: path_1.default.join(this.config.extensionPath, constants_1.OUTPUT_DIR),
|
|
106
|
+
functionsConfig,
|
|
107
|
+
root: appPath,
|
|
108
|
+
cardConfigs: this.cardConfigs || [],
|
|
109
|
+
});
|
|
110
|
+
logger_1.logger.info(`Running extension '${this.title}' from app '${this.appName}'`);
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
cleanup() {
|
|
114
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
115
|
+
if (this.shutdown) {
|
|
116
|
+
yield this.shutdown();
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
exports.default = new DevModeInterface();
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
interface BuildSingleExtenstionArgs {
|
|
2
|
+
file: string;
|
|
3
|
+
outputDir?: string;
|
|
4
|
+
emptyOutDir?: boolean;
|
|
5
|
+
minify?: boolean;
|
|
6
|
+
root?: string;
|
|
7
|
+
}
|
|
8
|
+
declare const extensionErrorBaseMessage: string;
|
|
9
|
+
declare function buildAllExtensions({ outputDir }: {
|
|
10
|
+
outputDir: string;
|
|
11
|
+
}): Promise<void>;
|
|
12
|
+
declare function buildSingleExtension({ file, outputDir, emptyOutDir, minify, root, }: BuildSingleExtenstionArgs): Promise<void>;
|
|
13
|
+
declare function remoteBuild(root: string, entryPoint: string, outputDir?: string): Promise<void>;
|
|
14
|
+
export { buildAllExtensions, buildSingleExtension, remoteBuild, extensionErrorBaseMessage, };
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.extensionErrorBaseMessage = exports.remoteBuild = exports.buildSingleExtension = exports.buildAllExtensions = void 0;
|
|
16
|
+
const vite_1 = require("vite");
|
|
17
|
+
const constants_1 = require("./constants");
|
|
18
|
+
const manifestPlugin_1 = __importDefault(require("./plugins/manifestPlugin"));
|
|
19
|
+
const path_1 = __importDefault(require("path"));
|
|
20
|
+
const utils_1 = require("./utils");
|
|
21
|
+
const config_1 = require("../cli/config");
|
|
22
|
+
const codeInjectionPlugin_1 = __importDefault(require("./plugins/codeInjectionPlugin"));
|
|
23
|
+
const allowedExtensions = ['.js', '.ts', '.tsx', '.jsx'];
|
|
24
|
+
const extensionErrorBaseMessage = `Supported file extensions are [${allowedExtensions.join(', ')}], received:`;
|
|
25
|
+
exports.extensionErrorBaseMessage = extensionErrorBaseMessage;
|
|
26
|
+
function buildAllExtensions({ outputDir }) {
|
|
27
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
28
|
+
const config = (0, config_1.loadConfig)();
|
|
29
|
+
const extensionKeys = Object.keys(config);
|
|
30
|
+
for (let i = 0; i < extensionKeys.length; ++i) {
|
|
31
|
+
const { data } = config[extensionKeys[i]];
|
|
32
|
+
yield buildSingleExtension({
|
|
33
|
+
file: data.module.file,
|
|
34
|
+
outputDir,
|
|
35
|
+
emptyOutDir: i === 0,
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
exports.buildAllExtensions = buildAllExtensions;
|
|
41
|
+
function buildSingleExtension({ file, outputDir = constants_1.OUTPUT_DIR, emptyOutDir = true, minify = false, root = process.cwd(), // This is the vite default, so using that as our default
|
|
42
|
+
}) {
|
|
43
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
44
|
+
const output = (0, utils_1.getUrlSafeFileName)(file);
|
|
45
|
+
yield (0, vite_1.build)({
|
|
46
|
+
root,
|
|
47
|
+
define: {
|
|
48
|
+
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'production'),
|
|
49
|
+
},
|
|
50
|
+
build: {
|
|
51
|
+
lib: {
|
|
52
|
+
entry: file,
|
|
53
|
+
name: output,
|
|
54
|
+
formats: ['iife'],
|
|
55
|
+
fileName: () => output,
|
|
56
|
+
},
|
|
57
|
+
rollupOptions: Object.assign(Object.assign({}, constants_1.ROLLUP_OPTIONS), { plugins: [(0, manifestPlugin_1.default)({ output }), (0, codeInjectionPlugin_1.default)({ file })] }),
|
|
58
|
+
outDir: outputDir,
|
|
59
|
+
emptyOutDir,
|
|
60
|
+
minify,
|
|
61
|
+
},
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
exports.buildSingleExtension = buildSingleExtension;
|
|
66
|
+
function remoteBuild(root, entryPoint, outputDir = constants_1.OUTPUT_DIR) {
|
|
67
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
68
|
+
const fileInfo = path_1.default.parse(entryPoint);
|
|
69
|
+
if (!allowedExtensions.includes(fileInfo.ext)) {
|
|
70
|
+
throw new Error(`${extensionErrorBaseMessage} ${fileInfo.ext}`);
|
|
71
|
+
}
|
|
72
|
+
yield buildSingleExtension({
|
|
73
|
+
file: entryPoint,
|
|
74
|
+
outputDir,
|
|
75
|
+
minify: true,
|
|
76
|
+
root,
|
|
77
|
+
});
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
exports.remoteBuild = remoteBuild;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
declare const OUTPUT_DIR = "dist";
|
|
2
|
+
declare const MAIN_APP_CONFIG = "app.json";
|
|
3
|
+
declare const MANIFEST_FILE = "manifest.json";
|
|
4
|
+
declare const VITE_DEFAULT_PORT = 5173;
|
|
5
|
+
declare const WEBSOCKET_PORT = 5174;
|
|
6
|
+
declare const ROLLUP_OPTIONS: {
|
|
7
|
+
external: string[];
|
|
8
|
+
output: {
|
|
9
|
+
globals: {
|
|
10
|
+
react: string;
|
|
11
|
+
'@remote-ui/react': string;
|
|
12
|
+
};
|
|
13
|
+
extend: boolean;
|
|
14
|
+
};
|
|
15
|
+
};
|
|
16
|
+
declare const EXTENSIONS_MESSAGE_VERSION = 1;
|
|
17
|
+
declare const WEBSOCKET_MESSAGE_VERSION = 0;
|
|
18
|
+
declare const SERVER_CAPABILITIES: string[];
|
|
19
|
+
export { ROLLUP_OPTIONS, OUTPUT_DIR, MAIN_APP_CONFIG, MANIFEST_FILE, EXTENSIONS_MESSAGE_VERSION, VITE_DEFAULT_PORT, WEBSOCKET_MESSAGE_VERSION, WEBSOCKET_PORT, SERVER_CAPABILITIES, };
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SERVER_CAPABILITIES = exports.WEBSOCKET_PORT = exports.WEBSOCKET_MESSAGE_VERSION = exports.VITE_DEFAULT_PORT = exports.EXTENSIONS_MESSAGE_VERSION = exports.MANIFEST_FILE = exports.MAIN_APP_CONFIG = exports.OUTPUT_DIR = exports.ROLLUP_OPTIONS = void 0;
|
|
4
|
+
const OUTPUT_DIR = 'dist';
|
|
5
|
+
exports.OUTPUT_DIR = OUTPUT_DIR;
|
|
6
|
+
const MAIN_APP_CONFIG = 'app.json';
|
|
7
|
+
exports.MAIN_APP_CONFIG = MAIN_APP_CONFIG;
|
|
8
|
+
const MANIFEST_FILE = 'manifest.json';
|
|
9
|
+
exports.MANIFEST_FILE = MANIFEST_FILE;
|
|
10
|
+
const VITE_DEFAULT_PORT = 5173;
|
|
11
|
+
exports.VITE_DEFAULT_PORT = VITE_DEFAULT_PORT;
|
|
12
|
+
const WEBSOCKET_PORT = 5174;
|
|
13
|
+
exports.WEBSOCKET_PORT = WEBSOCKET_PORT;
|
|
14
|
+
const ROLLUP_OPTIONS = {
|
|
15
|
+
// Deps to exclude from the bundle
|
|
16
|
+
external: ['react', 'react-dom', '@remote-ui/react'],
|
|
17
|
+
output: {
|
|
18
|
+
// Maps libs to the variables to be injected via the window
|
|
19
|
+
globals: {
|
|
20
|
+
react: 'React',
|
|
21
|
+
'@remote-ui/react': 'RemoteUI',
|
|
22
|
+
},
|
|
23
|
+
extend: true,
|
|
24
|
+
},
|
|
25
|
+
};
|
|
26
|
+
exports.ROLLUP_OPTIONS = ROLLUP_OPTIONS;
|
|
27
|
+
const EXTENSIONS_MESSAGE_VERSION = 1;
|
|
28
|
+
exports.EXTENSIONS_MESSAGE_VERSION = EXTENSIONS_MESSAGE_VERSION;
|
|
29
|
+
const WEBSOCKET_MESSAGE_VERSION = 0;
|
|
30
|
+
exports.WEBSOCKET_MESSAGE_VERSION = WEBSOCKET_MESSAGE_VERSION;
|
|
31
|
+
const SERVER_CAPABILITIES = [
|
|
32
|
+
// Supports running app functions locally
|
|
33
|
+
'app-functions-local-dev',
|
|
34
|
+
];
|
|
35
|
+
exports.SERVER_CAPABILITIES = SERVER_CAPABILITIES;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { ExtensionConfig } from './types';
|
|
2
|
+
import { ServiceConfiguration } from '@hubspot/app-functions-dev-server/dist/types';
|
|
3
|
+
interface StartDevModeArgs {
|
|
4
|
+
outputDir?: string;
|
|
5
|
+
extensionConfig: ExtensionConfig;
|
|
6
|
+
webSocketPort?: number;
|
|
7
|
+
expressPort?: number;
|
|
8
|
+
root?: string;
|
|
9
|
+
functionsConfig: Partial<ServiceConfiguration>;
|
|
10
|
+
cardConfigs: string[];
|
|
11
|
+
}
|
|
12
|
+
declare function startDevMode({ extensionConfig, functionsConfig, outputDir, expressPort, webSocketPort, root, cardConfigs, }: StartDevModeArgs): Promise<() => Promise<void>>;
|
|
13
|
+
export { startDevMode };
|