@forge/api 2.11.1 → 2.12.0-next.1

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 CHANGED
@@ -1,5 +1,17 @@
1
1
  # @forge/api
2
2
 
3
+ ## 2.12.0-next.1
4
+
5
+ ### Patch Changes
6
+
7
+ - 82ea466: Add metrics for NodeJS runtime
8
+
9
+ ## 2.12.0-next.0
10
+
11
+ ### Minor Changes
12
+
13
+ - 60a3be66: Add NodeJS runtime support for unauthenticated product requests via the api object
14
+
3
15
  ## 2.11.1
4
16
 
5
17
  ### Patch Changes
@@ -3,7 +3,9 @@ import { RequestInfo, RequestInit, Response } from 'node-fetch';
3
3
  import { Url } from 'url';
4
4
  import { FetchAPI } from '..';
5
5
  declare type FetchFunction = (url: RequestInfo | Url, options: RequestInit | undefined) => Promise<Response>;
6
- export declare const createProxyFetch: (provider: 'app' | 'user' | undefined, remote: 'jira' | 'confluence' | 'stargate' | 'bitbucket') => FetchFunction;
6
+ declare type ProxyUrlProvider = 'app' | 'user' | 'none';
7
+ declare type ProxyUrlRemote = 'jira' | 'confluence' | 'stargate' | 'bitbucket';
8
+ export declare const createProxyFetch: (provider: ProxyUrlProvider, remote: ProxyUrlRemote) => FetchFunction;
7
9
  export declare function getNodeRuntimeAPI(): FetchAPI;
8
10
  export declare function getSandboxRuntimeAPI(api: any): FetchAPI;
9
11
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"fetch.d.ts","sourceRoot":"","sources":["../../src/api/fetch.ts"],"names":[],"mappings":";AAAA,OAAc,EAAE,WAAW,EAAE,WAAW,EAAE,QAAQ,EAAW,MAAM,YAAY,CAAC;AAChF,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAE1B,OAAO,EAAE,QAAQ,EAAE,MAAM,IAAI,CAAC;AAK9B,aAAK,aAAa,GAAG,CAAC,GAAG,EAAE,WAAW,GAAG,GAAG,EAAE,OAAO,EAAE,WAAW,GAAG,SAAS,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;AAIrG,eAAO,MAAM,gBAAgB,aACjB,KAAK,GAAG,MAAM,GAAG,SAAS,UAC5B,MAAM,GAAG,YAAY,GAAG,UAAU,GAAG,WAAW,KACvD,aAwBF,CAAC;AAuBF,wBAAgB,iBAAiB,IAAI,QAAQ,CAoB5C;AAED,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,GAAG,GAAG,QAAQ,CAEvD"}
1
+ {"version":3,"file":"fetch.d.ts","sourceRoot":"","sources":["../../src/api/fetch.ts"],"names":[],"mappings":";AAAA,OAAc,EAAE,WAAW,EAAE,WAAW,EAAE,QAAQ,EAAW,MAAM,YAAY,CAAC;AAChF,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAE1B,OAAO,EAAE,QAAQ,EAAE,MAAM,IAAI,CAAC;AAS9B,aAAK,aAAa,GAAG,CAAC,GAAG,EAAE,WAAW,GAAG,GAAG,EAAE,OAAO,EAAE,WAAW,GAAG,SAAS,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;AACrG,aAAK,gBAAgB,GAAG,KAAK,GAAG,MAAM,GAAG,MAAM,CAAC;AAChD,aAAK,cAAc,GAAG,MAAM,GAAG,YAAY,GAAG,UAAU,GAAG,WAAW,CAAC;AAuBvE,eAAO,MAAM,gBAAgB,aAAc,gBAAgB,UAAU,cAAc,KAAG,aAsCrF,CAAC;AAuBF,wBAAgB,iBAAiB,IAAI,QAAQ,CAoB5C;AAED,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,GAAG,GAAG,QAAQ,CAEvD"}
package/out/api/fetch.js CHANGED
@@ -8,22 +8,54 @@ const runtime_1 = require("./runtime");
8
8
  const polyfill_response_1 = require("./polyfill-response");
9
9
  const egress_1 = require("@forge/egress");
10
10
  const errors_1 = require("./errors");
11
+ const perf_hooks_1 = require("perf_hooks");
12
+ const FORGE_PROXY_UPSTREAM_LATENCY_HEADER = 'forge-proxy-upstream-latency';
11
13
  const ATLASSIAN_TOKEN_SERVICE_KEY = 'atlassian-token-service-key';
14
+ const providerToMetric = {
15
+ app: 'asApp',
16
+ user: 'asUser'
17
+ };
18
+ const remoteToMetric = {
19
+ jira: 'requestJira',
20
+ confluence: 'requestConfluence',
21
+ bitbucket: 'requestBitbucket',
22
+ stargate: 'requestAtlassian'
23
+ };
24
+ const metricName = (provider, remote) => {
25
+ if (provider === 'none') {
26
+ return `api.${remoteToMetric[remote]}`;
27
+ }
28
+ return `api.${providerToMetric[provider]}.${remoteToMetric[remote]}`;
29
+ };
12
30
  const createProxyFetch = (provider, remote) => {
13
31
  return async (url, options) => {
14
- const { proxy } = (0, runtime_1.getRuntime)();
32
+ const { proxy, metrics } = (0, runtime_1.getRuntime)();
15
33
  const request = new node_fetch_1.Request(url, options);
16
- const proxyRequest = new node_fetch_1.Request(`${proxy.url}/fpp/provider/${provider}/remote/${remote}`, request);
17
- proxyRequest.headers.set('Forge-Proxy-Target-Relative', request.url);
18
- proxyRequest.headers.set('Forge-Proxy-Authorization', `Bearer ${proxy.token}`);
19
- const response = await (0, node_fetch_1.default)(proxyRequest);
20
- if (response.headers.has('forge-proxy-error')) {
21
- if (response.headers.get('forge-proxy-error') === 'NEEDS_AUTHENTICATION_ERR') {
22
- throw new errors_1.NeedsAuthenticationError('Authentication Required', ATLASSIAN_TOKEN_SERVICE_KEY);
34
+ const metric = metricName(provider, remote);
35
+ const timer = metrics.timing(metric, { proxy: 'true' }).measure();
36
+ metrics.counter(metric).incr();
37
+ try {
38
+ const proxyRequest = new node_fetch_1.Request(`${proxy.url}/fpp/provider/${provider}/remote/${remote}`, request);
39
+ proxyRequest.headers.set('Forge-Proxy-Target-Relative', request.url);
40
+ proxyRequest.headers.set('Forge-Proxy-Authorization', `Bearer ${proxy.token}`);
41
+ const requestStart = perf_hooks_1.performance.now();
42
+ const response = await (0, node_fetch_1.default)(proxyRequest);
43
+ const requestEnd = perf_hooks_1.performance.now();
44
+ const proxyUpstreamLatency = parseInt(response.headers.get(FORGE_PROXY_UPSTREAM_LATENCY_HEADER) || '');
45
+ if (proxyUpstreamLatency) {
46
+ metrics.timing('proxy-success-overhead').set(requestEnd - requestStart - proxyUpstreamLatency);
47
+ }
48
+ if (response.headers.has('forge-proxy-error')) {
49
+ if (response.headers.get('forge-proxy-error') === 'NEEDS_AUTHENTICATION_ERR') {
50
+ throw new errors_1.NeedsAuthenticationError('Authentication Required', ATLASSIAN_TOKEN_SERVICE_KEY);
51
+ }
52
+ throw new errors_1.ProxyRequestError(response.status, response.headers.get('forge-proxy-error'));
23
53
  }
24
- throw new errors_1.ProxyRequestError(response.status, response.headers.get('forge-proxy-error'));
54
+ return response;
55
+ }
56
+ finally {
57
+ timer.stop();
25
58
  }
26
- return response;
27
59
  };
28
60
  };
29
61
  exports.createProxyFetch = createProxyFetch;
@@ -41,8 +73,8 @@ const wrapExternalEgress = (url, options) => {
41
73
  function getNodeRuntimeAPI() {
42
74
  return {
43
75
  fetch: (0, _1.wrapWithRouteUnwrapper)(wrapExternalEgress),
44
- requestJira: throwNotImplementedError,
45
- requestConfluence: throwNotImplementedError,
76
+ requestJira: (0, _1.wrapRequestProduct)((0, exports.createProxyFetch)('none', 'jira')),
77
+ requestConfluence: (0, _1.wrapRequestProduct)((0, exports.createProxyFetch)('none', 'confluence')),
46
78
  requestBitbucket: throwNotImplementedError,
47
79
  asUser: () => ({
48
80
  requestJira: (0, _1.wrapRequestProduct)((0, exports.createProxyFetch)('user', 'jira')),
@@ -1,3 +1,4 @@
1
+ import type { Metrics } from '@forge/util/packages/metrics-interface';
1
2
  export declare type ForgeRuntime = {
2
3
  proxy: {
3
4
  token: string;
@@ -8,6 +9,7 @@ export declare type ForgeRuntime = {
8
9
  lambdaContext: {
9
10
  awsRequestId: string;
10
11
  };
12
+ metrics: Metrics;
11
13
  };
12
14
  export declare function getRuntime(): ForgeRuntime;
13
15
  //# sourceMappingURL=runtime.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../src/api/runtime.ts"],"names":[],"mappings":"AAKA,oBAAY,YAAY,GAAG;IACzB,KAAK,EAAE;QACL,KAAK,EAAE,MAAM,CAAC;QACd,GAAG,EAAE,MAAM,CAAC;KACb,CAAC;IACF,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,aAAa,EAAE;QACb,YAAY,EAAE,MAAM,CAAC;KACtB,CAAC;CACH,CAAC;AAEF,wBAAgB,UAAU,IAAI,YAAY,CAOzC"}
1
+ {"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../src/api/runtime.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,wCAAwC,CAAC;AAOtE,oBAAY,YAAY,GAAG;IACzB,KAAK,EAAE;QACL,KAAK,EAAE,MAAM,CAAC;QACd,GAAG,EAAE,MAAM,CAAC;KACb,CAAC;IACF,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,aAAa,EAAE;QACb,YAAY,EAAE,MAAM,CAAC;KACtB,CAAC;IACF,OAAO,EAAE,OAAO,CAAC;CAClB,CAAC;AAEF,wBAAgB,UAAU,IAAI,YAAY,CAOzC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@forge/api",
3
- "version": "2.11.1",
3
+ "version": "2.12.0-next.1",
4
4
  "description": "Forge API methods",
5
5
  "author": "Atlassian",
6
6
  "license": "UNLICENSED",
@@ -12,13 +12,14 @@
12
12
  "compile": "tsc -b -v"
13
13
  },
14
14
  "devDependencies": {
15
+ "@forge/util": "1.2.1",
15
16
  "nock": "^10.0.6",
16
17
  "@types/node": "^12.12.63"
17
18
  },
18
19
  "dependencies": {
19
- "@forge/auth": "^0.0.1",
20
- "@forge/egress": "^1.1.2",
21
- "@forge/storage": "^1.3.2",
20
+ "@forge/auth": "0.0.1",
21
+ "@forge/egress": "1.1.2",
22
+ "@forge/storage": "1.3.2",
22
23
  "@types/node-fetch": "^2.5.7",
23
24
  "node-fetch": "2.6.7"
24
25
  }