js-dos 7.2.1 → 7.2.6

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.
Files changed (52) hide show
  1. package/.github/workflows/codeql-analysis.yml +70 -0
  2. package/README.md +2 -2
  3. package/dist/emulators-ui-loader.png +0 -0
  4. package/dist/js-dos.css +199 -8
  5. package/dist/js-dos.js +16 -1
  6. package/dist/js-dos.js.map +1 -1
  7. package/dist/types/src/backend/jj/jj-config.d.ts +6 -0
  8. package/dist/types/src/backend/jj/latency.d.ts +8 -0
  9. package/dist/types/src/{personal.d.ts → backend/v7/personal.d.ts} +0 -0
  10. package/dist/types/src/backend/v7/v7-config.d.ts +8 -0
  11. package/dist/types/src/components/region.d.ts +6 -0
  12. package/dist/types/src/components/sidebar/active-token.d.ts +2 -0
  13. package/dist/types/src/components/sidebar/create-token.d.ts +2 -0
  14. package/dist/types/src/components/sidebar/latency-info.d.ts +7 -0
  15. package/dist/types/src/components/sidebar/main.d.ts +2 -0
  16. package/dist/types/src/components/sidebar/networking.d.ts +2 -0
  17. package/dist/types/src/components/tip.d.ts +2 -0
  18. package/dist/types/src/hardware-transport-layer.d.ts +4 -2
  19. package/dist/types/src/icons.d.ts +30 -0
  20. package/dist/types/src/player-app.d.ts +22 -2
  21. package/dist/types/src/player.d.ts +2 -0
  22. package/dist/types/src/xhr.d.ts +1 -0
  23. package/dist/types/{sls → v7-services}/src/personal.d.ts +0 -0
  24. package/dist/wdosbox.js +1 -1
  25. package/dist/wdosbox.js.symbols +3132 -3071
  26. package/dist/wdosbox.wasm +0 -0
  27. package/examples/digger/index.html +5 -1
  28. package/package.json +7 -4
  29. package/v7-services/.env +6 -0
  30. package/v7-services/ok.yaml +24 -0
  31. package/v7-services/package.json +17 -0
  32. package/v7-services/redeploy-ok.sh +25 -0
  33. package/v7-services/serverless.yml +140 -0
  34. package/v7-services/src/networking/day.ts +5 -0
  35. package/v7-services/src/networking/get-free-token.ts +33 -0
  36. package/v7-services/src/networking/get-token-cost.ts +31 -0
  37. package/v7-services/src/networking/get-token-info.ts +16 -0
  38. package/v7-services/src/networking/ipx/put-ipx-ip.ts +20 -0
  39. package/v7-services/src/networking/ipx/start-ipx.ts +16 -0
  40. package/v7-services/src/networking/ipx/stop-ipx.ts +19 -0
  41. package/v7-services/src/networking/limits.ts +3 -0
  42. package/v7-services/src/networking/token.ts +238 -0
  43. package/v7-services/src/ok.ts +7 -0
  44. package/v7-services/src/personal-acl.ts +33 -0
  45. package/v7-services/src/personal-put.ts +35 -0
  46. package/v7-services/src/personal.ts +18 -0
  47. package/v7-services/src/responses.ts +28 -0
  48. package/v7-services/src/user.ts +3 -0
  49. package/v7-services/yarn.lock +4400 -0
  50. package/yarn-error.log +9 -9
  51. package/dist/emulators-ui-loader.gif +0 -0
  52. package/examples/digger/bundle.jsdos +0 -0
package/dist/wdosbox.wasm CHANGED
Binary file
@@ -24,7 +24,11 @@
24
24
  let bundleUrl = "https://cdn.dos.zone/original/2X/2/24b00b14f118580763440ecaddcc948f8cb94f14.jsdos"; // digger
25
25
  // bundleUrl = "https://cdn.dos.zone/original/2X/6/6a2bfa87c031c2a11ab212758a5d914f7c112eeb.jsdos"; // dagnerous dave 2
26
26
  // bundleUrl = "https://cdn.dos.zone/original/2X/1/1b063b2520052ebb504184667ac95e72423331de.jsdos"; // lost vikings
27
- bundleUrl = "bundle.jsdos";
27
+ // bundleUrl = "doom.jsdos";
28
+ // bundleUrl = "wolf.jsdos";
29
+ // bundleUrl = "heroes2.jsdos";
30
+ // bundleUrl = "https://doszone-uploads.s3.dualstack.eu-central-1.amazonaws.com/original/2X/6/60b165c86771eadf24cb2f81aef4656b85d167a6.jsdos";
31
+ // bundleUrl = "doom_coop.jsdos";
28
32
  let clientId = null;
29
33
  emulators.pathPrefix = "/dist/";
30
34
  Dos(document.getElementById("jsdos"), {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "js-dos",
3
- "version": "7.2.1",
3
+ "version": "7.2.6",
4
4
  "description": "Easiest API to run dos programs in browser",
5
5
  "main": "dist/js-dos.js",
6
6
  "types": "dist/types/src/player.d.ts",
@@ -21,7 +21,7 @@
21
21
  "dosbox"
22
22
  ],
23
23
  "author": "Alexander Guryanov (aka caiiiycuk)",
24
- "license": "ISC",
24
+ "license": "GPL-2.0",
25
25
  "bugs": {
26
26
  "url": "https://github.com/caiiiycuk/js-dos/issues"
27
27
  },
@@ -48,8 +48,8 @@
48
48
  "browserify": "^17.0.0",
49
49
  "core-js": "^3.17.1",
50
50
  "del": "^5.1.0",
51
- "emulators": "^0.72.0",
52
- "emulators-ui": "^0.72.2",
51
+ "emulators": "^0.72.1",
52
+ "emulators-ui": "^0.72.8",
53
53
  "eslint": "^7.32.0",
54
54
  "eslint-config-google": "^0.14.0",
55
55
  "gulp": "^4.0.2",
@@ -66,5 +66,8 @@
66
66
  "typescript": "^4.4.4",
67
67
  "vinyl-buffer": "^1.0.1",
68
68
  "vinyl-source-stream": "^2.0.0"
69
+ },
70
+ "dependencies": {
71
+ "nanoid": "^3.1.30"
69
72
  }
70
73
  }
@@ -0,0 +1,6 @@
1
+ # Learn more about about the credentials needed
2
+ # to deploy your app https://github.com/serverless/components#credentials
3
+
4
+ # AWS:
5
+ # AWS_ACCESS_KEY_ID=<your access key>
6
+ # AWS_SECRET_ACCESS_KEY=<your secret access key>
@@ -0,0 +1,24 @@
1
+ service: jsdos-ok
2
+
3
+ package:
4
+ exclude:
5
+ - 'node_modules/**'
6
+
7
+ provider:
8
+ name: aws
9
+ runtime: nodejs14.x
10
+ memorySize: 128
11
+ versionFunctions: false
12
+
13
+ functions:
14
+ ok:
15
+ handler: src/ok.ok
16
+ name: jsdos-ok
17
+ events:
18
+ - http:
19
+ path: /ok
20
+ method: get
21
+ cors: true
22
+
23
+ plugins:
24
+ - serverless-plugin-typescript
@@ -0,0 +1,17 @@
1
+ {
2
+ "name": "js-dos-v7-services",
3
+ "description": "",
4
+ "version": "0.1.0",
5
+ "license": "GPL-2.0",
6
+ "dependencies": {
7
+ "nanoid": "^3.1.30"
8
+ },
9
+ "devDependencies": {
10
+ "@types/aws-lambda": "^8.10.88",
11
+ "@types/node": "^14.6.4",
12
+ "aws-sdk": "^2.1048.0",
13
+ "serverless": "^2.69.1",
14
+ "serverless-plugin-typescript": "^2.1.0",
15
+ "typescript": "^4.5.4"
16
+ }
17
+ }
@@ -0,0 +1,25 @@
1
+ #!/bin/sh
2
+
3
+ set -ex
4
+
5
+ yarn run sls deploy -c ok.yaml --verbose --region us-east-1
6
+ yarn run sls deploy -c ok.yaml --verbose --region us-east-2
7
+ yarn run sls deploy -c ok.yaml --verbose --region us-west-1
8
+ yarn run sls deploy -c ok.yaml --verbose --region us-west-2
9
+ yarn run sls deploy -c ok.yaml --verbose --region eu-central-1
10
+ yarn run sls deploy -c ok.yaml --verbose --region eu-west-1
11
+ yarn run sls deploy -c ok.yaml --verbose --region eu-west-2
12
+ yarn run sls deploy -c ok.yaml --verbose --region eu-south-1
13
+ yarn run sls deploy -c ok.yaml --verbose --region eu-west-3
14
+ yarn run sls deploy -c ok.yaml --verbose --region eu-north-1
15
+ yarn run sls deploy -c ok.yaml --verbose --region ap-east-1
16
+ yarn run sls deploy -c ok.yaml --verbose --region ap-south-1
17
+ yarn run sls deploy -c ok.yaml --verbose --region ap-northeast-3
18
+ yarn run sls deploy -c ok.yaml --verbose --region ap-northeast-2
19
+ yarn run sls deploy -c ok.yaml --verbose --region ap-southeast-1
20
+ yarn run sls deploy -c ok.yaml --verbose --region ap-southeast-2
21
+ yarn run sls deploy -c ok.yaml --verbose --region ap-northeast-1
22
+ yarn run sls deploy -c ok.yaml --verbose --region ca-central-1
23
+ yarn run sls deploy -c ok.yaml --verbose --region me-south-1
24
+ yarn run sls deploy -c ok.yaml --verbose --region sa-east-1
25
+ yarn run sls deploy -c ok.yaml --verbose --region af-south-1
@@ -0,0 +1,140 @@
1
+ org: caiiiycuk
2
+ app: jsdos-backend
3
+ service: jsdos-v7
4
+
5
+ provider:
6
+ name: aws
7
+ runtime: nodejs14.x
8
+ region: eu-central-1
9
+ memorySize: 256
10
+ versionFunctions: false
11
+ environment:
12
+ NETWORKING_TABLE: "v2_r1_dznetworking"
13
+ PUT_CURL: "jjs-putCurl"
14
+ RUN_INSTANCE: "jjs-runInstanceV2"
15
+ iamRoleStatements:
16
+ - Effect: Allow
17
+ Action:
18
+ - s3:ListBucket
19
+ Resource:
20
+ - "arn:aws:s3:::doszone-uploads"
21
+ - Effect: Allow
22
+ Action:
23
+ - s3:Get*
24
+ - s3:Put*
25
+ Resource:
26
+ - "arn:aws:s3:::doszone-uploads/*"
27
+ - Effect: Allow
28
+ Action:
29
+ - lambda:InvokeFunction
30
+ Resource:
31
+ - "arn:aws:lambda:${opt:region, self:provider.region}:*:function:${self:provider.environment.PUT_CURL}"
32
+ - "arn:aws:lambda:${opt:region, self:provider.region}:*:function:${self:provider.environment.RUN_INSTANCE}"
33
+ - Effect: Allow
34
+ Action:
35
+ - dynamodb:Query
36
+ - dynamodb:Scan
37
+ - dynamodb:GetItem
38
+ - dynamodb:PutItem
39
+ - dynamodb:UpdateItem
40
+ - dynamodb:DeleteItem
41
+ Resource:
42
+ - "arn:aws:dynamodb:${opt:region, self:provider.region}:*:table/${self:provider.environment.NETWORKING_TABLE}"
43
+
44
+ functions:
45
+ getTokenCost:
46
+ handler: src/networking/get-token-cost.getTokenCost
47
+ name: jsdos-getTokenCost
48
+ events:
49
+ - http:
50
+ path: /token/cost/get
51
+ method: get
52
+ cors: true
53
+ getFreeToken:
54
+ handler: src/networking/get-free-token.getFreeToken
55
+ name: jsdos-getFreeToken
56
+ events:
57
+ - http:
58
+ path: /token/free/get
59
+ method: get
60
+ cors: true
61
+ getTokenInfo:
62
+ handler: src/networking/get-token-info.getTokenInfo
63
+ name: jsdos-getTokenInfo
64
+ events:
65
+ - http:
66
+ path: /token/info/get
67
+ method: get
68
+ cors: true
69
+ startIpx:
70
+ handler: src/networking/ipx/start-ipx.startIpx
71
+ name: jsdos-startIpx
72
+ events:
73
+ - http:
74
+ path: /token/ipx/start
75
+ method: get
76
+ cors: true
77
+ putIpxIp:
78
+ handler: src/networking/ipx/put-ipx-ip.putIpxIp
79
+ name: jsdos-putIpxIp
80
+ events:
81
+ - http:
82
+ path: /token/ipx/ip/put
83
+ method: put
84
+ cors: true
85
+ stopIpx:
86
+ handler: src/networking/ipx/stop-ipx.stopIpx
87
+ name: jsdos-stopIpx
88
+ events:
89
+ - http:
90
+ path: /token/ipx/stop
91
+ method: post
92
+ cors: true
93
+ personalPut:
94
+ handler: src/personal-put.personalPut
95
+ name: jsdos-personalPut
96
+ events:
97
+ - http:
98
+ path: /personal/put
99
+ method: post
100
+ cors: true
101
+ personalAcl:
102
+ handler: src/personal-acl.personalAcl
103
+ name: jsdos-personalAcl
104
+ events:
105
+ - http:
106
+ path: /personal/acl
107
+ method: post
108
+ cors: true
109
+
110
+ resources:
111
+ Resources:
112
+ dznetworking:
113
+ Type: 'AWS::DynamoDB::Table'
114
+ DeletionPolicy: Retain
115
+ Properties:
116
+ AttributeDefinitions:
117
+ -
118
+ AttributeName: key
119
+ AttributeType: S
120
+ -
121
+ AttributeName: day
122
+ AttributeType: N
123
+ KeySchema:
124
+ -
125
+ AttributeName: key
126
+ KeyType: HASH
127
+ GlobalSecondaryIndexes:
128
+ -
129
+ IndexName: day
130
+ KeySchema:
131
+ -
132
+ AttributeName: day
133
+ KeyType: HASH
134
+ Projection:
135
+ ProjectionType: ALL
136
+ TableName: ${self:provider.environment.NETWORKING_TABLE}
137
+ BillingMode: PAY_PER_REQUEST
138
+
139
+ plugins:
140
+ - serverless-plugin-typescript
@@ -0,0 +1,5 @@
1
+ export function getDayOrigin() {
2
+ const date = new Date();
3
+ return (Date.UTC(date.getFullYear(), date.getMonth(), date.getDate()) -
4
+ Date.UTC(date.getFullYear(), 0, 0)) / 24 / 60 / 60 / 1000 + date.getFullYear() * 366;
5
+ }
@@ -0,0 +1,33 @@
1
+ import { error, badRequest, success } from "../responses";
2
+ import { getDayOrigin } from "./day";
3
+ import { freeTierSoftLimit, freeTierHardLimit } from "./limits";
4
+ import { createFreeToken, getFreeTierHardCount, getFreeTierSoftCount } from "./token";
5
+
6
+ export const getFreeToken = async (event: any) => {
7
+ const namespace = event.queryStringParameters?.namespace;
8
+ const id = event.queryStringParameters?.id;
9
+ const region = event.queryStringParameters?.region;
10
+ const day = getDayOrigin();
11
+
12
+ if (!namespace || !id || !region) {
13
+ return badRequest();
14
+ }
15
+
16
+ const softCount = await getFreeTierSoftCount(namespace, id, day);
17
+ if (softCount >= freeTierSoftLimit) {
18
+ return error("free-soft-limit");
19
+ }
20
+
21
+ const hardCount = await getFreeTierHardCount(day);
22
+ if (hardCount >= freeTierHardLimit) {
23
+ return error("free-hard-limit");
24
+ }
25
+
26
+ try {
27
+ return success({
28
+ token: await createFreeToken(namespace, id, day, region),
29
+ });
30
+ } catch (e) {
31
+ return error(e.message);
32
+ }
33
+ };
@@ -0,0 +1,31 @@
1
+ import { error, badRequest, success } from "../responses";
2
+ import { getDayOrigin } from "./day";
3
+ import { freeTierSoftLimit, freeTierSec, freeTierHardLimit } from "./limits";
4
+ import { getFreeTierHardCount, getFreeTierSoftCount } from "./token";
5
+
6
+ export const getTokenCost = async (event: any) => {
7
+ const namespace = event.queryStringParameters?.namespace;
8
+ const id = event.queryStringParameters?.id;
9
+ const durationSec = Number.parseInt(event.queryStringParameters?.durationSec);
10
+ const day = getDayOrigin();
11
+
12
+ if (!namespace || !id || !durationSec || isNaN(durationSec)) {
13
+ return badRequest();
14
+ }
15
+
16
+ if (freeTierSec !== durationSec) {
17
+ return error("30-min-required");
18
+ }
19
+
20
+ if (await getFreeTierSoftCount(namespace, id, day) >= freeTierSoftLimit) {
21
+ return error("free-soft-limit");
22
+ }
23
+
24
+ if (await getFreeTierHardCount(day) >= freeTierHardLimit) {
25
+ return error("free-hard-limit");
26
+ }
27
+
28
+ return success({
29
+ cost: 0,
30
+ });
31
+ };
@@ -0,0 +1,16 @@
1
+ import { badRequest, error, success } from "../responses";
2
+ import { getToken } from "./token";
3
+
4
+ export const getTokenInfo = async (event: any) => {
5
+ const token = event.queryStringParameters?.token;
6
+
7
+ if (!token) {
8
+ return badRequest();
9
+ }
10
+
11
+ try {
12
+ return success(await getToken(token));
13
+ } catch (e) {
14
+ return error(e.message);
15
+ }
16
+ };
@@ -0,0 +1,20 @@
1
+ import { error, badRequest, success } from "../../responses";
2
+ import { putIp } from "../token";
3
+
4
+ export const putIpxIp = async (event: any) => {
5
+ const token = event.queryStringParameters?.token;
6
+ const arn = event.queryStringParameters?.arn;
7
+ const ip = event.queryStringParameters.ip;
8
+
9
+ if (!token || !arn || !ip) {
10
+ return badRequest();
11
+ }
12
+
13
+ try {
14
+ await putIp(token, arn, ip, "ipx");
15
+ return success({});
16
+ } catch (e) {
17
+ console.error("Can't update ipx ip", e);
18
+ return error(e.message);
19
+ }
20
+ };
@@ -0,0 +1,16 @@
1
+ import { error, badRequest, success } from "../../responses";
2
+ import { newTask } from "../token";
3
+
4
+ export const startIpx = async (event: any) => {
5
+ const token = event.queryStringParameters?.token;
6
+ if (!token) {
7
+ return badRequest();
8
+ }
9
+
10
+ try {
11
+ return success({ arn: await newTask(token, "ipx") });
12
+ } catch (e) {
13
+ console.error("Can't start ipx-server", e);
14
+ return error(e.message);
15
+ }
16
+ };
@@ -0,0 +1,19 @@
1
+ import { error, badRequest, success } from "../../responses";
2
+ import { stopTask } from "../token";
3
+
4
+ export const stopIpx = async (event: any) => {
5
+ const token = event.queryStringParameters?.token;
6
+ const arn = event.queryStringParameters?.arn;
7
+
8
+ if (!token || !arn) {
9
+ return badRequest();
10
+ }
11
+
12
+ try {
13
+ await stopTask(token, arn, "ipx");
14
+ return success({});
15
+ } catch (e) {
16
+ console.error("Can't update ipx ip", e);
17
+ return error(e.message);
18
+ }
19
+ };
@@ -0,0 +1,3 @@
1
+ export const freeTierSoftLimit = 24;
2
+ export const freeTierHardLimit = 256;
3
+ export const freeTierSec = 30 * 60; // 30 min
@@ -0,0 +1,238 @@
1
+ import * as AWS from "aws-sdk";
2
+ import { freeTierHardLimit, freeTierSec, freeTierSoftLimit } from "./limits";
3
+ import { customAlphabet } from "nanoid/async";
4
+
5
+ const dynamoDb = new AWS.DynamoDB.DocumentClient();
6
+ const NETWORKING_TABLE = process.env.NETWORKING_TABLE as string;
7
+
8
+ const lambda = new AWS.Lambda();
9
+ const RunInstanceLambda = process.env.RUN_INSTANCE as string;
10
+
11
+ const nanoid = customAlphabet("0123456789abcdefghijklmnopqrstuvwxyz", 6);
12
+
13
+ interface Token {
14
+ day: number,
15
+ region: string,
16
+ endTime: number,
17
+ ttlSec: number,
18
+ }
19
+
20
+ export type TaskType = "ipx";
21
+
22
+ export async function getFreeTierSoftCount(namespace: string, id: string, day: number): Promise<number> {
23
+ const freeTierSoftKey = getFreeTierSoftKey(namespace, id, day);
24
+ const response = await dynamoDb.get({
25
+ TableName: NETWORKING_TABLE,
26
+ Key: {
27
+ key: freeTierSoftKey,
28
+ },
29
+ }).promise();
30
+
31
+ return response.Item?.count || 0;
32
+ }
33
+
34
+ export async function getFreeTierHardCount(day: number): Promise<number> {
35
+ const freeTierHardKey = getFreeTierHardKey(day);
36
+ const response = await dynamoDb.get({
37
+ TableName: NETWORKING_TABLE,
38
+ Key: {
39
+ key: freeTierHardKey,
40
+ },
41
+ }).promise();
42
+
43
+ return response.Item?.count || 0;
44
+ }
45
+
46
+ export async function createFreeToken(namespace: string, id: string, day: number, region: string): Promise<string> {
47
+ const freeTierSoftKey = getFreeTierSoftKey(namespace, id, day);
48
+ const freeTierHardKey = getFreeTierHardKey(day);
49
+
50
+ const inc = async (key: string, inc: number) => {
51
+ const updateParams: AWS.DynamoDB.DocumentClient.UpdateItemInput = {
52
+ TableName: NETWORKING_TABLE,
53
+ Key: {
54
+ key,
55
+ },
56
+ UpdateExpression: "ADD #count :inc",
57
+ ExpressionAttributeNames: {
58
+ "#count": "count",
59
+ },
60
+ ExpressionAttributeValues: {
61
+ ":inc": inc,
62
+ },
63
+ ReturnValues: "ALL_NEW",
64
+ };
65
+
66
+ const response = await dynamoDb.update(updateParams).promise();
67
+ if (typeof response.Attributes?.count !== "number") {
68
+ console.error("Can't get updated count value for key " + key, response);
69
+ throw new Error("Can't get updated count value for key " + key);
70
+ }
71
+
72
+ return response.Attributes?.count as number;
73
+ };
74
+
75
+ const [softCount, hardCount] = await Promise.all([inc(freeTierSoftKey, 1), inc(freeTierHardKey, 1)]);
76
+
77
+ try {
78
+ if (softCount > freeTierSoftLimit) {
79
+ throw new Error("free-soft-limit");
80
+ }
81
+
82
+ if (hardCount > freeTierHardLimit) {
83
+ throw new Error("free-hard-limit");
84
+ }
85
+ } catch (e: any) {
86
+ // rollback
87
+ await Promise.all([inc(freeTierSoftKey, -1), inc(freeTierHardKey, -1)]);
88
+ throw e;
89
+ }
90
+
91
+ return createToken(namespace, id, day, region, freeTierSec);
92
+ }
93
+
94
+ export async function getToken(token: string): Promise<Token> {
95
+ const item = (await dynamoDb.get({
96
+ TableName: NETWORKING_TABLE,
97
+ Key: {
98
+ key: getTokenKey(token),
99
+ },
100
+ }).promise()).Item as Token | undefined;
101
+
102
+ if (item === undefined) {
103
+ throw new Error("not-found");
104
+ }
105
+
106
+ item.ttlSec = Math.round((item.endTime - new Date().getTime()) / 1000);
107
+
108
+ return item;
109
+ }
110
+
111
+ export async function createToken(namespace: string, id: string, day: number,
112
+ region: string, durationSec: number): Promise<string> {
113
+ let token: string | null = null;
114
+ while (token === null) {
115
+ token = await nanoid();
116
+
117
+ const createParams: AWS.DynamoDB.DocumentClient.PutItemInput = {
118
+ TableName: NETWORKING_TABLE,
119
+ Item: {
120
+ "key": getTokenKey(token),
121
+ namespace,
122
+ id,
123
+ day,
124
+ region,
125
+ durationSec,
126
+ "createdAt": new Date().getTime(),
127
+ "endTime": new Date().getTime() + durationSec * 1000,
128
+ },
129
+ ConditionExpression: "attribute_not_exists(#key)",
130
+ ExpressionAttributeNames: {
131
+ "#key": "key",
132
+ },
133
+ };
134
+
135
+ try {
136
+ await dynamoDb.put(createParams).promise();
137
+ } catch (e) {
138
+ console.error(e);
139
+ token = null;
140
+ }
141
+ }
142
+
143
+ return token;
144
+ }
145
+
146
+ export async function newTask(tokenId: string, task: TaskType) {
147
+ const token = await getToken(tokenId);
148
+
149
+ if (token.ttlSec < 60) { // 1min to start container
150
+ throw new Error("ended");
151
+ }
152
+
153
+ const result = await lambda.invoke({
154
+ FunctionName: RunInstanceLambda,
155
+ Payload: JSON.stringify({
156
+ token: tokenId,
157
+ region: token.region,
158
+ task,
159
+ }),
160
+ }).promise();
161
+
162
+ if (!result.Payload) {
163
+ throw new Error("unable-to-start-task");
164
+ }
165
+
166
+ const payload = JSON.parse(JSON.parse(result.Payload as string).body);
167
+
168
+ if (payload.success === false) {
169
+ throw new Error(payload.errorCode);
170
+ }
171
+
172
+ const arn = payload.arn;
173
+
174
+ if (arn === undefined) {
175
+ throw new Error("ARN missed in runInstanceV2 response");
176
+ }
177
+
178
+ const updateParams: AWS.DynamoDB.DocumentClient.UpdateItemInput = {
179
+ TableName: NETWORKING_TABLE,
180
+ Key: {
181
+ key: getTokenKey(tokenId),
182
+ },
183
+ UpdateExpression: `SET ${task}Arn = :arn`,
184
+ ExpressionAttributeValues: {
185
+ ":arn": arn,
186
+ },
187
+ };
188
+
189
+ await dynamoDb.update(updateParams).promise();
190
+
191
+ return arn;
192
+ }
193
+
194
+ export async function putIp(token: string, arn: string, ip: string, task: TaskType) {
195
+ const updateParams: AWS.DynamoDB.DocumentClient.UpdateItemInput = {
196
+ TableName: NETWORKING_TABLE,
197
+ Key: {
198
+ key: getTokenKey(token),
199
+ },
200
+ UpdateExpression: `SET ${task}Ip = :ip`,
201
+ ConditionExpression: `${task}Arn = :arn`,
202
+ ExpressionAttributeValues: {
203
+ ":arn": arn,
204
+ ":ip": ip,
205
+ },
206
+ };
207
+
208
+ await dynamoDb.update(updateParams).promise();
209
+ }
210
+
211
+ export async function stopTask(token: string, arn: string, task: TaskType) {
212
+ const updateParams: AWS.DynamoDB.DocumentClient.UpdateItemInput = {
213
+ TableName: NETWORKING_TABLE,
214
+ Key: {
215
+ key: getTokenKey(token),
216
+ },
217
+ UpdateExpression: `REMOVE ${task}Arn, ${task}Ip`,
218
+ ConditionExpression: `${task}Arn = :arn`,
219
+ ExpressionAttributeValues: {
220
+ ":arn": arn,
221
+ },
222
+ };
223
+
224
+ await dynamoDb.update(updateParams).promise();
225
+ }
226
+
227
+
228
+ function getFreeTierSoftKey(namespace: string, id: string, day: number) {
229
+ return "free-soft " + day + " " + id + "@" + namespace;
230
+ }
231
+
232
+ function getFreeTierHardKey(day: number) {
233
+ return "free-hard " + day;
234
+ }
235
+
236
+ function getTokenKey(token: string) {
237
+ return "token " + token;
238
+ }
@@ -0,0 +1,7 @@
1
+ import { Handler } from "aws-lambda";
2
+
3
+ import { success } from "./responses";
4
+
5
+ export const ok: Handler = async (event: any) => {
6
+ return success({});
7
+ };