@forge/runtime 5.7.0-next.0 → 5.8.0-next.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/CHANGELOG.md +12 -0
- package/out/app-manifest.js +13 -12
- package/out/context.js +3 -6
- package/out/feature-flag.js +3 -4
- package/out/limits/tracker.js +2 -2
- package/out/metrics/metrics.js +0 -1
- package/out/sandbox/inspector.js +35 -41
- package/out/sandbox/invocation-request.js +15 -20
- package/out/sandbox/sandbox.d.ts +1 -0
- package/out/sandbox/sandbox.d.ts.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# @forge/runtime
|
|
2
2
|
|
|
3
|
+
## 5.8.0-next.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- ee4e0a1: allow app developer choose location to save the bundled app code
|
|
8
|
+
|
|
9
|
+
## 5.7.0
|
|
10
|
+
|
|
11
|
+
### Minor Changes
|
|
12
|
+
|
|
13
|
+
- 092b932: hasCredentials to check only the account to be used
|
|
14
|
+
|
|
3
15
|
## 5.7.0-next.0
|
|
4
16
|
|
|
5
17
|
### Minor Changes
|
package/out/app-manifest.js
CHANGED
|
@@ -45,14 +45,6 @@ const AppManifestRequiredFields = t.type({
|
|
|
45
45
|
});
|
|
46
46
|
const AppManifestType = t.intersection([AppManifestRequiredFields, AppManifestOptionalFields]);
|
|
47
47
|
class AppManifest {
|
|
48
|
-
static FILE_NAME = 'manifest.yml';
|
|
49
|
-
static async fromFile(filePath) {
|
|
50
|
-
const fullPath = path_1.default.join(filePath, AppManifest.FILE_NAME);
|
|
51
|
-
const manifestContents = (0, fs_1.readFileSync)(fullPath, 'utf-8');
|
|
52
|
-
const manifest = yaml_1.default.parse(manifestContents);
|
|
53
|
-
return new AppManifest(manifest);
|
|
54
|
-
}
|
|
55
|
-
manifest;
|
|
56
48
|
constructor(manifest) {
|
|
57
49
|
if (!AppManifestType.is(manifest)) {
|
|
58
50
|
throw new Error('invalid manifest');
|
|
@@ -61,23 +53,32 @@ class AppManifest {
|
|
|
61
53
|
this.manifest = manifest;
|
|
62
54
|
}
|
|
63
55
|
}
|
|
56
|
+
static async fromFile(filePath) {
|
|
57
|
+
const fullPath = path_1.default.join(filePath, AppManifest.FILE_NAME);
|
|
58
|
+
const manifestContents = (0, fs_1.readFileSync)(fullPath, 'utf-8');
|
|
59
|
+
const manifest = yaml_1.default.parse(manifestContents);
|
|
60
|
+
return new AppManifest(manifest);
|
|
61
|
+
}
|
|
64
62
|
getHostForRemote(remote) {
|
|
65
|
-
|
|
66
|
-
|
|
63
|
+
var _a;
|
|
64
|
+
const found = (_a = this.manifest.remotes) === null || _a === void 0 ? void 0 : _a.find(({ key }) => key === remote);
|
|
65
|
+
return found === null || found === void 0 ? void 0 : found.baseUrl;
|
|
67
66
|
}
|
|
68
67
|
getDefaultRemoteForProvider(provider) {
|
|
69
68
|
const providerConfig = this.getExternalAuthProviderConfig(provider);
|
|
70
|
-
const remotes = providerConfig
|
|
69
|
+
const remotes = providerConfig === null || providerConfig === void 0 ? void 0 : providerConfig.remotes;
|
|
71
70
|
if (remotes && remotes.length > 0) {
|
|
72
71
|
return remotes[0];
|
|
73
72
|
}
|
|
74
73
|
return undefined;
|
|
75
74
|
}
|
|
76
75
|
getExternalAuthProviderConfig(provider) {
|
|
77
|
-
|
|
76
|
+
var _a;
|
|
77
|
+
return (_a = this.manifest.providers) === null || _a === void 0 ? void 0 : _a.auth.find((v) => v.key === provider);
|
|
78
78
|
}
|
|
79
79
|
getEgressAllowlist() {
|
|
80
80
|
return this.manifest.egress || [];
|
|
81
81
|
}
|
|
82
82
|
}
|
|
83
83
|
exports.AppManifest = AppManifest;
|
|
84
|
+
AppManifest.FILE_NAME = 'manifest.yml';
|
package/out/context.js
CHANGED
|
@@ -31,21 +31,18 @@ function createPrincipal(cfg) {
|
|
|
31
31
|
}
|
|
32
32
|
exports.createPrincipal = createPrincipal;
|
|
33
33
|
function createLicenseContext(cfg) {
|
|
34
|
+
var _a;
|
|
34
35
|
const { license } = cfg.meta;
|
|
35
36
|
if (license) {
|
|
36
37
|
return {
|
|
37
38
|
license: {
|
|
38
|
-
isActive: license.isActive
|
|
39
|
+
isActive: (_a = license.isActive) !== null && _a !== void 0 ? _a : false
|
|
39
40
|
}
|
|
40
41
|
};
|
|
41
42
|
}
|
|
42
43
|
}
|
|
43
44
|
exports.createLicenseContext = createLicenseContext;
|
|
44
45
|
function setupRequestContext(cfg) {
|
|
45
|
-
return {
|
|
46
|
-
principal: createPrincipal(cfg),
|
|
47
|
-
...createLicenseContext(cfg),
|
|
48
|
-
...createInstallationContext(cfg)
|
|
49
|
-
};
|
|
46
|
+
return Object.assign(Object.assign({ principal: createPrincipal(cfg) }, createLicenseContext(cfg)), createInstallationContext(cfg));
|
|
50
47
|
}
|
|
51
48
|
exports.setupRequestContext = setupRequestContext;
|
package/out/feature-flag.js
CHANGED
|
@@ -10,13 +10,12 @@ exports.XEN_RUNTIME_ENABLE_NETWORK_LIMITS = 'xen-runtime-enable-network-limits';
|
|
|
10
10
|
exports.XEN_RUNTIME_SHOULD_BLOCK_EXTERNAL_FETCH = 'xen-runtime-should-block-external-fetch';
|
|
11
11
|
exports.XEN_RUNTIME_SHOULD_REPORT_METRICS = 'xen-runtime-should-report-metrics';
|
|
12
12
|
class FeatureFlags {
|
|
13
|
-
flags;
|
|
14
|
-
static fromRequestMetaData(metaData) {
|
|
15
|
-
return new FeatureFlags(metaData.featureFlags || []);
|
|
16
|
-
}
|
|
17
13
|
constructor(flags) {
|
|
18
14
|
this.flags = flags;
|
|
19
15
|
}
|
|
16
|
+
static fromRequestMetaData(metaData) {
|
|
17
|
+
return new FeatureFlags(metaData.featureFlags || []);
|
|
18
|
+
}
|
|
20
19
|
isFeatureFlagEnabled(flag) {
|
|
21
20
|
return this.flags.includes(flag);
|
|
22
21
|
}
|
package/out/limits/tracker.js
CHANGED
|
@@ -6,9 +6,9 @@ exports.Limit = {
|
|
|
6
6
|
FetchRequestLimit: 'forge-fetch-request-count'
|
|
7
7
|
};
|
|
8
8
|
class PerInvocationLimitsTracker {
|
|
9
|
-
limits = {};
|
|
10
|
-
limitCount = {};
|
|
11
9
|
constructor(limits) {
|
|
10
|
+
this.limits = {};
|
|
11
|
+
this.limitCount = {};
|
|
12
12
|
this.limits = limits || {};
|
|
13
13
|
}
|
|
14
14
|
incrementCount(limitKey, by = 1) {
|
package/out/metrics/metrics.js
CHANGED
package/out/sandbox/inspector.js
CHANGED
|
@@ -62,24 +62,37 @@ function processArgForLogConsole(arg) {
|
|
|
62
62
|
}
|
|
63
63
|
const className = type === 'object' ? arg.constructor.name : undefined;
|
|
64
64
|
const subtype = inspectorSubtypeEntries.find((a) => a[1](arg));
|
|
65
|
-
return {
|
|
66
|
-
type,
|
|
67
|
-
...(className ? { className } : undefined),
|
|
68
|
-
...(subtype ? { subtype: subtype[0] } : undefined),
|
|
69
|
-
value: arg,
|
|
70
|
-
description: (0, util_1.inspect)(arg)
|
|
71
|
-
};
|
|
65
|
+
return Object.assign(Object.assign(Object.assign({ type }, (className ? { className } : undefined)), (subtype ? { subtype: subtype[0] } : undefined)), { value: arg, description: (0, util_1.inspect)(arg) });
|
|
72
66
|
}
|
|
73
67
|
class ChromeInspector {
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
68
|
+
constructor() {
|
|
69
|
+
this.frontendMsgsForNewSandbox = [];
|
|
70
|
+
this.sendMessageToFrontend = (message) => {
|
|
71
|
+
const wss = this.wss;
|
|
72
|
+
if (!wss) {
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
if (VERBOSE_LOG) {
|
|
76
|
+
log('Message to frontend:\n' + message);
|
|
77
|
+
}
|
|
78
|
+
wss.clients.forEach((ws) => ws.send(message));
|
|
79
|
+
};
|
|
80
|
+
this.stopSession = () => {
|
|
81
|
+
const wss = this.wss;
|
|
82
|
+
if (!wss) {
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
if (CLOSE_CONNECTION_ON_SESSION_STOP) {
|
|
86
|
+
wss.clients.forEach((ws) => ws.close());
|
|
87
|
+
}
|
|
88
|
+
const callbacks = this.callbacks;
|
|
89
|
+
if (!callbacks) {
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
this.callbacks = undefined;
|
|
93
|
+
callbacks.onSessionStop();
|
|
94
|
+
};
|
|
95
|
+
}
|
|
83
96
|
startServer(port = 0) {
|
|
84
97
|
const wss = new ws_1.default.Server({ port });
|
|
85
98
|
wss.on('connection', (ws) => {
|
|
@@ -190,31 +203,6 @@ class ChromeInspector {
|
|
|
190
203
|
throw Error('Unable to find port for inspector server');
|
|
191
204
|
}
|
|
192
205
|
}
|
|
193
|
-
sendMessageToFrontend = (message) => {
|
|
194
|
-
const wss = this.wss;
|
|
195
|
-
if (!wss) {
|
|
196
|
-
return;
|
|
197
|
-
}
|
|
198
|
-
if (VERBOSE_LOG) {
|
|
199
|
-
log('Message to frontend:\n' + message);
|
|
200
|
-
}
|
|
201
|
-
wss.clients.forEach((ws) => ws.send(message));
|
|
202
|
-
};
|
|
203
|
-
stopSession = () => {
|
|
204
|
-
const wss = this.wss;
|
|
205
|
-
if (!wss) {
|
|
206
|
-
return;
|
|
207
|
-
}
|
|
208
|
-
if (CLOSE_CONNECTION_ON_SESSION_STOP) {
|
|
209
|
-
wss.clients.forEach((ws) => ws.close());
|
|
210
|
-
}
|
|
211
|
-
const callbacks = this.callbacks;
|
|
212
|
-
if (!callbacks) {
|
|
213
|
-
return;
|
|
214
|
-
}
|
|
215
|
-
this.callbacks = undefined;
|
|
216
|
-
callbacks.onSessionStop();
|
|
217
|
-
};
|
|
218
206
|
forceResetFrontendState() {
|
|
219
207
|
for (const evt of ChromeInspector.FORCE_RESET_FRONTEND_STATE_EVENTS) {
|
|
220
208
|
this.sendMessageToFrontend(evt);
|
|
@@ -243,6 +231,12 @@ class ChromeInspector {
|
|
|
243
231
|
}
|
|
244
232
|
}
|
|
245
233
|
exports.ChromeInspector = ChromeInspector;
|
|
234
|
+
ChromeInspector.DENY_CODE = 1011;
|
|
235
|
+
ChromeInspector.DENY_REASON = 'Only one frontend is allowed';
|
|
236
|
+
ChromeInspector.FORCE_RESET_FRONTEND_STATE_EVENTS = [
|
|
237
|
+
'{"method":"Runtime.executionContextsCleared"}',
|
|
238
|
+
'{"method":"Inspector.targetReloadedAfterCrash"}'
|
|
239
|
+
];
|
|
246
240
|
exports.notImplementedInspector = {
|
|
247
241
|
startServer: () => {
|
|
248
242
|
throw new Error('Not implemented');
|
|
@@ -6,13 +6,10 @@ const feature_flag_1 = require("../feature-flag");
|
|
|
6
6
|
const ari_1 = require("@forge/util/packages/ari");
|
|
7
7
|
const __1 = require("..");
|
|
8
8
|
class XenInvocationRequestImpl {
|
|
9
|
-
request;
|
|
10
|
-
invocationId;
|
|
11
|
-
featureFlags;
|
|
12
|
-
serviceTokens = [];
|
|
13
9
|
constructor(request, invocationId) {
|
|
14
10
|
this.request = request;
|
|
15
11
|
this.invocationId = invocationId;
|
|
12
|
+
this.serviceTokens = [];
|
|
16
13
|
this.serviceTokens = this.buildServiceTokens(request._meta.tokens);
|
|
17
14
|
}
|
|
18
15
|
buildServiceTokens(tokens) {
|
|
@@ -80,10 +77,11 @@ class XenInvocationRequestImpl {
|
|
|
80
77
|
return this.request._meta.appToken;
|
|
81
78
|
}
|
|
82
79
|
getProxy() {
|
|
80
|
+
var _a;
|
|
83
81
|
if (!this.isFeatureFlagEnabled(feature_flag_1.XEN_RUNTIME_ENABLE_EGRESS_PROXY)) {
|
|
84
82
|
return undefined;
|
|
85
83
|
}
|
|
86
|
-
return this.request._meta
|
|
84
|
+
return (_a = this.request._meta) === null || _a === void 0 ? void 0 : _a.proxy;
|
|
87
85
|
}
|
|
88
86
|
getAllTokens() {
|
|
89
87
|
return this.serviceTokens;
|
|
@@ -117,9 +115,12 @@ function xenInvocationRequestFactory(invocation) {
|
|
|
117
115
|
}
|
|
118
116
|
exports.xenInvocationRequestFactory = xenInvocationRequestFactory;
|
|
119
117
|
class InvocationRequest {
|
|
120
|
-
sandboxConfig
|
|
121
|
-
|
|
122
|
-
|
|
118
|
+
constructor(sandboxConfig, xenInvocationRequest, manifest) {
|
|
119
|
+
this.sandboxConfig = sandboxConfig;
|
|
120
|
+
this.xenInvocationRequest = xenInvocationRequest;
|
|
121
|
+
this.manifest = manifest;
|
|
122
|
+
this.thirdPartyAuthTokenReferences = this.getThirdPartyTokenReferences();
|
|
123
|
+
}
|
|
123
124
|
static async setup(sandboxConfig, xenInvocationRequest) {
|
|
124
125
|
const manifest = await app_manifest_1.AppManifest.fromFile(sandboxConfig.appPath);
|
|
125
126
|
return this.setupSync(sandboxConfig, xenInvocationRequest, manifest);
|
|
@@ -127,13 +128,6 @@ class InvocationRequest {
|
|
|
127
128
|
static setupSync(sandboxConfig, xenInvocationRequest, manifest) {
|
|
128
129
|
return new InvocationRequest(sandboxConfig, xenInvocationRequest, manifest);
|
|
129
130
|
}
|
|
130
|
-
thirdPartyAuthTokenReferences;
|
|
131
|
-
constructor(sandboxConfig, xenInvocationRequest, manifest) {
|
|
132
|
-
this.sandboxConfig = sandboxConfig;
|
|
133
|
-
this.xenInvocationRequest = xenInvocationRequest;
|
|
134
|
-
this.manifest = manifest;
|
|
135
|
-
this.thirdPartyAuthTokenReferences = this.getThirdPartyTokenReferences();
|
|
136
|
-
}
|
|
137
131
|
getAppAri() {
|
|
138
132
|
return this.manifest.manifest.app.id;
|
|
139
133
|
}
|
|
@@ -231,16 +225,16 @@ class InvocationRequest {
|
|
|
231
225
|
return serviceTokens ? serviceTokens[0] : undefined;
|
|
232
226
|
}
|
|
233
227
|
getAtlassianServiceToken() {
|
|
228
|
+
var _a;
|
|
234
229
|
const atlassianTokens = this.getAllTokens(this.getAtlassianTokenServiceKey());
|
|
235
|
-
return this.pickTokenToUse(atlassianTokens)
|
|
230
|
+
return (_a = this.pickTokenToUse(atlassianTokens)) === null || _a === void 0 ? void 0 : _a.token;
|
|
236
231
|
}
|
|
237
232
|
getAppTokenKey() {
|
|
238
233
|
return '__atlassian-app-token';
|
|
239
234
|
}
|
|
240
235
|
getThirdPartyTokenReferenceList(serviceKey) {
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
.map((service) => service.reference) || []);
|
|
236
|
+
var _a;
|
|
237
|
+
return (((_a = this.thirdPartyAuthTokenReferences) === null || _a === void 0 ? void 0 : _a.filter((ref) => ref.serviceKey === serviceKey).map((service) => service.reference)) || []);
|
|
244
238
|
}
|
|
245
239
|
getThirdPartyTokenReferences() {
|
|
246
240
|
return this.getThirdPartyTokens().map(({ service, token }, index) => {
|
|
@@ -256,7 +250,8 @@ class InvocationRequest {
|
|
|
256
250
|
return this.getAllTokens().filter(({ service }) => service !== this.getAtlassianTokenServiceKey());
|
|
257
251
|
}
|
|
258
252
|
getThirdPartyToken(serviceKey) {
|
|
259
|
-
|
|
253
|
+
var _a, _b;
|
|
254
|
+
return (_b = (_a = this.thirdPartyAuthTokenReferences) === null || _a === void 0 ? void 0 : _a.find((ref) => ref.reference === serviceKey || ref.serviceKey === serviceKey)) === null || _b === void 0 ? void 0 : _b.token;
|
|
260
255
|
}
|
|
261
256
|
getAppVersion() {
|
|
262
257
|
return this.xenInvocationRequest.getAppVersion();
|
package/out/sandbox/sandbox.d.ts
CHANGED
|
@@ -18,5 +18,6 @@ export declare type FunctionResult = any;
|
|
|
18
18
|
export interface Sandbox {
|
|
19
19
|
name: string;
|
|
20
20
|
execute(xenInvocationRequest: XenInvocationRequest, invocationLimits: LimitsTracker, inspector?: Inspector): Promise<InvocationResult>;
|
|
21
|
+
stop(): void;
|
|
21
22
|
}
|
|
22
23
|
//# sourceMappingURL=sandbox.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sandbox.d.ts","sourceRoot":"","sources":["../../src/sandbox/sandbox.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAE5D,oBAAY,aAAa,GAAG;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,WAAW,aAAa;IAC5B,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACpB;AAGD,oBAAY,eAAe,GAAG,GAAG,CAAC;AAClC,oBAAY,cAAc,GAAG,GAAG,CAAC;AAEjC,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CACL,oBAAoB,EAAE,oBAAoB,EAC1C,gBAAgB,EAAE,aAAa,EAC/B,SAAS,CAAC,EAAE,SAAS,GACpB,OAAO,CAAC,gBAAgB,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"sandbox.d.ts","sourceRoot":"","sources":["../../src/sandbox/sandbox.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAE5D,oBAAY,aAAa,GAAG;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,WAAW,aAAa;IAC5B,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACpB;AAGD,oBAAY,eAAe,GAAG,GAAG,CAAC;AAClC,oBAAY,cAAc,GAAG,GAAG,CAAC;AAEjC,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CACL,oBAAoB,EAAE,oBAAoB,EAC1C,gBAAgB,EAAE,aAAa,EAC/B,SAAS,CAAC,EAAE,SAAS,GACpB,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAC7B,IAAI,IAAI,IAAI,CAAC;CACd"}
|