@adonisjs/repl 4.0.0-7 → 4.0.0-9

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/build/index.js CHANGED
@@ -1,9 +1,297 @@
1
- /*
2
- * @adonisjs/repl
3
- *
4
- * (c) AdonisJS
5
- *
6
- * For the full copyright and license information, please view the LICENSE
7
- * file that was distributed with this source code.
8
- */
9
- export { Repl } from './src/repl.js';
1
+ // src/repl.ts
2
+ import stringWidth from "string-width";
3
+ import useColors from "@poppinss/colors";
4
+ import { inspect, promisify as utilPromisify } from "node:util";
5
+ import { Recoverable, start as startRepl } from "node:repl";
6
+ var GLOBAL_NODE_PROPERTIES = [
7
+ "performance",
8
+ "global",
9
+ "clearInterval",
10
+ "clearTimeout",
11
+ "setInterval",
12
+ "setTimeout",
13
+ "queueMicrotask",
14
+ "clearImmediate",
15
+ "setImmediate",
16
+ "structuredClone",
17
+ "atob",
18
+ "btoa",
19
+ "fetch",
20
+ "crypto"
21
+ ];
22
+ var TS_UTILS_HELPERS = [
23
+ "__extends",
24
+ "__assign",
25
+ "__rest",
26
+ "__decorate",
27
+ "__param",
28
+ "__esDecorate",
29
+ "__runInitializers",
30
+ "__propKey",
31
+ "__setFunctionName",
32
+ "__metadata",
33
+ "__awaiter",
34
+ "__generator",
35
+ "__exportStar",
36
+ "__createBinding",
37
+ "__values",
38
+ "__read",
39
+ "__spread",
40
+ "__spreadArrays",
41
+ "__spreadArray",
42
+ "__await",
43
+ "__asyncGenerator",
44
+ "__asyncDelegator",
45
+ "__asyncValues",
46
+ "__makeTemplateObject",
47
+ "__importStar",
48
+ "__importDefault",
49
+ "__classPrivateFieldGet",
50
+ "__classPrivateFieldSet",
51
+ "__classPrivateFieldIn"
52
+ ];
53
+ var Repl = class {
54
+ /**
55
+ * Length of the longest custom method name. We need to show a
56
+ * symmetric view of custom methods and their description
57
+ */
58
+ #longestCustomMethodName = 0;
59
+ /**
60
+ * Reference to the original `eval` method of the repl server.
61
+ * Since we are monkey patching it, we need a reference to it
62
+ * to call it after our custom logic
63
+ */
64
+ #originalEval;
65
+ /**
66
+ * Compiler that will transform the user input just
67
+ * before evaluation
68
+ */
69
+ #compiler;
70
+ /**
71
+ * Path to the history file
72
+ */
73
+ #historyFilePath;
74
+ /**
75
+ * Set of registered ready callbacks
76
+ */
77
+ #onReadyCallbacks = [];
78
+ /**
79
+ * A set of registered custom methods
80
+ */
81
+ #customMethods = {};
82
+ /**
83
+ * Colors reference
84
+ */
85
+ colors = useColors.ansi();
86
+ /**
87
+ * Reference to the repl server. Available after the `start` method
88
+ * is invoked
89
+ */
90
+ server;
91
+ constructor(options) {
92
+ this.#compiler = options?.compiler;
93
+ this.#historyFilePath = options?.historyFilePath;
94
+ }
95
+ /**
96
+ * Registering custom methods with the server context by wrapping
97
+ * them inside a function and passes the REPL server instance
98
+ * to the method
99
+ */
100
+ #registerCustomMethodWithContext(name) {
101
+ const customMethod = this.#customMethods[name];
102
+ if (!customMethod) {
103
+ return;
104
+ }
105
+ const handler = (...args) => customMethod.handler(this, ...args);
106
+ Object.defineProperty(handler, "name", { value: customMethod.handler.name });
107
+ this.server.context[name] = handler;
108
+ }
109
+ /**
110
+ * Setup context with default globals
111
+ */
112
+ #setupContext() {
113
+ this.addMethod(
114
+ "clear",
115
+ function clear(repl, key) {
116
+ if (!key) {
117
+ console.log(repl.colors.red("Define a property name to remove from the context"));
118
+ } else {
119
+ delete repl.server.context[key];
120
+ }
121
+ repl.server.displayPrompt();
122
+ },
123
+ {
124
+ description: "Clear a property from the REPL context",
125
+ usage: `clear ${this.colors.gray("(propertyName)")}`
126
+ }
127
+ );
128
+ this.addMethod(
129
+ "p",
130
+ function promisify(_, fn) {
131
+ return utilPromisify(fn);
132
+ },
133
+ {
134
+ description: 'Promisify a function. Similar to Node.js "util.promisify"',
135
+ usage: `p ${this.colors.gray("(function)")}`
136
+ }
137
+ );
138
+ Object.keys(this.#customMethods).forEach((name) => {
139
+ this.#registerCustomMethodWithContext(name);
140
+ });
141
+ }
142
+ /**
143
+ * Find if the error is recoverable or not
144
+ */
145
+ #isRecoverableError(error) {
146
+ return /^(Unexpected end of input|Unexpected token|' expected)/.test(error.message);
147
+ }
148
+ /**
149
+ * Custom eval method to execute the user code
150
+ *
151
+ * Basically we are monkey patching the original eval method, because
152
+ * we want to:
153
+ * - Compile the user code before executing it
154
+ * - And also benefit from the original eval method that supports
155
+ * cool features like top level await
156
+ */
157
+ #eval(code, context, filename, callback) {
158
+ try {
159
+ const compiled = this.#compiler ? this.#compiler.compile(code, filename) : code;
160
+ return this.#originalEval(compiled, context, filename, callback);
161
+ } catch (error) {
162
+ if (this.#isRecoverableError(error)) {
163
+ callback(new Recoverable(error), null);
164
+ return;
165
+ }
166
+ callback(error, null);
167
+ }
168
+ }
169
+ /**
170
+ * Setup history file
171
+ */
172
+ #setupHistory() {
173
+ if (!this.#historyFilePath) {
174
+ return;
175
+ }
176
+ this.server.setupHistory(this.#historyFilePath, (error) => {
177
+ if (!error) {
178
+ return;
179
+ }
180
+ console.log(this.colors.red("Unable to write to the history file. Exiting"));
181
+ console.error(error);
182
+ process.exit(1);
183
+ });
184
+ }
185
+ /**
186
+ * Prints the help for the context properties
187
+ */
188
+ #printContextHelp() {
189
+ console.log("");
190
+ console.log(this.colors.green("CONTEXT PROPERTIES/METHODS:"));
191
+ const context = Object.keys(this.server.context).reduce(
192
+ (result, key) => {
193
+ if (!this.#customMethods[key] && !GLOBAL_NODE_PROPERTIES.includes(key) && !TS_UTILS_HELPERS.includes(key)) {
194
+ result[key] = this.server.context[key];
195
+ }
196
+ return result;
197
+ },
198
+ {}
199
+ );
200
+ console.log(inspect(context, false, 1, true));
201
+ }
202
+ /**
203
+ * Prints the help for the custom methods
204
+ */
205
+ #printCustomMethodsHelp() {
206
+ console.log("");
207
+ console.log(this.colors.green("GLOBAL METHODS:"));
208
+ Object.keys(this.#customMethods).forEach((method) => {
209
+ const { options } = this.#customMethods[method];
210
+ const usage = this.colors.yellow(options.usage || method);
211
+ const spaces = " ".repeat(this.#longestCustomMethodName - options.width + 2);
212
+ const description = this.colors.dim(options.description || "");
213
+ console.log(`${usage}${spaces}${description}`);
214
+ });
215
+ }
216
+ /**
217
+ * Prints the context to the console
218
+ */
219
+ #ls() {
220
+ this.#printCustomMethodsHelp();
221
+ this.#printContextHelp();
222
+ this.server.displayPrompt();
223
+ }
224
+ /**
225
+ * Notify by writing to the console
226
+ */
227
+ notify(message) {
228
+ console.log(this.colors.yellow().italic(message));
229
+ if (this.server) {
230
+ this.server.displayPrompt();
231
+ }
232
+ }
233
+ /**
234
+ * Register a callback to be invoked once the server is ready
235
+ */
236
+ ready(callback) {
237
+ this.#onReadyCallbacks.push(callback);
238
+ return this;
239
+ }
240
+ /**
241
+ * Register a custom loader function to be added to the context
242
+ */
243
+ addMethod(name, handler, options) {
244
+ const width = stringWidth(options?.usage || name);
245
+ if (width > this.#longestCustomMethodName) {
246
+ this.#longestCustomMethodName = width;
247
+ }
248
+ this.#customMethods[name] = { handler, options: Object.assign({ width }, options) };
249
+ if (this.server) {
250
+ this.#registerCustomMethodWithContext(name);
251
+ }
252
+ return this;
253
+ }
254
+ /**
255
+ * Returns the collection of registered methods
256
+ */
257
+ getMethods() {
258
+ return this.#customMethods;
259
+ }
260
+ /**
261
+ * Register a compiler. Make sure register the compiler before
262
+ * calling the start method
263
+ */
264
+ useCompiler(compiler) {
265
+ this.#compiler = compiler;
266
+ return this;
267
+ }
268
+ /**
269
+ * Start the REPL server
270
+ */
271
+ start() {
272
+ console.log("");
273
+ this.notify('Type ".ls" to a view list of available context methods/properties');
274
+ this.server = startRepl({
275
+ prompt: `> ${this.#compiler?.supportsTypescript ? "(ts) " : "(js) "}`,
276
+ input: process.stdin,
277
+ output: process.stdout,
278
+ terminal: process.stdout.isTTY && !Number.parseInt(process.env.NODE_NO_READLINE, 10),
279
+ useGlobal: true
280
+ });
281
+ this.server.defineCommand("ls", {
282
+ help: "View list of available context methods/properties",
283
+ action: this.#ls.bind(this)
284
+ });
285
+ this.#setupContext();
286
+ this.#setupHistory();
287
+ this.#originalEval = this.server.eval;
288
+ this.server.eval = this.#eval.bind(this);
289
+ this.server.displayPrompt();
290
+ this.#onReadyCallbacks.forEach((callback) => callback(this));
291
+ return this;
292
+ }
293
+ };
294
+ export {
295
+ Repl
296
+ };
297
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/repl.ts"],"sourcesContent":["/*\n * @adonisjs/repl\n *\n * (c) AdonisJS\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nimport stringWidth from 'string-width'\nimport useColors from '@poppinss/colors'\nimport type { Colors } from '@poppinss/colors/types'\nimport { inspect, promisify as utilPromisify } from 'node:util'\nimport { REPLServer, Recoverable, start as startRepl } from 'node:repl'\n\nimport type { MethodCallback, MethodOptions, Compiler } from './types.js'\n\n/**\n * List of node global properties to remove from the\n * ls inspect\n */\nconst GLOBAL_NODE_PROPERTIES = [\n 'performance',\n 'global',\n 'clearInterval',\n 'clearTimeout',\n 'setInterval',\n 'setTimeout',\n 'queueMicrotask',\n 'clearImmediate',\n 'setImmediate',\n 'structuredClone',\n 'atob',\n 'btoa',\n 'fetch',\n 'crypto',\n]\n\nconst TS_UTILS_HELPERS = [\n '__extends',\n '__assign',\n '__rest',\n '__decorate',\n '__param',\n '__esDecorate',\n '__runInitializers',\n '__propKey',\n '__setFunctionName',\n '__metadata',\n '__awaiter',\n '__generator',\n '__exportStar',\n '__createBinding',\n '__values',\n '__read',\n '__spread',\n '__spreadArrays',\n '__spreadArray',\n '__await',\n '__asyncGenerator',\n '__asyncDelegator',\n '__asyncValues',\n '__makeTemplateObject',\n '__importStar',\n '__importDefault',\n '__classPrivateFieldGet',\n '__classPrivateFieldSet',\n '__classPrivateFieldIn',\n]\n\nexport class Repl {\n /**\n * Length of the longest custom method name. We need to show a\n * symmetric view of custom methods and their description\n */\n #longestCustomMethodName = 0\n\n /**\n * Reference to the original `eval` method of the repl server.\n * Since we are monkey patching it, we need a reference to it\n * to call it after our custom logic\n */\n #originalEval?: Function\n\n /**\n * Compiler that will transform the user input just\n * before evaluation\n */\n #compiler?: Compiler\n\n /**\n * Path to the history file\n */\n #historyFilePath?: string\n\n /**\n * Set of registered ready callbacks\n */\n #onReadyCallbacks: ((repl: Repl) => void)[] = []\n\n /**\n * A set of registered custom methods\n */\n #customMethods: {\n [name: string]: { handler: MethodCallback; options: MethodOptions & { width: number } }\n } = {}\n\n /**\n * Colors reference\n */\n colors: Colors = useColors.ansi()\n\n /**\n * Reference to the repl server. Available after the `start` method\n * is invoked\n */\n server?: REPLServer\n\n constructor(options?: { compiler?: Compiler; historyFilePath?: string }) {\n this.#compiler = options?.compiler\n this.#historyFilePath = options?.historyFilePath\n }\n\n /**\n * Registering custom methods with the server context by wrapping\n * them inside a function and passes the REPL server instance\n * to the method\n */\n #registerCustomMethodWithContext(name: string) {\n const customMethod = this.#customMethods[name]\n if (!customMethod) {\n return\n }\n\n /**\n * Wrap handler\n */\n const handler = (...args: any[]) => customMethod.handler(this, ...args)\n\n /**\n * Re-define the function name to be more description\n */\n Object.defineProperty(handler, 'name', { value: customMethod.handler.name })\n\n /**\n * Register with the context\n */\n this.server!.context[name] = handler\n }\n\n /**\n * Setup context with default globals\n */\n #setupContext() {\n /**\n * Register \"clear\" method\n */\n this.addMethod(\n 'clear',\n function clear(repl: Repl, key: string) {\n if (!key) {\n console.log(repl.colors.red('Define a property name to remove from the context'))\n } else {\n delete repl.server!.context[key]\n }\n repl.server!.displayPrompt()\n },\n {\n description: 'Clear a property from the REPL context',\n usage: `clear ${this.colors.gray('(propertyName)')}`,\n }\n )\n\n /**\n * Register \"p\" method\n */\n this.addMethod(\n 'p',\n function promisify(_: Repl, fn: Function) {\n return utilPromisify(fn)\n },\n {\n description: 'Promisify a function. Similar to Node.js \"util.promisify\"',\n usage: `p ${this.colors.gray('(function)')}`,\n }\n )\n\n /**\n * Register all custom methods with the context\n */\n Object.keys(this.#customMethods).forEach((name) => {\n this.#registerCustomMethodWithContext(name)\n })\n }\n\n /**\n * Find if the error is recoverable or not\n */\n #isRecoverableError(error: any) {\n return /^(Unexpected end of input|Unexpected token|' expected)/.test(error.message)\n }\n\n /**\n * Custom eval method to execute the user code\n *\n * Basically we are monkey patching the original eval method, because\n * we want to:\n * - Compile the user code before executing it\n * - And also benefit from the original eval method that supports\n * cool features like top level await\n */\n #eval(\n code: string,\n context: any,\n filename: string,\n callback: (err: Error | null, result?: any) => void\n ) {\n try {\n const compiled = this.#compiler ? this.#compiler!.compile(code, filename) : code\n return this.#originalEval!(compiled, context, filename, callback)\n } catch (error) {\n if (this.#isRecoverableError(error)) {\n callback(new Recoverable(error), null)\n return\n }\n\n callback(error, null)\n }\n }\n\n /**\n * Setup history file\n */\n #setupHistory() {\n if (!this.#historyFilePath) {\n return\n }\n\n this.server!.setupHistory(this.#historyFilePath, (error) => {\n if (!error) {\n return\n }\n\n console.log(this.colors.red('Unable to write to the history file. Exiting'))\n console.error(error)\n process.exit(1)\n })\n }\n\n /**\n * Prints the help for the context properties\n */\n #printContextHelp() {\n /**\n * Print context properties\n */\n console.log('')\n console.log(this.colors.green('CONTEXT PROPERTIES/METHODS:'))\n\n const context = Object.keys(this.server!.context).reduce(\n (result, key) => {\n if (\n !this.#customMethods[key] &&\n !GLOBAL_NODE_PROPERTIES.includes(key) &&\n !TS_UTILS_HELPERS.includes(key)\n ) {\n result[key] = this.server!.context[key]\n }\n\n return result\n },\n {} as Record<string, any>\n )\n\n console.log(inspect(context, false, 1, true))\n }\n\n /**\n * Prints the help for the custom methods\n */\n #printCustomMethodsHelp() {\n /**\n * Print loader methods\n */\n console.log('')\n console.log(this.colors.green('GLOBAL METHODS:'))\n\n Object.keys(this.#customMethods).forEach((method) => {\n const { options } = this.#customMethods[method]\n\n const usage = this.colors.yellow(options.usage || method)\n const spaces = ' '.repeat(this.#longestCustomMethodName - options.width + 2)\n const description = this.colors.dim(options.description || '')\n\n console.log(`${usage}${spaces}${description}`)\n })\n }\n\n /**\n * Prints the context to the console\n */\n #ls() {\n this.#printCustomMethodsHelp()\n this.#printContextHelp()\n this.server!.displayPrompt()\n }\n\n /**\n * Notify by writing to the console\n */\n notify(message: string) {\n console.log(this.colors.yellow().italic(message))\n if (this.server) {\n this.server.displayPrompt()\n }\n }\n\n /**\n * Register a callback to be invoked once the server is ready\n */\n ready(callback: (repl: Repl) => void): this {\n this.#onReadyCallbacks.push(callback)\n return this\n }\n\n /**\n * Register a custom loader function to be added to the context\n */\n addMethod(name: string, handler: MethodCallback, options?: MethodOptions): this {\n const width = stringWidth(options?.usage || name)\n if (width > this.#longestCustomMethodName) {\n this.#longestCustomMethodName = width\n }\n\n this.#customMethods[name] = { handler, options: Object.assign({ width }, options) }\n\n /**\n * Register method right away when server has been started\n */\n if (this.server) {\n this.#registerCustomMethodWithContext(name)\n }\n\n return this\n }\n\n /**\n * Returns the collection of registered methods\n */\n getMethods() {\n return this.#customMethods\n }\n\n /**\n * Register a compiler. Make sure register the compiler before\n * calling the start method\n */\n useCompiler(compiler: Compiler): this {\n this.#compiler = compiler\n return this\n }\n\n /**\n * Start the REPL server\n */\n start() {\n console.log('')\n this.notify('Type \".ls\" to a view list of available context methods/properties')\n\n this.server = startRepl({\n prompt: `> ${this.#compiler?.supportsTypescript ? '(ts) ' : '(js) '}`,\n input: process.stdin,\n output: process.stdout,\n terminal: process.stdout.isTTY && !Number.parseInt(process.env.NODE_NO_READLINE!, 10),\n useGlobal: true,\n })\n\n /**\n * Define the `ls` command\n */\n this.server!.defineCommand('ls', {\n help: 'View list of available context methods/properties',\n action: this.#ls.bind(this),\n })\n\n /**\n * Setup context and history\n */\n this.#setupContext()\n this.#setupHistory()\n\n /**\n * Monkey patch the eval method\n */\n this.#originalEval = this.server.eval\n // @ts-ignore\n this.server.eval = this.#eval.bind(this)\n\n /**\n * Display prompt\n */\n this.server.displayPrompt()\n\n /**\n * Execute onReady callbacks\n */\n this.#onReadyCallbacks.forEach((callback) => callback(this))\n\n return this\n }\n}\n"],"mappings":"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","names":[]}
@@ -1,4 +1,4 @@
1
- /// <reference types="@types/node" resolution-mode="require"/>
1
+ /// <reference types="node" resolution-mode="require"/>
2
2
  import type { Colors } from '@poppinss/colors/types';
3
3
  import { REPLServer } from 'node:repl';
4
4
  import type { MethodCallback, MethodOptions, Compiler } from './types.js';
package/package.json CHANGED
@@ -1,16 +1,16 @@
1
1
  {
2
2
  "name": "@adonisjs/repl",
3
3
  "description": "REPL for AdonisJS",
4
- "version": "4.0.0-7",
4
+ "version": "4.0.0-9",
5
5
  "engines": {
6
6
  "node": ">=18.16.0"
7
7
  },
8
8
  "main": "build/index.js",
9
9
  "type": "module",
10
10
  "files": [
11
- "build/src",
12
- "build/index.d.ts",
13
- "build/index.js"
11
+ "build",
12
+ "!build/bin",
13
+ "!build/examples"
14
14
  ],
15
15
  "exports": {
16
16
  ".": "./build/index.js",
@@ -22,9 +22,10 @@
22
22
  "lint": "eslint . --ext=.ts",
23
23
  "clean": "del-cli build",
24
24
  "typecheck": "tsc --noEmit",
25
- "compile": "npm run lint && npm run clean && tsc",
25
+ "precompile": "npm run lint && npm run clean",
26
+ "compile": "tsup-node && tsc --emitDeclarationOnly --declaration",
26
27
  "build": "npm run compile",
27
- "release": "np --message=\"chore(release): %s\"",
28
+ "release": "np",
28
29
  "version": "npm run build",
29
30
  "sync-labels": "github-label-sync --labels .github/labels.json adonisjs/repl",
30
31
  "quick:test": "node --enable-source-maps --loader=ts-node/esm bin/test.ts",
@@ -32,29 +33,29 @@
32
33
  "prepublishOnly": "npm run build"
33
34
  },
34
35
  "devDependencies": {
35
- "@adonisjs/eslint-config": "^1.1.8",
36
- "@adonisjs/prettier-config": "^1.1.8",
37
- "@adonisjs/tsconfig": "^1.1.8",
38
- "@commitlint/cli": "^17.7.1",
39
- "@commitlint/config-conventional": "^17.7.0",
40
- "@japa/assert": "^2.0.0-1",
41
- "@japa/runner": "^3.0.0-2",
42
- "@swc/core": "^1.3.78",
43
- "@types/node": "^20.5.3",
36
+ "@adonisjs/eslint-config": "^1.1.9",
37
+ "@adonisjs/prettier-config": "^1.1.9",
38
+ "@adonisjs/tsconfig": "^1.1.9",
39
+ "@commitlint/cli": "^18.4.3",
40
+ "@commitlint/config-conventional": "^18.4.3",
41
+ "@japa/assert": "^2.0.1",
42
+ "@japa/runner": "^3.1.0",
43
+ "@swc/core": "^1.3.99",
44
+ "@types/node": "^20.9.4",
44
45
  "c8": "^8.0.1",
45
- "copyfiles": "^2.4.1",
46
- "del-cli": "^5.0.0",
47
- "eslint": "^8.47.0",
46
+ "del-cli": "^5.1.0",
47
+ "eslint": "^8.54.0",
48
48
  "github-label-sync": "^2.3.1",
49
49
  "husky": "^8.0.3",
50
50
  "np": "^8.0.4",
51
- "prettier": "^3.0.2",
51
+ "prettier": "^3.1.0",
52
52
  "ts-node": "^10.9.1",
53
- "typescript": "^5.1.3"
53
+ "tsup": "^8.0.1",
54
+ "typescript": "5.2.2"
54
55
  },
55
56
  "dependencies": {
56
- "@poppinss/colors": "4.1.0-2",
57
- "string-width": "^6.1.0"
57
+ "@poppinss/colors": "^4.1.1",
58
+ "string-width": "^7.0.0"
58
59
  },
59
60
  "author": "virk,julien-r44,adonisjs",
60
61
  "license": "MIT",
@@ -98,5 +99,16 @@
98
99
  "exclude": [
99
100
  "tests/**"
100
101
  ]
102
+ },
103
+ "tsup": {
104
+ "entry": [
105
+ "./index.ts"
106
+ ],
107
+ "outDir": "./build",
108
+ "clean": true,
109
+ "format": "esm",
110
+ "dts": false,
111
+ "sourcemap": true,
112
+ "target": "esnext"
101
113
  }
102
114
  }
package/build/src/repl.js DELETED
@@ -1,340 +0,0 @@
1
- /*
2
- * @adonisjs/repl
3
- *
4
- * (c) AdonisJS
5
- *
6
- * For the full copyright and license information, please view the LICENSE
7
- * file that was distributed with this source code.
8
- */
9
- import stringWidth from 'string-width';
10
- import useColors from '@poppinss/colors';
11
- import { inspect, promisify as utilPromisify } from 'node:util';
12
- import { Recoverable, start as startRepl } from 'node:repl';
13
- /**
14
- * List of node global properties to remove from the
15
- * ls inspect
16
- */
17
- const GLOBAL_NODE_PROPERTIES = [
18
- 'performance',
19
- 'global',
20
- 'clearInterval',
21
- 'clearTimeout',
22
- 'setInterval',
23
- 'setTimeout',
24
- 'queueMicrotask',
25
- 'clearImmediate',
26
- 'setImmediate',
27
- 'structuredClone',
28
- 'atob',
29
- 'btoa',
30
- 'fetch',
31
- 'crypto',
32
- ];
33
- const TS_UTILS_HELPERS = [
34
- '__extends',
35
- '__assign',
36
- '__rest',
37
- '__decorate',
38
- '__param',
39
- '__esDecorate',
40
- '__runInitializers',
41
- '__propKey',
42
- '__setFunctionName',
43
- '__metadata',
44
- '__awaiter',
45
- '__generator',
46
- '__exportStar',
47
- '__createBinding',
48
- '__values',
49
- '__read',
50
- '__spread',
51
- '__spreadArrays',
52
- '__spreadArray',
53
- '__await',
54
- '__asyncGenerator',
55
- '__asyncDelegator',
56
- '__asyncValues',
57
- '__makeTemplateObject',
58
- '__importStar',
59
- '__importDefault',
60
- '__classPrivateFieldGet',
61
- '__classPrivateFieldSet',
62
- '__classPrivateFieldIn',
63
- ];
64
- export class Repl {
65
- /**
66
- * Length of the longest custom method name. We need to show a
67
- * symmetric view of custom methods and their description
68
- */
69
- #longestCustomMethodName = 0;
70
- /**
71
- * Reference to the original `eval` method of the repl server.
72
- * Since we are monkey patching it, we need a reference to it
73
- * to call it after our custom logic
74
- */
75
- #originalEval;
76
- /**
77
- * Compiler that will transform the user input just
78
- * before evaluation
79
- */
80
- #compiler;
81
- /**
82
- * Path to the history file
83
- */
84
- #historyFilePath;
85
- /**
86
- * Set of registered ready callbacks
87
- */
88
- #onReadyCallbacks = [];
89
- /**
90
- * A set of registered custom methods
91
- */
92
- #customMethods = {};
93
- /**
94
- * Colors reference
95
- */
96
- colors = useColors.ansi();
97
- /**
98
- * Reference to the repl server. Available after the `start` method
99
- * is invoked
100
- */
101
- server;
102
- constructor(options) {
103
- this.#compiler = options?.compiler;
104
- this.#historyFilePath = options?.historyFilePath;
105
- }
106
- /**
107
- * Registering custom methods with the server context by wrapping
108
- * them inside a function and passes the REPL server instance
109
- * to the method
110
- */
111
- #registerCustomMethodWithContext(name) {
112
- const customMethod = this.#customMethods[name];
113
- if (!customMethod) {
114
- return;
115
- }
116
- /**
117
- * Wrap handler
118
- */
119
- const handler = (...args) => customMethod.handler(this, ...args);
120
- /**
121
- * Re-define the function name to be more description
122
- */
123
- Object.defineProperty(handler, 'name', { value: customMethod.handler.name });
124
- /**
125
- * Register with the context
126
- */
127
- this.server.context[name] = handler;
128
- }
129
- /**
130
- * Setup context with default globals
131
- */
132
- #setupContext() {
133
- /**
134
- * Register "clear" method
135
- */
136
- this.addMethod('clear', function clear(repl, key) {
137
- if (!key) {
138
- console.log(repl.colors.red('Define a property name to remove from the context'));
139
- }
140
- else {
141
- delete repl.server.context[key];
142
- }
143
- repl.server.displayPrompt();
144
- }, {
145
- description: 'Clear a property from the REPL context',
146
- usage: `clear ${this.colors.gray('(propertyName)')}`,
147
- });
148
- /**
149
- * Register "p" method
150
- */
151
- this.addMethod('p', function promisify(_, fn) {
152
- return utilPromisify(fn);
153
- }, {
154
- description: 'Promisify a function. Similar to Node.js "util.promisify"',
155
- usage: `p ${this.colors.gray('(function)')}`,
156
- });
157
- /**
158
- * Register all custom methods with the context
159
- */
160
- Object.keys(this.#customMethods).forEach((name) => {
161
- this.#registerCustomMethodWithContext(name);
162
- });
163
- }
164
- /**
165
- * Find if the error is recoverable or not
166
- */
167
- #isRecoverableError(error) {
168
- return /^(Unexpected end of input|Unexpected token|' expected)/.test(error.message);
169
- }
170
- /**
171
- * Custom eval method to execute the user code
172
- *
173
- * Basically we are monkey patching the original eval method, because
174
- * we want to:
175
- * - Compile the user code before executing it
176
- * - And also benefit from the original eval method that supports
177
- * cool features like top level await
178
- */
179
- #eval(code, context, filename, callback) {
180
- try {
181
- const compiled = this.#compiler ? this.#compiler.compile(code, filename) : code;
182
- return this.#originalEval(compiled, context, filename, callback);
183
- }
184
- catch (error) {
185
- if (this.#isRecoverableError(error)) {
186
- callback(new Recoverable(error), null);
187
- return;
188
- }
189
- callback(error, null);
190
- }
191
- }
192
- /**
193
- * Setup history file
194
- */
195
- #setupHistory() {
196
- if (!this.#historyFilePath) {
197
- return;
198
- }
199
- this.server.setupHistory(this.#historyFilePath, (error) => {
200
- if (!error) {
201
- return;
202
- }
203
- console.log(this.colors.red('Unable to write to the history file. Exiting'));
204
- console.error(error);
205
- process.exit(1);
206
- });
207
- }
208
- /**
209
- * Prints the help for the context properties
210
- */
211
- #printContextHelp() {
212
- /**
213
- * Print context properties
214
- */
215
- console.log('');
216
- console.log(this.colors.green('CONTEXT PROPERTIES/METHODS:'));
217
- const context = Object.keys(this.server.context).reduce((result, key) => {
218
- if (!this.#customMethods[key] &&
219
- !GLOBAL_NODE_PROPERTIES.includes(key) &&
220
- !TS_UTILS_HELPERS.includes(key)) {
221
- result[key] = this.server.context[key];
222
- }
223
- return result;
224
- }, {});
225
- console.log(inspect(context, false, 1, true));
226
- }
227
- /**
228
- * Prints the help for the custom methods
229
- */
230
- #printCustomMethodsHelp() {
231
- /**
232
- * Print loader methods
233
- */
234
- console.log('');
235
- console.log(this.colors.green('GLOBAL METHODS:'));
236
- Object.keys(this.#customMethods).forEach((method) => {
237
- const { options } = this.#customMethods[method];
238
- const usage = this.colors.yellow(options.usage || method);
239
- const spaces = ' '.repeat(this.#longestCustomMethodName - options.width + 2);
240
- const description = this.colors.dim(options.description || '');
241
- console.log(`${usage}${spaces}${description}`);
242
- });
243
- }
244
- /**
245
- * Prints the context to the console
246
- */
247
- #ls() {
248
- this.#printCustomMethodsHelp();
249
- this.#printContextHelp();
250
- this.server.displayPrompt();
251
- }
252
- /**
253
- * Notify by writing to the console
254
- */
255
- notify(message) {
256
- console.log(this.colors.yellow().italic(message));
257
- if (this.server) {
258
- this.server.displayPrompt();
259
- }
260
- }
261
- /**
262
- * Register a callback to be invoked once the server is ready
263
- */
264
- ready(callback) {
265
- this.#onReadyCallbacks.push(callback);
266
- return this;
267
- }
268
- /**
269
- * Register a custom loader function to be added to the context
270
- */
271
- addMethod(name, handler, options) {
272
- const width = stringWidth(options?.usage || name);
273
- if (width > this.#longestCustomMethodName) {
274
- this.#longestCustomMethodName = width;
275
- }
276
- this.#customMethods[name] = { handler, options: Object.assign({ width }, options) };
277
- /**
278
- * Register method right away when server has been started
279
- */
280
- if (this.server) {
281
- this.#registerCustomMethodWithContext(name);
282
- }
283
- return this;
284
- }
285
- /**
286
- * Returns the collection of registered methods
287
- */
288
- getMethods() {
289
- return this.#customMethods;
290
- }
291
- /**
292
- * Register a compiler. Make sure register the compiler before
293
- * calling the start method
294
- */
295
- useCompiler(compiler) {
296
- this.#compiler = compiler;
297
- return this;
298
- }
299
- /**
300
- * Start the REPL server
301
- */
302
- start() {
303
- console.log('');
304
- this.notify('Type ".ls" to a view list of available context methods/properties');
305
- this.server = startRepl({
306
- prompt: `> ${this.#compiler?.supportsTypescript ? '(ts) ' : '(js) '}`,
307
- input: process.stdin,
308
- output: process.stdout,
309
- terminal: process.stdout.isTTY && !Number.parseInt(process.env.NODE_NO_READLINE, 10),
310
- useGlobal: true,
311
- });
312
- /**
313
- * Define the `ls` command
314
- */
315
- this.server.defineCommand('ls', {
316
- help: 'View list of available context methods/properties',
317
- action: this.#ls.bind(this),
318
- });
319
- /**
320
- * Setup context and history
321
- */
322
- this.#setupContext();
323
- this.#setupHistory();
324
- /**
325
- * Monkey patch the eval method
326
- */
327
- this.#originalEval = this.server.eval;
328
- // @ts-ignore
329
- this.server.eval = this.#eval.bind(this);
330
- /**
331
- * Display prompt
332
- */
333
- this.server.displayPrompt();
334
- /**
335
- * Execute onReady callbacks
336
- */
337
- this.#onReadyCallbacks.forEach((callback) => callback(this));
338
- return this;
339
- }
340
- }
@@ -1,9 +0,0 @@
1
- /*
2
- * @adonisjs/repl
3
- *
4
- * (c) AdonisJS
5
- *
6
- * For the full copyright and license information, please view the LICENSE
7
- * file that was distributed with this source code.
8
- */
9
- export {};