@forestadmin/forest-cloud 1.0.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.
Files changed (45) hide show
  1. package/LICENSE +674 -0
  2. package/README.md +21 -0
  3. package/dist/build-command.d.ts +2 -0
  4. package/dist/build-command.js +48 -0
  5. package/dist/command.d.ts +3 -0
  6. package/dist/command.js +12 -0
  7. package/dist/dialogs/action-runner.d.ts +3 -0
  8. package/dist/dialogs/action-runner.js +28 -0
  9. package/dist/dialogs/ask-to-overwrite-customizations.d.ts +4 -0
  10. package/dist/dialogs/ask-to-overwrite-customizations.js +30 -0
  11. package/dist/dialogs/check-latest-version.d.ts +4 -0
  12. package/dist/dialogs/check-latest-version.js +24 -0
  13. package/dist/errors.d.ts +8 -0
  14. package/dist/errors.js +18 -0
  15. package/dist/index.d.ts +3 -0
  16. package/dist/index.js +3 -0
  17. package/dist/login.d.ts +3 -0
  18. package/dist/login.js +23 -0
  19. package/dist/make-commands.d.ts +5 -0
  20. package/dist/make-commands.js +136 -0
  21. package/dist/services/access-file.d.ts +2 -0
  22. package/dist/services/access-file.js +20 -0
  23. package/dist/services/bootstrap-path-manager.d.ts +18 -0
  24. package/dist/services/bootstrap-path-manager.js +48 -0
  25. package/dist/services/bootstrap.d.ts +4 -0
  26. package/dist/services/bootstrap.js +79 -0
  27. package/dist/services/dist-path-manager.d.ts +7 -0
  28. package/dist/services/dist-path-manager.js +19 -0
  29. package/dist/services/environment-variables.d.ts +6 -0
  30. package/dist/services/environment-variables.js +92 -0
  31. package/dist/services/event-subscriber.d.ts +12 -0
  32. package/dist/services/event-subscriber.js +66 -0
  33. package/dist/services/http-server.d.ts +25 -0
  34. package/dist/services/http-server.js +110 -0
  35. package/dist/services/packager.d.ts +3 -0
  36. package/dist/services/packager.js +17 -0
  37. package/dist/services/publish.d.ts +4 -0
  38. package/dist/services/publish.js +47 -0
  39. package/dist/services/update-typings.d.ts +6 -0
  40. package/dist/services/update-typings.js +50 -0
  41. package/dist/templates/env.txt +2 -0
  42. package/dist/templates/index.txt +19 -0
  43. package/dist/types.d.ts +87 -0
  44. package/dist/types.js +3 -0
  45. package/package.json +62 -0
@@ -0,0 +1,19 @@
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
+ const path_1 = __importDefault(require("path"));
7
+ class DistPathManager {
8
+ constructor(cloudCustomizerPath) {
9
+ this.cloudCustomizerPath = cloudCustomizerPath ?? '.';
10
+ }
11
+ get zip() {
12
+ return path_1.default.join(this.cloudCustomizerPath, 'dist', 'code-customizations.zip');
13
+ }
14
+ get distCodeCustomizations() {
15
+ return path_1.default.join(this.cloudCustomizerPath, 'dist', 'code-customizations');
16
+ }
17
+ }
18
+ exports.default = DistPathManager;
19
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGlzdC1wYXRoLW1hbmFnZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc2VydmljZXMvZGlzdC1wYXRoLW1hbmFnZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSxnREFBd0I7QUFFeEIsTUFBcUIsZUFBZTtJQUdsQyxZQUFZLG1CQUE0QjtRQUN0QyxJQUFJLENBQUMsbUJBQW1CLEdBQUcsbUJBQW1CLElBQUksR0FBRyxDQUFDO0lBQ3hELENBQUM7SUFFRCxJQUFJLEdBQUc7UUFDTCxPQUFPLGNBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLG1CQUFtQixFQUFFLE1BQU0sRUFBRSx5QkFBeUIsQ0FBQyxDQUFDO0lBQ2hGLENBQUM7SUFFRCxJQUFJLHNCQUFzQjtRQUN4QixPQUFPLGNBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLG1CQUFtQixFQUFFLE1BQU0sRUFBRSxxQkFBcUIsQ0FBQyxDQUFDO0lBQzVFLENBQUM7Q0FDRjtBQWRELGtDQWNDIn0=
@@ -0,0 +1,6 @@
1
+ import { EnvironmentVariables } from '../types';
2
+ export declare function getEnvironmentVariables(): Promise<EnvironmentVariables>;
3
+ export declare function validateServerUrl(serverUrl: string): void;
4
+ export declare function validateSubscriptionUrl(subscriptionUrl: string): void;
5
+ export declare function validateEnvironmentVariables(env: EnvironmentVariables): void;
6
+ //# sourceMappingURL=environment-variables.d.ts.map
@@ -0,0 +1,92 @@
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 (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ var __importDefault = (this && this.__importDefault) || function (mod) {
26
+ return (mod && mod.__esModule) ? mod : { "default": mod };
27
+ };
28
+ Object.defineProperty(exports, "__esModule", { value: true });
29
+ exports.validateEnvironmentVariables = exports.validateSubscriptionUrl = exports.validateServerUrl = exports.getEnvironmentVariables = void 0;
30
+ const fs = __importStar(require("fs"));
31
+ const promises_1 = require("node:fs/promises");
32
+ const node_os_1 = require("node:os");
33
+ const path_1 = __importDefault(require("path"));
34
+ const errors_1 = require("../errors");
35
+ const getTokenFromToolbelt = async () => {
36
+ const baseTokenPath = process.env.TOKEN_PATH || (0, node_os_1.homedir)();
37
+ const tokenPath = path_1.default.join(baseTokenPath, '.forest.d', '.forestrc');
38
+ if (fs.existsSync(tokenPath))
39
+ return (0, promises_1.readFile)(tokenPath, 'utf8');
40
+ return null;
41
+ };
42
+ async function getEnvironmentVariables() {
43
+ return {
44
+ FOREST_ENV_SECRET: process.env.FOREST_ENV_SECRET,
45
+ FOREST_SERVER_URL: process.env.FOREST_SERVER_URL || 'https://api.forestadmin.com',
46
+ FOREST_SUBSCRIPTION_URL: process.env.FOREST_SUBSCRIPTION_URL || 'wss://api.forestadmin.com/subscriptions',
47
+ FOREST_AUTH_TOKEN: process.env.FOREST_AUTH_TOKEN || (await getTokenFromToolbelt()),
48
+ };
49
+ }
50
+ exports.getEnvironmentVariables = getEnvironmentVariables;
51
+ function validateUrl(url, variableName, protocols) {
52
+ if (!url) {
53
+ throw new errors_1.BusinessError(`Missing ${variableName}. Please check your .env file.`);
54
+ }
55
+ let givenUrl;
56
+ try {
57
+ givenUrl = new URL(url);
58
+ }
59
+ catch (err) {
60
+ throw new errors_1.BusinessError(`${variableName} is invalid. Please check your .env file.\n${err.message}`);
61
+ }
62
+ if (!protocols.includes(givenUrl.protocol)) {
63
+ throw new errors_1.BusinessError(`${variableName} is invalid, it must start with '${protocols
64
+ .map(protocol => `${protocol}//`)
65
+ .join("' or '")}'. Please check your .env file.`);
66
+ }
67
+ }
68
+ function validateServerUrl(serverUrl) {
69
+ validateUrl(serverUrl, 'FOREST_SERVER_URL', ['http:', 'https:']);
70
+ }
71
+ exports.validateServerUrl = validateServerUrl;
72
+ function validateSubscriptionUrl(subscriptionUrl) {
73
+ validateUrl(subscriptionUrl, 'FOREST_SUBSCRIPTION_URL', ['wss:']);
74
+ }
75
+ exports.validateSubscriptionUrl = validateSubscriptionUrl;
76
+ function validateEnvironmentVariables(env) {
77
+ if (!env.FOREST_ENV_SECRET) {
78
+ throw new errors_1.BusinessError('Missing FOREST_ENV_SECRET. Please check your .env file.');
79
+ }
80
+ if (typeof env.FOREST_ENV_SECRET !== 'string' || !/^[0-9a-f]{64}$/.test(env.FOREST_ENV_SECRET)) {
81
+ throw new errors_1.BusinessError(
82
+ // eslint-disable-next-line max-len
83
+ 'FOREST_ENV_SECRET is invalid. Please check your .env file.\n\tYou can retrieve its value from environment settings on Forest Admin.');
84
+ }
85
+ if (!env.FOREST_AUTH_TOKEN) {
86
+ throw new errors_1.BusinessError('Missing authentication token. Your TOKEN_PATH is probably wrong on .env file.');
87
+ }
88
+ validateServerUrl(env.FOREST_SERVER_URL);
89
+ validateSubscriptionUrl(env.FOREST_SUBSCRIPTION_URL);
90
+ }
91
+ exports.validateEnvironmentVariables = validateEnvironmentVariables;
92
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZW52aXJvbm1lbnQtdmFyaWFibGVzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3NlcnZpY2VzL2Vudmlyb25tZW50LXZhcmlhYmxlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLHVDQUF5QjtBQUN6QiwrQ0FBNEM7QUFDNUMscUNBQWtDO0FBQ2xDLGdEQUF3QjtBQUV4QixzQ0FBMEM7QUFHMUMsTUFBTSxvQkFBb0IsR0FBRyxLQUFLLElBQTRCLEVBQUU7SUFDOUQsTUFBTSxhQUFhLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyxVQUFVLElBQUksSUFBQSxpQkFBTyxHQUFFLENBQUM7SUFDMUQsTUFBTSxTQUFTLEdBQUcsY0FBSSxDQUFDLElBQUksQ0FBQyxhQUFhLEVBQUUsV0FBVyxFQUFFLFdBQVcsQ0FBQyxDQUFDO0lBRXJFLElBQUksRUFBRSxDQUFDLFVBQVUsQ0FBQyxTQUFTLENBQUM7UUFBRSxPQUFPLElBQUEsbUJBQVEsRUFBQyxTQUFTLEVBQUUsTUFBTSxDQUFDLENBQUM7SUFFakUsT0FBTyxJQUFJLENBQUM7QUFDZCxDQUFDLENBQUM7QUFFSyxLQUFLLFVBQVUsdUJBQXVCO0lBQzNDLE9BQU87UUFDTCxpQkFBaUIsRUFBRSxPQUFPLENBQUMsR0FBRyxDQUFDLGlCQUFpQjtRQUNoRCxpQkFBaUIsRUFBRSxPQUFPLENBQUMsR0FBRyxDQUFDLGlCQUFpQixJQUFJLDZCQUE2QjtRQUNqRix1QkFBdUIsRUFDckIsT0FBTyxDQUFDLEdBQUcsQ0FBQyx1QkFBdUIsSUFBSSx5Q0FBeUM7UUFDbEYsaUJBQWlCLEVBQUUsT0FBTyxDQUFDLEdBQUcsQ0FBQyxpQkFBaUIsSUFBSSxDQUFDLE1BQU0sb0JBQW9CLEVBQUUsQ0FBQztLQUNuRixDQUFDO0FBQ0osQ0FBQztBQVJELDBEQVFDO0FBRUQsU0FBUyxXQUFXLENBQUMsR0FBVyxFQUFFLFlBQW9CLEVBQUUsU0FBbUI7SUFDekUsSUFBSSxDQUFDLEdBQUcsRUFBRTtRQUNSLE1BQU0sSUFBSSxzQkFBYSxDQUFDLFdBQVcsWUFBWSxnQ0FBZ0MsQ0FBQyxDQUFDO0tBQ2xGO0lBRUQsSUFBSSxRQUFRLENBQUM7SUFFYixJQUFJO1FBQ0YsUUFBUSxHQUFHLElBQUksR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0tBQ3pCO0lBQUMsT0FBTyxHQUFHLEVBQUU7UUFDWixNQUFNLElBQUksc0JBQWEsQ0FDckIsR0FBRyxZQUFZLDhDQUE4QyxHQUFHLENBQUMsT0FBTyxFQUFFLENBQzNFLENBQUM7S0FDSDtJQUVELElBQUksQ0FBQyxTQUFTLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsRUFBRTtRQUMxQyxNQUFNLElBQUksc0JBQWEsQ0FDckIsR0FBRyxZQUFZLG9DQUFvQyxTQUFTO2FBQ3pELEdBQUcsQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDLEdBQUcsUUFBUSxJQUFJLENBQUM7YUFDaEMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxpQ0FBaUMsQ0FDbkQsQ0FBQztLQUNIO0FBQ0gsQ0FBQztBQUVELFNBQWdCLGlCQUFpQixDQUFDLFNBQWlCO0lBQ2pELFdBQVcsQ0FBQyxTQUFTLEVBQUUsbUJBQW1CLEVBQUUsQ0FBQyxPQUFPLEVBQUUsUUFBUSxDQUFDLENBQUMsQ0FBQztBQUNuRSxDQUFDO0FBRkQsOENBRUM7QUFFRCxTQUFnQix1QkFBdUIsQ0FBQyxlQUF1QjtJQUM3RCxXQUFXLENBQUMsZUFBZSxFQUFFLHlCQUF5QixFQUFFLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztBQUNwRSxDQUFDO0FBRkQsMERBRUM7QUFFRCxTQUFnQiw0QkFBNEIsQ0FBQyxHQUF5QjtJQUNwRSxJQUFJLENBQUMsR0FBRyxDQUFDLGlCQUFpQixFQUFFO1FBQzFCLE1BQU0sSUFBSSxzQkFBYSxDQUFDLHlEQUF5RCxDQUFDLENBQUM7S0FDcEY7SUFFRCxJQUFJLE9BQU8sR0FBRyxDQUFDLGlCQUFpQixLQUFLLFFBQVEsSUFBSSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsaUJBQWlCLENBQUMsRUFBRTtRQUM5RixNQUFNLElBQUksc0JBQWE7UUFDckIsbUNBQW1DO1FBQ25DLHFJQUFxSSxDQUN0SSxDQUFDO0tBQ0g7SUFFRCxJQUFJLENBQUMsR0FBRyxDQUFDLGlCQUFpQixFQUFFO1FBQzFCLE1BQU0sSUFBSSxzQkFBYSxDQUNyQiwrRUFBK0UsQ0FDaEYsQ0FBQztLQUNIO0lBRUQsaUJBQWlCLENBQUMsR0FBRyxDQUFDLGlCQUFpQixDQUFDLENBQUM7SUFDekMsdUJBQXVCLENBQUMsR0FBRyxDQUFDLHVCQUF1QixDQUFDLENBQUM7QUFDdkQsQ0FBQztBQXBCRCxvRUFvQkMifQ==
@@ -0,0 +1,12 @@
1
+ export default class EventSubscriber {
2
+ private readonly client;
3
+ private readonly subscriptionClient;
4
+ private failureSubscription;
5
+ private deployedSubscription;
6
+ constructor(subscriptionUrl: string, bearerToken: string);
7
+ subscribeToCodeCustomization(subscriptionId: string): Promise<{
8
+ error?: string;
9
+ }>;
10
+ destroy(): void;
11
+ }
12
+ //# sourceMappingURL=event-subscriber.d.ts.map
@@ -0,0 +1,66 @@
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
+ const apollo_cache_inmemory_1 = require("apollo-cache-inmemory");
7
+ const apollo_client_1 = require("apollo-client");
8
+ const apollo_link_ws_1 = require("apollo-link-ws");
9
+ const graphql_tag_1 = __importDefault(require("graphql-tag"));
10
+ const subscriptions_transport_ws_1 = require("subscriptions-transport-ws");
11
+ const ws_1 = __importDefault(require("ws"));
12
+ const errors_1 = require("../errors");
13
+ const CUSTOMIZATION_FAILED_SUBSCRIPTION = (0, graphql_tag_1.default) `
14
+ subscription FullHostedCustomizationFailed($publishId: String!) {
15
+ fullHostedCustomizationFailed(publishId: $publishId) {
16
+ error
17
+ }
18
+ }
19
+ `;
20
+ const CUSTOMIZATION_DEPLOYED_SUBSCRIPTION = (0, graphql_tag_1.default) `
21
+ subscription FullHostedCustomizationDeployed($publishId: String!) {
22
+ fullHostedCustomizationDeployed(publishId: $publishId) {
23
+ timestamp
24
+ }
25
+ }
26
+ `;
27
+ class EventSubscriber {
28
+ constructor(subscriptionUrl, bearerToken) {
29
+ this.subscriptionClient = new subscriptions_transport_ws_1.SubscriptionClient(subscriptionUrl, {
30
+ connectionParams: {
31
+ authToken: bearerToken,
32
+ },
33
+ }, ws_1.default);
34
+ const wsLink = new apollo_link_ws_1.WebSocketLink(this.subscriptionClient);
35
+ this.client = new apollo_client_1.ApolloClient({
36
+ link: wsLink,
37
+ cache: new apollo_cache_inmemory_1.InMemoryCache(),
38
+ });
39
+ }
40
+ async subscribeToCodeCustomization(subscriptionId) {
41
+ return new Promise((resolve, reject) => {
42
+ this.failureSubscription = this.client
43
+ .subscribe({
44
+ query: CUSTOMIZATION_FAILED_SUBSCRIPTION,
45
+ variables: { publishId: subscriptionId },
46
+ })
47
+ .subscribe(({ data }) => resolve(data.fullHostedCustomizationFailed), error => reject(error));
48
+ this.deployedSubscription = this.client
49
+ .subscribe({
50
+ query: CUSTOMIZATION_DEPLOYED_SUBSCRIPTION,
51
+ variables: { publishId: subscriptionId },
52
+ })
53
+ .subscribe(({ data }) => resolve(data.fullHostedCustomizationDeployed), error => reject(error));
54
+ }).catch(error => {
55
+ throw new errors_1.BusinessError(`Error while listening to code customization events: ${error.message}`);
56
+ });
57
+ }
58
+ destroy() {
59
+ this.failureSubscription?.unsubscribe();
60
+ this.deployedSubscription?.unsubscribe();
61
+ this.client.stop();
62
+ this.subscriptionClient.close();
63
+ }
64
+ }
65
+ exports.default = EventSubscriber;
66
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXZlbnQtc3Vic2NyaWJlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zZXJ2aWNlcy9ldmVudC1zdWJzY3JpYmVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsaUVBQTZFO0FBQzdFLGlEQUE2QztBQUM3QyxtREFBK0M7QUFDL0MsOERBQThCO0FBQzlCLDJFQUFnRTtBQUNoRSw0Q0FBMkI7QUFFM0Isc0NBQTBDO0FBRTFDLE1BQU0saUNBQWlDLEdBQUcsSUFBQSxxQkFBRyxFQUFBOzs7Ozs7Q0FNNUMsQ0FBQztBQUVGLE1BQU0sbUNBQW1DLEdBQUcsSUFBQSxxQkFBRyxFQUFBOzs7Ozs7Q0FNOUMsQ0FBQztBQUVGLE1BQXFCLGVBQWU7SUFPbEMsWUFBWSxlQUF1QixFQUFFLFdBQW1CO1FBQ3RELElBQUksQ0FBQyxrQkFBa0IsR0FBRyxJQUFJLCtDQUFrQixDQUM5QyxlQUFlLEVBQ2Y7WUFDRSxnQkFBZ0IsRUFBRTtnQkFDaEIsU0FBUyxFQUFFLFdBQVc7YUFDdkI7U0FDRixFQUNELFlBQVMsQ0FDVixDQUFDO1FBQ0YsTUFBTSxNQUFNLEdBQUcsSUFBSSw4QkFBYSxDQUFDLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO1FBRTFELElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSw0QkFBWSxDQUFDO1lBQzdCLElBQUksRUFBRSxNQUFNO1lBQ1osS0FBSyxFQUFFLElBQUkscUNBQWEsRUFBRTtTQUMzQixDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQsS0FBSyxDQUFDLDRCQUE0QixDQUFDLGNBQXNCO1FBQ3ZELE9BQU8sSUFBSSxPQUFPLENBQUMsQ0FBQyxPQUFPLEVBQUUsTUFBTSxFQUFFLEVBQUU7WUFDckMsSUFBSSxDQUFDLG1CQUFtQixHQUFHLElBQUksQ0FBQyxNQUFNO2lCQUNuQyxTQUFTLENBQUM7Z0JBQ1QsS0FBSyxFQUFFLGlDQUFpQztnQkFDeEMsU0FBUyxFQUFFLEVBQUUsU0FBUyxFQUFFLGNBQWMsRUFBRTthQUN6QyxDQUFDO2lCQUNELFNBQVMsQ0FDUixDQUFDLEVBQUUsSUFBSSxFQUFFLEVBQUUsRUFBRSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsNkJBQTZCLENBQUMsRUFDekQsS0FBSyxDQUFDLEVBQUUsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQ3ZCLENBQUM7WUFFSixJQUFJLENBQUMsb0JBQW9CLEdBQUcsSUFBSSxDQUFDLE1BQU07aUJBQ3BDLFNBQVMsQ0FBQztnQkFDVCxLQUFLLEVBQUUsbUNBQW1DO2dCQUMxQyxTQUFTLEVBQUUsRUFBRSxTQUFTLEVBQUUsY0FBYyxFQUFFO2FBQ3pDLENBQUM7aUJBQ0QsU0FBUyxDQUNSLENBQUMsRUFBRSxJQUFJLEVBQUUsRUFBRSxFQUFFLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQywrQkFBK0IsQ0FBQyxFQUMzRCxLQUFLLENBQUMsRUFBRSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FDdkIsQ0FBQztRQUNOLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsRUFBRTtZQUNmLE1BQU0sSUFBSSxzQkFBYSxDQUNyQix1REFBd0QsS0FBZSxDQUFDLE9BQU8sRUFBRSxDQUNsRixDQUFDO1FBQ0osQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQsT0FBTztRQUNMLElBQUksQ0FBQyxtQkFBbUIsRUFBRSxXQUFXLEVBQUUsQ0FBQztRQUN4QyxJQUFJLENBQUMsb0JBQW9CLEVBQUUsV0FBVyxFQUFFLENBQUM7UUFDekMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUNuQixJQUFJLENBQUMsa0JBQWtCLENBQUMsS0FBSyxFQUFFLENBQUM7SUFDbEMsQ0FBQztDQUNGO0FBM0RELGtDQTJEQyJ9
@@ -0,0 +1,25 @@
1
+ import { Table } from '@forestadmin/datasource-sql';
2
+ export default class HttpServer {
3
+ private readonly serverUrl;
4
+ private readonly headers;
5
+ constructor(serverUrl: string, secretKey: string, bearerToken: string);
6
+ static downloadCloudCustomizerTemplate(destination: string): Promise<void>;
7
+ getIntrospection(): Promise<Table[]>;
8
+ postUploadRequest(contentLength: number): Promise<{
9
+ url: string;
10
+ fields: Record<string, string>;
11
+ }>;
12
+ postPublish(): Promise<{
13
+ subscriptionId: string;
14
+ }>;
15
+ getLastPublishedCodeDetails(): Promise<{
16
+ date: Date;
17
+ relativeDate: string;
18
+ user: {
19
+ name: string;
20
+ email: string;
21
+ };
22
+ }>;
23
+ static getLatestVersion(packageName: string): Promise<string>;
24
+ }
25
+ //# sourceMappingURL=http-server.d.ts.map
@@ -0,0 +1,110 @@
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 (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ var __importDefault = (this && this.__importDefault) || function (mod) {
26
+ return (mod && mod.__esModule) ? mod : { "default": mod };
27
+ };
28
+ Object.defineProperty(exports, "__esModule", { value: true });
29
+ const axios = __importStar(require("axios"));
30
+ const fs = __importStar(require("fs"));
31
+ const latest_version_1 = __importDefault(require("latest-version"));
32
+ const errors_1 = require("../errors");
33
+ async function handledAxios(axiosRequestConfig, { errorMessage }) {
34
+ try {
35
+ return (await axios.default(axiosRequestConfig)).data;
36
+ }
37
+ catch (e) {
38
+ const error = e;
39
+ let details;
40
+ if (error instanceof axios.AxiosError) {
41
+ const errors = error.response?.data?.errors;
42
+ details = errors?.map(innerError => `\n 🚨 ${innerError.detail}`);
43
+ }
44
+ const detailsOrEmpty = details ? ` ${details}` : '';
45
+ throw new errors_1.BusinessError(`${errorMessage}: ${error.message}${detailsOrEmpty}`);
46
+ }
47
+ }
48
+ class HttpServer {
49
+ constructor(serverUrl, secretKey, bearerToken) {
50
+ this.serverUrl = serverUrl;
51
+ this.headers = {
52
+ 'forest-secret-key': secretKey,
53
+ Authorization: `Bearer ${bearerToken}`,
54
+ 'Content-Type': 'application/json',
55
+ };
56
+ }
57
+ static async downloadCloudCustomizerTemplate(destination) {
58
+ const response = await axios.default({
59
+ url: 'https://github.com/ForestAdmin/cloud-customizer/archive/main.zip',
60
+ method: 'get',
61
+ responseType: 'stream',
62
+ });
63
+ const stream = fs.createWriteStream(destination);
64
+ response.data.pipe(stream);
65
+ await new Promise((resolve, reject) => {
66
+ stream.on('finish', resolve);
67
+ stream.on('error', reject);
68
+ });
69
+ }
70
+ async getIntrospection() {
71
+ return handledAxios({
72
+ url: `${this.serverUrl}/api/full-hosted-agent/introspection`,
73
+ method: 'GET',
74
+ headers: this.headers,
75
+ }, {
76
+ errorMessage: 'Failed to retrieve database schema from Forest Admin server',
77
+ });
78
+ }
79
+ async postUploadRequest(contentLength) {
80
+ return handledAxios({
81
+ url: `${this.serverUrl}/api/full-hosted-agent/upload-request`,
82
+ method: 'POST',
83
+ headers: this.headers,
84
+ data: { contentLength },
85
+ }, {
86
+ errorMessage: 'Failed to request upload url from Forest Admin server',
87
+ });
88
+ }
89
+ async postPublish() {
90
+ return handledAxios({
91
+ url: `${this.serverUrl}/api/full-hosted-agent/publish`,
92
+ method: 'POST',
93
+ headers: this.headers,
94
+ }, {
95
+ errorMessage: 'Failed to request publication of code customization',
96
+ });
97
+ }
98
+ async getLastPublishedCodeDetails() {
99
+ return handledAxios({
100
+ url: `${this.serverUrl}/api/full-hosted-agent/last-published-code-details`,
101
+ method: 'GET',
102
+ headers: this.headers,
103
+ }, { errorMessage: `Failed to retrieve last published code details` });
104
+ }
105
+ static async getLatestVersion(packageName) {
106
+ return (0, latest_version_1.default)(packageName);
107
+ }
108
+ }
109
+ exports.default = HttpServer;
110
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaHR0cC1zZXJ2ZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc2VydmljZXMvaHR0cC1zZXJ2ZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUNBLDZDQUErQjtBQUMvQix1Q0FBeUI7QUFDekIsb0VBQTJDO0FBRTNDLHNDQUEwQztBQUUxQyxLQUFLLFVBQVUsWUFBWSxDQUN6QixrQkFBNEMsRUFDNUMsRUFBRSxZQUFZLEVBQTRCO0lBRTFDLElBQUk7UUFDRixPQUFPLENBQUMsTUFBTSxLQUFLLENBQUMsT0FBTyxDQUFDLGtCQUFrQixDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUM7S0FDdkQ7SUFBQyxPQUFPLENBQUMsRUFBRTtRQUNWLE1BQU0sS0FBSyxHQUFVLENBQUMsQ0FBQztRQUV2QixJQUFJLE9BQU8sQ0FBQztRQUVaLElBQUksS0FBSyxZQUFZLEtBQUssQ0FBQyxVQUFVLEVBQUU7WUFDckMsTUFBTSxNQUFNLEdBQXlDLEtBQUssQ0FBQyxRQUFRLEVBQUUsSUFBSSxFQUFFLE1BQU0sQ0FBQztZQUNsRixPQUFPLEdBQUcsTUFBTSxFQUFFLEdBQUcsQ0FBQyxVQUFVLENBQUMsRUFBRSxDQUFDLFNBQVMsVUFBVSxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUM7U0FDbkU7UUFFRCxNQUFNLGNBQWMsR0FBRyxPQUFPLENBQUMsQ0FBQyxDQUFDLElBQUksT0FBTyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztRQUNwRCxNQUFNLElBQUksc0JBQWEsQ0FBQyxHQUFHLFlBQVksS0FBSyxLQUFLLENBQUMsT0FBTyxHQUFHLGNBQWMsRUFBRSxDQUFDLENBQUM7S0FDL0U7QUFDSCxDQUFDO0FBRUQsTUFBcUIsVUFBVTtJQUc3QixZQUFZLFNBQWlCLEVBQUUsU0FBaUIsRUFBRSxXQUFtQjtRQUNuRSxJQUFJLENBQUMsU0FBUyxHQUFHLFNBQVMsQ0FBQztRQUMzQixJQUFJLENB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
@@ -0,0 +1,3 @@
1
+ import DistPathManager from './dist-path-manager';
2
+ export default function packageCustomizations(distPathManager: DistPathManager): Promise<void>;
3
+ //# sourceMappingURL=packager.d.ts.map
@@ -0,0 +1,17 @@
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
+ const adm_zip_1 = __importDefault(require("adm-zip"));
7
+ const path_1 = __importDefault(require("path"));
8
+ const access_file_1 = require("./access-file");
9
+ async function packageCustomizations(distPathManager) {
10
+ const { zip: zipPath, distCodeCustomizations: distPath } = distPathManager;
11
+ await (0, access_file_1.throwIfNoBuiltCode)(distPath);
12
+ const zip = new adm_zip_1.default();
13
+ zip.addLocalFolder(distPath, path_1.default.join('nodejs', 'customization'));
14
+ await zip.writeZipPromise(zipPath, { overwrite: true });
15
+ }
16
+ exports.default = packageCustomizations;
17
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFja2FnZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc2VydmljZXMvcGFja2FnZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSxzREFBNkI7QUFDN0IsZ0RBQXdCO0FBRXhCLCtDQUFtRDtBQUdwQyxLQUFLLFVBQVUscUJBQXFCLENBQUMsZUFBZ0M7SUFDbEYsTUFBTSxFQUFFLEdBQUcsRUFBRSxPQUFPLEVBQUUsc0JBQXNCLEVBQUUsUUFBUSxFQUFFLEdBQUcsZUFBZSxDQUFDO0lBQzNFLE1BQU0sSUFBQSxnQ0FBa0IsRUFBQyxRQUFRLENBQUMsQ0FBQztJQUNuQyxNQUFNLEdBQUcsR0FBVyxJQUFJLGlCQUFNLEVBQUUsQ0FBQztJQUNqQyxHQUFHLENBQUMsY0FBYyxDQUFDLFFBQVEsRUFBRSxjQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxlQUFlLENBQUMsQ0FBQyxDQUFDO0lBQ25FLE1BQU0sR0FBRyxDQUFDLGVBQWUsQ0FBQyxPQUFPLEVBQUUsRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztBQUMxRCxDQUFDO0FBTkQsd0NBTUMifQ==
@@ -0,0 +1,4 @@
1
+ import DistPathManager from './dist-path-manager';
2
+ import HttpServer from './http-server';
3
+ export default function publish(httpServer: HttpServer, distPathManager: DistPathManager): Promise<string>;
4
+ //# sourceMappingURL=publish.d.ts.map
@@ -0,0 +1,47 @@
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
+ const adm_zip_1 = __importDefault(require("adm-zip"));
7
+ const form_data_1 = __importDefault(require("form-data"));
8
+ const errors_1 = require("../errors");
9
+ function getKeyFromPolicy(policy) {
10
+ const decoded = JSON.parse(Buffer.from(policy.split('.')[0], 'base64').toString());
11
+ const keyCondition = decoded.conditions?.find(condition => Array.isArray(condition) && condition[0] === 'starts-with' && condition[1] === '$key');
12
+ return keyCondition[2];
13
+ }
14
+ async function publish(httpServer, distPathManager) {
15
+ try {
16
+ let buffer;
17
+ const zipPath = distPathManager.zip;
18
+ try {
19
+ const zip = new adm_zip_1.default(zipPath);
20
+ buffer = zip.toBuffer();
21
+ }
22
+ catch (error) {
23
+ throw new errors_1.BusinessError(`Cannot read code-customization zip file - At path: ${zipPath}\n ${error.message}`);
24
+ }
25
+ const { url, fields } = await httpServer.postUploadRequest(buffer.byteLength);
26
+ const form = new form_data_1.default();
27
+ form.append('key', getKeyFromPolicy(fields.Policy));
28
+ Object.entries(fields).forEach(([field, value]) => {
29
+ form.append(field, value);
30
+ });
31
+ form.append('file', buffer);
32
+ await new Promise((resolve, reject) => {
33
+ form.submit(url, (err, res) => {
34
+ if (err)
35
+ reject(err);
36
+ resolve(res);
37
+ });
38
+ });
39
+ const { subscriptionId } = await httpServer.postPublish();
40
+ return subscriptionId;
41
+ }
42
+ catch (error) {
43
+ throw new errors_1.BusinessError(`Publish failed: ${error.message}`);
44
+ }
45
+ }
46
+ exports.default = publish;
47
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHVibGlzaC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zZXJ2aWNlcy9wdWJsaXNoLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsc0RBQTZCO0FBQzdCLDBEQUFpQztBQUlqQyxzQ0FBMEM7QUFFMUMsU0FBUyxnQkFBZ0IsQ0FBQyxNQUFjO0lBQ3RDLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLFFBQVEsQ0FBQyxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUM7SUFDbkYsTUFBTSxZQUFZLEdBQUcsT0FBTyxDQUFDLFVBQVUsRUFBRSxJQUFJLENBQzNDLFNBQVMsQ0FBQyxFQUFFLENBQ1YsS0FBSyxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsSUFBSSxTQUFTLENBQUMsQ0FBQyxDQUFDLEtBQUssYUFBYSxJQUFJLFNBQVMsQ0FBQyxDQUFDLENBQUMsS0FBSyxNQUFNLENBQ3hGLENBQUM7SUFFRixPQUFPLFlBQVksQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN6QixDQUFDO0FBRWMsS0FBSyxVQUFVLE9BQU8sQ0FDbkMsVUFBc0IsRUFDdEIsZUFBZ0M7SUFFaEMsSUFBSTtRQUNGLElBQUksTUFBYyxDQUFDO1FBQ25CLE1BQU0sT0FBTyxHQUFHLGVBQWUsQ0FBQyxHQUFHLENBQUM7UUFFcEMsSUFBSTtZQUNGLE1BQU0sR0FBRyxHQUFXLElBQUksaUJBQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUN4QyxNQUFNLEdBQUcsR0FBRyxDQUFDLFFBQVEsRUFBRSxDQUFDO1NBQ3pCO1FBQUMsT0FBTyxLQUFLLEVBQUU7WUFDZCxNQUFNLElBQUksc0JBQWEsQ0FDckIsc0RBQXNELE9BQU8sTUFBTSxLQUFLLENBQUMsT0FBTyxFQUFFLENBQ25GLENBQUM7U0FDSDtRQUVELE1BQU0sRUFBRSxHQUFHLEVBQUUsTUFBTSxFQUFFLEdBQUcsTUFBTSxVQUFVLENBQUMsaUJBQWlCLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBRTlFLE1BQU0sSUFBSSxHQUFHLElBQUksbUJBQVEsRUFBRSxDQUFDO1FBQzVCLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxFQUFFLGdCQUFnQixDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDO1FBQ3BELE1BQU0sQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxLQUFLLEVBQUUsS0FBSyxDQUFDLEVBQUUsRUFBRTtZQUNoRCxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssRUFBRSxLQUFLLENBQUMsQ0FBQztRQUM1QixDQUFDLENBQUMsQ0FBQztRQUNILElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1FBRTVCLE1BQU0sSUFBSSxPQUFPLENBQUMsQ0FBQyxPQUFPLEVBQUUsTUFBTSxFQUFFLEVBQUU7WUFDcEMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLEVBQUU7Z0JBQzVCLElBQUksR0FBRztvQkFBRSxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUM7Z0JBQ3JCLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUNmLENBQUMsQ0FBQyxDQUFDO1FBQ0wsQ0FBQyxDQUFDLENBQUM7UUFFSCxNQUFNLEVBQUUsY0FBYyxFQUFFLEdBQUcsTUFBTSxVQUFVLENBQUMsV0FBVyxFQUFFLENBQUM7UUFFMUQsT0FBTyxjQUFjLENBQUM7S0FDdkI7SUFBQyxPQUFPLEtBQUssRUFBRTtRQUNkLE1BQU0sSUFBSSxzQkFBYSxDQUFDLG1CQUFtQixLQUFLLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQztLQUM3RDtBQUNILENBQUM7QUF2Q0QsMEJBdUNDIn0=
@@ -0,0 +1,6 @@
1
+ import { Table } from '@forestadmin/datasource-sql';
2
+ import BootstrapPathManager from './bootstrap-path-manager';
3
+ import DistPathManager from './dist-path-manager';
4
+ export declare function updateTypings(introspection: Table[], bootstrapPathManager: BootstrapPathManager): Promise<void>;
5
+ export declare function updateTypingsWithCustomizations(introspection: Table[], distPathManager: DistPathManager, bootstrapPathManager: BootstrapPathManager): Promise<void>;
6
+ //# sourceMappingURL=update-typings.d.ts.map
@@ -0,0 +1,50 @@
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.updateTypingsWithCustomizations = exports.updateTypings = void 0;
7
+ const agent_1 = require("@forestadmin/agent");
8
+ const datasource_sql_1 = require("@forestadmin/datasource-sql");
9
+ const path_1 = __importDefault(require("path"));
10
+ const access_file_1 = require("./access-file");
11
+ const errors_1 = require("../errors");
12
+ function loadCustomization(agent, builtCodePath) {
13
+ // eslint-disable-next-line
14
+ const customization = require(builtCodePath);
15
+ const entryPoint = customization?.default || customization;
16
+ if (typeof entryPoint !== 'function') {
17
+ throw new errors_1.CustomizationError('Customization file must export a function');
18
+ }
19
+ try {
20
+ entryPoint(agent);
21
+ }
22
+ catch (error) {
23
+ throw new errors_1.CustomizationError(`Issue with customizations: ${error.name}\n${error.message}`, error.stack);
24
+ }
25
+ }
26
+ function buildAgent(introspection) {
27
+ const agentOptions = {
28
+ authSecret: 'a'.repeat(64),
29
+ envSecret: 'a'.repeat(64),
30
+ loggerLevel: 'Error',
31
+ isProduction: false,
32
+ };
33
+ const agent = (0, agent_1.createAgent)(agentOptions);
34
+ agent.addDataSource((0, datasource_sql_1.createSqlDataSource)(`sqlite::memory:`, { introspection }));
35
+ return agent;
36
+ }
37
+ async function updateTypings(introspection, bootstrapPathManager) {
38
+ const agent = buildAgent(introspection);
39
+ await agent.updateTypesOnFileSystem(bootstrapPathManager.typingsDuringBootstrap, 3);
40
+ }
41
+ exports.updateTypings = updateTypings;
42
+ async function updateTypingsWithCustomizations(introspection, distPathManager, bootstrapPathManager) {
43
+ const builtCodePath = path_1.default.resolve(distPathManager.distCodeCustomizations);
44
+ await (0, access_file_1.throwIfNoBuiltCode)(builtCodePath);
45
+ const agent = buildAgent(introspection);
46
+ loadCustomization(agent, builtCodePath);
47
+ await agent.updateTypesOnFileSystem(bootstrapPathManager.typings, 3);
48
+ }
49
+ exports.updateTypingsWithCustomizations = updateTypingsWithCustomizations;
50
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXBkYXRlLXR5cGluZ3MuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc2VydmljZXMvdXBkYXRlLXR5cGluZ3MudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBQUEsOENBQStEO0FBQy9ELGdFQUF5RTtBQUN6RSxnREFBd0I7QUFFeEIsK0NBQW1EO0FBR25ELHNDQUErQztBQUcvQyxTQUFTLGlCQUFpQixDQUFDLEtBQVksRUFBRSxhQUFxQjtJQUM1RCwyQkFBMkI7SUFDM0IsTUFBTSxhQUFhLEdBQUcsT0FBTyxDQUFDLGFBQWEsQ0FBQyxDQUFDO0lBQzdDLE1BQU0sVUFBVSxHQUFHLGFBQWEsRUFBRSxPQUFPLElBQUksYUFBYSxDQUFDO0lBRTNELElBQUksT0FBTyxVQUFVLEtBQUssVUFBVSxFQUFFO1FBQ3BDLE1BQU0sSUFBSSwyQkFBa0IsQ0FBQywyQ0FBMkMsQ0FBQyxDQUFDO0tBQzNFO0lBRUQsSUFBSTtRQUNGLFVBQVUsQ0FBQyxLQUFLLENBQUMsQ0FBQztLQUNuQjtJQUFDLE9BQU8sS0FBSyxFQUFFO1FBQ2QsTUFBTSxJQUFJLDJCQUFrQixDQUMxQiw4QkFBOEIsS0FBSyxDQUFDLElBQUksS0FBSyxLQUFLLENBQUMsT0FBTyxFQUFFLEVBQzVELEtBQUssQ0FBQyxLQUFLLENBQ1osQ0FBQztLQUNIO0FBQ0gsQ0FBQztBQUVELFNBQVMsVUFBVSxDQUFDLGFBQXNCO0lBQ3hDLE1BQU0sWUFBWSxHQUFpQjtRQUNqQyxVQUFVLEVBQUUsR0FBRyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUM7UUFDMUIsU0FBUyxFQUFFLEdBQUcsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDO1FBQ3pCLFdBQVcsRUFBRSxPQUFPO1FBQ3BCLFlBQVksRUFBRSxLQUFLO0tBQ3BCLENBQUM7SUFDRixNQUFNLEtBQUssR0FBRyxJQUFBLG1CQUFXLEVBQUMsWUFBWSxDQUFDLENBQUM7SUFDeEMsS0FBSyxDQUFDLGFBQWEsQ0FBQyxJQUFBLG9DQUFtQixFQUFDLGlCQUFpQixFQUFFLEVBQUUsYUFBYSxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBRS9FLE9BQU8sS0FBSyxDQUFDO0FBQ2YsQ0FBQztBQUVNLEtBQUssVUFBVSxhQUFhLENBQ2pDLGFBQXNCLEVBQ3RCLG9CQUEwQztJQUUxQyxNQUFNLEtBQUssR0FBRyxVQUFVLENBQUMsYUFBYSxDQUFDLENBQUM7SUFDeEMsTUFBTSxLQUFLLENBQUMsdUJBQXVCLENBQUMsb0JBQW9CLENBQUMsc0JBQXNCLEVBQUUsQ0FBQyxDQUFDLENBQUM7QUFDdEYsQ0FBQztBQU5ELHNDQU1DO0FBRU0sS0FBSyxVQUFVLCtCQUErQixDQUNuRCxhQUFzQixFQUN0QixlQUFnQyxFQUNoQyxvQkFBMEM7SUFFMUMsTUFBTSxhQUFhLEdBQUcsY0FBSSxDQUFDLE9BQU8sQ0FBQyxlQUFlLENBQUMsc0JBQXNCLENBQUMsQ0FBQztJQUMzRSxNQUFNLElBQUEsZ0NBQWtCLEVBQUMsYUFBYSxDQUFDLENBQUM7SUFDeEMsTUFBTSxLQUFLLEdBQUcsVUFBVSxDQUFDLGFBQWEsQ0FBQyxDQUFDO0lBQ3hDLGlCQUFpQixDQUFDLEtBQUssRUFBRSxhQUFhLENBQUMsQ0FBQztJQUN4QyxNQUFNLEtBQUssQ0FBQyx1QkFBdUIsQ0FBQyxvQkFBb0IsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDLENBQUM7QUFDdkUsQ0FBQztBQVZELDBFQVVDIn0=
@@ -0,0 +1,2 @@
1
+ FOREST_ENV_SECRET=<FOREST_ENV_SECRET_TO_REPLACE>
2
+ TOKEN_PATH=<TOKEN_PATH_TO_REPLACE>
@@ -0,0 +1,19 @@
1
+ import type { Agent } from '@forestadmin/forest-cloud';
2
+
3
+ import { Schema } from '../typings';
4
+
5
+ /*
6
+ You can find the documentation of the agent at the following URL to
7
+ help you to understand how to use the agent and how to customize your project.
8
+ =======================================================================
9
+ ===== https://docs.forestadmin.com/developer-guide-agents-nodejs/ =====
10
+ =======================================================================
11
+
12
+ Run with npm or yarn this command to publish this code to your backend.
13
+ =======================================================================
14
+ ================== forestadmin:build:package:publish ==================
15
+ =======================================================================
16
+ */
17
+ export default function customizeAgent(agent: Agent<Schema>) {
18
+
19
+ }
@@ -0,0 +1,87 @@
1
+ import type { CollectionCustomizer, DataSourceChartDefinition, Plugin, TCollectionName, TSchema } from '@forestadmin/datasource-customizer';
2
+ import BootstrapPathManager from './services/bootstrap-path-manager';
3
+ import DistPathManager from './services/dist-path-manager';
4
+ import EventSubscriber from './services/event-subscriber';
5
+ import HttpServer from './services/http-server';
6
+ /**
7
+ * This agent the central object used to customize your cloud project
8
+ * some methods available in self-hosted, such as:
9
+ * @method addDataSource are currently not supported in cloud
10
+ */
11
+ export type Agent<S extends TSchema = TSchema> = {
12
+ /**
13
+ * Allow to interact with a decorated collection
14
+ * @param name the name of the collection to manipulate
15
+ * @param handle a function that provide a collection builder on the given collection name
16
+ * @see {@link https://docs.forestadmin.com/developer-guide-agents-nodejs/agent-customization/agent-customization Documentation Link}
17
+ * @example
18
+ * .customizeCollection('books', books => books.renameField('xx', 'yy'))
19
+ */
20
+ customizeCollection<N extends TCollectionName<S>>(name: N, handle: (collection: CollectionCustomizer<S, N>) => unknown): Agent<S>;
21
+ /**
22
+ * Remove collections from the exported schema (they will still be usable within the agent).
23
+ * @param names the collections to remove
24
+ * @example
25
+ * .removeField('aCollectionToRemove', 'anotherCollectionToRemove');
26
+ */
27
+ removeCollection(...names: TCollectionName<S>[]): Agent<S>;
28
+ /**
29
+ * Create a new API chart
30
+ * @param name name of the chart
31
+ * @param definition definition of the chart
32
+ * @see {@link https://docs.forestadmin.com/developer-guide-agents-nodejs/agent-customization/charts Documentation Link}
33
+ * @example
34
+ * .addChart('numCustomers', (context, resultBuilder) => {
35
+ * return resultBuilder.distribution({
36
+ * tomatoes: 10,
37
+ * potatoes: 20,
38
+ * carrots: 30,
39
+ * });
40
+ * })
41
+ */
42
+ addChart(name: string, definition: DataSourceChartDefinition<S>): Agent<S>;
43
+ /**
44
+ * Load a plugin across all collections
45
+ * @param plugin instance of the plugin
46
+ * @param options options which need to be passed to the plugin
47
+ * @see {@link https://docs.forestadmin.com/developer-guide-agents-nodejs/agent-customization/plugins Documentation Link}
48
+ * @example
49
+ * import advancedExportPlugin from '@forestadmin/plugin-advanced-export';
50
+ *
51
+ * agent.use(advancedExportPlugin, { format: 'xlsx' });
52
+ */
53
+ use<Options>(plugin: Plugin<Options>, options?: Options): Agent<S>;
54
+ };
55
+ export type EnvironmentVariables = {
56
+ FOREST_ENV_SECRET: string;
57
+ FOREST_SERVER_URL: string;
58
+ FOREST_SUBSCRIPTION_URL: string;
59
+ FOREST_AUTH_TOKEN: string;
60
+ };
61
+ export type MakeCommands = {
62
+ buildEventSubscriber: BuildEventSubscriber;
63
+ buildHttpServer: BuildHttpServer;
64
+ getEnvironmentVariables: () => Promise<EnvironmentVariables>;
65
+ getCurrentVersion: () => string;
66
+ bootstrapPathManager: BootstrapPathManager;
67
+ distPathManager: DistPathManager;
68
+ logger: Logger;
69
+ login: Login;
70
+ };
71
+ export type Spinner = {
72
+ start: (text?: string) => void;
73
+ succeed: (text?: string) => void;
74
+ warn: (text?: string) => void;
75
+ info: (text?: string) => void;
76
+ fail: (text?: string) => void;
77
+ stop: () => void;
78
+ };
79
+ export type Logger = {
80
+ spinner: Spinner;
81
+ log: (text?: string) => void;
82
+ error: (text?: string) => void;
83
+ };
84
+ export type Login = (logger: Logger) => Promise<void>;
85
+ export type BuildHttpServer = (envs: EnvironmentVariables) => HttpServer;
86
+ export type BuildEventSubscriber = (vars: EnvironmentVariables) => EventSubscriber;
87
+ //# sourceMappingURL=types.d.ts.map
package/dist/types.js ADDED
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvdHlwZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IiJ9