@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.
- package/LICENSE +674 -0
- package/README.md +21 -0
- package/dist/build-command.d.ts +2 -0
- package/dist/build-command.js +48 -0
- package/dist/command.d.ts +3 -0
- package/dist/command.js +12 -0
- package/dist/dialogs/action-runner.d.ts +3 -0
- package/dist/dialogs/action-runner.js +28 -0
- package/dist/dialogs/ask-to-overwrite-customizations.d.ts +4 -0
- package/dist/dialogs/ask-to-overwrite-customizations.js +30 -0
- package/dist/dialogs/check-latest-version.d.ts +4 -0
- package/dist/dialogs/check-latest-version.js +24 -0
- package/dist/errors.d.ts +8 -0
- package/dist/errors.js +18 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +3 -0
- package/dist/login.d.ts +3 -0
- package/dist/login.js +23 -0
- package/dist/make-commands.d.ts +5 -0
- package/dist/make-commands.js +136 -0
- package/dist/services/access-file.d.ts +2 -0
- package/dist/services/access-file.js +20 -0
- package/dist/services/bootstrap-path-manager.d.ts +18 -0
- package/dist/services/bootstrap-path-manager.js +48 -0
- package/dist/services/bootstrap.d.ts +4 -0
- package/dist/services/bootstrap.js +79 -0
- package/dist/services/dist-path-manager.d.ts +7 -0
- package/dist/services/dist-path-manager.js +19 -0
- package/dist/services/environment-variables.d.ts +6 -0
- package/dist/services/environment-variables.js +92 -0
- package/dist/services/event-subscriber.d.ts +12 -0
- package/dist/services/event-subscriber.js +66 -0
- package/dist/services/http-server.d.ts +25 -0
- package/dist/services/http-server.js +110 -0
- package/dist/services/packager.d.ts +3 -0
- package/dist/services/packager.js +17 -0
- package/dist/services/publish.d.ts +4 -0
- package/dist/services/publish.js +47 -0
- package/dist/services/update-typings.d.ts +6 -0
- package/dist/services/update-typings.js +50 -0
- package/dist/templates/env.txt +2 -0
- package/dist/templates/index.txt +19 -0
- package/dist/types.d.ts +87 -0
- package/dist/types.js +3 -0
- 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,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,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,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
|
+
}
|
package/dist/types.d.ts
ADDED
|
@@ -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