@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.
Files changed (125) hide show
  1. package/LICENSE +661 -0
  2. package/README.md +29 -0
  3. package/build.config.ts +22 -0
  4. package/client.d.ts +2 -0
  5. package/client.js +1 -0
  6. package/dist/client/index.d.ts +15 -0
  7. package/dist/client/index.js +10 -0
  8. package/dist/externalVersion.js +21 -0
  9. package/dist/index.d.ts +10 -0
  10. package/dist/index.js +48 -0
  11. package/dist/locale/en-US.json +61 -0
  12. package/dist/locale/index.d.ts +141 -0
  13. package/dist/locale/index.js +79 -0
  14. package/dist/locale/zh-CN.json +61 -0
  15. package/dist/node_modules/ses/LICENSE +201 -0
  16. package/dist/node_modules/ses/LICENSE-aura +16 -0
  17. package/dist/node_modules/ses/LICENSE-caja +13 -0
  18. package/dist/node_modules/ses/LICENSE-corejs +19 -0
  19. package/dist/node_modules/ses/LICENSE-v8 +9 -0
  20. package/dist/node_modules/ses/assert-shim.js +1 -0
  21. package/dist/node_modules/ses/compartment-shim.js +1 -0
  22. package/dist/node_modules/ses/console-shim.js +1 -0
  23. package/dist/node_modules/ses/dist/lockdown.cjs +13912 -0
  24. package/dist/node_modules/ses/dist/lockdown.umd.js +13912 -0
  25. package/dist/node_modules/ses/dist/lockdown.umd.min.js +1 -0
  26. package/dist/node_modules/ses/dist/ses-hermes.cjs +13912 -0
  27. package/dist/node_modules/ses/dist/ses.cjs +1 -0
  28. package/dist/node_modules/ses/dist/ses.umd.js +13912 -0
  29. package/dist/node_modules/ses/dist/ses.umd.min.js +1 -0
  30. package/dist/node_modules/ses/dist/types.d.cts +606 -0
  31. package/dist/node_modules/ses/index.js +18 -0
  32. package/dist/node_modules/ses/lockdown-shim.js +1 -0
  33. package/dist/node_modules/ses/lockdown.js +1 -0
  34. package/dist/node_modules/ses/package.json +1 -0
  35. package/dist/node_modules/ses/src/assert-shim.js +4 -0
  36. package/dist/node_modules/ses/src/assert-sloppy-mode.js +11 -0
  37. package/dist/node_modules/ses/src/cauterize-property.js +69 -0
  38. package/dist/node_modules/ses/src/commons.js +425 -0
  39. package/dist/node_modules/ses/src/compartment-evaluate.js +93 -0
  40. package/dist/node_modules/ses/src/compartment-shim.js +22 -0
  41. package/dist/node_modules/ses/src/compartment.js +477 -0
  42. package/dist/node_modules/ses/src/console-shim.js +50 -0
  43. package/dist/node_modules/ses/src/enable-property-overrides.js +211 -0
  44. package/dist/node_modules/ses/src/enablements.js +244 -0
  45. package/dist/node_modules/ses/src/error/assert.js +584 -0
  46. package/dist/node_modules/ses/src/error/console.js +541 -0
  47. package/dist/node_modules/ses/src/error/fatal-assert.js +54 -0
  48. package/dist/node_modules/ses/src/error/internal-types.js +98 -0
  49. package/dist/node_modules/ses/src/error/note-log-args.js +77 -0
  50. package/dist/node_modules/ses/src/error/stringify-utils.js +195 -0
  51. package/dist/node_modules/ses/src/error/tame-console.js +197 -0
  52. package/dist/node_modules/ses/src/error/tame-error-constructor.js +284 -0
  53. package/dist/node_modules/ses/src/error/tame-v8-error-constructor.js +386 -0
  54. package/dist/node_modules/ses/src/error/types.js +59 -0
  55. package/dist/node_modules/ses/src/error/unhandled-rejection.js +122 -0
  56. package/dist/node_modules/ses/src/eval-scope.js +89 -0
  57. package/dist/node_modules/ses/src/get-anonymous-intrinsics.js +181 -0
  58. package/dist/node_modules/ses/src/get-source-url.js +50 -0
  59. package/dist/node_modules/ses/src/global-object.js +175 -0
  60. package/dist/node_modules/ses/src/intrinsics.js +192 -0
  61. package/dist/node_modules/ses/src/lockdown-shim.js +37 -0
  62. package/dist/node_modules/ses/src/lockdown.js +558 -0
  63. package/dist/node_modules/ses/src/make-eval-function.js +28 -0
  64. package/dist/node_modules/ses/src/make-evaluate.js +110 -0
  65. package/dist/node_modules/ses/src/make-function-constructor.js +79 -0
  66. package/dist/node_modules/ses/src/make-hardener.js +275 -0
  67. package/dist/node_modules/ses/src/make-safe-evaluator.js +112 -0
  68. package/dist/node_modules/ses/src/module-instance.js +497 -0
  69. package/dist/node_modules/ses/src/module-link.js +159 -0
  70. package/dist/node_modules/ses/src/module-load.js +719 -0
  71. package/dist/node_modules/ses/src/module-proxy.js +200 -0
  72. package/dist/node_modules/ses/src/permits-intrinsics.js +291 -0
  73. package/dist/node_modules/ses/src/permits.js +1761 -0
  74. package/dist/node_modules/ses/src/reporting-types.d.ts +13 -0
  75. package/dist/node_modules/ses/src/reporting.js +105 -0
  76. package/dist/node_modules/ses/src/scope-constants.js +180 -0
  77. package/dist/node_modules/ses/src/shim-arraybuffer-transfer.js +85 -0
  78. package/dist/node_modules/ses/src/sloppy-globals-scope-terminator.js +61 -0
  79. package/dist/node_modules/ses/src/strict-scope-terminator.js +99 -0
  80. package/dist/node_modules/ses/src/tame-date-constructor.js +127 -0
  81. package/dist/node_modules/ses/src/tame-domains.js +41 -0
  82. package/dist/node_modules/ses/src/tame-faux-data-properties.js +210 -0
  83. package/dist/node_modules/ses/src/tame-function-constructors.js +140 -0
  84. package/dist/node_modules/ses/src/tame-function-tostring.js +50 -0
  85. package/dist/node_modules/ses/src/tame-harden.js +29 -0
  86. package/dist/node_modules/ses/src/tame-locale-methods.js +78 -0
  87. package/dist/node_modules/ses/src/tame-math-object.js +41 -0
  88. package/dist/node_modules/ses/src/tame-module-source.js +51 -0
  89. package/dist/node_modules/ses/src/tame-regenerator-runtime.js +29 -0
  90. package/dist/node_modules/ses/src/tame-regexp-constructor.js +65 -0
  91. package/dist/node_modules/ses/src/tame-symbol-constructor.js +64 -0
  92. package/dist/node_modules/ses/src/transforms.js +267 -0
  93. package/dist/node_modules/ses/tools.js +25 -0
  94. package/dist/node_modules/ses/types.d.ts +606 -0
  95. package/dist/server/actions/ui-schema-action.d.ts +27 -0
  96. package/dist/server/actions/ui-schema-action.js +118 -0
  97. package/dist/server/collections/flowModelTreePath.d.ts +11 -0
  98. package/dist/server/collections/flowModelTreePath.js +74 -0
  99. package/dist/server/collections/flowModels.d.ts +11 -0
  100. package/dist/server/collections/flowModels.js +57 -0
  101. package/dist/server/collections/flowsql.d.ts +10 -0
  102. package/dist/server/collections/flowsql.js +51 -0
  103. package/dist/server/dao/ui_schema_node_dao.d.ts +26 -0
  104. package/dist/server/dao/ui_schema_node_dao.js +24 -0
  105. package/dist/server/helper.d.ts +8 -0
  106. package/dist/server/helper.js +9 -0
  107. package/dist/server/index.d.ts +9 -0
  108. package/dist/server/index.js +42 -0
  109. package/dist/server/model.d.ts +12 -0
  110. package/dist/server/model.js +38 -0
  111. package/dist/server/plugin.d.ts +26 -0
  112. package/dist/server/plugin.js +270 -0
  113. package/dist/server/repository.d.ts +116 -0
  114. package/dist/server/repository.js +1209 -0
  115. package/dist/server/server.d.ts +16 -0
  116. package/dist/server/server.js +198 -0
  117. package/dist/server/template/contexts.d.ts +73 -0
  118. package/dist/server/template/contexts.js +233 -0
  119. package/dist/server/template/resolver.d.ts +30 -0
  120. package/dist/server/template/resolver.js +225 -0
  121. package/dist/server/variables/registry.d.ts +42 -0
  122. package/dist/server/variables/registry.js +299 -0
  123. package/package.json +28 -0
  124. package/server.d.ts +2 -0
  125. package/server.js +1 -0
@@ -0,0 +1,79 @@
1
+ import {
2
+ FERAL_FUNCTION,
3
+ arrayJoin,
4
+ arrayPop,
5
+ defineProperties,
6
+ getPrototypeOf,
7
+ } from './commons.js';
8
+ import { assert } from './error/assert.js';
9
+
10
+ const { Fail } = assert;
11
+
12
+ /*
13
+ * makeFunctionConstructor()
14
+ * A safe version of the native Function which relies on
15
+ * the safety of `safe-eval` for confinement, unless `no-eval`
16
+ * is specified (then a TypeError is thrown on use).
17
+ */
18
+ export const makeFunctionConstructor = evaluator => {
19
+ // Define an unused parameter to ensure Function.length === 1
20
+ const newFunction = function Function(_body) {
21
+ // Sanitize all parameters at the entry point.
22
+ // eslint-disable-next-line prefer-rest-params
23
+ const bodyText = `${arrayPop(arguments) || ''}`;
24
+ // eslint-disable-next-line prefer-rest-params
25
+ const parameters = `${arrayJoin(arguments, ',')}`;
26
+
27
+ // Are parameters and bodyText valid code, or is someone
28
+ // attempting an injection attack? This will throw a SyntaxError if:
29
+ // - parameters doesn't parse as parameters
30
+ // - bodyText doesn't parse as a function body
31
+ // - either contain a call to super() or references a super property.
32
+ //
33
+ // It seems that XS may still be vulnerable to the attack explained at
34
+ // https://github.com/tc39/ecma262/pull/2374#issuecomment-813769710
35
+ // where `new Function('/*', '*/ ) {')` would incorrectly validate.
36
+ // Before we worried about this, we check the parameters and bodyText
37
+ // together in one call
38
+ // ```js
39
+ // new FERAL_FUNCTION(parameters, bodyTest);
40
+ // ```
41
+ // However, this check is vulnerable to that bug. Aside from that case,
42
+ // all engines do seem to validate the parameters, taken by themselves,
43
+ // correctly. And all engines do seem to validate the bodyText, taken
44
+ // by itself correctly. So with the following two checks, SES builds a
45
+ // correct safe `Function` constructor by composing two calls to an
46
+ // original unsafe `Function` constructor that may suffer from this bug
47
+ // but is otherwise correctly validating.
48
+ //
49
+ // eslint-disable-next-line no-new
50
+ new FERAL_FUNCTION(parameters, '');
51
+ // eslint-disable-next-line no-new
52
+ new FERAL_FUNCTION(bodyText);
53
+
54
+ // Safe to be combined. Defeat potential trailing comments.
55
+ // TODO: since we create an anonymous function, the 'this' value
56
+ // isn't bound to the global object as per specs, but set as undefined.
57
+ const src = `(function anonymous(${parameters}\n) {\n${bodyText}\n})`;
58
+ return evaluator(src);
59
+ };
60
+
61
+ defineProperties(newFunction, {
62
+ // Ensure that any function created in any evaluator in a realm is an
63
+ // instance of Function in any evaluator of the same realm.
64
+ prototype: {
65
+ value: FERAL_FUNCTION.prototype,
66
+ writable: false,
67
+ enumerable: false,
68
+ configurable: false,
69
+ },
70
+ });
71
+
72
+ // Assert identity of Function.__proto__ accross all compartments
73
+ getPrototypeOf(FERAL_FUNCTION) === FERAL_FUNCTION.prototype ||
74
+ Fail`Function prototype is the same accross compartments`;
75
+ getPrototypeOf(newFunction) === FERAL_FUNCTION.prototype ||
76
+ Fail`Function constructor prototype is the same across compartments`;
77
+
78
+ return newFunction;
79
+ };
@@ -0,0 +1,275 @@
1
+ // Adapted from SES/Caja - Copyright (C) 2011 Google Inc.
2
+ // Copyright (C) 2018 Agoric
3
+
4
+ // Licensed under the Apache License, Version 2.0 (the "License");
5
+ // you may not use this file except in compliance with the License.
6
+ // You may obtain a copy of the License at
7
+ //
8
+ // http://www.apache.org/licenses/LICENSE-2.0
9
+ //
10
+ // Unless required by applicable law or agreed to in writing, software
11
+ // distributed under the License is distributed on an "AS IS" BASIS,
12
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ // See the License for the specific language governing permissions and
14
+ // limitations under the License.
15
+
16
+ // based upon:
17
+ // https://github.com/google/caja/blob/master/src/com/google/caja/ses/startSES.js
18
+ // https://github.com/google/caja/blob/master/src/com/google/caja/ses/repairES5.js
19
+ // then copied from proposal-frozen-realms deep-freeze.js
20
+ // then copied from SES/src/bundle/deepFreeze.js
21
+
22
+ // @ts-check
23
+
24
+ import {
25
+ Set,
26
+ String,
27
+ TypeError,
28
+ WeakSet,
29
+ globalThis,
30
+ apply,
31
+ arrayForEach,
32
+ defineProperty,
33
+ freeze,
34
+ getOwnPropertyDescriptor,
35
+ getOwnPropertyDescriptors,
36
+ getPrototypeOf,
37
+ isInteger,
38
+ isPrimitive,
39
+ hasOwn,
40
+ ownKeys,
41
+ preventExtensions,
42
+ setAdd,
43
+ setForEach,
44
+ setHas,
45
+ toStringTagSymbol,
46
+ typedArrayPrototype,
47
+ weaksetAdd,
48
+ weaksetHas,
49
+ FERAL_STACK_GETTER,
50
+ FERAL_STACK_SETTER,
51
+ isError,
52
+ } from './commons.js';
53
+ import { assert } from './error/assert.js';
54
+
55
+ /**
56
+ * @import {Harden} from '../types.js'
57
+ */
58
+
59
+ // Obtain the string tag accessor of of TypedArray so we can indirectly use the
60
+ // TypedArray brand check it employs.
61
+ const typedArrayToStringTag = getOwnPropertyDescriptor(
62
+ typedArrayPrototype,
63
+ toStringTagSymbol,
64
+ );
65
+ assert(typedArrayToStringTag);
66
+ const getTypedArrayToStringTag = typedArrayToStringTag.get;
67
+ assert(getTypedArrayToStringTag);
68
+
69
+ // Exported for tests.
70
+ /**
71
+ * Duplicates packages/marshal/src/helpers/passStyle-helpers.js to avoid a dependency.
72
+ *
73
+ * @param {unknown} object
74
+ */
75
+ export const isTypedArray = object => {
76
+ // The object must pass a brand check or toStringTag will return undefined.
77
+ const tag = apply(getTypedArrayToStringTag, object, []);
78
+ return tag !== undefined;
79
+ };
80
+
81
+ /**
82
+ * Tests if a property key is an integer-valued canonical numeric index.
83
+ * https://tc39.es/ecma262/#sec-canonicalnumericindexstring
84
+ *
85
+ * @param {string | symbol} propertyKey
86
+ */
87
+ const isCanonicalIntegerIndexString = propertyKey => {
88
+ const n = +String(propertyKey);
89
+ return isInteger(n) && String(n) === propertyKey;
90
+ };
91
+
92
+ /**
93
+ * @template T
94
+ * @param {ArrayLike<T>} array
95
+ */
96
+ const freezeTypedArray = array => {
97
+ preventExtensions(array);
98
+
99
+ // Downgrade writable expandos to readonly, even if non-configurable.
100
+ // We get each descriptor individually rather than using
101
+ // getOwnPropertyDescriptors in order to fail safe when encountering
102
+ // an obscure GraalJS issue where getOwnPropertyDescriptor returns
103
+ // undefined for a property that does exist.
104
+ arrayForEach(ownKeys(array), (/** @type {string | symbol} */ name) => {
105
+ const desc = getOwnPropertyDescriptor(array, name);
106
+ assert(desc);
107
+ // TypedArrays are integer-indexed exotic objects, which define special
108
+ // treatment for property names in canonical numeric form:
109
+ // integers in range are permanently writable and non-configurable.
110
+ // https://tc39.es/ecma262/#sec-integer-indexed-exotic-objects
111
+ //
112
+ // This is analogous to the data of a hardened Map or Set,
113
+ // so we carve out this exceptional behavior but make all other
114
+ // properties non-configurable.
115
+ if (!isCanonicalIntegerIndexString(name)) {
116
+ defineProperty(array, name, {
117
+ ...desc,
118
+ writable: false,
119
+ configurable: false,
120
+ });
121
+ }
122
+ });
123
+ };
124
+
125
+ /**
126
+ * Create a `harden` function.
127
+ *
128
+ * @returns {Harden}
129
+ */
130
+ export const makeHardener = () => {
131
+ // Use a native hardener if possible.
132
+ if (typeof globalThis.harden === 'function') {
133
+ const safeHarden = globalThis.harden;
134
+ return safeHarden;
135
+ }
136
+
137
+ const hardened = new WeakSet();
138
+
139
+ const { harden } = {
140
+ /**
141
+ * @template T
142
+ * @param {T} root
143
+ * @returns {T}
144
+ */
145
+ harden(root) {
146
+ const toFreeze = new Set();
147
+
148
+ // If val is something we should be freezing but aren't yet,
149
+ // add it to toFreeze.
150
+ /**
151
+ * @param {any} val
152
+ */
153
+ function enqueue(val) {
154
+ if (isPrimitive(val)) {
155
+ // ignore primitives
156
+ return;
157
+ }
158
+ const type = typeof val;
159
+ if (type !== 'object' && type !== 'function') {
160
+ // future proof: break until someone figures out what it should do
161
+ throw TypeError(`Unexpected typeof: ${type}`);
162
+ }
163
+ if (weaksetHas(hardened, val) || setHas(toFreeze, val)) {
164
+ // Ignore if this is an exit, or we've already visited it
165
+ return;
166
+ }
167
+ // console.warn(`adding ${val} to toFreeze`, val);
168
+ setAdd(toFreeze, val);
169
+ }
170
+
171
+ /**
172
+ * @param {any} obj
173
+ */
174
+ const baseFreezeAndTraverse = obj => {
175
+ // Now freeze the object to ensure reactive
176
+ // objects such as proxies won't add properties
177
+ // during traversal, before they get frozen.
178
+
179
+ // Object are verified before being enqueued,
180
+ // therefore this is a valid candidate.
181
+ // Throws if this fails (strict mode).
182
+ // Also throws if the object is an ArrayBuffer or any TypedArray.
183
+ if (isTypedArray(obj)) {
184
+ freezeTypedArray(obj);
185
+ } else {
186
+ freeze(obj);
187
+ }
188
+
189
+ // we rely upon certain commitments of Object.freeze and proxies here
190
+
191
+ // get stable/immutable outbound links before a Proxy has a chance to do
192
+ // something sneaky.
193
+ const descs = getOwnPropertyDescriptors(obj);
194
+ const proto = getPrototypeOf(obj);
195
+ enqueue(proto);
196
+
197
+ arrayForEach(ownKeys(descs), (/** @type {string | symbol} */ name) => {
198
+ // The 'name' may be a symbol, and TypeScript doesn't like us to
199
+ // index arbitrary symbols on objects, so we pretend they're just
200
+ // strings.
201
+ const desc = descs[/** @type {string} */ (name)];
202
+ // getOwnPropertyDescriptors is guaranteed to return well-formed
203
+ // descriptors, but they still inherit from Object.prototype. If
204
+ // someone has poisoned Object.prototype to add 'value' or 'get'
205
+ // properties, then a simple 'if ("value" in desc)' or 'desc.value'
206
+ // test could be confused. We use hasOwnProperty to be sure about
207
+ // whether 'value' is present or not, which tells us for sure that
208
+ // this is a data property.
209
+ if (hasOwn(desc, 'value')) {
210
+ enqueue(desc.value);
211
+ } else {
212
+ enqueue(desc.get);
213
+ enqueue(desc.set);
214
+ }
215
+ });
216
+ };
217
+
218
+ const freezeAndTraverse =
219
+ FERAL_STACK_GETTER === undefined && FERAL_STACK_SETTER === undefined
220
+ ? // On platforms without v8's error own stack accessor problem,
221
+ // don't pay for any extra overhead.
222
+ baseFreezeAndTraverse
223
+ : obj => {
224
+ if (isError(obj)) {
225
+ // Only pay the overhead if it first passes this cheap isError
226
+ // check. Otherwise, it will be unrepaired, but won't be judged
227
+ // to be a passable error anyway, so will not be unsafe.
228
+ const stackDesc = getOwnPropertyDescriptor(obj, 'stack');
229
+ if (
230
+ stackDesc &&
231
+ stackDesc.get === FERAL_STACK_GETTER &&
232
+ stackDesc.configurable
233
+ ) {
234
+ // Can only repair if it is configurable. Otherwise, leave
235
+ // unrepaired, in which case it will not be judged passable,
236
+ // avoiding a safety problem.
237
+ defineProperty(obj, 'stack', {
238
+ // NOTE: Calls getter during harden, which seems dangerous.
239
+ // But we're only calling the problematic getter whose
240
+ // hazards we think we understand.
241
+ // @ts-expect-error TS should know FERAL_STACK_GETTER
242
+ // cannot be `undefined` here.
243
+ // See https://github.com/endojs/endo/pull/2232#discussion_r1575179471
244
+ value: apply(FERAL_STACK_GETTER, obj, []),
245
+ });
246
+ }
247
+ }
248
+ return baseFreezeAndTraverse(obj);
249
+ };
250
+
251
+ const dequeue = () => {
252
+ // New values added before forEach() has finished will be visited.
253
+ setForEach(toFreeze, freezeAndTraverse);
254
+ };
255
+
256
+ /** @param {any} value */
257
+ const markHardened = value => {
258
+ weaksetAdd(hardened, value);
259
+ };
260
+
261
+ const commit = () => {
262
+ setForEach(toFreeze, markHardened);
263
+ };
264
+
265
+ enqueue(root);
266
+ dequeue();
267
+ // console.warn("toFreeze set:", toFreeze);
268
+ commit();
269
+
270
+ return root;
271
+ },
272
+ };
273
+
274
+ return harden;
275
+ };
@@ -0,0 +1,112 @@
1
+ // Portions adapted from V8 - Copyright 2016 the V8 project authors.
2
+ // https://github.com/v8/v8/blob/master/src/builtins/builtins-function.cc
3
+
4
+ import { apply, arrayFlatMap, freeze, identity } from './commons.js';
5
+ import { strictScopeTerminator } from './strict-scope-terminator.js';
6
+ import { createSloppyGlobalsScopeTerminator } from './sloppy-globals-scope-terminator.js';
7
+ import { makeEvalScopeKit } from './eval-scope.js';
8
+ import { applyTransforms, mandatoryTransforms } from './transforms.js';
9
+ import { makeEvaluate } from './make-evaluate.js';
10
+ import { assert } from './error/assert.js';
11
+
12
+ const { Fail } = assert;
13
+
14
+ /**
15
+ * makeSafeEvaluator()
16
+ * Build the low-level operation used by all evaluators:
17
+ * eval(), Function(), Compartment.prototype.evaluate().
18
+ *
19
+ * @param {object} options
20
+ * @param {object} options.globalObject
21
+ * @param {object} [options.moduleLexicals]
22
+ * @param {Array<import('./lockdown.js').Transform>} [options.globalTransforms]
23
+ * @param {boolean} [options.sloppyGlobalsMode]
24
+ */
25
+ export const makeSafeEvaluator = ({
26
+ globalObject,
27
+ moduleLexicals = {},
28
+ globalTransforms = [],
29
+ sloppyGlobalsMode = false,
30
+ }) => {
31
+ const scopeTerminator = sloppyGlobalsMode
32
+ ? createSloppyGlobalsScopeTerminator(globalObject)
33
+ : strictScopeTerminator;
34
+ const evalScopeKit = makeEvalScopeKit();
35
+ const { evalScope } = evalScopeKit;
36
+
37
+ const evaluateContext = freeze({
38
+ evalScope,
39
+ moduleLexicals,
40
+ globalObject,
41
+ scopeTerminator,
42
+ });
43
+
44
+ // Defer creating the actual evaluator to first use.
45
+ // Creating a compartment should be possible in no-eval environments
46
+ // It also allows more global constants to be captured by the optimizer
47
+ let evaluate;
48
+ const provideEvaluate = () => {
49
+ if (!evaluate) {
50
+ evaluate = makeEvaluate(evaluateContext);
51
+ }
52
+ };
53
+
54
+ /**
55
+ * @param {string} source
56
+ * @param {object} [options]
57
+ * @param {Array<import('./lockdown.js').Transform>} [options.localTransforms]
58
+ */
59
+ const safeEvaluate = (source, options) => {
60
+ const { localTransforms = [] } = options || {};
61
+ provideEvaluate();
62
+
63
+ // Execute the mandatory transforms last to ensure that any rewritten code
64
+ // meets those mandatory requirements.
65
+ source = applyTransforms(
66
+ source,
67
+ arrayFlatMap(
68
+ [localTransforms, globalTransforms, [mandatoryTransforms]],
69
+ identity,
70
+ ),
71
+ );
72
+
73
+ let err;
74
+ try {
75
+ // Allow next reference to eval produce the unsafe FERAL_EVAL.
76
+ // eslint-disable-next-line @endo/no-polymorphic-call
77
+ evalScopeKit.allowNextEvalToBeUnsafe();
78
+
79
+ // Ensure that "this" resolves to the safe global.
80
+ return apply(evaluate, globalObject, [source]);
81
+ } catch (e) {
82
+ // stash the child-code error in hopes of debugging the internal failure
83
+ err = e;
84
+ throw e;
85
+ } finally {
86
+ const unsafeEvalWasStillExposed = 'eval' in evalScope;
87
+ delete evalScope.eval;
88
+ if (unsafeEvalWasStillExposed) {
89
+ // Barring a defect in the SES shim, the evalScope should allow the
90
+ // powerful, unsafe `eval` to be used by `evaluate` exactly once, as the
91
+ // very first name that it attempts to access from the lexical scope.
92
+ // A defect in the SES shim could throw an exception after we set
93
+ // `evalScope.eval` and before `evaluate` calls `eval` internally.
94
+ // If we get here, SES is very broken.
95
+ // This condition is one where this vat is now hopelessly confused, and
96
+ // the vat as a whole should be aborted.
97
+ // No further code should run.
98
+ // All immediately reachable state should be abandoned.
99
+ // However, that is not yet possible, so we at least prevent further
100
+ // variable resolution via the scopeHandler, and throw an error with
101
+ // diagnostic info including the thrown error if any from evaluating the
102
+ // source code.
103
+ evalScopeKit.revoked = { err };
104
+ // TODO A GOOD PLACE TO PANIC(), i.e., kill the vat incarnation.
105
+ // See https://github.com/Agoric/SES-shim/issues/490
106
+ Fail`handler did not reset allowNextEvalToBeUnsafe ${err}`;
107
+ }
108
+ }
109
+ };
110
+
111
+ return { safeEvaluate };
112
+ };