@adonisjs/repl 4.0.0-1 → 4.0.0-10

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/LICENSE.md CHANGED
@@ -1,9 +1,9 @@
1
- # The MIT License
2
-
3
- Copyright 2022 Harminder Virk, contributors
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6
-
7
- The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8
-
9
- THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1
+ # The MIT License
2
+
3
+ Copyright 2022 Harminder Virk, contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6
+
7
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8
+
9
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  <br />
4
4
 
5
- [![gh-workflow-image]][gh-workflow-url] [![npm-image]][npm-url] ![][typescript-image] [![license-image]][license-url] [![snyk-image]][snyk-url]
5
+ [![gh-workflow-image]][gh-workflow-url] [![npm-image]][npm-url] ![][typescript-image] [![license-image]][license-url]
6
6
 
7
7
  ## Introduction
8
8
  REPL for AdonisJS applications. Syntax highlighting, bracket matching, ESM and TypeScript support out of the box.
@@ -21,8 +21,8 @@ In order to ensure that the AdonisJS community is welcoming to all, please revie
21
21
  ## License
22
22
  AdonisJS Repl is open-sourced software licensed under the [MIT license](LICENSE.md).
23
23
 
24
- [gh-workflow-image]: https://img.shields.io/github/actions/workflow/status/adonisjs/repl/test.yml?style=for-the-badge
25
- [gh-workflow-url]: https://github.com/adonisjs/repl/actions/workflows/test.yml "Github action"
24
+ [gh-workflow-image]: https://img.shields.io/github/actions/workflow/status/adonisjs/repl/checks.yml?style=for-the-badge
25
+ [gh-workflow-url]: https://github.com/adonisjs/repl/actions/workflows/checks.yml "Github action"
26
26
 
27
27
  [npm-image]: https://img.shields.io/npm/v/@adonisjs/repl/latest.svg?style=for-the-badge&logo=npm
28
28
  [npm-url]: https://www.npmjs.com/package/@adonisjs/repl/v/latest "npm"
@@ -31,6 +31,3 @@ AdonisJS Repl is open-sourced software licensed under the [MIT license](LICENSE.
31
31
 
32
32
  [license-url]: LICENSE.md
33
33
  [license-image]: https://img.shields.io/github/license/adonisjs/repl?style=for-the-badge
34
-
35
- [snyk-image]: https://img.shields.io/snyk/vulnerabilities/github/adonisjs/repl?label=Snyk%20Vulnerabilities&style=for-the-badge
36
- [snyk-url]: https://snyk.io/test/github/adonisjs/repl?targetFile=package.json "snyk"
package/build/index.d.ts CHANGED
@@ -1,2 +1 @@
1
- import './src/types/extended.js';
2
1
  export { Repl } from './src/repl.js';
package/build/index.js CHANGED
@@ -1,10 +1,302 @@
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 './src/types/extended.js';
10
- 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
+ "navigator"
22
+ ];
23
+ var TS_UTILS_HELPERS = [
24
+ "__extends",
25
+ "__assign",
26
+ "__rest",
27
+ "__decorate",
28
+ "__param",
29
+ "__esDecorate",
30
+ "__runInitializers",
31
+ "__propKey",
32
+ "__setFunctionName",
33
+ "__metadata",
34
+ "__awaiter",
35
+ "__generator",
36
+ "__exportStar",
37
+ "__createBinding",
38
+ "__values",
39
+ "__read",
40
+ "__spread",
41
+ "__spreadArrays",
42
+ "__spreadArray",
43
+ "__await",
44
+ "__asyncGenerator",
45
+ "__asyncDelegator",
46
+ "__asyncValues",
47
+ "__makeTemplateObject",
48
+ "__importStar",
49
+ "__importDefault",
50
+ "__classPrivateFieldGet",
51
+ "__classPrivateFieldSet",
52
+ "__classPrivateFieldIn"
53
+ ];
54
+ var Repl = class {
55
+ #replOptions;
56
+ /**
57
+ * Length of the longest custom method name. We need to show a
58
+ * symmetric view of custom methods and their description
59
+ */
60
+ #longestCustomMethodName = 0;
61
+ /**
62
+ * Reference to the original `eval` method of the repl server.
63
+ * Since we are monkey patching it, we need a reference to it
64
+ * to call it after our custom logic
65
+ */
66
+ #originalEval;
67
+ /**
68
+ * Compiler that will transform the user input just
69
+ * before evaluation
70
+ */
71
+ #compiler;
72
+ /**
73
+ * Path to the history file
74
+ */
75
+ #historyFilePath;
76
+ /**
77
+ * Set of registered ready callbacks
78
+ */
79
+ #onReadyCallbacks = [];
80
+ /**
81
+ * A set of registered custom methods
82
+ */
83
+ #customMethods = {};
84
+ /**
85
+ * Colors reference
86
+ */
87
+ colors = useColors.ansi();
88
+ /**
89
+ * Reference to the repl server. Available after the `start` method
90
+ * is invoked
91
+ */
92
+ server;
93
+ constructor(options) {
94
+ const { compiler, historyFilePath, ...rest } = options || {};
95
+ this.#compiler = compiler;
96
+ this.#historyFilePath = historyFilePath;
97
+ this.#replOptions = rest;
98
+ }
99
+ /**
100
+ * Registering custom methods with the server context by wrapping
101
+ * them inside a function and passes the REPL server instance
102
+ * to the method
103
+ */
104
+ #registerCustomMethodWithContext(name) {
105
+ const customMethod = this.#customMethods[name];
106
+ if (!customMethod) {
107
+ return;
108
+ }
109
+ const handler = (...args) => customMethod.handler(this, ...args);
110
+ Object.defineProperty(handler, "name", { value: customMethod.handler.name });
111
+ this.server.context[name] = handler;
112
+ }
113
+ /**
114
+ * Setup context with default globals
115
+ */
116
+ #setupContext() {
117
+ this.addMethod(
118
+ "clear",
119
+ function clear(repl, key) {
120
+ if (!key) {
121
+ console.log(repl.colors.red("Define a property name to remove from the context"));
122
+ } else {
123
+ delete repl.server.context[key];
124
+ }
125
+ repl.server.displayPrompt();
126
+ },
127
+ {
128
+ description: "Clear a property from the REPL context",
129
+ usage: `clear ${this.colors.gray("(propertyName)")}`
130
+ }
131
+ );
132
+ this.addMethod(
133
+ "p",
134
+ function promisify(_, fn) {
135
+ return utilPromisify(fn);
136
+ },
137
+ {
138
+ description: 'Promisify a function. Similar to Node.js "util.promisify"',
139
+ usage: `p ${this.colors.gray("(function)")}`
140
+ }
141
+ );
142
+ Object.keys(this.#customMethods).forEach((name) => {
143
+ this.#registerCustomMethodWithContext(name);
144
+ });
145
+ }
146
+ /**
147
+ * Find if the error is recoverable or not
148
+ */
149
+ #isRecoverableError(error) {
150
+ return /^(Unexpected end of input|Unexpected token|' expected)/.test(error.message);
151
+ }
152
+ /**
153
+ * Custom eval method to execute the user code
154
+ *
155
+ * Basically we are monkey patching the original eval method, because
156
+ * we want to:
157
+ * - Compile the user code before executing it
158
+ * - And also benefit from the original eval method that supports
159
+ * cool features like top level await
160
+ */
161
+ #eval(code, context, filename, callback) {
162
+ try {
163
+ const compiled = this.#compiler ? this.#compiler.compile(code, filename) : code;
164
+ return this.#originalEval(compiled, context, filename, callback);
165
+ } catch (error) {
166
+ if (this.#isRecoverableError(error)) {
167
+ callback(new Recoverable(error), null);
168
+ return;
169
+ }
170
+ callback(error, null);
171
+ }
172
+ }
173
+ /**
174
+ * Setup history file
175
+ */
176
+ #setupHistory() {
177
+ if (!this.#historyFilePath) {
178
+ return;
179
+ }
180
+ this.server.setupHistory(this.#historyFilePath, (error) => {
181
+ if (!error) {
182
+ return;
183
+ }
184
+ console.log(this.colors.red("Unable to write to the history file. Exiting"));
185
+ console.error(error);
186
+ process.exit(1);
187
+ });
188
+ }
189
+ /**
190
+ * Prints the help for the context properties
191
+ */
192
+ #printContextHelp() {
193
+ console.log("");
194
+ console.log(this.colors.green("CONTEXT PROPERTIES/METHODS:"));
195
+ const context = Object.keys(this.server.context).reduce(
196
+ (result, key) => {
197
+ if (!this.#customMethods[key] && !GLOBAL_NODE_PROPERTIES.includes(key) && !TS_UTILS_HELPERS.includes(key)) {
198
+ result[key] = this.server.context[key];
199
+ }
200
+ return result;
201
+ },
202
+ {}
203
+ );
204
+ console.log(inspect(context, false, 1, true));
205
+ }
206
+ /**
207
+ * Prints the help for the custom methods
208
+ */
209
+ #printCustomMethodsHelp() {
210
+ console.log("");
211
+ console.log(this.colors.green("GLOBAL METHODS:"));
212
+ Object.keys(this.#customMethods).forEach((method) => {
213
+ const { options } = this.#customMethods[method];
214
+ const usage = this.colors.yellow(options.usage || method);
215
+ const spaces = " ".repeat(this.#longestCustomMethodName - options.width + 2);
216
+ const description = this.colors.dim(options.description || "");
217
+ console.log(`${usage}${spaces}${description}`);
218
+ });
219
+ }
220
+ /**
221
+ * Prints the context to the console
222
+ */
223
+ #ls() {
224
+ this.#printCustomMethodsHelp();
225
+ this.#printContextHelp();
226
+ this.server.displayPrompt();
227
+ }
228
+ /**
229
+ * Notify by writing to the console
230
+ */
231
+ notify(message) {
232
+ console.log(this.colors.yellow().italic(message));
233
+ if (this.server) {
234
+ this.server.displayPrompt();
235
+ }
236
+ }
237
+ /**
238
+ * Register a callback to be invoked once the server is ready
239
+ */
240
+ ready(callback) {
241
+ this.#onReadyCallbacks.push(callback);
242
+ return this;
243
+ }
244
+ /**
245
+ * Register a custom loader function to be added to the context
246
+ */
247
+ addMethod(name, handler, options) {
248
+ const width = stringWidth(options?.usage || name);
249
+ if (width > this.#longestCustomMethodName) {
250
+ this.#longestCustomMethodName = width;
251
+ }
252
+ this.#customMethods[name] = { handler, options: Object.assign({ width }, options) };
253
+ if (this.server) {
254
+ this.#registerCustomMethodWithContext(name);
255
+ }
256
+ return this;
257
+ }
258
+ /**
259
+ * Returns the collection of registered methods
260
+ */
261
+ getMethods() {
262
+ return this.#customMethods;
263
+ }
264
+ /**
265
+ * Register a compiler. Make sure register the compiler before
266
+ * calling the start method
267
+ */
268
+ useCompiler(compiler) {
269
+ this.#compiler = compiler;
270
+ return this;
271
+ }
272
+ /**
273
+ * Start the REPL server
274
+ */
275
+ start() {
276
+ console.log("");
277
+ this.notify('Type ".ls" to a view list of available context methods/properties');
278
+ this.server = startRepl({
279
+ prompt: `> ${this.#compiler?.supportsTypescript ? "(ts) " : "(js) "}`,
280
+ input: process.stdin,
281
+ output: process.stdout,
282
+ terminal: process.stdout.isTTY && !Number.parseInt(process.env.NODE_NO_READLINE, 10),
283
+ useGlobal: true,
284
+ ...this.#replOptions
285
+ });
286
+ this.server.defineCommand("ls", {
287
+ help: "View list of available context methods/properties",
288
+ action: this.#ls.bind(this)
289
+ });
290
+ this.#setupContext();
291
+ this.#setupHistory();
292
+ this.#originalEval = this.server.eval;
293
+ this.server.eval = this.#eval.bind(this);
294
+ this.server.displayPrompt();
295
+ this.#onReadyCallbacks.forEach((callback) => callback(this));
296
+ return this;
297
+ }
298
+ };
299
+ export {
300
+ Repl
301
+ };
302
+ //# 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 { type REPLServer, Recoverable, type ReplOptions, 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 'navigator',\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 #replOptions: ReplOptions\n\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 } & ReplOptions) {\n const { compiler, historyFilePath, ...rest } = options || {}\n this.#compiler = compiler\n this.#historyFilePath = historyFilePath\n this.#replOptions = rest\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 ...this.#replOptions,\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,7 +1,7 @@
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
- import { REPLServer } from 'node:repl';
4
- import { Handler, ContextOptions, Compiler } from './types.js';
3
+ import { type REPLServer, type ReplOptions } from 'node:repl';
4
+ import type { MethodCallback, MethodOptions, Compiler } from './types.js';
5
5
  export declare class Repl {
6
6
  #private;
7
7
  /**
@@ -16,15 +16,11 @@ export declare class Repl {
16
16
  constructor(options?: {
17
17
  compiler?: Compiler;
18
18
  historyFilePath?: string;
19
- });
19
+ } & ReplOptions);
20
20
  /**
21
21
  * Notify by writing to the console
22
22
  */
23
23
  notify(message: string): void;
24
- /**
25
- * Start the REPL server
26
- */
27
- start(): this;
28
24
  /**
29
25
  * Register a callback to be invoked once the server is ready
30
26
  */
@@ -32,5 +28,25 @@ export declare class Repl {
32
28
  /**
33
29
  * Register a custom loader function to be added to the context
34
30
  */
35
- addMethod(name: string, handler: Handler, options?: ContextOptions): this;
31
+ addMethod(name: string, handler: MethodCallback, options?: MethodOptions): this;
32
+ /**
33
+ * Returns the collection of registered methods
34
+ */
35
+ getMethods(): {
36
+ [name: string]: {
37
+ handler: MethodCallback;
38
+ options: MethodOptions & {
39
+ width: number;
40
+ };
41
+ };
42
+ };
43
+ /**
44
+ * Register a compiler. Make sure register the compiler before
45
+ * calling the start method
46
+ */
47
+ useCompiler(compiler: Compiler): this;
48
+ /**
49
+ * Start the REPL server
50
+ */
51
+ start(): this;
36
52
  }
@@ -1,13 +1,12 @@
1
1
  import { Repl } from './repl.js';
2
2
  /**
3
- * Custom method handler
3
+ * Custom method callback function
4
4
  */
5
- export type Handler = (repl: Repl, ...args: any[]) => any;
5
+ export type MethodCallback = (repl: Repl, ...args: any[]) => any;
6
6
  /**
7
- * Options that can be set when defining a loader
8
- * method
7
+ * Options that can be set when defining a custom method
9
8
  */
10
- export type ContextOptions = {
9
+ export type MethodOptions = {
11
10
  description?: string;
12
11
  usage?: string;
13
12
  };
package/package.json CHANGED
@@ -1,21 +1,20 @@
1
1
  {
2
2
  "name": "@adonisjs/repl",
3
3
  "description": "REPL for AdonisJS",
4
- "version": "4.0.0-1",
5
- "main": "build/index.js",
6
- "type": "module",
4
+ "version": "4.0.0-10",
7
5
  "engines": {
8
6
  "node": ">=18.16.0"
9
7
  },
8
+ "main": "build/index.js",
9
+ "type": "module",
10
10
  "files": [
11
- "build/src",
12
- "build/factories",
13
- "build/index.d.ts",
14
- "build/index.js"
11
+ "build",
12
+ "!build/bin",
13
+ "!build/examples"
15
14
  ],
16
15
  "exports": {
17
16
  ".": "./build/index.js",
18
- "./types": "./build/src/types/main.js"
17
+ "./types": "./build/src/types.js"
19
18
  },
20
19
  "scripts": {
21
20
  "pretest": "npm run lint",
@@ -23,9 +22,10 @@
23
22
  "lint": "eslint . --ext=.ts",
24
23
  "clean": "del-cli build",
25
24
  "typecheck": "tsc --noEmit",
26
- "compile": "npm run lint && npm run clean && tsc",
25
+ "precompile": "npm run lint && npm run clean",
26
+ "compile": "tsup-node && tsc --emitDeclarationOnly --declaration",
27
27
  "build": "npm run compile",
28
- "release": "np --message=\"chore(release): %s\"",
28
+ "release": "np",
29
29
  "version": "npm run build",
30
30
  "sync-labels": "github-label-sync --labels .github/labels.json adonisjs/repl",
31
31
  "quick:test": "node --enable-source-maps --loader=ts-node/esm bin/test.ts",
@@ -33,29 +33,29 @@
33
33
  "prepublishOnly": "npm run build"
34
34
  },
35
35
  "devDependencies": {
36
- "@adonisjs/core": "^6.1.5-4",
37
- "@adonisjs/eslint-config": "^1.1.7",
38
- "@adonisjs/prettier-config": "^1.1.7",
39
- "@adonisjs/tsconfig": "^1.1.7",
40
- "@japa/assert": "^2.0.0-1",
41
- "@japa/file-system": "^2.0.0-1",
42
- "@japa/runner": "^3.0.0-2",
43
- "@swc/core": "^1.3.67",
44
- "@types/node": "^20.3.3",
45
- "c8": "^8.0.0",
46
- "copyfiles": "^2.4.1",
47
- "del-cli": "^5.0.0",
48
- "eslint": "^8.44.0",
36
+ "@adonisjs/eslint-config": "^1.2.0",
37
+ "@adonisjs/prettier-config": "^1.2.0",
38
+ "@adonisjs/tsconfig": "^1.2.0",
39
+ "@commitlint/cli": "^18.4.3",
40
+ "@commitlint/config-conventional": "^18.4.3",
41
+ "@japa/assert": "^2.1.0",
42
+ "@japa/runner": "^3.1.1",
43
+ "@swc/core": "^1.3.101",
44
+ "@types/node": "^20.10.5",
45
+ "c8": "^8.0.1",
46
+ "del-cli": "^5.1.0",
47
+ "eslint": "^8.56.0",
49
48
  "github-label-sync": "^2.3.1",
50
49
  "husky": "^8.0.3",
51
- "np": "^8.0.4",
52
- "prettier": "^2.8.8",
53
- "ts-node": "^10.9.1",
54
- "typescript": "^5.1.3"
50
+ "np": "^9.2.0",
51
+ "prettier": "^3.1.1",
52
+ "ts-node": "^10.9.2",
53
+ "tsup": "^8.0.1",
54
+ "typescript": "^5.3.3"
55
55
  },
56
56
  "dependencies": {
57
- "@poppinss/colors": "4.1.0-2",
58
- "string-width": "^6.1.0"
57
+ "@poppinss/colors": "^4.1.2",
58
+ "string-width": "^7.0.0"
59
59
  },
60
60
  "author": "virk,julien-r44,adonisjs",
61
61
  "license": "MIT",
@@ -83,7 +83,7 @@
83
83
  },
84
84
  "publishConfig": {
85
85
  "access": "public",
86
- "tag": "latest"
86
+ "tag": "next"
87
87
  },
88
88
  "np": {
89
89
  "message": "chore(release): %s",
@@ -99,5 +99,16 @@
99
99
  "exclude": [
100
100
  "tests/**"
101
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"
102
113
  }
103
114
  }
package/build/src/repl.js DELETED
@@ -1,346 +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 useColors from '@poppinss/colors';
10
- import { Recoverable, start as startRepl } from 'node:repl';
11
- import stringWidth from 'string-width';
12
- import { inspect, promisify as utilPromisify } from 'node:util';
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
- const icons = process.platform === 'win32' && !process.env.WT_SESSION
65
- ? { tick: '√', pointer: '>' }
66
- : { tick: '✔', pointer: '❯' };
67
- export class Repl {
68
- /**
69
- * Length of the longest custom method name. We need to show a
70
- * symmetric view of custom methods and their description
71
- */
72
- #longestCustomMethodName = 0;
73
- /**
74
- * Reference to the original `eval` method of the repl server.
75
- * Since we are monkey patching it, we need a reference to it
76
- * to call it after our custom logic
77
- */
78
- #originalEval = null;
79
- /**
80
- * Compiler that will transform the user input just
81
- * before evaluation
82
- */
83
- #compiler;
84
- /**
85
- * Set of registered ready callbacks
86
- */
87
- #onReadyCallbacks = [];
88
- /**
89
- * A set of registered custom methods
90
- */
91
- #customMethods = {};
92
- /**
93
- * Path to the history file
94
- */
95
- #historyFilePath;
96
- /**
97
- * Colors reference
98
- */
99
- colors = useColors.ansi();
100
- /**
101
- * Reference to the repl server. Available after the `start` method
102
- * is invoked
103
- */
104
- server;
105
- constructor(options) {
106
- this.#compiler = options?.compiler;
107
- this.#historyFilePath = options?.historyFilePath;
108
- }
109
- /**
110
- * Prints the welcome message
111
- */
112
- #printWelcomeMessage() {
113
- console.log('');
114
- /**
115
- * Log about typescript support
116
- */
117
- if (this.#compiler?.supportsTypescript) {
118
- console.log(`${this.colors.green(icons.tick)} ${this.colors.dim('typescript compilation supported')}`);
119
- console.log('');
120
- }
121
- /**
122
- * Log about help command
123
- */
124
- this.notify('Type ".ls" to a view list of available context methods/properties');
125
- }
126
- /**
127
- * Setup context with default globals
128
- */
129
- #setupContext() {
130
- /**
131
- * Register "clear" method
132
- */
133
- this.addMethod('clear', function clear(repl, key) {
134
- if (!key) {
135
- console.log(repl.colors.red('Define a property name to remove from the context'));
136
- }
137
- else {
138
- delete repl.server.context[key];
139
- }
140
- repl.server.displayPrompt();
141
- }, {
142
- description: 'Clear a property from the REPL context',
143
- usage: `clear ${this.colors.gray('(propertyName)')}`,
144
- });
145
- /**
146
- * Register "p" method
147
- */
148
- this.addMethod('p', function promisify(_, fn) {
149
- return utilPromisify(fn);
150
- }, {
151
- description: 'Promisify a function. Similar to Node.js "util.promisify"',
152
- usage: `p ${this.colors.gray('(function)')}`,
153
- });
154
- /**
155
- * Register all custom methods with the context
156
- */
157
- this.#registerCustomMethodsWithContext();
158
- }
159
- /**
160
- * Register custom methods with the server context
161
- */
162
- #registerCustomMethodsWithContext() {
163
- Object.keys(this.#customMethods).forEach((name) => {
164
- this.#registerCustomMethodWithContext(name);
165
- });
166
- }
167
- /**
168
- * Find if the error is recoverable or not
169
- */
170
- #isRecoverableError(error) {
171
- return /^(Unexpected end of input|Unexpected token|' expected)/.test(error.message);
172
- }
173
- /**
174
- * Custom eval method to execute the user code
175
- *
176
- * Basically we are monkey patching the original eval method.
177
- * The reason why we need to do that is because we want :
178
- * - to compile the user code before executing it
179
- * - and also benefit from the original eval method that supports
180
- * cool features like top level await.
181
- */
182
- #eval(code, context, filename, callback) {
183
- try {
184
- const compiled = this.#compiler.compile(code, filename)
185
- .replace('export { };', '')
186
- .replace(/\/\/# sourceMappingURL=(.*)$/, '/** sourceMappingURL=$1 */');
187
- return this.#originalEval(compiled, context, filename, callback);
188
- }
189
- catch (error) {
190
- if (this.#isRecoverableError(error)) {
191
- callback(new Recoverable(error), null);
192
- return;
193
- }
194
- callback(error, null);
195
- }
196
- }
197
- /**
198
- * Setup history file
199
- */
200
- #setupHistory() {
201
- if (!this.#historyFilePath) {
202
- return;
203
- }
204
- this.server.setupHistory(this.#historyFilePath, (error) => {
205
- if (!error) {
206
- return;
207
- }
208
- console.log(this.colors.red('Unable to write to the history file. Exiting'));
209
- console.error(error);
210
- process.exit(1);
211
- });
212
- }
213
- /**
214
- * Prints the help for the context properties
215
- */
216
- #printContextHelp() {
217
- /**
218
- * Print context properties
219
- */
220
- console.log('');
221
- console.log(this.colors.green('CONTEXT PROPERTIES/METHODS:'));
222
- const context = Object.keys(this.server.context).reduce((result, key) => {
223
- if (!this.#customMethods[key] &&
224
- !GLOBAL_NODE_PROPERTIES.includes(key) &&
225
- !TS_UTILS_HELPERS.includes(key)) {
226
- result[key] = this.server.context[key];
227
- }
228
- return result;
229
- }, {});
230
- console.log(inspect(context, false, 1, true));
231
- }
232
- /**
233
- * Prints the help for the custom methods
234
- */
235
- #printCustomMethodsHelp() {
236
- /**
237
- * Print loader methods
238
- */
239
- console.log('');
240
- console.log(this.colors.green('GLOBAL METHODS:'));
241
- Object.keys(this.#customMethods).forEach((method) => {
242
- const { options } = this.#customMethods[method];
243
- const spaces = new Array(this.#longestCustomMethodName - options.width + 2).join(' ');
244
- console.log(`${this.colors.yellow(options.usage || method)}${spaces}${this.colors.dim(options.description || '')}`);
245
- });
246
- }
247
- #registerCustomMethodWithContext(name) {
248
- const customMethod = this.#customMethods[name];
249
- if (!customMethod) {
250
- return;
251
- }
252
- /**
253
- * Wrap handler
254
- */
255
- const handler = (...args) => customMethod.handler(this, ...args);
256
- /**
257
- * Re-define the function name to be more description
258
- */
259
- Object.defineProperty(handler, 'name', { value: customMethod.handler.name });
260
- /**
261
- * Register with the context
262
- */
263
- this.server.context[name] = handler;
264
- }
265
- /**
266
- * Prints the context to the console
267
- */
268
- #ls() {
269
- this.#printCustomMethodsHelp();
270
- this.#printContextHelp();
271
- this.server.displayPrompt();
272
- }
273
- /**
274
- * Notify by writing to the console
275
- */
276
- notify(message) {
277
- console.log(this.colors.yellow().italic(message));
278
- if (this.server) {
279
- this.server.displayPrompt();
280
- }
281
- }
282
- /**
283
- * Start the REPL server
284
- */
285
- start() {
286
- this.#printWelcomeMessage();
287
- this.server = startRepl({
288
- prompt: '> ',
289
- input: process.stdin,
290
- output: process.stdout,
291
- terminal: process.stdout.isTTY && !Number.parseInt(process.env.NODE_NO_READLINE, 10),
292
- useGlobal: true,
293
- });
294
- /**
295
- * Define the `ls` command
296
- */
297
- this.server.defineCommand('ls', {
298
- help: 'View list of available context methods/properties',
299
- action: this.#ls.bind(this),
300
- });
301
- /**
302
- * Setup context and history
303
- */
304
- this.#setupContext();
305
- this.#setupHistory();
306
- /**
307
- * Monkey patch the eval method
308
- */
309
- this.#originalEval = this.server.eval;
310
- // @ts-ignore
311
- this.server.eval = this.#eval.bind(this);
312
- /**
313
- * Display prompt
314
- */
315
- this.server.displayPrompt();
316
- /**
317
- * Execute onReady callbacks
318
- */
319
- this.#onReadyCallbacks.forEach((callback) => callback(this));
320
- return this;
321
- }
322
- /**
323
- * Register a callback to be invoked once the server is ready
324
- */
325
- ready(callback) {
326
- this.#onReadyCallbacks.push(callback);
327
- return this;
328
- }
329
- /**
330
- * Register a custom loader function to be added to the context
331
- */
332
- addMethod(name, handler, options) {
333
- const width = stringWidth(options?.usage || name);
334
- if (width > this.#longestCustomMethodName) {
335
- this.#longestCustomMethodName = width;
336
- }
337
- this.#customMethods[name] = { handler, options: Object.assign({ width }, options) };
338
- /**
339
- * Register method right away when server has been started
340
- */
341
- if (this.server) {
342
- this.#registerCustomMethodWithContext(name);
343
- }
344
- return this;
345
- }
346
- }
@@ -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 {};