@nocobase/plugin-flow-engine 2.0.0-alpha.2
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 +661 -0
- package/README.md +29 -0
- package/build.config.ts +22 -0
- package/client.d.ts +2 -0
- package/client.js +1 -0
- package/dist/client/index.d.ts +15 -0
- package/dist/client/index.js +10 -0
- package/dist/externalVersion.js +21 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +48 -0
- package/dist/locale/en-US.json +61 -0
- package/dist/locale/index.d.ts +141 -0
- package/dist/locale/index.js +79 -0
- package/dist/locale/zh-CN.json +61 -0
- package/dist/node_modules/ses/LICENSE +201 -0
- package/dist/node_modules/ses/LICENSE-aura +16 -0
- package/dist/node_modules/ses/LICENSE-caja +13 -0
- package/dist/node_modules/ses/LICENSE-corejs +19 -0
- package/dist/node_modules/ses/LICENSE-v8 +9 -0
- package/dist/node_modules/ses/assert-shim.js +1 -0
- package/dist/node_modules/ses/compartment-shim.js +1 -0
- package/dist/node_modules/ses/console-shim.js +1 -0
- package/dist/node_modules/ses/dist/lockdown.cjs +13912 -0
- package/dist/node_modules/ses/dist/lockdown.umd.js +13912 -0
- package/dist/node_modules/ses/dist/lockdown.umd.min.js +1 -0
- package/dist/node_modules/ses/dist/ses-hermes.cjs +13912 -0
- package/dist/node_modules/ses/dist/ses.cjs +1 -0
- package/dist/node_modules/ses/dist/ses.umd.js +13912 -0
- package/dist/node_modules/ses/dist/ses.umd.min.js +1 -0
- package/dist/node_modules/ses/dist/types.d.cts +606 -0
- package/dist/node_modules/ses/index.js +18 -0
- package/dist/node_modules/ses/lockdown-shim.js +1 -0
- package/dist/node_modules/ses/lockdown.js +1 -0
- package/dist/node_modules/ses/package.json +1 -0
- package/dist/node_modules/ses/src/assert-shim.js +4 -0
- package/dist/node_modules/ses/src/assert-sloppy-mode.js +11 -0
- package/dist/node_modules/ses/src/cauterize-property.js +69 -0
- package/dist/node_modules/ses/src/commons.js +425 -0
- package/dist/node_modules/ses/src/compartment-evaluate.js +93 -0
- package/dist/node_modules/ses/src/compartment-shim.js +22 -0
- package/dist/node_modules/ses/src/compartment.js +477 -0
- package/dist/node_modules/ses/src/console-shim.js +50 -0
- package/dist/node_modules/ses/src/enable-property-overrides.js +211 -0
- package/dist/node_modules/ses/src/enablements.js +244 -0
- package/dist/node_modules/ses/src/error/assert.js +584 -0
- package/dist/node_modules/ses/src/error/console.js +541 -0
- package/dist/node_modules/ses/src/error/fatal-assert.js +54 -0
- package/dist/node_modules/ses/src/error/internal-types.js +98 -0
- package/dist/node_modules/ses/src/error/note-log-args.js +77 -0
- package/dist/node_modules/ses/src/error/stringify-utils.js +195 -0
- package/dist/node_modules/ses/src/error/tame-console.js +197 -0
- package/dist/node_modules/ses/src/error/tame-error-constructor.js +284 -0
- package/dist/node_modules/ses/src/error/tame-v8-error-constructor.js +386 -0
- package/dist/node_modules/ses/src/error/types.js +59 -0
- package/dist/node_modules/ses/src/error/unhandled-rejection.js +122 -0
- package/dist/node_modules/ses/src/eval-scope.js +89 -0
- package/dist/node_modules/ses/src/get-anonymous-intrinsics.js +181 -0
- package/dist/node_modules/ses/src/get-source-url.js +50 -0
- package/dist/node_modules/ses/src/global-object.js +175 -0
- package/dist/node_modules/ses/src/intrinsics.js +192 -0
- package/dist/node_modules/ses/src/lockdown-shim.js +37 -0
- package/dist/node_modules/ses/src/lockdown.js +558 -0
- package/dist/node_modules/ses/src/make-eval-function.js +28 -0
- package/dist/node_modules/ses/src/make-evaluate.js +110 -0
- package/dist/node_modules/ses/src/make-function-constructor.js +79 -0
- package/dist/node_modules/ses/src/make-hardener.js +275 -0
- package/dist/node_modules/ses/src/make-safe-evaluator.js +112 -0
- package/dist/node_modules/ses/src/module-instance.js +497 -0
- package/dist/node_modules/ses/src/module-link.js +159 -0
- package/dist/node_modules/ses/src/module-load.js +719 -0
- package/dist/node_modules/ses/src/module-proxy.js +200 -0
- package/dist/node_modules/ses/src/permits-intrinsics.js +291 -0
- package/dist/node_modules/ses/src/permits.js +1761 -0
- package/dist/node_modules/ses/src/reporting-types.d.ts +13 -0
- package/dist/node_modules/ses/src/reporting.js +105 -0
- package/dist/node_modules/ses/src/scope-constants.js +180 -0
- package/dist/node_modules/ses/src/shim-arraybuffer-transfer.js +85 -0
- package/dist/node_modules/ses/src/sloppy-globals-scope-terminator.js +61 -0
- package/dist/node_modules/ses/src/strict-scope-terminator.js +99 -0
- package/dist/node_modules/ses/src/tame-date-constructor.js +127 -0
- package/dist/node_modules/ses/src/tame-domains.js +41 -0
- package/dist/node_modules/ses/src/tame-faux-data-properties.js +210 -0
- package/dist/node_modules/ses/src/tame-function-constructors.js +140 -0
- package/dist/node_modules/ses/src/tame-function-tostring.js +50 -0
- package/dist/node_modules/ses/src/tame-harden.js +29 -0
- package/dist/node_modules/ses/src/tame-locale-methods.js +78 -0
- package/dist/node_modules/ses/src/tame-math-object.js +41 -0
- package/dist/node_modules/ses/src/tame-module-source.js +51 -0
- package/dist/node_modules/ses/src/tame-regenerator-runtime.js +29 -0
- package/dist/node_modules/ses/src/tame-regexp-constructor.js +65 -0
- package/dist/node_modules/ses/src/tame-symbol-constructor.js +64 -0
- package/dist/node_modules/ses/src/transforms.js +267 -0
- package/dist/node_modules/ses/tools.js +25 -0
- package/dist/node_modules/ses/types.d.ts +606 -0
- package/dist/server/actions/ui-schema-action.d.ts +27 -0
- package/dist/server/actions/ui-schema-action.js +118 -0
- package/dist/server/collections/flowModelTreePath.d.ts +11 -0
- package/dist/server/collections/flowModelTreePath.js +74 -0
- package/dist/server/collections/flowModels.d.ts +11 -0
- package/dist/server/collections/flowModels.js +57 -0
- package/dist/server/collections/flowsql.d.ts +10 -0
- package/dist/server/collections/flowsql.js +51 -0
- package/dist/server/dao/ui_schema_node_dao.d.ts +26 -0
- package/dist/server/dao/ui_schema_node_dao.js +24 -0
- package/dist/server/helper.d.ts +8 -0
- package/dist/server/helper.js +9 -0
- package/dist/server/index.d.ts +9 -0
- package/dist/server/index.js +42 -0
- package/dist/server/model.d.ts +12 -0
- package/dist/server/model.js +38 -0
- package/dist/server/plugin.d.ts +26 -0
- package/dist/server/plugin.js +270 -0
- package/dist/server/repository.d.ts +116 -0
- package/dist/server/repository.js +1209 -0
- package/dist/server/server.d.ts +16 -0
- package/dist/server/server.js +198 -0
- package/dist/server/template/contexts.d.ts +73 -0
- package/dist/server/template/contexts.js +233 -0
- package/dist/server/template/resolver.d.ts +30 -0
- package/dist/server/template/resolver.js +225 -0
- package/dist/server/variables/registry.d.ts +42 -0
- package/dist/server/variables/registry.js +299 -0
- package/package.json +28 -0
- package/server.d.ts +2 -0
- package/server.js +1 -0
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
import {
|
|
2
|
+
FERAL_ERROR,
|
|
3
|
+
apply,
|
|
4
|
+
construct,
|
|
5
|
+
defineProperties,
|
|
6
|
+
setPrototypeOf,
|
|
7
|
+
getOwnPropertyDescriptor,
|
|
8
|
+
defineProperty,
|
|
9
|
+
getOwnPropertyDescriptors,
|
|
10
|
+
} from '../commons.js';
|
|
11
|
+
import { NativeErrors } from '../permits.js';
|
|
12
|
+
import { tameV8ErrorConstructor } from './tame-v8-error-constructor.js';
|
|
13
|
+
|
|
14
|
+
// Present on at least FF and XS. Proposed by Error-proposal. The original
|
|
15
|
+
// is dangerous, so tameErrorConstructor replaces it with a safe one.
|
|
16
|
+
// We grab the original here before it gets replaced.
|
|
17
|
+
const stackDesc = getOwnPropertyDescriptor(FERAL_ERROR.prototype, 'stack');
|
|
18
|
+
const stackGetter = stackDesc && stackDesc.get;
|
|
19
|
+
|
|
20
|
+
// Use concise methods to obtain named functions without constructors.
|
|
21
|
+
const tamedMethods = {
|
|
22
|
+
getStackString(error) {
|
|
23
|
+
if (typeof stackGetter === 'function') {
|
|
24
|
+
return apply(stackGetter, error, []);
|
|
25
|
+
} else if ('stack' in error) {
|
|
26
|
+
// The fallback is to just use the de facto `error.stack` if present
|
|
27
|
+
return `${error.stack}`;
|
|
28
|
+
}
|
|
29
|
+
return '';
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
let initialGetStackString = tamedMethods.getStackString;
|
|
33
|
+
|
|
34
|
+
export default function tameErrorConstructor(
|
|
35
|
+
errorTaming = 'safe',
|
|
36
|
+
stackFiltering = 'concise',
|
|
37
|
+
) {
|
|
38
|
+
const ErrorPrototype = FERAL_ERROR.prototype;
|
|
39
|
+
|
|
40
|
+
const { captureStackTrace: originalCaptureStackTrace } = FERAL_ERROR;
|
|
41
|
+
const platform =
|
|
42
|
+
typeof originalCaptureStackTrace === 'function' ? 'v8' : 'unknown';
|
|
43
|
+
|
|
44
|
+
const makeErrorConstructor = (_ = {}) => {
|
|
45
|
+
// eslint-disable-next-line no-shadow
|
|
46
|
+
const ResultError = function Error(...rest) {
|
|
47
|
+
let error;
|
|
48
|
+
if (new.target === undefined) {
|
|
49
|
+
error = apply(FERAL_ERROR, this, rest);
|
|
50
|
+
} else {
|
|
51
|
+
error = construct(FERAL_ERROR, rest, new.target);
|
|
52
|
+
}
|
|
53
|
+
if (platform === 'v8') {
|
|
54
|
+
// TODO Likely expensive!
|
|
55
|
+
apply(originalCaptureStackTrace, FERAL_ERROR, [error, ResultError]);
|
|
56
|
+
}
|
|
57
|
+
return error;
|
|
58
|
+
};
|
|
59
|
+
defineProperties(ResultError, {
|
|
60
|
+
length: { value: 1 },
|
|
61
|
+
prototype: {
|
|
62
|
+
value: ErrorPrototype,
|
|
63
|
+
writable: false,
|
|
64
|
+
enumerable: false,
|
|
65
|
+
configurable: false,
|
|
66
|
+
},
|
|
67
|
+
});
|
|
68
|
+
return ResultError;
|
|
69
|
+
};
|
|
70
|
+
const InitialError = makeErrorConstructor({ powers: 'original' });
|
|
71
|
+
const SharedError = makeErrorConstructor({ powers: 'none' });
|
|
72
|
+
defineProperties(ErrorPrototype, {
|
|
73
|
+
constructor: { value: SharedError },
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
for (const NativeError of NativeErrors) {
|
|
77
|
+
setPrototypeOf(NativeError, SharedError);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// https://v8.dev/docs/stack-trace-api#compatibility advises that
|
|
81
|
+
// programmers can "always" set `Error.stackTraceLimit`
|
|
82
|
+
// even on non-v8 platforms. On non-v8
|
|
83
|
+
// it will have no effect, but this advice only makes sense
|
|
84
|
+
// if the assignment itself does not fail, which it would
|
|
85
|
+
// if `Error` were naively frozen. Hence, we add setters that
|
|
86
|
+
// accept but ignore the assignment on non-v8 platforms.
|
|
87
|
+
defineProperties(InitialError, {
|
|
88
|
+
stackTraceLimit: {
|
|
89
|
+
get() {
|
|
90
|
+
if (typeof FERAL_ERROR.stackTraceLimit === 'number') {
|
|
91
|
+
// FERAL_ERROR.stackTraceLimit is only on v8
|
|
92
|
+
return FERAL_ERROR.stackTraceLimit;
|
|
93
|
+
}
|
|
94
|
+
return undefined;
|
|
95
|
+
},
|
|
96
|
+
set(newLimit) {
|
|
97
|
+
if (typeof newLimit !== 'number') {
|
|
98
|
+
// silently do nothing. This behavior doesn't precisely
|
|
99
|
+
// emulate v8 edge-case behavior. But given the purpose
|
|
100
|
+
// of this emulation, having edge cases err towards
|
|
101
|
+
// harmless seems the safer option.
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
if (typeof FERAL_ERROR.stackTraceLimit === 'number') {
|
|
105
|
+
// FERAL_ERROR.stackTraceLimit is only on v8
|
|
106
|
+
FERAL_ERROR.stackTraceLimit = newLimit;
|
|
107
|
+
// We place the useless return on the next line to ensure
|
|
108
|
+
// that anything we place after the if in the future only
|
|
109
|
+
// happens if the then-case does not.
|
|
110
|
+
// eslint-disable-next-line no-useless-return
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
},
|
|
114
|
+
// WTF on v8 stackTraceLimit is enumerable
|
|
115
|
+
enumerable: false,
|
|
116
|
+
configurable: true,
|
|
117
|
+
},
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
if (errorTaming === 'unsafe-debug' && platform === 'v8') {
|
|
121
|
+
// This case is a kludge to work around
|
|
122
|
+
// https://github.com/endojs/endo/issues/1798
|
|
123
|
+
// https://github.com/endojs/endo/issues/2348
|
|
124
|
+
// https://github.com/Agoric/agoric-sdk/issues/8662
|
|
125
|
+
|
|
126
|
+
defineProperties(InitialError, {
|
|
127
|
+
prepareStackTrace: {
|
|
128
|
+
get() {
|
|
129
|
+
return FERAL_ERROR.prepareStackTrace;
|
|
130
|
+
},
|
|
131
|
+
set(newPrepareStackTrace) {
|
|
132
|
+
FERAL_ERROR.prepareStackTrace = newPrepareStackTrace;
|
|
133
|
+
},
|
|
134
|
+
enumerable: false,
|
|
135
|
+
configurable: true,
|
|
136
|
+
},
|
|
137
|
+
captureStackTrace: {
|
|
138
|
+
value: FERAL_ERROR.captureStackTrace,
|
|
139
|
+
writable: true,
|
|
140
|
+
enumerable: false,
|
|
141
|
+
configurable: true,
|
|
142
|
+
},
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
const descs = getOwnPropertyDescriptors(InitialError);
|
|
146
|
+
defineProperties(SharedError, {
|
|
147
|
+
stackTraceLimit: descs.stackTraceLimit,
|
|
148
|
+
prepareStackTrace: descs.prepareStackTrace,
|
|
149
|
+
captureStackTrace: descs.captureStackTrace,
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
return {
|
|
153
|
+
'%InitialGetStackString%': initialGetStackString,
|
|
154
|
+
'%InitialError%': InitialError,
|
|
155
|
+
'%SharedError%': SharedError,
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// The default SharedError much be completely powerless even on v8,
|
|
160
|
+
// so the lenient `stackTraceLimit` accessor does nothing on all
|
|
161
|
+
// platforms.
|
|
162
|
+
defineProperties(SharedError, {
|
|
163
|
+
stackTraceLimit: {
|
|
164
|
+
get() {
|
|
165
|
+
return undefined;
|
|
166
|
+
},
|
|
167
|
+
set(_newLimit) {
|
|
168
|
+
// do nothing
|
|
169
|
+
},
|
|
170
|
+
enumerable: false,
|
|
171
|
+
configurable: true,
|
|
172
|
+
},
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
if (platform === 'v8') {
|
|
176
|
+
// `SharedError.prepareStackTrace`, if it exists, must also be
|
|
177
|
+
// powerless. However, from what we've heard, depd expects to be able to
|
|
178
|
+
// assign to it without the assignment throwing. It is normally a function
|
|
179
|
+
// that returns a stack string to be magically added to error objects.
|
|
180
|
+
// However, as long as we're adding a lenient standin, we may as well
|
|
181
|
+
// accommodate any who expect to get a function they can call and get
|
|
182
|
+
// a string back. This prepareStackTrace is a do-nothing function that
|
|
183
|
+
// always returns the empty string.
|
|
184
|
+
defineProperties(SharedError, {
|
|
185
|
+
prepareStackTrace: {
|
|
186
|
+
get() {
|
|
187
|
+
return () => '';
|
|
188
|
+
},
|
|
189
|
+
set(_prepareFn) {
|
|
190
|
+
// do nothing
|
|
191
|
+
},
|
|
192
|
+
enumerable: false,
|
|
193
|
+
configurable: true,
|
|
194
|
+
},
|
|
195
|
+
captureStackTrace: {
|
|
196
|
+
value: (errorish, _constructorOpt) => {
|
|
197
|
+
defineProperty(errorish, 'stack', {
|
|
198
|
+
value: '',
|
|
199
|
+
});
|
|
200
|
+
},
|
|
201
|
+
writable: false,
|
|
202
|
+
enumerable: false,
|
|
203
|
+
configurable: true,
|
|
204
|
+
},
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
if (platform === 'v8') {
|
|
209
|
+
initialGetStackString = tameV8ErrorConstructor(
|
|
210
|
+
FERAL_ERROR,
|
|
211
|
+
InitialError,
|
|
212
|
+
errorTaming,
|
|
213
|
+
stackFiltering,
|
|
214
|
+
);
|
|
215
|
+
} else if (errorTaming === 'unsafe' || errorTaming === 'unsafe-debug') {
|
|
216
|
+
// v8 has too much magic around their 'stack' own property for it to
|
|
217
|
+
// coexist cleanly with this accessor. So only install it on non-v8
|
|
218
|
+
|
|
219
|
+
// Error.prototype.stack property as proposed at
|
|
220
|
+
// https://tc39.es/proposal-error-stacks/
|
|
221
|
+
// with the fix proposed at
|
|
222
|
+
// https://github.com/tc39/proposal-error-stacks/issues/46
|
|
223
|
+
// On others, this still protects from the override mistake,
|
|
224
|
+
// essentially like enable-property-overrides.js would
|
|
225
|
+
// once this accessor property itself is frozen, as will happen
|
|
226
|
+
// later during lockdown.
|
|
227
|
+
//
|
|
228
|
+
// However, there is here a change from the intent in the current
|
|
229
|
+
// state of the proposal. If experience tells us whether this change
|
|
230
|
+
// is a good idea, we should modify the proposal accordingly. There is
|
|
231
|
+
// much code in the world that assumes `error.stack` is a string. So
|
|
232
|
+
// where the proposal accommodates secure operation by making the
|
|
233
|
+
// property optional, we instead accommodate secure operation by
|
|
234
|
+
// having the secure form always return only the stable part, the
|
|
235
|
+
// stringified error instance, and omitting all the frame information
|
|
236
|
+
// rather than omitting the property.
|
|
237
|
+
defineProperties(ErrorPrototype, {
|
|
238
|
+
stack: {
|
|
239
|
+
get() {
|
|
240
|
+
return initialGetStackString(this);
|
|
241
|
+
},
|
|
242
|
+
set(newValue) {
|
|
243
|
+
defineProperties(this, {
|
|
244
|
+
stack: {
|
|
245
|
+
value: newValue,
|
|
246
|
+
writable: true,
|
|
247
|
+
enumerable: true,
|
|
248
|
+
configurable: true,
|
|
249
|
+
},
|
|
250
|
+
});
|
|
251
|
+
},
|
|
252
|
+
},
|
|
253
|
+
});
|
|
254
|
+
} else {
|
|
255
|
+
// v8 has too much magic around their 'stack' own property for it to
|
|
256
|
+
// coexist cleanly with this accessor. So only install it on non-v8
|
|
257
|
+
defineProperties(ErrorPrototype, {
|
|
258
|
+
stack: {
|
|
259
|
+
get() {
|
|
260
|
+
// https://github.com/tc39/proposal-error-stacks/issues/46
|
|
261
|
+
// allows this to not add an unpleasant newline. Otherwise
|
|
262
|
+
// we should fix this.
|
|
263
|
+
return `${this}`;
|
|
264
|
+
},
|
|
265
|
+
set(newValue) {
|
|
266
|
+
defineProperties(this, {
|
|
267
|
+
stack: {
|
|
268
|
+
value: newValue,
|
|
269
|
+
writable: true,
|
|
270
|
+
enumerable: true,
|
|
271
|
+
configurable: true,
|
|
272
|
+
},
|
|
273
|
+
});
|
|
274
|
+
},
|
|
275
|
+
},
|
|
276
|
+
});
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
return {
|
|
280
|
+
'%InitialGetStackString%': initialGetStackString,
|
|
281
|
+
'%InitialError%': InitialError,
|
|
282
|
+
'%SharedError%': SharedError,
|
|
283
|
+
};
|
|
284
|
+
}
|
|
@@ -0,0 +1,386 @@
|
|
|
1
|
+
import {
|
|
2
|
+
WeakMap,
|
|
3
|
+
WeakSet,
|
|
4
|
+
apply,
|
|
5
|
+
arrayFilter,
|
|
6
|
+
arrayJoin,
|
|
7
|
+
arrayMap,
|
|
8
|
+
arraySlice,
|
|
9
|
+
create,
|
|
10
|
+
defineProperties,
|
|
11
|
+
fromEntries,
|
|
12
|
+
reflectSet,
|
|
13
|
+
regexpExec,
|
|
14
|
+
regexpTest,
|
|
15
|
+
weakmapGet,
|
|
16
|
+
weakmapSet,
|
|
17
|
+
weaksetAdd,
|
|
18
|
+
weaksetHas,
|
|
19
|
+
TypeError,
|
|
20
|
+
} from '../commons.js';
|
|
21
|
+
|
|
22
|
+
// Permit names from https://v8.dev/docs/stack-trace-api
|
|
23
|
+
// Permiting only the names used by error-stack-shim/src/v8StackFrames
|
|
24
|
+
// callSiteToFrame to shim the error stack proposal.
|
|
25
|
+
const safeV8CallSiteMethodNames = [
|
|
26
|
+
// suppress 'getThis' definitely
|
|
27
|
+
'getTypeName',
|
|
28
|
+
// suppress 'getFunction' definitely
|
|
29
|
+
'getFunctionName',
|
|
30
|
+
'getMethodName',
|
|
31
|
+
'getFileName',
|
|
32
|
+
'getLineNumber',
|
|
33
|
+
'getColumnNumber',
|
|
34
|
+
'getEvalOrigin',
|
|
35
|
+
'isToplevel',
|
|
36
|
+
'isEval',
|
|
37
|
+
'isNative',
|
|
38
|
+
'isConstructor',
|
|
39
|
+
'isAsync',
|
|
40
|
+
// suppress 'isPromiseAll' for now
|
|
41
|
+
// suppress 'getPromiseIndex' for now
|
|
42
|
+
|
|
43
|
+
// Additional names found by experiment, absent from
|
|
44
|
+
// https://v8.dev/docs/stack-trace-api
|
|
45
|
+
'getPosition',
|
|
46
|
+
'getScriptNameOrSourceURL',
|
|
47
|
+
|
|
48
|
+
'toString', // TODO replace to use only permitted info
|
|
49
|
+
];
|
|
50
|
+
|
|
51
|
+
// TODO this is a ridiculously expensive way to attenuate callsites.
|
|
52
|
+
// Before that matters, we should switch to a reasonable representation.
|
|
53
|
+
const safeV8CallSiteFacet = callSite => {
|
|
54
|
+
const methodEntry = name => {
|
|
55
|
+
const method = callSite[name];
|
|
56
|
+
return [name, () => apply(method, callSite, [])];
|
|
57
|
+
};
|
|
58
|
+
const o = fromEntries(arrayMap(safeV8CallSiteMethodNames, methodEntry));
|
|
59
|
+
return create(o, {});
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
const safeV8SST = sst => arrayMap(sst, safeV8CallSiteFacet);
|
|
63
|
+
|
|
64
|
+
// If it has `/node_modules/` anywhere in it, on Node it is likely
|
|
65
|
+
// to be a dependent package of the current package, and so to
|
|
66
|
+
// be an infrastructure frame to be dropped from concise stack traces.
|
|
67
|
+
const FILENAME_NODE_DEPENDENTS_CENSOR = /\/node_modules\//;
|
|
68
|
+
|
|
69
|
+
// If it begins with `internal/` or `node:internal` then it is likely
|
|
70
|
+
// part of the node infrustructre itself, to be dropped from concise
|
|
71
|
+
// stack traces.
|
|
72
|
+
const FILENAME_NODE_INTERNALS_CENSOR = /^(?:node:)?internal\//;
|
|
73
|
+
|
|
74
|
+
// Frames within SES `assert.js` should be dropped from concise stack traces, as
|
|
75
|
+
// these are just steps towards creating the error object in question.
|
|
76
|
+
const FILENAME_ASSERT_CENSOR = /\/packages\/ses\/src\/error\/assert\.js$/;
|
|
77
|
+
|
|
78
|
+
// Frames within the `eventual-send` shim should be dropped so that concise
|
|
79
|
+
// deep stacks omit the internals of the eventual-sending mechanism causing
|
|
80
|
+
// asynchronous messages to be sent.
|
|
81
|
+
// Note that the eventual-send package will move from agoric-sdk to
|
|
82
|
+
// Endo, so this rule will be of general interest.
|
|
83
|
+
const FILENAME_EVENTUAL_SEND_CENSOR = /\/packages\/eventual-send\/src\//;
|
|
84
|
+
|
|
85
|
+
// Frames within the `ses-ava` package should be dropped from concise stack
|
|
86
|
+
// traces, as they just support exposing error details to AVA.
|
|
87
|
+
const FILENAME_SES_AVA_CENSOR = /\/packages\/ses-ava\/src\/ses-ava-test\.js$/;
|
|
88
|
+
|
|
89
|
+
// Any stack frame whose `fileName` matches any of these censor patterns
|
|
90
|
+
// will be omitted from concise stacks.
|
|
91
|
+
// TODO Enable users to configure FILENAME_CENSORS via `lockdown` options.
|
|
92
|
+
const FILENAME_CENSORS = [
|
|
93
|
+
FILENAME_NODE_DEPENDENTS_CENSOR,
|
|
94
|
+
FILENAME_NODE_INTERNALS_CENSOR,
|
|
95
|
+
FILENAME_ASSERT_CENSOR,
|
|
96
|
+
FILENAME_EVENTUAL_SEND_CENSOR,
|
|
97
|
+
FILENAME_SES_AVA_CENSOR,
|
|
98
|
+
];
|
|
99
|
+
|
|
100
|
+
// Should a stack frame with this as its fileName be included in a concise
|
|
101
|
+
// stack trace?
|
|
102
|
+
// Exported only so it can be unit tested.
|
|
103
|
+
// TODO Move so that it applies not just to v8.
|
|
104
|
+
export const filterFileName = fileName => {
|
|
105
|
+
if (!fileName) {
|
|
106
|
+
// Stack frames with no fileName should appear in concise stack traces.
|
|
107
|
+
return true;
|
|
108
|
+
}
|
|
109
|
+
for (const filter of FILENAME_CENSORS) {
|
|
110
|
+
if (regexpTest(filter, fileName)) {
|
|
111
|
+
return false;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
return true;
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
// The ad-hoc rule of the current pattern is that any likely-file-path or
|
|
118
|
+
// likely url-path prefix, ending in a `/.../` should get dropped.
|
|
119
|
+
// Anything to the left of the likely path text is kept.
|
|
120
|
+
// Everything to the right of `/.../` is kept. Thus
|
|
121
|
+
// `'Object.bar (/vat-v1/.../eventual-send/test/deep-send.test.js:13:21)'`
|
|
122
|
+
// simplifies to
|
|
123
|
+
// `'Object.bar (eventual-send/test/deep-send.test.js:13:21)'`.
|
|
124
|
+
//
|
|
125
|
+
// See thread starting at
|
|
126
|
+
// https://github.com/Agoric/agoric-sdk/issues/2326#issuecomment-773020389
|
|
127
|
+
const CALLSITE_ELLIPSIS_PATTERN1 = /^((?:.*[( ])?)[:/\w_-]*\/\.\.\.\/(.+)$/;
|
|
128
|
+
|
|
129
|
+
// The ad-hoc rule of the current pattern is that any likely-file-path or
|
|
130
|
+
// likely url-path prefix consisting of `.../` should get dropped.
|
|
131
|
+
// Anything to the left of the likely path text is kept.
|
|
132
|
+
// Everything to the right of `.../` is kept. Thus
|
|
133
|
+
// `'Object.bar (.../eventual-send/test/deep-send.test.js:13:21)'`
|
|
134
|
+
// simplifies to
|
|
135
|
+
// `'Object.bar (eventual-send/test/deep-send.test.js:13:21)'`.
|
|
136
|
+
//
|
|
137
|
+
// See thread starting at
|
|
138
|
+
// https://github.com/Agoric/agoric-sdk/issues/2326#issuecomment-773020389
|
|
139
|
+
const CALLSITE_ELLIPSIS_PATTERN2 = /^((?:.*[( ])?)\.\.\.\/(.+)$/;
|
|
140
|
+
|
|
141
|
+
// The ad-hoc rule of the current pattern is that any likely-file-path or
|
|
142
|
+
// likely url-path prefix, ending in a `/` and prior to `package/` should get
|
|
143
|
+
// dropped.
|
|
144
|
+
// Anything to the left of the likely path prefix text is kept. `package/` and
|
|
145
|
+
// everything to its right is kept. Thus
|
|
146
|
+
// `'Object.bar (/Users/markmiller/src/ongithub/agoric/agoric-sdk/packages/eventual-send/test/deep-send.test.js:13:21)'`
|
|
147
|
+
// simplifies to
|
|
148
|
+
// `'Object.bar (packages/eventual-send/test/deep-send.test.js:13:21)'`.
|
|
149
|
+
// Note that `/packages/` is a convention for monorepos encouraged by
|
|
150
|
+
// lerna.
|
|
151
|
+
const CALLSITE_PACKAGES_PATTERN = /^((?:.*[( ])?)[:/\w_-]*\/(packages\/.+)$/;
|
|
152
|
+
|
|
153
|
+
// The ad-hoc rule of the current pattern is that any likely-file-path or
|
|
154
|
+
// likely url-path prefix of the form `file://` but not `file:///` gets
|
|
155
|
+
// dropped.
|
|
156
|
+
// Anything to the left of the likely path prefix text is kept. Everything to
|
|
157
|
+
// the right of `file://` is kept. Thus
|
|
158
|
+
// `'Object.bar (file:///Users/markmiller/src/ongithub/endojs/endo/packages/eventual-send/test/deep-send.test.js:13:21)'` is unchanged but
|
|
159
|
+
// `'Object.bar (file://test/deep-send.test.js:13:21)'`
|
|
160
|
+
|
|
161
|
+
// simplifies to
|
|
162
|
+
// `'Object.bar (test/deep-send.test.js:13:21)'`.
|
|
163
|
+
// The reason is that `file:///` usually precedes an absolute path which is
|
|
164
|
+
// clickable without removing the `file:///`, whereas `file://` usually precedes
|
|
165
|
+
// a relative path which, for whatever vscode reason, is not clickable until the
|
|
166
|
+
// `file://` is removed.
|
|
167
|
+
const CALLSITE_FILE_2SLASH_PATTERN = /^((?:.*[( ])?)file:\/\/([^/].*)$/;
|
|
168
|
+
|
|
169
|
+
// The use of these callSite patterns below assumes that any match will bind
|
|
170
|
+
// capture groups containing the parts of the original string we want
|
|
171
|
+
// to keep. The parts outside those capture groups will be dropped from concise
|
|
172
|
+
// stacks.
|
|
173
|
+
// TODO Enable users to configure CALLSITE_PATTERNS via `lockdown` options.
|
|
174
|
+
const CALLSITE_PATTERNS = [
|
|
175
|
+
CALLSITE_ELLIPSIS_PATTERN1,
|
|
176
|
+
CALLSITE_ELLIPSIS_PATTERN2,
|
|
177
|
+
CALLSITE_PACKAGES_PATTERN,
|
|
178
|
+
CALLSITE_FILE_2SLASH_PATTERN,
|
|
179
|
+
];
|
|
180
|
+
|
|
181
|
+
// For a stack frame that should be included in a concise stack trace, if
|
|
182
|
+
// `callSiteString` is the original stringified stack frame, return the
|
|
183
|
+
// possibly-shorter stringified stack frame that should be shown instead.
|
|
184
|
+
// Exported only so it can be unit tested.
|
|
185
|
+
// TODO Move so that it applies not just to v8.
|
|
186
|
+
/**
|
|
187
|
+
* @param {string} callSiteString
|
|
188
|
+
*/
|
|
189
|
+
export const shortenCallSiteString = callSiteString => {
|
|
190
|
+
for (const filter of CALLSITE_PATTERNS) {
|
|
191
|
+
const match = regexpExec(filter, callSiteString);
|
|
192
|
+
if (match) {
|
|
193
|
+
return arrayJoin(arraySlice(match, 1), '');
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
return callSiteString;
|
|
197
|
+
};
|
|
198
|
+
|
|
199
|
+
export const tameV8ErrorConstructor = (
|
|
200
|
+
OriginalError,
|
|
201
|
+
InitialError,
|
|
202
|
+
errorTaming,
|
|
203
|
+
stackFiltering,
|
|
204
|
+
) => {
|
|
205
|
+
if (errorTaming === 'unsafe-debug') {
|
|
206
|
+
throw TypeError(
|
|
207
|
+
'internal: v8+unsafe-debug special case should already be done',
|
|
208
|
+
);
|
|
209
|
+
}
|
|
210
|
+
// TODO: Proper CallSite types
|
|
211
|
+
/** @typedef {{}} CallSite */
|
|
212
|
+
|
|
213
|
+
const originalCaptureStackTrace = OriginalError.captureStackTrace;
|
|
214
|
+
|
|
215
|
+
const omitFrames =
|
|
216
|
+
stackFiltering === 'concise' || stackFiltering === 'omit-frames';
|
|
217
|
+
|
|
218
|
+
const shortenPaths =
|
|
219
|
+
stackFiltering === 'concise' || stackFiltering === 'shorten-paths';
|
|
220
|
+
|
|
221
|
+
// const callSiteFilter = _callSite => true;
|
|
222
|
+
const callSiteFilter = callSite => {
|
|
223
|
+
if (omitFrames) {
|
|
224
|
+
// eslint-disable-next-line @endo/no-polymorphic-call
|
|
225
|
+
return filterFileName(callSite.getFileName());
|
|
226
|
+
}
|
|
227
|
+
return true;
|
|
228
|
+
};
|
|
229
|
+
|
|
230
|
+
const callSiteStringifier = callSite => {
|
|
231
|
+
let callSiteString = `${callSite}`;
|
|
232
|
+
if (shortenPaths) {
|
|
233
|
+
callSiteString = shortenCallSiteString(callSiteString);
|
|
234
|
+
}
|
|
235
|
+
return `\n at ${callSiteString}`;
|
|
236
|
+
};
|
|
237
|
+
|
|
238
|
+
const stackStringFromSST = (_error, sst) =>
|
|
239
|
+
arrayJoin(
|
|
240
|
+
arrayMap(arrayFilter(sst, callSiteFilter), callSiteStringifier),
|
|
241
|
+
'',
|
|
242
|
+
);
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* @typedef {object} StructuredStackInfo
|
|
246
|
+
* @property {CallSite[]} callSites
|
|
247
|
+
* @property {undefined} [stackString]
|
|
248
|
+
*/
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* @typedef {object} ParsedStackInfo
|
|
252
|
+
* @property {undefined} [callSites]
|
|
253
|
+
* @property {string} stackString
|
|
254
|
+
*/
|
|
255
|
+
|
|
256
|
+
// Mapping from error instance to the stack for that instance.
|
|
257
|
+
// The stack info is either the structured stack trace
|
|
258
|
+
// or the generated tamed stack string
|
|
259
|
+
/** @type {WeakMap<Error, ParsedStackInfo | StructuredStackInfo>} */
|
|
260
|
+
const stackInfos = new WeakMap();
|
|
261
|
+
|
|
262
|
+
// Use concise methods to obtain named functions without constructors.
|
|
263
|
+
const tamedMethods = {
|
|
264
|
+
// The optional `optFn` argument is for cutting off the bottom of
|
|
265
|
+
// the stack --- for capturing the stack only above the topmost
|
|
266
|
+
// call to that function. Since this isn't the "real" captureStackTrace
|
|
267
|
+
// but instead calls the real one, if no other cutoff is provided,
|
|
268
|
+
// we cut this one off.
|
|
269
|
+
captureStackTrace(error, optFn = tamedMethods.captureStackTrace) {
|
|
270
|
+
if (typeof originalCaptureStackTrace === 'function') {
|
|
271
|
+
// OriginalError.captureStackTrace is only on v8
|
|
272
|
+
apply(originalCaptureStackTrace, OriginalError, [error, optFn]);
|
|
273
|
+
return;
|
|
274
|
+
}
|
|
275
|
+
reflectSet(error, 'stack', '');
|
|
276
|
+
},
|
|
277
|
+
// Shim of proposed special power, to reside by default only
|
|
278
|
+
// in the start compartment, for getting the stack traceback
|
|
279
|
+
// string associated with an error.
|
|
280
|
+
// See https://tc39.es/proposal-error-stacks/
|
|
281
|
+
getStackString(error) {
|
|
282
|
+
let stackInfo = weakmapGet(stackInfos, error);
|
|
283
|
+
|
|
284
|
+
if (stackInfo === undefined) {
|
|
285
|
+
// The following will call `prepareStackTrace()` synchronously
|
|
286
|
+
// which will populate stackInfos
|
|
287
|
+
// eslint-disable-next-line no-void
|
|
288
|
+
void error.stack;
|
|
289
|
+
stackInfo = weakmapGet(stackInfos, error);
|
|
290
|
+
if (!stackInfo) {
|
|
291
|
+
stackInfo = { stackString: '' };
|
|
292
|
+
weakmapSet(stackInfos, error, stackInfo);
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
// prepareStackTrace() may generate the stackString
|
|
297
|
+
// if errorTaming === 'unsafe'
|
|
298
|
+
|
|
299
|
+
if (stackInfo.stackString !== undefined) {
|
|
300
|
+
return stackInfo.stackString;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
const stackString = stackStringFromSST(error, stackInfo.callSites);
|
|
304
|
+
weakmapSet(stackInfos, error, { stackString });
|
|
305
|
+
|
|
306
|
+
return stackString;
|
|
307
|
+
},
|
|
308
|
+
prepareStackTrace(error, sst) {
|
|
309
|
+
if (errorTaming === 'unsafe') {
|
|
310
|
+
const stackString = stackStringFromSST(error, sst);
|
|
311
|
+
weakmapSet(stackInfos, error, { stackString });
|
|
312
|
+
return `${error}${stackString}`;
|
|
313
|
+
} else {
|
|
314
|
+
weakmapSet(stackInfos, error, { callSites: sst });
|
|
315
|
+
return '';
|
|
316
|
+
}
|
|
317
|
+
},
|
|
318
|
+
};
|
|
319
|
+
|
|
320
|
+
// A prepareFn is a prepareStackTrace function.
|
|
321
|
+
// An sst is a `structuredStackTrace`, which is an array of
|
|
322
|
+
// callsites.
|
|
323
|
+
// A user prepareFn is a prepareFn defined by a client of this API,
|
|
324
|
+
// and provided by assigning to `Error.prepareStackTrace`.
|
|
325
|
+
// A user prepareFn should only receive an attenuated sst, which
|
|
326
|
+
// is an array of attenuated callsites.
|
|
327
|
+
// A system prepareFn is the prepareFn created by this module to
|
|
328
|
+
// be installed on the real `Error` constructor, to receive
|
|
329
|
+
// an original sst, i.e., an array of unattenuated callsites.
|
|
330
|
+
// An input prepareFn is a function the user assigns to
|
|
331
|
+
// `Error.prepareStackTrace`, which might be a user prepareFn or
|
|
332
|
+
// a system prepareFn previously obtained by reading
|
|
333
|
+
// `Error.prepareStackTrace`.
|
|
334
|
+
|
|
335
|
+
const defaultPrepareFn = tamedMethods.prepareStackTrace;
|
|
336
|
+
|
|
337
|
+
OriginalError.prepareStackTrace = defaultPrepareFn;
|
|
338
|
+
|
|
339
|
+
// A weakset branding some functions as system prepareFns, all of which
|
|
340
|
+
// must be defined by this module, since they can receive an
|
|
341
|
+
// unattenuated sst.
|
|
342
|
+
const systemPrepareFnSet = new WeakSet([defaultPrepareFn]);
|
|
343
|
+
|
|
344
|
+
const systemPrepareFnFor = inputPrepareFn => {
|
|
345
|
+
if (weaksetHas(systemPrepareFnSet, inputPrepareFn)) {
|
|
346
|
+
return inputPrepareFn;
|
|
347
|
+
}
|
|
348
|
+
// Use concise methods to obtain named functions without constructors.
|
|
349
|
+
const systemMethods = {
|
|
350
|
+
prepareStackTrace(error, sst) {
|
|
351
|
+
weakmapSet(stackInfos, error, { callSites: sst });
|
|
352
|
+
return inputPrepareFn(error, safeV8SST(sst));
|
|
353
|
+
},
|
|
354
|
+
};
|
|
355
|
+
weaksetAdd(systemPrepareFnSet, systemMethods.prepareStackTrace);
|
|
356
|
+
return systemMethods.prepareStackTrace;
|
|
357
|
+
};
|
|
358
|
+
|
|
359
|
+
// Note `stackTraceLimit` accessor already defined by
|
|
360
|
+
// tame-error-constructor.js
|
|
361
|
+
defineProperties(InitialError, {
|
|
362
|
+
captureStackTrace: {
|
|
363
|
+
value: tamedMethods.captureStackTrace,
|
|
364
|
+
writable: true,
|
|
365
|
+
enumerable: false,
|
|
366
|
+
configurable: true,
|
|
367
|
+
},
|
|
368
|
+
prepareStackTrace: {
|
|
369
|
+
get() {
|
|
370
|
+
return OriginalError.prepareStackTrace;
|
|
371
|
+
},
|
|
372
|
+
set(inputPrepareStackTraceFn) {
|
|
373
|
+
if (typeof inputPrepareStackTraceFn === 'function') {
|
|
374
|
+
const systemPrepareFn = systemPrepareFnFor(inputPrepareStackTraceFn);
|
|
375
|
+
OriginalError.prepareStackTrace = systemPrepareFn;
|
|
376
|
+
} else {
|
|
377
|
+
OriginalError.prepareStackTrace = defaultPrepareFn;
|
|
378
|
+
}
|
|
379
|
+
},
|
|
380
|
+
enumerable: false,
|
|
381
|
+
configurable: true,
|
|
382
|
+
},
|
|
383
|
+
});
|
|
384
|
+
|
|
385
|
+
return tamedMethods.getStackString;
|
|
386
|
+
};
|