@forge/realtime 0.0.2-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 +7 -0
- package/LICENSE.txt +7 -0
- package/package.json +23 -0
- package/src/__test__/publish.test.ts +34 -0
- package/src/__test__/runtime.test.ts +13 -0
- package/src/__test__/utils.ts +31 -0
- package/src/index.ts +1 -0
- package/src/publish.ts +36 -0
- package/src/runtime.ts +9 -0
- package/tsconfig.json +18 -0
package/CHANGELOG.md
ADDED
package/LICENSE.txt
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
Copyright (c) 2025 Atlassian
|
|
2
|
+
Permission is hereby granted to use this software in accordance with the terms
|
|
3
|
+
and conditions outlined in the Atlassian Developer Terms, which can be found
|
|
4
|
+
at the following URL:
|
|
5
|
+
https://developer.atlassian.com/platform/marketplace/atlassian-developer-terms/
|
|
6
|
+
By using this software, you agree to comply with these terms and conditions.
|
|
7
|
+
If you do not agree with these terms, you are not permitted to use this software.
|
package/package.json
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@forge/realtime",
|
|
3
|
+
"version": "0.0.2-next.0",
|
|
4
|
+
"description": "Forge realtime",
|
|
5
|
+
"main": "out/index.js",
|
|
6
|
+
"types": "out/index.d.ts",
|
|
7
|
+
"author": "Atlassian",
|
|
8
|
+
"license": "SEE LICENSE IN LICENSE.txt",
|
|
9
|
+
"scripts": {
|
|
10
|
+
"build": "yarn run clean && yarn run compile",
|
|
11
|
+
"clean": "rm -rf ./out && rm -f tsconfig.tsbuildinfo",
|
|
12
|
+
"compile": "tsc -b -v",
|
|
13
|
+
"postbuild": "yarn bolt w forge-scripts preserve-deprecated-tags ../forge-realtime"
|
|
14
|
+
},
|
|
15
|
+
"devDependencies": {
|
|
16
|
+
"@forge/api": "6.0.0-next.0",
|
|
17
|
+
"@forge/util": "^1.4.9",
|
|
18
|
+
"@types/node": "20.19.0"
|
|
19
|
+
},
|
|
20
|
+
"publishConfig": {
|
|
21
|
+
"registry": "https://packages.atlassian.com/api/npm/npm-public/"
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import * as runtime from '../runtime';
|
|
2
|
+
import { publish } from '../publish';
|
|
3
|
+
import { FORGE_RUNTIME } from './utils';
|
|
4
|
+
|
|
5
|
+
describe('publish', () => {
|
|
6
|
+
it('should publish an event', async () => {
|
|
7
|
+
jest.spyOn(runtime, '__getRuntime').mockReturnValue(FORGE_RUNTIME);
|
|
8
|
+
|
|
9
|
+
const mockForgeFetch = jest.fn().mockResolvedValue({
|
|
10
|
+
text: async () => 'Hello Magic',
|
|
11
|
+
status: 200,
|
|
12
|
+
headers: { get: () => undefined }
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
(global as any).__forge_fetch__ = mockForgeFetch;
|
|
16
|
+
|
|
17
|
+
const response = await publish('my-channel', 'this is an event payload');
|
|
18
|
+
|
|
19
|
+
expect(response.status).toBe(200)
|
|
20
|
+
expect(mockForgeFetch).toHaveBeenCalledWith(
|
|
21
|
+
{
|
|
22
|
+
type: 'realtime'
|
|
23
|
+
},
|
|
24
|
+
'/',
|
|
25
|
+
{
|
|
26
|
+
method: 'POST',
|
|
27
|
+
body: '{"query":"mutation publishRealtimeChannel{\\n ecosystem {\\n publishRealtimeChannel(\\n context: \\"{\\\\\\"appId\\\\\\":\\\\\\"aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa\\\\\\",\\\\\\"contextAri\\\\\\":\\\\\\"ari:cloud:jira::site/ffffffff-ffff-ffff-ffff-ffffffffffff\\\\\\"}\\"\\n installationId: \\"iiiiiiii-iiii-iiii-iiii-iiiiiiiiiiii\\"\\n name: \\"my-channel\\"\\n payload: \\"this is an event payload\\"\\n ) {\\n eventId,\\n eventTimestamp\\n }\\n }\\n }"}',
|
|
28
|
+
headers: {
|
|
29
|
+
'Content-Type': 'application/json'
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
);
|
|
33
|
+
});
|
|
34
|
+
});
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { __getRuntime } from '../runtime';
|
|
2
|
+
import { FORGE_RUNTIME } from './utils';
|
|
3
|
+
|
|
4
|
+
describe('__getRuntime', () => {
|
|
5
|
+
it('should return the runtime object', async () => {
|
|
6
|
+
(global as any).__forge_runtime__ = FORGE_RUNTIME;
|
|
7
|
+
|
|
8
|
+
const runtime = __getRuntime();
|
|
9
|
+
|
|
10
|
+
expect(runtime.appContext.appId).toBe('aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa');
|
|
11
|
+
expect(runtime.contextAri).toBe('ari:cloud:jira::site/ffffffff-ffff-ffff-ffff-ffffffffffff');
|
|
12
|
+
});
|
|
13
|
+
});
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { ForgeRuntime } from '@forge/api';
|
|
2
|
+
import { NoMetrics } from '@forge/util/packages/metrics-interface';
|
|
3
|
+
|
|
4
|
+
export const FORGE_RUNTIME: ForgeRuntime = {
|
|
5
|
+
container: { runtime: 'node', region: 'us-west-2' },
|
|
6
|
+
proxy: { url: 'https://foo', token: 'token' },
|
|
7
|
+
contextAri: 'ari:cloud:jira::site/ffffffff-ffff-ffff-ffff-ffffffffffff',
|
|
8
|
+
appContext: {
|
|
9
|
+
appId: 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa',
|
|
10
|
+
environmentId: 'eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee',
|
|
11
|
+
environmentType: 'DEVELOPMENT',
|
|
12
|
+
invocationId: '33333',
|
|
13
|
+
installationId: 'iiiiiiii-iiii-iiii-iiii-iiiiiiiiiiii',
|
|
14
|
+
appVersion: '1.2.3',
|
|
15
|
+
functionKey: 'functionKey',
|
|
16
|
+
moduleType: 'moduleType',
|
|
17
|
+
moduleKey: 'moduleKey',
|
|
18
|
+
license: { isActive: true }
|
|
19
|
+
},
|
|
20
|
+
tracing: {
|
|
21
|
+
traceId: 'traceId',
|
|
22
|
+
spanId: 'spanId'
|
|
23
|
+
},
|
|
24
|
+
allowedEgress: [],
|
|
25
|
+
lambdaContext: {
|
|
26
|
+
awsRequestId: '123',
|
|
27
|
+
getRemainingTimeInMillis: jest.fn()
|
|
28
|
+
},
|
|
29
|
+
metrics: new NoMetrics(),
|
|
30
|
+
featureFlags: jest.fn()
|
|
31
|
+
};
|
package/src/index.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { publish } from './publish';
|
package/src/publish.ts
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { __getRuntime } from './runtime';
|
|
2
|
+
|
|
3
|
+
export const publish = async (channelName: string, eventPayload: string) => {
|
|
4
|
+
const { contextAri, appContext } = __getRuntime();
|
|
5
|
+
|
|
6
|
+
// Do not change the whitespace of the context object it has to be this exactly to match https://bitbucket.org/atlassian/app-client-events-service/src/master/
|
|
7
|
+
const graphqlBody = JSON.stringify({
|
|
8
|
+
query: `mutation publishRealtimeChannel{
|
|
9
|
+
ecosystem {
|
|
10
|
+
publishRealtimeChannel(
|
|
11
|
+
context: "{\\"appId\\":\\"${appContext.appId}\\",\\"contextAri\\":\\"${contextAri}\\"}"
|
|
12
|
+
installationId: "${appContext.installationId}"
|
|
13
|
+
name: "${channelName}"
|
|
14
|
+
payload: "${eventPayload}"
|
|
15
|
+
) {
|
|
16
|
+
eventId,
|
|
17
|
+
eventTimestamp
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}`
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
return await (global as any).__forge_fetch__(
|
|
24
|
+
{
|
|
25
|
+
type: 'realtime'
|
|
26
|
+
},
|
|
27
|
+
'/',
|
|
28
|
+
{
|
|
29
|
+
method: 'POST',
|
|
30
|
+
body: graphqlBody,
|
|
31
|
+
headers: {
|
|
32
|
+
'Content-Type': 'application/json'
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
);
|
|
36
|
+
};
|
package/src/runtime.ts
ADDED
package/tsconfig.json
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"extends": "../../tsconfig-base.json",
|
|
3
|
+
"compilerOptions": {
|
|
4
|
+
"lib": [
|
|
5
|
+
"es2017",
|
|
6
|
+
"DOM"
|
|
7
|
+
],
|
|
8
|
+
"outDir": "./out",
|
|
9
|
+
"rootDir": "src",
|
|
10
|
+
"composite": true,
|
|
11
|
+
"moduleResolution": "node"
|
|
12
|
+
},
|
|
13
|
+
"references": [
|
|
14
|
+
{
|
|
15
|
+
"path": "../forge-api"
|
|
16
|
+
}
|
|
17
|
+
]
|
|
18
|
+
}
|