Skip to content

Commit 992d3b7

Browse files
committed
[source-map-support] Improve types
- add `state` parameter to `wrapCallSite` - add `CallSite` definition - allow `url` in `UrlAndMap` to be optional - add missing doc comments - improve tests
1 parent 0a4b8f5 commit 992d3b7

2 files changed

Lines changed: 256 additions & 50 deletions

File tree

types/source-map-support/index.d.ts

Lines changed: 168 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,32 +4,111 @@
44
// Jason Cheatham <https://github.com/jason0x43>
55
// Alcedo Nathaniel De Guzman Jr <https://github.com/natealcedo>
66
// Griffin Yourick <https://github.com/tough-griff>
7+
// BendingBender <https://github.com/BendingBender>
78
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
89

910
import { RawSourceMap } from 'source-map';
1011

1112
/**
12-
* Output of retrieveSourceMap().
13-
* From source-map-support:
14-
* The map field may be either a string or the parsed JSON object (i.e.,
15-
* it must be a valid argument to the SourceMapConsumer constructor).
13+
* Output of `retrieveSourceMap()`.
14+
* The map field may be either a string or the parsed JSON object (i.e.,
15+
* it must be a valid argument to the SourceMapConsumer constructor).
1616
*/
1717
export interface UrlAndMap {
18-
url: string;
18+
url?: string | undefined;
1919
map: string | RawSourceMap;
2020
}
2121

22+
export type Environment = 'auto' | 'browser' | 'node';
23+
2224
/**
2325
* Options to install().
2426
*/
2527
export interface Options {
28+
/**
29+
* This module installs two things: a change to the `stack` property on `Error`
30+
* objects and a handler for uncaught exceptions that mimics node's default exception
31+
* handler (the handler can be seen in the demos below). You may want to disable the
32+
* handler if you have your own uncaught exception handler. This can be done by passing
33+
* an argument to the installer.
34+
*
35+
* @example
36+
* import { install } from 'source-map-support';
37+
*
38+
* install({
39+
* handleUncaughtExceptions: false
40+
* });
41+
*/
2642
handleUncaughtExceptions?: boolean | undefined;
43+
/**
44+
* To support files with inline source maps, the `hookRequire` options can be specified,
45+
* which will monitor all source files for inline source maps.
46+
*
47+
* This monkey patches the `require` module loading chain, so is not enabled by default
48+
* and is not recommended for any sort of production usage.
49+
*
50+
* @example
51+
* import { install } from 'source-map-support';
52+
*
53+
* install({
54+
* hookRequire: true
55+
* });
56+
* ```
57+
*/
2758
hookRequire?: boolean | undefined;
59+
/**
60+
* If `true`, the caches are reset before a stack trace formatting operation.
61+
*/
2862
emptyCacheBetweenOperations?: boolean | undefined;
29-
environment?: 'auto' | 'browser' | 'node' | undefined;
63+
/**
64+
* The module will by default assume a browser environment if `XMLHttpRequest` and `window`
65+
* are defined. If either of these do not exist it will instead assume a node environment.
66+
* In some rare cases, e.g. when running a browser emulation and where both variables are
67+
* also set, you can explicitly specify the environment to be either `'browser'` or `'node'`.
68+
*
69+
* @example
70+
* import { install } from 'source-map-support';
71+
*
72+
* install({
73+
* environment: 'node'
74+
* });
75+
*/
76+
environment?: Environment | undefined;
77+
/**
78+
* Disable all other means of retrieving file contents and use only the provided
79+
* `retrieveFile` handler.
80+
*/
3081
overrideRetrieveFile?: boolean | undefined;
82+
/**
83+
* Disable all other means of retrieving source maps and use only the provided
84+
* `retrieveSourceMap` handler.
85+
*/
3186
overrideRetrieveSourceMap?: boolean | undefined;
32-
retrieveFile?(path: string): string;
87+
/**
88+
* Allow sources to be found by methods other than reading the files
89+
* directly from disk.
90+
*/
91+
retrieveFile?(path: string): string | null;
92+
/**
93+
* This module loads source maps from the filesystem by default. You can provide alternate
94+
* loading behavior through a callback as shown below. For example, [Meteor](https://github.com/meteor)
95+
* keeps all source maps cached in memory to avoid disk access.
96+
*
97+
* @example
98+
* import { install } from 'source-map-support';
99+
*
100+
* install({
101+
* retrieveSourceMap(source) {
102+
* if (source === 'compiled.js') {
103+
* return {
104+
* url: 'original.js',
105+
* map: fs.readFileSync('compiled.js.map', 'utf8')
106+
* };
107+
* }
108+
* return null;
109+
* }
110+
* });
111+
*/
33112
retrieveSourceMap?(source: string): UrlAndMap | null;
34113
}
35114

@@ -39,14 +118,94 @@ export interface Position {
39118
column: number;
40119
}
41120

42-
export function wrapCallSite(frame: any /* StackFrame */): any /* StackFrame */;
121+
export interface State {
122+
nextPosition: Position | null;
123+
curPosition: Position | null;
124+
}
125+
126+
export interface CallSite {
127+
/**
128+
* Value of "this"
129+
*/
130+
getThis(): any;
131+
132+
/**
133+
* Type of "this" as a string.
134+
* This is the name of the function stored in the constructor field of
135+
* "this", if available. Otherwise the object's [[Class]] internal
136+
* property.
137+
*/
138+
getTypeName(): string | null;
139+
140+
/**
141+
* Current function
142+
*/
143+
getFunction(): ((...args: unknown[]) => any) | undefined;
144+
145+
/**
146+
* Name of the current function, typically its name property.
147+
* If a name property is not available an attempt will be made to try
148+
* to infer a name from the function's context.
149+
*/
150+
getFunctionName(): string | null;
151+
152+
/**
153+
* Name of the property [of "this" or one of its prototypes] that holds
154+
* the current function
155+
*/
156+
getMethodName(): string | null;
157+
158+
/**
159+
* Name of the script [if this function was defined in a script]
160+
*/
161+
getFileName(): string | null;
162+
163+
/**
164+
* Current line number [if this function was defined in a script]
165+
*/
166+
getLineNumber(): number | null;
167+
168+
/**
169+
* Current column number [if this function was defined in a script]
170+
*/
171+
getColumnNumber(): number | null;
172+
173+
/**
174+
* A call site object representing the location where eval was called
175+
* [if this function was created using a call to eval]
176+
*/
177+
getEvalOrigin(): string | undefined;
178+
179+
/**
180+
* Is this a toplevel invocation, that is, is "this" the global object?
181+
*/
182+
isToplevel(): boolean;
183+
184+
/**
185+
* Does this call take place in code defined by a call to eval?
186+
*/
187+
isEval(): boolean;
188+
189+
/**
190+
* Is this call in native V8 code?
191+
*/
192+
isNative(): boolean;
193+
194+
/**
195+
* Is this a constructor call?
196+
*/
197+
isConstructor(): boolean;
198+
199+
getScriptNameOrSourceURL?(): string;
200+
}
201+
202+
export function wrapCallSite(frame: CallSite, state?: State): CallSite;
43203
export function getErrorSource(error: Error): string | null;
44204
export function mapSourcePosition(position: Position): Position;
45205
export function retrieveSourceMap(source: string): UrlAndMap | null;
46206
export function resetRetrieveHandlers(): void;
47207

48208
/**
49209
* Install SourceMap support.
50-
* @param options Can be used to e.g. disable uncaughtException handler.
51210
*/
52211
export function install(options?: Options): void;
Lines changed: 88 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,58 @@
11
import 'source-map-support/register';
2-
import sms = require('source-map-support');
2+
import * as sms from 'source-map-support';
33

4-
sms.install();
5-
6-
function retrieveFile(path: string): string {
7-
return 'foo';
8-
}
9-
10-
function retrieveSourceMap(source: string): sms.UrlAndMap | null {
11-
return source
12-
? {
13-
url: 'http://foo',
14-
map: 'foo',
15-
}
16-
: null;
17-
}
18-
19-
const options: sms.Options = {
20-
emptyCacheBetweenOperations: false,
21-
handleUncaughtExceptions: false,
22-
retrieveFile,
23-
retrieveSourceMap,
24-
environment: 'node',
25-
hookRequire: false,
26-
overrideRetrieveSourceMap: false,
27-
overrideRetrieveFile: false,
28-
};
29-
30-
sms.install(options);
4+
// test type exports
5+
type UrlAndMap = sms.UrlAndMap;
6+
type Environment = sms.Environment;
7+
type Options = sms.Options;
8+
type Position = sms.Position;
9+
type State = sms.State;
10+
type CallSite = sms.CallSite;
3111

12+
sms.install(); // $ExpectType void
13+
sms.install({ handleUncaughtExceptions: false }); // $ExpectType void
14+
sms.install({ hookRequire: false }); // $ExpectType void
15+
sms.install({ emptyCacheBetweenOperations: true }); // $ExpectType void
16+
sms.install({ environment: 'auto' }); // $ExpectType void
17+
sms.install({ environment: 'browser' }); // $ExpectType void
18+
sms.install({ environment: 'node' }); // $ExpectType void
19+
// @ts-expect-error
20+
sms.install({ environment: 'foo' });
21+
sms.install({ overrideRetrieveFile: true }); // $ExpectType void
22+
sms.install({ overrideRetrieveSourceMap: true }); // $ExpectType void
23+
// $ExpectType void
24+
sms.install({
25+
retrieveFile: path => {
26+
path; // $ExpectType string
27+
return null;
28+
},
29+
});
30+
sms.install({ retrieveFile: path => '' }); // $ExpectType void
31+
// @ts-expect-error
32+
sms.install({ retrieveFile: path => {} });
33+
// $ExpectType void
34+
sms.install({
35+
retrieveSourceMap: source => {
36+
source; // $ExpectType string
37+
return null;
38+
},
39+
});
40+
sms.install({ retrieveSourceMap: source => ({ map: 'foo' }) }); // $ExpectType void
41+
// $ExpectType void
42+
sms.install({
43+
retrieveSourceMap: source => {
44+
return {
45+
map: {
46+
mappings: '',
47+
names: [''],
48+
sources: [''],
49+
version: '',
50+
},
51+
};
52+
},
53+
});
54+
// $ExpectType void
3255
sms.install({
33-
...options,
3456
retrieveSourceMap(source) {
3557
return source
3658
? {
@@ -47,21 +69,46 @@ sms.install({
4769
: null;
4870
},
4971
});
72+
// $ExpectType void
73+
sms.install({
74+
retrieveSourceMap: source => {
75+
return {
76+
map: 'foo',
77+
url: 'foo',
78+
};
79+
},
80+
});
81+
// @ts-expect-error
82+
sms.install({ retrieveSourceMap: source => 'foo' });
5083

51-
let stackFrame: any; // TODO: this should be a StackFrame, but it seems this would need to be defined elsewhere (in e.g. lib.d.ts)
52-
stackFrame = sms.wrapCallSite(stackFrame);
53-
54-
let s: string | null;
55-
s = sms.getErrorSource(new Error('foo'));
56-
57-
let p: sms.Position = {
84+
declare const stackFrame: sms.CallSite;
85+
const position: sms.Position = {
5886
column: 0,
5987
line: 0,
6088
source: 'foo',
6189
};
62-
p = sms.mapSourcePosition(p);
90+
sms.wrapCallSite(stackFrame); // $ExpectType CallSite
91+
sms.wrapCallSite(stackFrame, { nextPosition: null, curPosition: null }); // $ExpectType CallSite
92+
sms.wrapCallSite(stackFrame, { nextPosition: position, curPosition: null }); // $ExpectType CallSite
93+
sms.wrapCallSite(stackFrame, { nextPosition: null, curPosition: position }); // $ExpectType CallSite
94+
sms.getErrorSource(new Error('foo')); // $ExpectType string | null
95+
// $ExpectType Position
96+
sms.mapSourcePosition(position);
97+
sms.resetRetrieveHandlers(); // $ExpectType void
6398

64-
let u: sms.UrlAndMap | null;
65-
u = retrieveSourceMap('foo');
66-
67-
sms.resetRetrieveHandlers();
99+
stackFrame.getThis(); // $ExpectType any
100+
stackFrame.getTypeName(); // $ExpectType string | null
101+
stackFrame.getFunction(); // $ExpectType ((...args: unknown[]) => any) | undefined
102+
stackFrame.getFunctionName(); // $ExpectType string | null
103+
stackFrame.getMethodName(); // $ExpectType string | null
104+
stackFrame.getFileName(); // $ExpectType string | null
105+
stackFrame.getLineNumber(); // $ExpectType number | null
106+
stackFrame.getColumnNumber(); // $ExpectType number | null
107+
stackFrame.getEvalOrigin(); // $ExpectType string | undefined
108+
stackFrame.isToplevel(); // $ExpectType boolean
109+
stackFrame.isEval(); // $ExpectType boolean
110+
stackFrame.isNative(); // $ExpectType boolean
111+
stackFrame.isConstructor(); // $ExpectType boolean
112+
if (stackFrame.getScriptNameOrSourceURL) {
113+
stackFrame.getScriptNameOrSourceURL(); // $ExpectType string
114+
}

0 commit comments

Comments
 (0)