@stainless-api/playgrounds 0.0.1-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +15 -0
- package/README.md +23 -0
- package/eslint.config.js +2 -0
- package/package.json +69 -0
- package/src/Logs.tsx +216 -0
- package/src/Panel.tsx +21 -0
- package/src/PlaygroundPanelWrapper.tsx +5 -0
- package/src/build-py-types.ts +152 -0
- package/src/build-ts-types.ts +70 -0
- package/src/build.ts +97 -0
- package/src/codemirror/comlink.ts +698 -0
- package/src/codemirror/curl/curlconverter.vendor.js +7959 -0
- package/src/codemirror/curl.ts +108 -0
- package/src/codemirror/deps.ts +12 -0
- package/src/codemirror/fix-lsp-markdown.ts +50 -0
- package/src/codemirror/lsp.ts +87 -0
- package/src/codemirror/python/anser.ts +398 -0
- package/src/codemirror/python/pyodide.ts +180 -0
- package/src/codemirror/python.ts +160 -0
- package/src/codemirror/react.tsx +615 -0
- package/src/codemirror/sanitize-html.ts +12 -0
- package/src/codemirror/shiki.ts +65 -0
- package/src/codemirror/typescript/cdn-typescript.d.ts +1 -0
- package/src/codemirror/typescript/cdn-typescript.js +1 -0
- package/src/codemirror/typescript/console.ts +590 -0
- package/src/codemirror/typescript/get-signature.ts +94 -0
- package/src/codemirror/typescript/prettier-plugin-external-typescript.vendor.js +4968 -0
- package/src/codemirror/typescript/runner.ts +396 -0
- package/src/codemirror/typescript/special-info.ts +171 -0
- package/src/codemirror/typescript/worker.ts +292 -0
- package/src/codemirror/typescript.tsx +198 -0
- package/src/create.tsx +44 -0
- package/src/icon.tsx +21 -0
- package/src/index.ts +6 -0
- package/src/logs-context.ts +5 -0
- package/src/playground.css +359 -0
- package/src/sandbox-worker/in-frame.js +179 -0
- package/src/sandbox-worker/index.ts +202 -0
- package/src/use-storage.ts +54 -0
- package/src/util.ts +29 -0
- package/src/virtual-module.d.ts +45 -0
- package/src/vite-env.d.ts +1 -0
- package/test/get-signature.test.ts +73 -0
- package/test/use-storage.test.ts +60 -0
- package/tsconfig.json +11 -0
|
@@ -0,0 +1,590 @@
|
|
|
1
|
+
import { JSLogType } from '../../Logs';
|
|
2
|
+
|
|
3
|
+
export type Printer = (...args: [JSLogType, (string | Part)[]] | ['clear']) => void;
|
|
4
|
+
type Logger = (...args: [JSLogType, unknown[]]) => void;
|
|
5
|
+
|
|
6
|
+
const stripMe = /^(?:.*Error.*\n)?.+\n/;
|
|
7
|
+
type Part = {
|
|
8
|
+
css: string | undefined;
|
|
9
|
+
value: unknown;
|
|
10
|
+
type: 'string' | 'object' | 'table';
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
function format(args: unknown[]): (string | Part)[] {
|
|
14
|
+
const first = args[0];
|
|
15
|
+
let a = 0;
|
|
16
|
+
const parts: (Part | string)[] = [];
|
|
17
|
+
|
|
18
|
+
if (typeof first == 'string' && args.length > 1) {
|
|
19
|
+
a++;
|
|
20
|
+
// Index of the first not-yet-appended character. Use this so we only
|
|
21
|
+
// have to append to `string` when a substitution occurs / at the end.
|
|
22
|
+
let appendedChars = 0;
|
|
23
|
+
let css: string | undefined;
|
|
24
|
+
for (let i = 0; i < first.length - 1; i++) {
|
|
25
|
+
const prevCss = css;
|
|
26
|
+
if (first[i] == '%') {
|
|
27
|
+
const char = first[++i];
|
|
28
|
+
if (a < args.length) {
|
|
29
|
+
let formattedArg: Part | null = null;
|
|
30
|
+
switch (char) {
|
|
31
|
+
case 's': {
|
|
32
|
+
// Format as a string.
|
|
33
|
+
formattedArg = {
|
|
34
|
+
css,
|
|
35
|
+
type: 'string',
|
|
36
|
+
value: String(args[a++]),
|
|
37
|
+
};
|
|
38
|
+
break;
|
|
39
|
+
}
|
|
40
|
+
case 'd':
|
|
41
|
+
case 'i': {
|
|
42
|
+
// Format as an integer.
|
|
43
|
+
const value = args[a++];
|
|
44
|
+
if (typeof value === 'symbol') {
|
|
45
|
+
formattedArg = {
|
|
46
|
+
css,
|
|
47
|
+
type: 'object',
|
|
48
|
+
value: NaN,
|
|
49
|
+
};
|
|
50
|
+
} else {
|
|
51
|
+
formattedArg = {
|
|
52
|
+
css,
|
|
53
|
+
type: 'object',
|
|
54
|
+
value: Number.parseInt(value as string, 10),
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
break;
|
|
58
|
+
}
|
|
59
|
+
case 'f': {
|
|
60
|
+
// Format as a floating point value.
|
|
61
|
+
const value = args[a++];
|
|
62
|
+
if (typeof value === 'symbol') {
|
|
63
|
+
formattedArg = {
|
|
64
|
+
css,
|
|
65
|
+
type: 'object',
|
|
66
|
+
value: NaN,
|
|
67
|
+
};
|
|
68
|
+
} else {
|
|
69
|
+
formattedArg = {
|
|
70
|
+
css,
|
|
71
|
+
type: 'object',
|
|
72
|
+
value: Number.parseFloat(value as string),
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
break;
|
|
76
|
+
}
|
|
77
|
+
case 'O':
|
|
78
|
+
case 'o': {
|
|
79
|
+
// Format as an object.
|
|
80
|
+
formattedArg = {
|
|
81
|
+
css,
|
|
82
|
+
type: 'object',
|
|
83
|
+
value: args[a++],
|
|
84
|
+
};
|
|
85
|
+
break;
|
|
86
|
+
}
|
|
87
|
+
case 'c': {
|
|
88
|
+
css = String(args[a++]);
|
|
89
|
+
formattedArg = {
|
|
90
|
+
css: '',
|
|
91
|
+
type: 'string',
|
|
92
|
+
value: '',
|
|
93
|
+
};
|
|
94
|
+
break;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
if (formattedArg !== null) {
|
|
99
|
+
if (appendedChars !== i - 1) {
|
|
100
|
+
parts.push(
|
|
101
|
+
{
|
|
102
|
+
css: prevCss,
|
|
103
|
+
value: first.slice(appendedChars, i - 1),
|
|
104
|
+
type: 'string',
|
|
105
|
+
},
|
|
106
|
+
formattedArg,
|
|
107
|
+
);
|
|
108
|
+
} else {
|
|
109
|
+
parts.push(formattedArg);
|
|
110
|
+
}
|
|
111
|
+
appendedChars = i + 1;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
if (char == '%') {
|
|
115
|
+
parts.push({
|
|
116
|
+
css: prevCss,
|
|
117
|
+
value: first.slice(appendedChars, i - 1) + '%',
|
|
118
|
+
type: 'string',
|
|
119
|
+
});
|
|
120
|
+
appendedChars = i + 1;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
parts.push({
|
|
125
|
+
css,
|
|
126
|
+
value: first.slice(appendedChars),
|
|
127
|
+
type: 'string',
|
|
128
|
+
});
|
|
129
|
+
css = undefined;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
for (; a < args.length; a++) {
|
|
133
|
+
if (a > 0) {
|
|
134
|
+
parts.push(' ');
|
|
135
|
+
}
|
|
136
|
+
if (typeof args[a] == 'string') {
|
|
137
|
+
parts.push(args[a] as string);
|
|
138
|
+
} else {
|
|
139
|
+
// Use default maximum depth for null or undefined arguments.
|
|
140
|
+
parts.push({
|
|
141
|
+
css: undefined,
|
|
142
|
+
type: 'object',
|
|
143
|
+
value: args[a],
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
return parts;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* The Console interface provides methods for logging information to the console,
|
|
153
|
+
* as well as other utility methods for debugging and inspecting code.
|
|
154
|
+
* Methods include logging, debugging, and timing functionality.
|
|
155
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/API/console
|
|
156
|
+
*/
|
|
157
|
+
export interface Console {
|
|
158
|
+
/**
|
|
159
|
+
* Tests that an expression is true. If not, logs an error message
|
|
160
|
+
* @param condition The expression to test for truthiness
|
|
161
|
+
* @param data Additional arguments to be printed if the assertion fails
|
|
162
|
+
* @example
|
|
163
|
+
* ```ts
|
|
164
|
+
* console.assert(1 === 1, "This won't show");
|
|
165
|
+
* console.assert(1 === 2, "This will show an error");
|
|
166
|
+
* ```
|
|
167
|
+
*/
|
|
168
|
+
assert(condition?: boolean, ...data: unknown[]): void;
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Clears the console if the environment allows it
|
|
172
|
+
* @example
|
|
173
|
+
* ```ts
|
|
174
|
+
* console.clear();
|
|
175
|
+
* ```
|
|
176
|
+
*/
|
|
177
|
+
clear(): void;
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Maintains an internal counter for a given label, incrementing it each time the method is called
|
|
181
|
+
* @param label The label to count. Defaults to 'default'
|
|
182
|
+
* @example
|
|
183
|
+
* ```ts
|
|
184
|
+
* console.count('myCounter');
|
|
185
|
+
* console.count('myCounter'); // Will show: myCounter: 2
|
|
186
|
+
* ```
|
|
187
|
+
*/
|
|
188
|
+
count(label?: string): void;
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Resets the counter for a given label
|
|
192
|
+
* @param label The label to reset. Defaults to 'default'
|
|
193
|
+
* @example
|
|
194
|
+
* ```ts
|
|
195
|
+
* console.count('myCounter');
|
|
196
|
+
* console.countReset('myCounter'); // Resets to 0
|
|
197
|
+
* ```
|
|
198
|
+
*/
|
|
199
|
+
countReset(label?: string): void;
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* Outputs a debugging message to the console
|
|
203
|
+
* @param data Values to be printed to the console
|
|
204
|
+
* @example
|
|
205
|
+
* ```ts
|
|
206
|
+
* console.debug('Debug message', { detail: 'some data' });
|
|
207
|
+
* ```
|
|
208
|
+
*/
|
|
209
|
+
debug(...data: unknown[]): void;
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Displays a list of the properties of a specified object
|
|
213
|
+
* @param item Object to display
|
|
214
|
+
* @param options Formatting options
|
|
215
|
+
* @example
|
|
216
|
+
* ```ts
|
|
217
|
+
* console.dir({ name: 'object', value: 42 }, { depth: 1 });
|
|
218
|
+
* ```
|
|
219
|
+
*/
|
|
220
|
+
dir(item?: unknown, options?: unknown): void;
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* @ignore
|
|
224
|
+
*/
|
|
225
|
+
dirxml(...data: unknown[]): void;
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* Outputs an error message to the console.
|
|
229
|
+
* This method routes the output to stderr,
|
|
230
|
+
* unlike other console methods that route to stdout.
|
|
231
|
+
* @param data Values to be printed to the console
|
|
232
|
+
* @example
|
|
233
|
+
* ```ts
|
|
234
|
+
* console.error('Error occurred:', new Error('Something went wrong'));
|
|
235
|
+
* ```
|
|
236
|
+
*/
|
|
237
|
+
error(...data: unknown[]): void;
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* Creates a new inline group in the console, indenting subsequent console messages
|
|
241
|
+
* @param data Labels for the group
|
|
242
|
+
* @example
|
|
243
|
+
* ```ts
|
|
244
|
+
* console.group('Group 1');
|
|
245
|
+
* console.log('Inside group 1');
|
|
246
|
+
* console.groupEnd();
|
|
247
|
+
* ```
|
|
248
|
+
*/
|
|
249
|
+
group(...data: unknown[]): void;
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* Creates a new inline group in the console that is initially collapsed
|
|
253
|
+
* @param data Labels for the group
|
|
254
|
+
* @example
|
|
255
|
+
* ```ts
|
|
256
|
+
* console.groupCollapsed('Details');
|
|
257
|
+
* console.log('Hidden until expanded');
|
|
258
|
+
* console.groupEnd();
|
|
259
|
+
* ```
|
|
260
|
+
*/
|
|
261
|
+
groupCollapsed(...data: unknown[]): void;
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* Exits the current inline group in the console
|
|
265
|
+
* @example
|
|
266
|
+
* ```ts
|
|
267
|
+
* console.group('Group');
|
|
268
|
+
* console.log('Grouped message');
|
|
269
|
+
* console.groupEnd();
|
|
270
|
+
* ```
|
|
271
|
+
*/
|
|
272
|
+
groupEnd(): void;
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
* Outputs an informational message to the console
|
|
276
|
+
* @param data Values to be printed to the console
|
|
277
|
+
* @example
|
|
278
|
+
* ```ts
|
|
279
|
+
* console.info('Application started', { version: '1.0.0' });
|
|
280
|
+
* ```
|
|
281
|
+
*/
|
|
282
|
+
info(...data: unknown[]): void;
|
|
283
|
+
|
|
284
|
+
/**
|
|
285
|
+
* Outputs a message to the console
|
|
286
|
+
* @param data Values to be printed to the console
|
|
287
|
+
* @example
|
|
288
|
+
* ```ts
|
|
289
|
+
* console.log('Hello', 'World', 123);
|
|
290
|
+
* ```
|
|
291
|
+
*/
|
|
292
|
+
log(...data: unknown[]): void;
|
|
293
|
+
|
|
294
|
+
/**
|
|
295
|
+
* Displays tabular data as a table
|
|
296
|
+
* @param tabularData Data to be displayed in table format
|
|
297
|
+
* @param properties Array of property names to be displayed
|
|
298
|
+
* @example
|
|
299
|
+
* ```ts
|
|
300
|
+
* console.table([
|
|
301
|
+
* { name: 'John', age: 30 },
|
|
302
|
+
* { name: 'Jane', age: 25 }
|
|
303
|
+
* ]);
|
|
304
|
+
* ```
|
|
305
|
+
*/
|
|
306
|
+
table(tabularData?: unknown, properties?: string[]): void;
|
|
307
|
+
|
|
308
|
+
/**
|
|
309
|
+
* Starts a timer you can use to track how long an operation takes
|
|
310
|
+
* @param label Timer label. Defaults to 'default'
|
|
311
|
+
* @example
|
|
312
|
+
* ```ts
|
|
313
|
+
* console.time('operation');
|
|
314
|
+
* // ... some code
|
|
315
|
+
* console.timeEnd('operation');
|
|
316
|
+
* ```
|
|
317
|
+
*/
|
|
318
|
+
time(label?: string): void;
|
|
319
|
+
|
|
320
|
+
/**
|
|
321
|
+
* Stops a timer that was previously started
|
|
322
|
+
* @param label Timer label to stop. Defaults to 'default'
|
|
323
|
+
* @example
|
|
324
|
+
* ```ts
|
|
325
|
+
* console.time('operation');
|
|
326
|
+
* // ... some code
|
|
327
|
+
* console.timeEnd('operation'); // Prints: operation: 1234ms
|
|
328
|
+
* ```
|
|
329
|
+
*/
|
|
330
|
+
timeEnd(label?: string): void;
|
|
331
|
+
|
|
332
|
+
/**
|
|
333
|
+
* Logs the current value of a timer that was previously started
|
|
334
|
+
* @param label Timer label
|
|
335
|
+
* @param data Additional data to log
|
|
336
|
+
* @example
|
|
337
|
+
* ```ts
|
|
338
|
+
* console.time('process');
|
|
339
|
+
* // ... some code
|
|
340
|
+
* console.timeLog('process', 'Checkpoint A');
|
|
341
|
+
* ```
|
|
342
|
+
*/
|
|
343
|
+
timeLog(label?: string, ...data: unknown[]): void;
|
|
344
|
+
|
|
345
|
+
/**
|
|
346
|
+
* Outputs a stack trace to the console
|
|
347
|
+
* @param data Values to be printed to the console
|
|
348
|
+
* @example
|
|
349
|
+
* ```ts
|
|
350
|
+
* console.trace('Trace message');
|
|
351
|
+
* ```
|
|
352
|
+
*/
|
|
353
|
+
trace(...data: unknown[]): void;
|
|
354
|
+
|
|
355
|
+
/**
|
|
356
|
+
* Outputs a warning message to the console
|
|
357
|
+
* @param data Values to be printed to the console
|
|
358
|
+
* @example
|
|
359
|
+
* ```ts
|
|
360
|
+
* console.warn('Deprecated feature used');
|
|
361
|
+
* ```
|
|
362
|
+
*/
|
|
363
|
+
warn(...data: unknown[]): void;
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
function isSet(value: unknown) {
|
|
367
|
+
try {
|
|
368
|
+
Set.prototype.has.call(value, null);
|
|
369
|
+
return true;
|
|
370
|
+
} catch {
|
|
371
|
+
return false;
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
function isMap(value: unknown) {
|
|
376
|
+
try {
|
|
377
|
+
Map.prototype.has.call(value, null);
|
|
378
|
+
return true;
|
|
379
|
+
} catch {
|
|
380
|
+
return false;
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
export function createConsole(printer: Printer): Console {
|
|
385
|
+
const groupStack: unknown[][] = [];
|
|
386
|
+
const countMap: Record<string, number> = { __proto__: null as never };
|
|
387
|
+
const timerTable: Record<string, number> = { __proto__: null as never };
|
|
388
|
+
const logger: Logger = (...args) => {
|
|
389
|
+
printer(args[0], format(args[1]));
|
|
390
|
+
};
|
|
391
|
+
return Object.defineProperties(
|
|
392
|
+
{
|
|
393
|
+
__proto__: {},
|
|
394
|
+
assert(condition: unknown = undefined, ...data: unknown[]) {
|
|
395
|
+
if (condition) {
|
|
396
|
+
return;
|
|
397
|
+
}
|
|
398
|
+
if (!data.length) {
|
|
399
|
+
data[0] = 'Assertion failed';
|
|
400
|
+
} else if (typeof data[0] === 'string') {
|
|
401
|
+
data[0] = `Assertion failed: ${data[0]}`;
|
|
402
|
+
} else {
|
|
403
|
+
data.unshift('Assertion failed');
|
|
404
|
+
}
|
|
405
|
+
logger('error', data);
|
|
406
|
+
},
|
|
407
|
+
clear() {
|
|
408
|
+
while (groupStack.length) {
|
|
409
|
+
logger('groupEnd', groupStack.pop()!);
|
|
410
|
+
}
|
|
411
|
+
printer('clear');
|
|
412
|
+
},
|
|
413
|
+
debug(...data: unknown[]) {
|
|
414
|
+
logger('debug', data);
|
|
415
|
+
},
|
|
416
|
+
error(...data: unknown[]) {
|
|
417
|
+
logger('error', data);
|
|
418
|
+
},
|
|
419
|
+
info(...data: unknown[]) {
|
|
420
|
+
logger('info', data);
|
|
421
|
+
},
|
|
422
|
+
log(...data: unknown[]) {
|
|
423
|
+
logger('log', data);
|
|
424
|
+
},
|
|
425
|
+
table(...args: unknown[]) {
|
|
426
|
+
const data = args[0];
|
|
427
|
+
const properties = args[1];
|
|
428
|
+
|
|
429
|
+
if (args.length > 2 || (properties !== undefined && !Array.isArray(properties))) {
|
|
430
|
+
logger('log', args);
|
|
431
|
+
return;
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
let resultData: Record<PropertyKey, unknown>;
|
|
435
|
+
const isSetObject = isSet(data);
|
|
436
|
+
const isMapObject = isMap(data);
|
|
437
|
+
const valuesKey = 'Values';
|
|
438
|
+
const indexKey = isSetObject || isMapObject ? '(iter idx)' : '(idx)';
|
|
439
|
+
|
|
440
|
+
if (isSetObject) {
|
|
441
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
442
|
+
resultData = [...(data as any)] as any;
|
|
443
|
+
} else if (isMapObject) {
|
|
444
|
+
let idx = 0;
|
|
445
|
+
resultData = { __proto__: null };
|
|
446
|
+
|
|
447
|
+
Map.prototype.forEach.call(data, (v, k) => {
|
|
448
|
+
resultData[idx] = { Key: k, Values: v };
|
|
449
|
+
idx++;
|
|
450
|
+
});
|
|
451
|
+
} else {
|
|
452
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
453
|
+
resultData = data as any;
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
const keys = Object.keys(resultData);
|
|
457
|
+
const numRows = keys.length;
|
|
458
|
+
|
|
459
|
+
const objectValues: Record<PropertyKey, unknown[]> = properties
|
|
460
|
+
? Object.fromEntries(properties.map((name) => [name, new Array(numRows).fill('')]))
|
|
461
|
+
: {};
|
|
462
|
+
const indexKeys: PropertyKey[] = [];
|
|
463
|
+
const values: unknown[] = [];
|
|
464
|
+
|
|
465
|
+
let hasPrimitives = false;
|
|
466
|
+
keys.forEach((k, idx) => {
|
|
467
|
+
const value = resultData[k];
|
|
468
|
+
const primitive = value === null || (typeof value !== 'function' && typeof value !== 'object');
|
|
469
|
+
if (properties === undefined && primitive) {
|
|
470
|
+
hasPrimitives = true;
|
|
471
|
+
values.push(value);
|
|
472
|
+
} else {
|
|
473
|
+
const valueObj = value || {};
|
|
474
|
+
const keys = properties || Object.keys(valueObj);
|
|
475
|
+
for (let i = 0; i < keys.length; ++i) {
|
|
476
|
+
const k = keys[i] as PropertyKey;
|
|
477
|
+
if (!primitive && Reflect.has(valueObj, k)) {
|
|
478
|
+
if (!Reflect.has(objectValues, k)) {
|
|
479
|
+
objectValues[k] = new Array(numRows).fill('');
|
|
480
|
+
}
|
|
481
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
482
|
+
objectValues[k]![idx] = (valueObj as any)[k];
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
values.push('');
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
indexKeys.push(k);
|
|
489
|
+
});
|
|
490
|
+
|
|
491
|
+
const headerKeys = Object.keys(objectValues);
|
|
492
|
+
const bodyValues = Object.values(objectValues);
|
|
493
|
+
const headerProps = properties || [...headerKeys, !isMapObject && hasPrimitives && valuesKey];
|
|
494
|
+
const header = [indexKey, ...headerProps].filter(Boolean);
|
|
495
|
+
const body = [indexKeys, ...bodyValues, values];
|
|
496
|
+
|
|
497
|
+
printer('log', [
|
|
498
|
+
{
|
|
499
|
+
css: undefined,
|
|
500
|
+
type: 'table',
|
|
501
|
+
value: [
|
|
502
|
+
header,
|
|
503
|
+
...Array.from(Object.assign({ __proto__: null, length: numRows }), (_, row) =>
|
|
504
|
+
header.map((_, col) => body[col]![row]),
|
|
505
|
+
),
|
|
506
|
+
],
|
|
507
|
+
},
|
|
508
|
+
]);
|
|
509
|
+
},
|
|
510
|
+
trace(...data: unknown[]) {
|
|
511
|
+
logger('trace', [...data, '\n' + new Error().stack!.replace(stripMe, '')]);
|
|
512
|
+
},
|
|
513
|
+
warn(...data: unknown[]) {
|
|
514
|
+
logger('warn', data);
|
|
515
|
+
},
|
|
516
|
+
dir(item: unknown = undefined) {
|
|
517
|
+
logger('dir', [item]);
|
|
518
|
+
},
|
|
519
|
+
dirxml(...data: unknown[]) {
|
|
520
|
+
logger('log', data);
|
|
521
|
+
},
|
|
522
|
+
count(label: string | undefined = undefined) {
|
|
523
|
+
if (label === undefined) label = 'default';
|
|
524
|
+
label += '';
|
|
525
|
+
countMap[label] ??= 0;
|
|
526
|
+
logger('log', [`${label}: ${++countMap[label]!}`]);
|
|
527
|
+
},
|
|
528
|
+
countReset(label: string | undefined = undefined) {
|
|
529
|
+
if (label === undefined) label = 'default';
|
|
530
|
+
label += '';
|
|
531
|
+
if (Object.hasOwn(countMap, label)) {
|
|
532
|
+
countMap[label] = 0;
|
|
533
|
+
} else {
|
|
534
|
+
logger('warn', [`Counter ${label} doesn't exist.`]);
|
|
535
|
+
}
|
|
536
|
+
},
|
|
537
|
+
group(...data: unknown[]) {
|
|
538
|
+
groupStack.push(data);
|
|
539
|
+
logger('group', data);
|
|
540
|
+
},
|
|
541
|
+
groupCollapsed(...data: unknown[]) {
|
|
542
|
+
groupStack.push(data);
|
|
543
|
+
logger('groupCollapsed', data);
|
|
544
|
+
},
|
|
545
|
+
groupEnd() {
|
|
546
|
+
const group = groupStack.pop();
|
|
547
|
+
if (group) logger('groupEnd', group);
|
|
548
|
+
},
|
|
549
|
+
time(label: string | undefined = undefined) {
|
|
550
|
+
if (label === undefined) label = 'default';
|
|
551
|
+
label += '';
|
|
552
|
+
if (Object.hasOwn(timerTable, label)) {
|
|
553
|
+
logger('warn', [`Timer "${label}" already exists.`]);
|
|
554
|
+
} else {
|
|
555
|
+
timerTable[label] = Date.now();
|
|
556
|
+
}
|
|
557
|
+
},
|
|
558
|
+
timeLog(label: string | undefined = undefined, ...data: unknown[]) {
|
|
559
|
+
if (label === undefined) label = 'default';
|
|
560
|
+
label += '';
|
|
561
|
+
if (Object.hasOwn(timerTable, label)) {
|
|
562
|
+
logger('log', [`${label}: ${Date.now() - timerTable[label]!}ms`, ...data]);
|
|
563
|
+
} else {
|
|
564
|
+
logger('warn', [`Timer "${label}" doesn't exist.`]);
|
|
565
|
+
}
|
|
566
|
+
},
|
|
567
|
+
timeEnd(label: string | undefined = undefined, ...data: unknown[]) {
|
|
568
|
+
if (label === undefined) label = 'default';
|
|
569
|
+
label += '';
|
|
570
|
+
if (Object.hasOwn(timerTable, label)) {
|
|
571
|
+
logger('log', [`${label}: ${Date.now() - timerTable[label]!}ms - timer ended`, ...data]);
|
|
572
|
+
delete timerTable[label];
|
|
573
|
+
} else {
|
|
574
|
+
logger('warn', [`Timer "${label}" doesn't exist.`]);
|
|
575
|
+
}
|
|
576
|
+
},
|
|
577
|
+
},
|
|
578
|
+
{
|
|
579
|
+
[Symbol.toStringTag]: {
|
|
580
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
581
|
+
// @ts-ignore ts doesn't support __proto__
|
|
582
|
+
__proto__: null,
|
|
583
|
+
value: 'console',
|
|
584
|
+
writable: false,
|
|
585
|
+
enumerable: false,
|
|
586
|
+
configurable: true,
|
|
587
|
+
},
|
|
588
|
+
},
|
|
589
|
+
);
|
|
590
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import jsTokens from 'js-tokens';
|
|
2
|
+
|
|
3
|
+
export function getSignature(source: string) {
|
|
4
|
+
let depth = 0;
|
|
5
|
+
let out = '';
|
|
6
|
+
let state = 0;
|
|
7
|
+
let isClass = false;
|
|
8
|
+
let maybeArrow = '';
|
|
9
|
+
let maybeGetSet = '';
|
|
10
|
+
loop: for (const t of jsTokens(source)) {
|
|
11
|
+
if (state === 0) {
|
|
12
|
+
if (t.type === 'WhiteSpace' || t.type.endsWith('Comment')) continue;
|
|
13
|
+
if (t.type === 'IdentifierName') {
|
|
14
|
+
if (t.value === 'async') {
|
|
15
|
+
out += t.value + ' ';
|
|
16
|
+
continue;
|
|
17
|
+
}
|
|
18
|
+
if (t.value === 'function' || (t.value === 'class' && (isClass = true))) {
|
|
19
|
+
out += t.value;
|
|
20
|
+
state = 1;
|
|
21
|
+
continue;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
if (t.type === 'Punctuator' && t.value === '(') {
|
|
25
|
+
out += 'function ';
|
|
26
|
+
state = 2;
|
|
27
|
+
} else {
|
|
28
|
+
state = 3;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
if (state === 1) {
|
|
32
|
+
if (t.type === 'WhiteSpace' || t.type.endsWith('Comment')) continue;
|
|
33
|
+
if (t.type === 'Punctuator' && t.value === '*') {
|
|
34
|
+
out += t.value;
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
37
|
+
if (t.type === 'IdentifierName') {
|
|
38
|
+
out += ' ' + t.value;
|
|
39
|
+
state = 2;
|
|
40
|
+
continue;
|
|
41
|
+
} else {
|
|
42
|
+
out += ' ';
|
|
43
|
+
state = 2;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
if (state === 3) {
|
|
47
|
+
if (t.type === 'WhiteSpace' || t.type.endsWith('Comment')) {
|
|
48
|
+
if (maybeGetSet) maybeGetSet = '';
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
if (t.type === 'Punctuator') {
|
|
52
|
+
if (t.value === '(') {
|
|
53
|
+
out += 'function ' + maybeGetSet + maybeArrow;
|
|
54
|
+
state = 2;
|
|
55
|
+
} else if (t.value === '=>') {
|
|
56
|
+
out += 'function (' + maybeArrow + ')';
|
|
57
|
+
break loop;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
if (t.type === 'IdentifierName' && (t.value === 'get' || t.value === 'set')) {
|
|
61
|
+
maybeGetSet = t.value;
|
|
62
|
+
} else {
|
|
63
|
+
maybeArrow += t.value;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
if (state === 2) {
|
|
67
|
+
if (t.type === 'Punctuator') {
|
|
68
|
+
switch (t.value) {
|
|
69
|
+
case '=>':
|
|
70
|
+
if (depth === 0) {
|
|
71
|
+
break loop;
|
|
72
|
+
}
|
|
73
|
+
break;
|
|
74
|
+
case '{':
|
|
75
|
+
if (depth === 0) {
|
|
76
|
+
break loop;
|
|
77
|
+
}
|
|
78
|
+
// falls through
|
|
79
|
+
case '(':
|
|
80
|
+
case '[':
|
|
81
|
+
depth++;
|
|
82
|
+
break;
|
|
83
|
+
case ')':
|
|
84
|
+
case ']':
|
|
85
|
+
case '}':
|
|
86
|
+
depth--;
|
|
87
|
+
break;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
out += t.value;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return out.trim() + (isClass ? ' {}' : '');
|
|
94
|
+
}
|