@akashic/headless-driver 2.9.1 → 2.10.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.
@@ -1,12 +1,14 @@
1
- import { NodeVM } from "vm2";
2
1
  import type { AMFlowClient } from "../play/amflow/AMFlowClient";
3
2
  import type { PlayManager } from "../play/PlayManager";
4
3
  import type { EncodingType } from "../utils";
5
4
  import type { RunnerStartParameters } from "./Runner";
6
5
  import type { RunnerExecutionMode, RunnerPlayer, RunnerRenderingMode } from "./types";
7
- import type { RunnerV1, RunnerV1Game } from "./v1";
8
- import type { RunnerV2, RunnerV2Game } from "./v2";
9
- import type { RunnerV3, RunnerV3Game } from "./v3";
6
+ import type { RunnerV1Game } from "./v1";
7
+ import { RunnerV1 } from "./v1";
8
+ import type { RunnerV2Game } from "./v2";
9
+ import { RunnerV2 } from "./v2";
10
+ import type { RunnerV3Game } from "./v3";
11
+ import { RunnerV3 } from "./v3";
10
12
  export interface CreateRunnerParameters {
11
13
  playId: string;
12
14
  amflow: AMFlowClient;
@@ -16,16 +18,14 @@ export interface CreateRunnerParameters {
16
18
  player?: RunnerPlayer;
17
19
  /**
18
20
  * 信頼されたコンテンツであるかどうか。
19
- * `true` の場合、そのコンテンツを「信頼されたもの」として扱い、外部モジュールまたは組み込みモジュールへのアクセスが許可される。
20
- * `false` の場合、コンテンツまたはエンジンモジュールでの動作が一部制限される (外部モジュールまたは組み込みモジュールへのアクセスが制限など)。
21
- * 特に理由がない限り `false` にしておくことを推奨。
21
+ * この設定は現在のバージョンにおいて形骸化している。本値により振る舞いは変化しない。
22
22
  * 初期値は `false` 。
23
23
  */
24
24
  trusted?: boolean;
25
25
  /**
26
26
  * レンダリングモード。
27
27
  * `"canvas"` を指定するとプライマリサーフェスの描画内容を `Runner#getPrimarySurface()` を経由して取得できる。
28
- * `"canvas"` を指定した場合 `trusted` を `true` にしなければならない。また、利用側で node-canvas をインストールしなければならない。
28
+ * `"canvas"` を指定した場合、利用側で node-canvas をインストールしなければならない。
29
29
  * 初期値は `"none"` 。
30
30
  */
31
31
  renderingMode?: RunnerRenderingMode;
@@ -68,8 +68,6 @@ export declare class RunnerManager {
68
68
  constructor(playManager: PlayManager);
69
69
  /**
70
70
  * Runner を作成する。
71
- * Runner は Node.js の Virtual Machine 上で実行される。
72
- * 主な制限事項として process へのアクセスが制限される。
73
71
  * @param params パラメータ
74
72
  */
75
73
  createRunner(params: CreateRunnerParameters): Promise<string>;
@@ -116,6 +114,5 @@ export declare class RunnerManager {
116
114
  protected resolveGameConfiguration(gameJsonUrl: string): Promise<GameConfiguration>;
117
115
  protected loadJSON<T>(contentUrl: string): Promise<T>;
118
116
  protected createLoadFileHandler(allowedUrls: (string | RegExp)[] | null): (url: string, encoding: EncodingType, callback: (err: Error | null, data?: string | Uint8Array) => void) => void;
119
- protected createVm(trusted?: boolean): NodeVM;
120
117
  }
121
118
  export {};
@@ -10,16 +10,12 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
10
10
  };
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.RunnerManager = void 0;
13
- const fs = require("fs");
14
13
  const path = require("path");
15
- const url = require("url");
16
- const vm2_1 = require("vm2");
17
- const ExecVmScriptV1 = require("../ExecuteVmScriptV1");
18
- const ExecVmScriptV2 = require("../ExecuteVmScriptV2");
19
- const ExecVmScriptV3 = require("../ExecuteVmScriptV3");
20
14
  const Logger_1 = require("../Logger");
21
15
  const utils_1 = require("../utils");
22
- const requireEngineFiles_1 = require("./v3/requireEngineFiles");
16
+ const v1_1 = require("./v1");
17
+ const v2_1 = require("./v2");
18
+ const v3_1 = require("./v3");
23
19
  /**
24
20
  * Runner を管理するマネージャ。
25
21
  */
@@ -31,8 +27,6 @@ class RunnerManager {
31
27
  }
32
28
  /**
33
29
  * Runner を作成する。
34
- * Runner は Node.js の Virtual Machine 上で実行される。
35
- * 主な制限事項として process へのアクセスが制限される。
36
30
  * @param params パラメータ
37
31
  */
38
32
  createRunner(params) {
@@ -87,20 +81,20 @@ class RunnerManager {
87
81
  if (gameConfiguration.definitions) {
88
82
  const defs = [];
89
83
  for (let i = 0; i < gameConfiguration.definitions.length; i++) {
90
- const _url = url.resolve(engineConfiguration.asset_base_url, gameConfiguration.definitions[i]);
84
+ const _url = (0, utils_1.resolveUrl)(engineConfiguration.asset_base_url, gameConfiguration.definitions[i]);
91
85
  const _def = yield this.loadJSON(_url);
92
86
  defs.push(_def);
93
87
  }
94
88
  version = defs.reduce((acc, def) => {
95
- return (def.environment && def.environment["sandbox-runtime"]) || acc;
89
+ var _a;
90
+ return (_a = (def.environment && def.environment["sandbox-runtime"])) !== null && _a !== void 0 ? _a : acc;
96
91
  }, version);
97
- configurationBaseUrl = url.resolve(engineConfiguration.content_url, "./");
92
+ configurationBaseUrl = (0, utils_1.resolveUrl)(engineConfiguration.content_url, "./");
98
93
  }
99
94
  else if (gameConfiguration.environment && gameConfiguration.environment["sandbox-runtime"]) {
100
95
  version = gameConfiguration.environment["sandbox-runtime"];
101
96
  }
102
97
  const runnerId = `${this.nextRunnerId++}`;
103
- const nvm = this.createVm(params.trusted);
104
98
  const runnerParameter = {
105
99
  contentUrl,
106
100
  assetBaseUrl: engineConfiguration.asset_base_url,
@@ -121,24 +115,15 @@ class RunnerManager {
121
115
  };
122
116
  if (version === "3") {
123
117
  (0, Logger_1.getSystemLogger)().info("v3 content");
124
- const filePath = ExecVmScriptV3.getFilePath();
125
- const str = fs.readFileSync(filePath, { encoding: "utf8" });
126
- const script = new vm2_1.VMScript(str, filePath);
127
- runner = nvm.run(script).createRunnerV3(runnerParameter);
118
+ runner = new v3_1.RunnerV3(runnerParameter);
128
119
  }
129
120
  else if (version === "2") {
130
121
  (0, Logger_1.getSystemLogger)().info("v2 content");
131
- const filePath = ExecVmScriptV2.getFilePath();
132
- const str = fs.readFileSync(filePath, { encoding: "utf8" });
133
- const script = new vm2_1.VMScript(str, filePath);
134
- runner = nvm.run(script).createRunnerV2(runnerParameter);
122
+ runner = new v2_1.RunnerV2(runnerParameter);
135
123
  }
136
124
  else {
137
125
  (0, Logger_1.getSystemLogger)().info("v1 content");
138
- const filePath = ExecVmScriptV1.getFilePath();
139
- const str = fs.readFileSync(filePath, { encoding: "utf8" });
140
- const script = new vm2_1.VMScript(str, filePath);
141
- runner = nvm.run(script).createRunnerV1(runnerParameter);
126
+ runner = new v1_1.RunnerV1(runnerParameter);
142
127
  }
143
128
  runner.errorTrigger.add((err) => {
144
129
  (0, Logger_1.getSystemLogger)().error(err.message);
@@ -285,27 +270,5 @@ class RunnerManager {
285
270
  });
286
271
  };
287
272
  }
288
- createVm(trusted = false) {
289
- return new vm2_1.NodeVM({
290
- sandbox: {
291
- trustedFunctions: {
292
- engineFiles: () => {
293
- return (0, requireEngineFiles_1.requireEngineFiles)();
294
- }
295
- }
296
- },
297
- require: trusted
298
- ? {
299
- context: "host",
300
- external: true,
301
- builtin: ["*"]
302
- }
303
- : {
304
- context: "sandbox",
305
- external: true,
306
- builtin: []
307
- }
308
- });
309
- }
310
273
  }
311
274
  exports.RunnerManager = RunnerManager;
@@ -7,8 +7,6 @@ export interface NodeScriptAssetParameters {
7
7
  loadFileHandler: RunnerLoadFileHandler;
8
8
  }
9
9
  export declare class NodeScriptAsset extends g.ScriptAsset {
10
- static PRE_SCRIPT: string;
11
- static POST_SCRIPT: string;
12
10
  private errorHandler;
13
11
  private loadFileHandler;
14
12
  constructor(param: NodeScriptAssetParameters);
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.NodeScriptAsset = void 0;
4
+ const vm_1 = require("vm");
4
5
  const engine_files_v1_1 = require("engine-files-v1");
5
6
  class NodeScriptAsset extends engine_files_v1_1.akashicEngine.ScriptAsset {
6
7
  constructor(param) {
@@ -21,9 +22,32 @@ class NodeScriptAsset extends engine_files_v1_1.akashicEngine.ScriptAsset {
21
22
  });
22
23
  }
23
24
  execute(execEnv) {
24
- const func = new Function("g", NodeScriptAsset.PRE_SCRIPT + this.script + NodeScriptAsset.POST_SCRIPT);
25
25
  try {
26
- func(execEnv);
26
+ const context = (0, vm_1.createContext)(Object.create(null));
27
+ (0, vm_1.runInContext)(`
28
+ (console, g) => {
29
+ globalThis.console = {
30
+ log: console.log,
31
+ info: console.info,
32
+ warn: console.warn,
33
+ error: console.error,
34
+ assert: console.assert,
35
+ clear: console.clear,
36
+ dir: console.dir,
37
+ time: console.time,
38
+ timeEnd: console.timeEnd,
39
+ trace: console.trace
40
+ };
41
+ globalThis.g = g;
42
+ }
43
+ `, context)(console, execEnv);
44
+ (0, vm_1.runInContext)(`
45
+ (function(exports, require, module, __filename, __dirname) {
46
+ ${this.script}
47
+ })(g.module.exports, g.module.require, g.module, g.filename, g.dirname);
48
+ `, context, {
49
+ filename: `${this.path}`
50
+ });
27
51
  }
28
52
  catch (e) {
29
53
  this.errorHandler(e);
@@ -31,6 +55,4 @@ class NodeScriptAsset extends engine_files_v1_1.akashicEngine.ScriptAsset {
31
55
  return execEnv.module.exports;
32
56
  }
33
57
  }
34
- NodeScriptAsset.PRE_SCRIPT = "(function(exports, require, module, __filename, __dirname) {\n";
35
- NodeScriptAsset.POST_SCRIPT = "\n})(g.module.exports, g.module.require, g.module, g.filename, g.dirname);";
36
58
  exports.NodeScriptAsset = NodeScriptAsset;
@@ -7,8 +7,6 @@ export interface NodeScriptAssetParameters {
7
7
  loadFileHandler: RunnerLoadFileHandler;
8
8
  }
9
9
  export declare class NodeScriptAsset extends g.ScriptAsset {
10
- static PRE_SCRIPT: string;
11
- static POST_SCRIPT: string;
12
10
  private errorHandler;
13
11
  private loadFileHandler;
14
12
  constructor(param: NodeScriptAssetParameters);
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.NodeScriptAsset = void 0;
4
+ const vm_1 = require("vm");
4
5
  const engine_files_v2_1 = require("engine-files-v2");
5
6
  class NodeScriptAsset extends engine_files_v2_1.akashicEngine.ScriptAsset {
6
7
  constructor(param) {
@@ -21,9 +22,32 @@ class NodeScriptAsset extends engine_files_v2_1.akashicEngine.ScriptAsset {
21
22
  });
22
23
  }
23
24
  execute(execEnv) {
24
- const func = new Function("g", NodeScriptAsset.PRE_SCRIPT + this.script + NodeScriptAsset.POST_SCRIPT);
25
25
  try {
26
- func(execEnv);
26
+ const context = (0, vm_1.createContext)(Object.create(null));
27
+ (0, vm_1.runInContext)(`
28
+ (console, g) => {
29
+ globalThis.console = {
30
+ log: console.log,
31
+ info: console.info,
32
+ warn: console.warn,
33
+ error: console.error,
34
+ assert: console.assert,
35
+ clear: console.clear,
36
+ dir: console.dir,
37
+ time: console.time,
38
+ timeEnd: console.timeEnd,
39
+ trace: console.trace
40
+ };
41
+ globalThis.g = g;
42
+ }
43
+ `, context)(console, execEnv);
44
+ (0, vm_1.runInContext)(`
45
+ (function(exports, require, module, __filename, __dirname) {
46
+ ${this.script}
47
+ })(g.module.exports, g.module.require, g.module, g.filename, g.dirname);
48
+ `, context, {
49
+ filename: `${this.path}`
50
+ });
27
51
  }
28
52
  catch (e) {
29
53
  this.errorHandler(e);
@@ -31,6 +55,4 @@ class NodeScriptAsset extends engine_files_v2_1.akashicEngine.ScriptAsset {
31
55
  return execEnv.module.exports;
32
56
  }
33
57
  }
34
- NodeScriptAsset.PRE_SCRIPT = "(function(exports, require, module, __filename, __dirname) {\n";
35
- NodeScriptAsset.POST_SCRIPT = "\n})(g.module.exports, g.module.require, g.module, g.filename, g.dirname);";
36
58
  exports.NodeScriptAsset = NodeScriptAsset;
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.NodeScriptAsset = void 0;
4
+ const vm_1 = require("vm");
4
5
  const Asset_1 = require("./Asset");
5
6
  class NodeScriptAsset extends Asset_1.Asset {
6
7
  constructor(param) {
@@ -40,14 +41,33 @@ class NodeScriptAsset extends Asset_1.Asset {
40
41
  for (const key of this.exports) {
41
42
  postScript += `exports["${key}"] = typeof ${key} !== "undefined" ? ${key} : undefined;\n`;
42
43
  }
43
- const func = new Function("g", "(function(exports, require, module, __filename, __dirname) {\n" +
44
- this.script +
45
- "\n" +
46
- postScript +
47
- "\n" +
48
- "})(g.module.exports, g.module.require, g.module, g.filename, g.dirname);");
49
44
  try {
50
- func(execEnv);
45
+ const context = (0, vm_1.createContext)(Object.create(null));
46
+ (0, vm_1.runInContext)(`
47
+ (console, g) => {
48
+ globalThis.console = {
49
+ log: console.log,
50
+ info: console.info,
51
+ warn: console.warn,
52
+ error: console.error,
53
+ assert: console.assert,
54
+ clear: console.clear,
55
+ dir: console.dir,
56
+ time: console.time,
57
+ timeEnd: console.timeEnd,
58
+ trace: console.trace
59
+ };
60
+ globalThis.g = g;
61
+ }
62
+ `, context)(console, execEnv);
63
+ (0, vm_1.runInContext)(`
64
+ (function(exports, require, module, __filename, __dirname) {
65
+ ${this.script}
66
+ ${postScript}
67
+ })(g.module.exports, g.module.require, g.module, g.filename, g.dirname);
68
+ `, context, {
69
+ filename: `${this.path}`
70
+ });
51
71
  }
52
72
  catch (e) {
53
73
  this.errorHandler(e);
package/lib/utils.d.ts CHANGED
@@ -21,3 +21,4 @@ export declare namespace LoadFileInternal {
21
21
  function loadImpl(url: string, encoding?: EncodingType): Promise<string | Uint8Array>;
22
22
  }
23
23
  export declare function isHttpProtocol(url: string): boolean;
24
+ export declare function resolveUrl(from: string, to: string): string;
package/lib/utils.js CHANGED
@@ -9,7 +9,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
9
9
  });
10
10
  };
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
- exports.isHttpProtocol = exports.LoadFileInternal = exports.loadFile = void 0;
12
+ exports.resolveUrl = exports.isHttpProtocol = exports.LoadFileInternal = exports.loadFile = void 0;
13
13
  const fs = require("fs");
14
14
  const node_fetch_1 = require("node-fetch");
15
15
  const waitings = [];
@@ -87,3 +87,14 @@ function isHttpProtocol(url) {
87
87
  return /^(http|https)\:\/\//.test(url);
88
88
  }
89
89
  exports.isHttpProtocol = isHttpProtocol;
90
+ // @see https://nodejs.org/api/url.html#urlresolvefrom-to
91
+ function resolveUrl(from, to) {
92
+ const resolvedUrl = new URL(to, new URL(from, "resolve://"));
93
+ if (resolvedUrl.protocol === "resolve:") {
94
+ // `from` is a relative URL.
95
+ const { pathname, search, hash } = resolvedUrl;
96
+ return pathname + search + hash;
97
+ }
98
+ return resolvedUrl.toString();
99
+ }
100
+ exports.resolveUrl = resolveUrl;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@akashic/headless-driver",
3
- "version": "2.9.1",
3
+ "version": "2.10.0",
4
4
  "description": "A library to execute contents using Akashic Engine headlessly",
5
5
  "main": "lib/index.js",
6
6
  "author": "DWANGO Co., Ltd.",
@@ -29,11 +29,10 @@
29
29
  "@akashic/trigger": "^2.0.0",
30
30
  "engine-files-v1": "npm:@akashic/engine-files@1.2.2",
31
31
  "engine-files-v2": "npm:@akashic/engine-files@2.2.3",
32
- "engine-files-v3": "npm:@akashic/engine-files@3.7.3",
32
+ "engine-files-v3": "npm:@akashic/engine-files@3.7.4",
33
33
  "js-sha256": "^0.9.0",
34
34
  "lodash.clonedeep": "^4.5.0",
35
- "node-fetch": "^2.6.7",
36
- "vm2": "3.9.11"
35
+ "node-fetch": "^2.6.7"
37
36
  },
38
37
  "devDependencies": {
39
38
  "@akashic/eslint-config": "^1.1.1",
@@ -56,7 +55,7 @@
56
55
  "npm-run-all": "^4.1.5",
57
56
  "pixelmatch": "^5.3.0",
58
57
  "pngjs": "^7.0.0",
59
- "prettier": "^2.7.1",
58
+ "prettier": "^3.0.0",
60
59
  "remark-cli": "^11.0.0",
61
60
  "rimraf": "^5.0.0",
62
61
  "serve-handler": "^6.1.3",
@@ -1,4 +0,0 @@
1
- import type { RunnerParameters } from "./runner";
2
- import { RunnerV1 } from "./runner/v1";
3
- export declare function createRunnerV1(params: RunnerParameters): RunnerV1;
4
- export declare function getFilePath(): string;
@@ -1,12 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getFilePath = exports.createRunnerV1 = void 0;
4
- const v1_1 = require("./runner/v1");
5
- function createRunnerV1(params) {
6
- return new v1_1.RunnerV1(params);
7
- }
8
- exports.createRunnerV1 = createRunnerV1;
9
- function getFilePath() {
10
- return __filename;
11
- }
12
- exports.getFilePath = getFilePath;
@@ -1,4 +0,0 @@
1
- import type { RunnerParameters } from "./runner";
2
- import { RunnerV2 } from "./runner/v2";
3
- export declare function createRunnerV2(params: RunnerParameters): RunnerV2;
4
- export declare function getFilePath(): string;
@@ -1,12 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getFilePath = exports.createRunnerV2 = void 0;
4
- const v2_1 = require("./runner/v2");
5
- function createRunnerV2(params) {
6
- return new v2_1.RunnerV2(params);
7
- }
8
- exports.createRunnerV2 = createRunnerV2;
9
- function getFilePath() {
10
- return __filename;
11
- }
12
- exports.getFilePath = getFilePath;
@@ -1,4 +0,0 @@
1
- import type { RunnerParameters } from "./runner";
2
- import { RunnerV3 } from "./runner/v3";
3
- export declare function createRunnerV3(params: RunnerParameters): RunnerV3;
4
- export declare function getFilePath(): string;
@@ -1,12 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getFilePath = exports.createRunnerV3 = void 0;
4
- const v3_1 = require("./runner/v3");
5
- function createRunnerV3(params) {
6
- return new v3_1.RunnerV3(params);
7
- }
8
- exports.createRunnerV3 = createRunnerV3;
9
- function getFilePath() {
10
- return __filename;
11
- }
12
- exports.getFilePath = getFilePath;