oorja 2.1.8 → 2.2.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/dist/commands/signout.js +3 -3
- package/dist/commands/teletype/index.d.ts +2 -2
- package/dist/commands/teletype/index.js +51 -40
- package/dist/lib/config.d.ts +15 -10
- package/dist/lib/config.js +55 -42
- package/dist/lib/connect/index.d.ts +9 -8
- package/dist/lib/connect/index.js +32 -37
- package/dist/lib/exit.d.ts +1 -0
- package/dist/lib/exit.js +44 -0
- package/dist/lib/oorja/client.js +11 -5
- package/dist/lib/oorja/geoMap.d.ts +246 -0
- package/dist/lib/oorja/geoMap.js +246 -0
- package/dist/lib/oorja/index.d.ts +24 -9
- package/dist/lib/oorja/index.js +146 -62
- package/dist/lib/oorja/preflight.d.ts +0 -6
- package/dist/lib/oorja/preflight.js +3 -92
- package/dist/lib/teletype/index.d.ts +7 -1
- package/dist/lib/teletype/index.js +10 -3
- package/dist/lib/utils.d.ts +1 -1
- package/dist/lib/utils.js +5 -5
- package/oclif.manifest.json +7 -7
- package/package.json +12 -18
package/dist/commands/signout.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { Command } from '@oclif/core';
|
|
2
|
-
import {
|
|
2
|
+
import { Config } from '../lib/config.js';
|
|
3
3
|
export class SignOut extends Command {
|
|
4
4
|
static description = `Sign-out of oorja. Clears saved auth-token`;
|
|
5
5
|
async run() {
|
|
6
|
-
const
|
|
7
|
-
|
|
6
|
+
const config = new Config(this.config.configDir);
|
|
7
|
+
config.setAccessToken('');
|
|
8
8
|
console.log('Sign-out complete');
|
|
9
9
|
}
|
|
10
10
|
}
|
|
@@ -11,10 +11,10 @@ export default class TeleTypeCommand extends Command {
|
|
|
11
11
|
new_space: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
12
12
|
};
|
|
13
13
|
static args: {
|
|
14
|
-
|
|
14
|
+
streamKey: import("@oclif/core/interfaces").Arg<string | undefined, Record<string, unknown>>;
|
|
15
15
|
};
|
|
16
16
|
run(): Promise<void>;
|
|
17
|
-
private
|
|
17
|
+
private streamUsingStreamKey;
|
|
18
18
|
private createRoomAndStream;
|
|
19
19
|
private clearstdin;
|
|
20
20
|
}
|
|
@@ -1,27 +1,29 @@
|
|
|
1
1
|
import inquirer from 'inquirer';
|
|
2
2
|
import { Command, Flags, Args } from '@oclif/core';
|
|
3
3
|
import ora from 'ora';
|
|
4
|
-
import
|
|
4
|
+
import { hostname } from 'os';
|
|
5
5
|
import chalk from 'chalk';
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import { printExitMessage,
|
|
9
|
-
|
|
6
|
+
import { Config, STREAM_KEY_SAMPLE } from '../../lib/config.js';
|
|
7
|
+
import { App, parseStreamKey } from '../../lib/oorja/index.js';
|
|
8
|
+
import { printExitMessage, promptStreamKey } from '../../lib/utils.js';
|
|
9
|
+
import { Unauthorized } from '../../lib/connect/errors.js';
|
|
10
|
+
import { exit } from '../../lib/exit.js';
|
|
10
11
|
export default class TeleTypeCommand extends Command {
|
|
11
12
|
static order = 1;
|
|
12
13
|
static aliases = ['tty'];
|
|
13
14
|
static description = `Launch a terminal streaming session in oorja.`;
|
|
14
15
|
static examples = [
|
|
15
16
|
`${chalk.blueBright('$ teletype')}
|
|
16
|
-
Will prompt to choose streaming destination - existing space or create a new
|
|
17
|
+
Will prompt to choose streaming destination - either enter a stream key for an existing space or create a new space.
|
|
17
18
|
|
|
18
19
|
`,
|
|
19
|
-
`${chalk.blueBright(`$ teletype '${
|
|
20
|
-
Will stream to the space
|
|
20
|
+
`${chalk.blueBright(`$ teletype '${STREAM_KEY_SAMPLE}'`)}
|
|
21
|
+
Will stream to the space using the secret stream-key. NOTE: stream-keys are personal (generated for you in the teletype app at oorja.io), do not accept them from other people, nor should
|
|
22
|
+
you share your stream-keys with others.
|
|
21
23
|
|
|
22
24
|
`,
|
|
23
25
|
`${chalk.blueBright('$ teletype -m')}
|
|
24
|
-
Will also allow participants to write to your terminal!
|
|
26
|
+
Will also allow participants to write to your terminal! Collaboration mode must be explicitly enabled.
|
|
25
27
|
|
|
26
28
|
`,
|
|
27
29
|
];
|
|
@@ -30,7 +32,7 @@ Will also allow participants to write to your terminal!
|
|
|
30
32
|
shell: Flags.string({
|
|
31
33
|
char: 's',
|
|
32
34
|
description: 'shell to use. e.g. bash, fish',
|
|
33
|
-
default:
|
|
35
|
+
default: 'bash',
|
|
34
36
|
}),
|
|
35
37
|
multiplex: Flags.boolean({
|
|
36
38
|
char: 'm',
|
|
@@ -44,61 +46,64 @@ Will also allow participants to write to your terminal!
|
|
|
44
46
|
}),
|
|
45
47
|
};
|
|
46
48
|
static args = {
|
|
47
|
-
|
|
49
|
+
streamKey: Args.string({}),
|
|
48
50
|
};
|
|
49
51
|
async run() {
|
|
50
52
|
const { args, flags: { shell, multiplex, new_space }, } = await this.parse(TeleTypeCommand);
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
53
|
+
const config = new Config(this.config.configDir);
|
|
54
|
+
const app = new App(config);
|
|
55
|
+
if (args.streamKey) {
|
|
56
|
+
await this.streamUsingStreamKey(app, { shell, multiplex, streamKey: args.streamKey });
|
|
57
|
+
exit(0);
|
|
54
58
|
}
|
|
55
59
|
if (new_space) {
|
|
56
|
-
await this.createRoomAndStream({ shell, multiplex });
|
|
57
|
-
|
|
60
|
+
await this.createRoomAndStream(app, { shell, multiplex });
|
|
61
|
+
exit(0);
|
|
58
62
|
}
|
|
59
63
|
console.log('(use -h for description and options) \n');
|
|
60
64
|
// room not known, prompt
|
|
61
|
-
const
|
|
62
|
-
const
|
|
65
|
+
const STREAM_USING_STREAM_KEY = 'Stream using stream-key (You can acquire your stream key from teletype app within the space)';
|
|
66
|
+
const STREAM_TO_NEW_SPACE = 'New space';
|
|
63
67
|
const { answer } = await inquirer.prompt([
|
|
64
68
|
{
|
|
65
69
|
type: 'list',
|
|
66
70
|
name: 'answer',
|
|
67
71
|
message: 'Choose streaming destination',
|
|
68
|
-
choices: [
|
|
72
|
+
choices: [STREAM_TO_NEW_SPACE, STREAM_USING_STREAM_KEY],
|
|
69
73
|
},
|
|
70
74
|
]);
|
|
71
75
|
switch (answer) {
|
|
72
|
-
case
|
|
73
|
-
await this.
|
|
76
|
+
case STREAM_USING_STREAM_KEY:
|
|
77
|
+
await this.streamUsingStreamKey(app, { shell, multiplex });
|
|
74
78
|
break;
|
|
75
|
-
case
|
|
76
|
-
await this.createRoomAndStream({ shell, multiplex });
|
|
79
|
+
case STREAM_TO_NEW_SPACE:
|
|
80
|
+
await this.createRoomAndStream(app, { shell, multiplex });
|
|
77
81
|
break;
|
|
78
82
|
}
|
|
79
|
-
|
|
83
|
+
exit(0);
|
|
80
84
|
}
|
|
81
|
-
async
|
|
82
|
-
const
|
|
83
|
-
if (!
|
|
84
|
-
printExitMessage(chalk.redBright('
|
|
85
|
-
|
|
85
|
+
async streamUsingStreamKey(app, options) {
|
|
86
|
+
const streamKey = options.streamKey || (await promptStreamKey());
|
|
87
|
+
if (!streamKey) {
|
|
88
|
+
printExitMessage(chalk.redBright('stream-key not provided :('));
|
|
89
|
+
exit();
|
|
86
90
|
}
|
|
87
|
-
const
|
|
88
|
-
const
|
|
91
|
+
const streamKeyStruct = parseStreamKey(streamKey);
|
|
92
|
+
const oorja = await app.init(streamKeyStruct);
|
|
93
|
+
const roomKey = oorja.getRoomKey(streamKeyStruct);
|
|
89
94
|
this.clearstdin();
|
|
90
|
-
await
|
|
95
|
+
await oorja.teletype({ roomKey, ...options, process });
|
|
91
96
|
}
|
|
92
|
-
async createRoomAndStream({ shell, multiplex }) {
|
|
93
|
-
const
|
|
97
|
+
async createRoomAndStream(app, { shell, multiplex }) {
|
|
98
|
+
const oorja = await app.init();
|
|
94
99
|
const spinner = ora({
|
|
95
100
|
text: chalk.bold('Creating space with TeleType app'),
|
|
96
101
|
discardStdin: false,
|
|
97
102
|
}).start();
|
|
98
103
|
const now = new Date();
|
|
99
|
-
const { roomKey } = await
|
|
104
|
+
const { roomKey } = await oorja
|
|
100
105
|
.createRoom({
|
|
101
|
-
roomName: `Teletype session - ${
|
|
106
|
+
roomName: `Teletype session - ${hostname()} @ ${now.getHours()}:${now.getMinutes().toString().padStart(2, '0')}`,
|
|
102
107
|
apps: {
|
|
103
108
|
defaultFocus: '39',
|
|
104
109
|
appList: [
|
|
@@ -111,15 +116,21 @@ Will also allow participants to write to your terminal!
|
|
|
111
116
|
},
|
|
112
117
|
})
|
|
113
118
|
.catch((e) => {
|
|
114
|
-
|
|
115
|
-
|
|
119
|
+
if (e instanceof Unauthorized) {
|
|
120
|
+
printExitMessage('Failed to create space. Are you sure your access-token is valid?');
|
|
121
|
+
}
|
|
122
|
+
else {
|
|
123
|
+
printExitMessage('Failed to create space. Try again later or try updating your oorja-cli');
|
|
124
|
+
}
|
|
125
|
+
exit(9);
|
|
126
|
+
return Promise.reject();
|
|
116
127
|
});
|
|
117
128
|
spinner.succeed(chalk.bold('Space created')).clear();
|
|
118
|
-
const link =
|
|
129
|
+
const link = oorja.linkForRoom(roomKey);
|
|
119
130
|
console.log(`\n${chalk.bold(chalk.blueBright(link))}\n`);
|
|
120
131
|
console.log(chalk.bold("^^ You'll be streaming here ^^"));
|
|
121
132
|
this.clearstdin();
|
|
122
|
-
return await
|
|
133
|
+
return await oorja.teletype({ roomKey, shell, multiplex, process });
|
|
123
134
|
}
|
|
124
135
|
clearstdin() {
|
|
125
136
|
process.stdin.read();
|
package/dist/lib/config.d.ts
CHANGED
|
@@ -1,18 +1,23 @@
|
|
|
1
|
-
|
|
2
|
-
export declare const CLI_VERSION = 2.6;
|
|
3
|
-
import Conf from 'conf';
|
|
4
|
-
export declare const config: Conf<string>;
|
|
1
|
+
export declare const CLI_VERSION = 2.7;
|
|
5
2
|
export type env = 'local' | 'prod';
|
|
3
|
+
export declare class Config {
|
|
4
|
+
streamKeyAuth: boolean;
|
|
5
|
+
private configPath;
|
|
6
|
+
private config;
|
|
7
|
+
constructor(configDir: string);
|
|
8
|
+
private loadConfig;
|
|
9
|
+
private saveConfig;
|
|
10
|
+
getEnv: () => env;
|
|
11
|
+
getAccessToken: () => string;
|
|
12
|
+
setAccessToken: (token: string) => void;
|
|
13
|
+
}
|
|
6
14
|
export type ConnectConfig = {
|
|
15
|
+
useHttps: boolean;
|
|
7
16
|
host: string;
|
|
8
|
-
token: string;
|
|
9
17
|
};
|
|
10
18
|
export declare const getConnectConfig: (env: env, region: string) => ConnectConfig;
|
|
11
|
-
export declare const
|
|
12
|
-
export declare const
|
|
13
|
-
export declare const determineENV: (roomURL?: URL) => env;
|
|
14
|
-
export declare const getENVAccessToken: (env: env) => string;
|
|
15
|
-
export declare const setENVAccessToken: (env: env, token: string) => void;
|
|
19
|
+
export declare const STREAM_KEY_SAMPLE = "sk-xxxx:space-id#encryption-secret";
|
|
20
|
+
export declare const INVALID_STREAM_KEY_MESSAGE: string;
|
|
16
21
|
export type oorjaConfig = {
|
|
17
22
|
host: string;
|
|
18
23
|
};
|
package/dist/lib/config.js
CHANGED
|
@@ -1,57 +1,70 @@
|
|
|
1
1
|
import chalk from 'chalk';
|
|
2
|
-
|
|
3
|
-
import
|
|
4
|
-
|
|
5
|
-
export
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
2
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
export const CLI_VERSION = 2.7;
|
|
5
|
+
export class Config {
|
|
6
|
+
streamKeyAuth = false;
|
|
7
|
+
configPath;
|
|
8
|
+
config = {};
|
|
9
|
+
constructor(configDir) {
|
|
10
|
+
this.configPath = path.join(configDir, 'config.json');
|
|
11
|
+
this.loadConfig();
|
|
12
|
+
}
|
|
13
|
+
loadConfig() {
|
|
14
|
+
try {
|
|
15
|
+
const data = readFileSync(this.configPath, 'utf8');
|
|
16
|
+
this.config = JSON.parse(data);
|
|
17
|
+
}
|
|
18
|
+
catch (error) {
|
|
19
|
+
if (error.code === 'ENOENT') {
|
|
20
|
+
// Config file doesn't exist, create it with default values
|
|
21
|
+
const dir = path.dirname(this.configPath);
|
|
22
|
+
if (!existsSync(dir)) {
|
|
23
|
+
mkdirSync(dir, { recursive: true });
|
|
24
|
+
}
|
|
25
|
+
this.saveConfig();
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
console.error(chalk.redBright('Error loading config:'), error.message, this.configPath);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
async saveConfig() {
|
|
33
|
+
try {
|
|
34
|
+
writeFileSync(this.configPath, JSON.stringify(this.config, null, 2), 'utf8');
|
|
35
|
+
}
|
|
36
|
+
catch (error) {
|
|
37
|
+
console.error(chalk.redBright('Error saving config:'), error.message);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
getEnv = () => {
|
|
41
|
+
return this.config['env'] ?? 'prod';
|
|
42
|
+
};
|
|
43
|
+
getAccessToken = () => {
|
|
44
|
+
return this.config[`${this.getEnv()}-access-token`] || '';
|
|
45
|
+
};
|
|
46
|
+
setAccessToken = (token) => {
|
|
47
|
+
this.config[`${this.getEnv()}-access-token`] = token;
|
|
48
|
+
this.saveConfig();
|
|
49
|
+
};
|
|
50
|
+
}
|
|
19
51
|
export const getConnectConfig = (env, region) => {
|
|
20
52
|
const getHost = (env) => {
|
|
21
53
|
switch (env) {
|
|
22
54
|
case 'local':
|
|
23
|
-
return '
|
|
55
|
+
return 'localhost:4000';
|
|
24
56
|
case 'prod':
|
|
25
57
|
return region ? `${region}.connect.oorja.io` : 'connect.oorja.io';
|
|
26
58
|
}
|
|
27
59
|
};
|
|
60
|
+
const host = getHost(env);
|
|
28
61
|
return {
|
|
29
|
-
|
|
30
|
-
|
|
62
|
+
useHttps: host.includes('oorja.io'),
|
|
63
|
+
host,
|
|
31
64
|
};
|
|
32
65
|
};
|
|
33
|
-
export const
|
|
34
|
-
export const
|
|
35
|
-
export const determineENV = (roomURL) => {
|
|
36
|
-
if (!roomURL)
|
|
37
|
-
return config.get('env') || 'prod';
|
|
38
|
-
switch (roomURL.host) {
|
|
39
|
-
case 'oorja.io':
|
|
40
|
-
case 'teletype.oorja.io':
|
|
41
|
-
return 'prod';
|
|
42
|
-
case 'localhost:3000':
|
|
43
|
-
return 'local';
|
|
44
|
-
default:
|
|
45
|
-
printExitMessage(INVALID_ROOM_LINK_MESSAGE);
|
|
46
|
-
process.exit(1);
|
|
47
|
-
}
|
|
48
|
-
};
|
|
49
|
-
export const getENVAccessToken = (env) => {
|
|
50
|
-
return config.get(`${env}-access-token`) || '';
|
|
51
|
-
};
|
|
52
|
-
export const setENVAccessToken = (env, token) => {
|
|
53
|
-
config.set(`${env}-access-token`, token);
|
|
54
|
-
};
|
|
66
|
+
export const STREAM_KEY_SAMPLE = 'sk-xxxx:space-id#encryption-secret';
|
|
67
|
+
export const INVALID_STREAM_KEY_MESSAGE = `${chalk.redBright('invalid stream-key ')}🤔. It should look like: ${chalk.blue(STREAM_KEY_SAMPLE)}`;
|
|
55
68
|
export const getoorjaConfig = (env) => {
|
|
56
69
|
let host;
|
|
57
70
|
switch (env) {
|
|
@@ -9,29 +9,30 @@ export declare class ConnectClient {
|
|
|
9
9
|
private headers;
|
|
10
10
|
private timeout;
|
|
11
11
|
private socket?;
|
|
12
|
-
|
|
12
|
+
private accessToken;
|
|
13
|
+
constructor(env: env, region: string, token: string);
|
|
14
|
+
setAccessToken: (token: string) => void;
|
|
13
15
|
private _fetch;
|
|
14
16
|
fetchCliManifest: () => Promise<CliManifest>;
|
|
15
|
-
fetchSessionUser: () => Promise<User>;
|
|
17
|
+
fetchSessionUser: (v2?: boolean) => Promise<User>;
|
|
16
18
|
createRoom: ({ roomName, apps }: CreateRoomOptions) => Promise<Room>;
|
|
17
19
|
createAnonymousUser: () => Promise<string>;
|
|
18
|
-
accessTokenFromRoomParticipantOTP: (roomId: string, otp: string) => Promise<string>;
|
|
19
20
|
fetchRoom: (roomId: string) => Promise<Room>;
|
|
20
21
|
establishSocket: () => Promise<void>;
|
|
21
|
-
joinChannel: ({ channel, params, onJoin, onClose, onError, onMessage, handleSessionJoin, handleSessionLeave, }: JoinChannelOptions<
|
|
22
|
+
joinChannel: ({ channel, params, onJoin, onClose, onError, onMessage, handleSessionJoin, handleSessionLeave, }: JoinChannelOptions<unknown, unknown>) => Channel;
|
|
22
23
|
destroy: () => Promise<unknown>;
|
|
23
24
|
}
|
|
24
25
|
export type CreateRoomOptions = {
|
|
25
26
|
roomName: string;
|
|
26
27
|
apps: RoomApps;
|
|
27
28
|
};
|
|
28
|
-
export type JoinChannelOptions<
|
|
29
|
+
export type JoinChannelOptions<Params, Metas> = {
|
|
29
30
|
channel: string;
|
|
30
|
-
params:
|
|
31
|
+
params: Params;
|
|
31
32
|
onJoin?: () => void;
|
|
32
33
|
onError?: (reason: any) => void;
|
|
33
34
|
onClose?: (payload: any, ref: any, joinRef: any) => void;
|
|
34
35
|
onMessage: (payload: any) => void;
|
|
35
|
-
handleSessionJoin: (session: string
|
|
36
|
-
handleSessionLeave: (session: string |
|
|
36
|
+
handleSessionJoin: (session: string, currentMetas: undefined | Metas, newMetas: Metas) => void;
|
|
37
|
+
handleSessionLeave: (session: string, currentMetas: undefined | Metas, leftMetas: Metas) => void;
|
|
37
38
|
};
|
|
@@ -8,6 +8,7 @@ import { Unauthorized, BadRequest } from './errors.js';
|
|
|
8
8
|
import { Socket, Presence } from 'phoenix';
|
|
9
9
|
import camelcaseKeys from 'camelcase-keys';
|
|
10
10
|
import { printExitMessage } from '../utils.js';
|
|
11
|
+
import { exit } from '../exit.js';
|
|
11
12
|
export class ApiClientError extends Error {
|
|
12
13
|
}
|
|
13
14
|
export class ConnectClient {
|
|
@@ -16,16 +17,22 @@ export class ConnectClient {
|
|
|
16
17
|
headers;
|
|
17
18
|
timeout;
|
|
18
19
|
socket;
|
|
19
|
-
|
|
20
|
+
accessToken;
|
|
21
|
+
constructor(env, region, token) {
|
|
20
22
|
const config = getConnectConfig(env, region);
|
|
21
|
-
this.baseURL = connectBaseURL(config.host);
|
|
23
|
+
this.baseURL = connectBaseURL(config.host, config.useHttps);
|
|
22
24
|
this.headers = {
|
|
23
|
-
'x-access-token':
|
|
25
|
+
'x-access-token': token || '',
|
|
24
26
|
'Content-Type': 'application/json',
|
|
25
27
|
};
|
|
28
|
+
this.accessToken = token || '';
|
|
26
29
|
this.timeout = 5000;
|
|
27
30
|
this.config = config;
|
|
28
31
|
}
|
|
32
|
+
setAccessToken = (token) => {
|
|
33
|
+
this.accessToken = token;
|
|
34
|
+
this.headers['x-access-token'] = token;
|
|
35
|
+
};
|
|
29
36
|
// Private helper to encapsulate fetch with timeout and consistent error handling.
|
|
30
37
|
async _fetch(path, options = {}) {
|
|
31
38
|
const controller = new AbortController();
|
|
@@ -54,7 +61,7 @@ export class ConnectClient {
|
|
|
54
61
|
}
|
|
55
62
|
fetchCliManifest = async () => {
|
|
56
63
|
try {
|
|
57
|
-
const response = await this._fetch('/cli');
|
|
64
|
+
const response = await this._fetch('/v1/cli');
|
|
58
65
|
const data = await response.json();
|
|
59
66
|
return camelcaseKeys(data);
|
|
60
67
|
}
|
|
@@ -62,9 +69,10 @@ export class ConnectClient {
|
|
|
62
69
|
return handleError(error);
|
|
63
70
|
}
|
|
64
71
|
};
|
|
65
|
-
fetchSessionUser = async () => {
|
|
72
|
+
fetchSessionUser = async (v2 = false) => {
|
|
73
|
+
const path = v2 ? '/v2/session/user_profile' : '/v1/session/user';
|
|
66
74
|
try {
|
|
67
|
-
const response = await this._fetch(
|
|
75
|
+
const response = await this._fetch(path);
|
|
68
76
|
const data = await response.json();
|
|
69
77
|
return defaultParser(data.data);
|
|
70
78
|
}
|
|
@@ -81,7 +89,7 @@ export class ConnectClient {
|
|
|
81
89
|
},
|
|
82
90
|
};
|
|
83
91
|
try {
|
|
84
|
-
const response = await this._fetch('/rooms', {
|
|
92
|
+
const response = await this._fetch('/v1/rooms', {
|
|
85
93
|
method: 'POST',
|
|
86
94
|
body: JSON.stringify(body),
|
|
87
95
|
});
|
|
@@ -94,7 +102,7 @@ export class ConnectClient {
|
|
|
94
102
|
};
|
|
95
103
|
createAnonymousUser = async () => {
|
|
96
104
|
try {
|
|
97
|
-
const response = await this._fetch('/session/anon', { method: 'POST' });
|
|
105
|
+
const response = await this._fetch('/v1/session/anon', { method: 'POST' });
|
|
98
106
|
const data = await response.json();
|
|
99
107
|
return data.access_token;
|
|
100
108
|
}
|
|
@@ -102,25 +110,9 @@ export class ConnectClient {
|
|
|
102
110
|
return handleError(error);
|
|
103
111
|
}
|
|
104
112
|
};
|
|
105
|
-
accessTokenFromRoomParticipantOTP = async (roomId, otp) => {
|
|
106
|
-
try {
|
|
107
|
-
const response = await this._fetch('/access_tokens/from_room_participant_otp', {
|
|
108
|
-
method: 'POST',
|
|
109
|
-
body: JSON.stringify({
|
|
110
|
-
room_id: roomId,
|
|
111
|
-
otp: otp,
|
|
112
|
-
}),
|
|
113
|
-
});
|
|
114
|
-
const data = await response.json();
|
|
115
|
-
return data.data.token;
|
|
116
|
-
}
|
|
117
|
-
catch (error) {
|
|
118
|
-
return handleError(error);
|
|
119
|
-
}
|
|
120
|
-
};
|
|
121
113
|
fetchRoom = async (roomId) => {
|
|
122
114
|
try {
|
|
123
|
-
const response = await this._fetch(`/rooms/${roomId}`);
|
|
115
|
+
const response = await this._fetch(`/v1/rooms/${roomId}`);
|
|
124
116
|
const data = await response.json();
|
|
125
117
|
return defaultParser(data.data);
|
|
126
118
|
}
|
|
@@ -129,7 +121,7 @@ export class ConnectClient {
|
|
|
129
121
|
}
|
|
130
122
|
};
|
|
131
123
|
establishSocket = async () => {
|
|
132
|
-
const protocolPrefix =
|
|
124
|
+
const protocolPrefix = this.config.useHttps ? 'wss://' : 'ws://';
|
|
133
125
|
const host = this.config.host;
|
|
134
126
|
const encodeMessage = function (rawdata, callback) {
|
|
135
127
|
return callback(encoder.encode(rawdata));
|
|
@@ -141,7 +133,7 @@ export class ConnectClient {
|
|
|
141
133
|
let initialConnection = false;
|
|
142
134
|
this.socket = new Socket(`${protocolPrefix}${host}/socket`, {
|
|
143
135
|
params: {
|
|
144
|
-
access_token: this.
|
|
136
|
+
access_token: this.accessToken,
|
|
145
137
|
},
|
|
146
138
|
transport: WebSocket,
|
|
147
139
|
heartbeatIntervalMs: 7500,
|
|
@@ -159,9 +151,8 @@ export class ConnectClient {
|
|
|
159
151
|
return;
|
|
160
152
|
}
|
|
161
153
|
printExitMessage('connection error');
|
|
162
|
-
|
|
154
|
+
exit(2);
|
|
163
155
|
});
|
|
164
|
-
// @ts-ignore
|
|
165
156
|
this.socket.connect();
|
|
166
157
|
});
|
|
167
158
|
};
|
|
@@ -173,16 +164,20 @@ export class ConnectClient {
|
|
|
173
164
|
chan.onError(onError);
|
|
174
165
|
if (onClose)
|
|
175
166
|
chan.onClose(onClose);
|
|
176
|
-
let presences = [];
|
|
177
167
|
chan.on('new_msg', (msg) => {
|
|
178
168
|
onMessage(msg);
|
|
179
169
|
});
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
170
|
+
const presence = new Presence(chan);
|
|
171
|
+
// https://hexdocs.pm/phoenix/js/index.html#handling-individual-presence-join-and-leave-events
|
|
172
|
+
presence.onJoin((key, current, newPres) => {
|
|
173
|
+
if (!current) {
|
|
174
|
+
handleSessionJoin(key, current, newPres);
|
|
175
|
+
}
|
|
183
176
|
});
|
|
184
|
-
|
|
185
|
-
|
|
177
|
+
presence.onLeave((key, current, leftPres) => {
|
|
178
|
+
if (current.metas.length === 0) {
|
|
179
|
+
handleSessionLeave(key, current, leftPres);
|
|
180
|
+
}
|
|
186
181
|
});
|
|
187
182
|
chan
|
|
188
183
|
.join()
|
|
@@ -197,7 +192,7 @@ export class ConnectClient {
|
|
|
197
192
|
return;
|
|
198
193
|
}
|
|
199
194
|
printExitMessage('error on channel');
|
|
200
|
-
|
|
195
|
+
exit(3);
|
|
201
196
|
});
|
|
202
197
|
return chan;
|
|
203
198
|
};
|
|
@@ -214,7 +209,7 @@ export class ConnectClient {
|
|
|
214
209
|
});
|
|
215
210
|
};
|
|
216
211
|
}
|
|
217
|
-
const connectBaseURL = (host) => `
|
|
212
|
+
const connectBaseURL = (host, useHttps) => `http${useHttps ? 's' : ''}://${host}/api`;
|
|
218
213
|
const handleError = (error) => {
|
|
219
214
|
// This function was originally designed for AxiosError.
|
|
220
215
|
// The custom _fetch method now throws an object with a `response` key
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function exit(exitCode?: number, streams?: any): void;
|
package/dist/lib/exit.js
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// because flushing stdout / graceful exit doesn't seem possible in nodejs?
|
|
2
|
+
// without this error-codes/logs just before exit is called won't show up..
|
|
3
|
+
/*
|
|
4
|
+
* exit
|
|
5
|
+
* https://github.com/cowboy/node-exit
|
|
6
|
+
*
|
|
7
|
+
* Copyright (c) 2013 "Cowboy" Ben Alman
|
|
8
|
+
* Licensed under the MIT license.
|
|
9
|
+
*/
|
|
10
|
+
'use strict';
|
|
11
|
+
export function exit(exitCode = 0, streams) {
|
|
12
|
+
if (!streams) {
|
|
13
|
+
streams = [process.stdout, process.stderr];
|
|
14
|
+
}
|
|
15
|
+
var drainCount = 0;
|
|
16
|
+
// Actually exit if all streams are drained.
|
|
17
|
+
function tryToExit() {
|
|
18
|
+
if (drainCount === streams.length) {
|
|
19
|
+
process.exit(exitCode);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
streams.forEach(function (stream) {
|
|
23
|
+
// Count drained streams now, but monitor non-drained streams.
|
|
24
|
+
if (stream.bufferSize === 0) {
|
|
25
|
+
drainCount++;
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
stream.write('', 'utf-8', function () {
|
|
29
|
+
drainCount++;
|
|
30
|
+
tryToExit();
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
// Prevent further writing.
|
|
34
|
+
stream.write = function () { };
|
|
35
|
+
});
|
|
36
|
+
// If all streams were already drained, exit now.
|
|
37
|
+
tryToExit();
|
|
38
|
+
// In Windows, when run as a Node.js child process, a script utilizing
|
|
39
|
+
// this library might just exit with a 0 exit code, regardless. This code,
|
|
40
|
+
// despite the fact that it looks a bit crazy, appears to fix that.
|
|
41
|
+
process.on('exit', function () {
|
|
42
|
+
process.exit(exitCode);
|
|
43
|
+
});
|
|
44
|
+
}
|
package/dist/lib/oorja/client.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import haversine from 'haversine-distance';
|
|
2
2
|
import { printExitMessage } from '../utils.js';
|
|
3
|
+
import { exit } from '../exit.js';
|
|
4
|
+
import { geoMap } from './geoMap.js';
|
|
3
5
|
export class OorjaClientError extends Error {
|
|
4
6
|
}
|
|
5
7
|
const _maybeError = (response) => {
|
|
@@ -24,18 +26,21 @@ class Client {
|
|
|
24
26
|
}
|
|
25
27
|
const _client = new Client();
|
|
26
28
|
export const getRegion = async () => {
|
|
27
|
-
const response = await _client.get('https://
|
|
29
|
+
const response = await _client.get('https://oorja.io/nudge', {
|
|
28
30
|
method: 'GET',
|
|
29
31
|
});
|
|
30
32
|
if (response.status !== 200) {
|
|
31
33
|
printExitMessage('There seems to be an issue with the network');
|
|
32
|
-
|
|
34
|
+
exit(1);
|
|
35
|
+
return Promise.reject();
|
|
33
36
|
}
|
|
34
37
|
const settings = (await response.json());
|
|
38
|
+
const country = (response.headers.get('cdn-requestcountrycode') || 'us').toUpperCase().trim();
|
|
39
|
+
const info = geoMap[country] || geoMap['US'];
|
|
35
40
|
try {
|
|
36
41
|
const clientLocation = {
|
|
37
|
-
lat: parseFloat(
|
|
38
|
-
lng: parseFloat(
|
|
42
|
+
lat: parseFloat(info[0]),
|
|
43
|
+
lng: parseFloat(info[1]),
|
|
39
44
|
};
|
|
40
45
|
const distances = settings.regions.map((region) => {
|
|
41
46
|
return {
|
|
@@ -48,6 +53,7 @@ export const getRegion = async () => {
|
|
|
48
53
|
}
|
|
49
54
|
catch {
|
|
50
55
|
printExitMessage('error determining region');
|
|
51
|
-
|
|
56
|
+
exit(1);
|
|
57
|
+
return Promise.reject();
|
|
52
58
|
}
|
|
53
59
|
};
|