@nocobase/plugin-flow-engine 2.0.0-alpha.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (127) 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 +25 -0
  112. package/dist/server/plugin.js +191 -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 +52 -0
  122. package/dist/server/variables/registry.js +333 -0
  123. package/dist/server/variables/utils.d.ts +17 -0
  124. package/dist/server/variables/utils.js +113 -0
  125. package/package.json +28 -0
  126. package/server.d.ts +2 -0
  127. package/server.js +1 -0
@@ -0,0 +1,584 @@
1
+ // Copyright (C) 2019 Agoric, under Apache License 2.0
2
+ // @ts-check
3
+
4
+ // To ensure that this module operates without special privilege, it should
5
+ // not reference the free variable `console` except for its own internal
6
+ // debugging purposes in the declaration of `internalDebugConsole`, which is
7
+ // normally commented out.
8
+
9
+ // This module however has top level mutable state which is observable to code
10
+ // given access to the `loggedErrorHandler`, such as the causal console
11
+ // of `console.js`. However, for code that does not have such access, this
12
+ // module should not be observably impure.
13
+
14
+ import {
15
+ RangeError,
16
+ TypeError,
17
+ WeakMap,
18
+ arrayJoin,
19
+ arrayMap,
20
+ arrayPop,
21
+ arrayPush,
22
+ assign,
23
+ freeze,
24
+ defineProperty,
25
+ globalThis,
26
+ is,
27
+ isError,
28
+ regexpTest,
29
+ stringIndexOf,
30
+ stringReplace,
31
+ stringSlice,
32
+ stringStartsWith,
33
+ weakmapDelete,
34
+ weakmapGet,
35
+ weakmapHas,
36
+ weakmapSet,
37
+ AggregateError,
38
+ getOwnPropertyDescriptors,
39
+ ownKeys,
40
+ create,
41
+ objectPrototype,
42
+ hasOwn,
43
+ } from '../commons.js';
44
+ import { an, bestEffortStringify } from './stringify-utils.js';
45
+ import './types.js';
46
+ import './internal-types.js';
47
+ import { makeNoteLogArgsArrayKit } from './note-log-args.js';
48
+
49
+ /**
50
+ * @import {BaseAssert, Assert, AssertionFunctions, AssertionUtilities, StringablePayload, DetailsToken, MakeAssert} from '../../types.js'
51
+ * @import {LogArgs, NoteCallback, LoggedErrorHandler} from "./internal-types.js";
52
+ */
53
+
54
+ // For our internal debugging purposes, uncomment
55
+ // const internalDebugConsole = console;
56
+
57
+ // /////////////////////////////////////////////////////////////////////////////
58
+
59
+ /** @type {WeakMap<StringablePayload, any>} */
60
+ const declassifiers = new WeakMap();
61
+
62
+ /** @type {AssertionUtilities['quote']} */
63
+ const quote = (payload, spaces = undefined) => {
64
+ const result = freeze({
65
+ toString: freeze(() => bestEffortStringify(payload, spaces)),
66
+ });
67
+ weakmapSet(declassifiers, result, payload);
68
+ return result;
69
+ };
70
+ freeze(quote);
71
+
72
+ const canBeBare = freeze(/^[\w:-]( ?[\w:-])*$/);
73
+
74
+ /**
75
+ * @type {AssertionUtilities['bare']}
76
+ */
77
+ const bare = (payload, spaces = undefined) => {
78
+ if (typeof payload !== 'string' || !regexpTest(canBeBare, payload)) {
79
+ return quote(payload, spaces);
80
+ }
81
+ const result = freeze({
82
+ toString: freeze(() => payload),
83
+ });
84
+ weakmapSet(declassifiers, result, payload);
85
+ return result;
86
+ };
87
+ freeze(bare);
88
+
89
+ // /////////////////////////////////////////////////////////////////////////////
90
+
91
+ /**
92
+ * @typedef {object} HiddenDetails
93
+ *
94
+ * Captures the arguments passed to the `details` template string tag.
95
+ *
96
+ * @property {TemplateStringsArray | string[]} template
97
+ * @property {any[]} args
98
+ */
99
+
100
+ /**
101
+ * @type {WeakMap<DetailsToken, HiddenDetails>}
102
+ *
103
+ * Maps from a details token which a `details` template literal returned
104
+ * to a record of the contents of that template literal expression.
105
+ */
106
+ const hiddenDetailsMap = new WeakMap();
107
+
108
+ /**
109
+ * @param {HiddenDetails} hiddenDetails
110
+ * @returns {string}
111
+ */
112
+ const getMessageString = ({ template, args }) => {
113
+ const parts = [template[0]];
114
+ for (let i = 0; i < args.length; i += 1) {
115
+ const arg = args[i];
116
+ let argStr;
117
+ if (weakmapHas(declassifiers, arg)) {
118
+ argStr = `${arg}`;
119
+ } else if (isError(arg)) {
120
+ argStr = `(${an(arg.name)})`;
121
+ } else {
122
+ argStr = `(${an(typeof arg)})`;
123
+ }
124
+ arrayPush(parts, argStr, template[i + 1]);
125
+ }
126
+ return arrayJoin(parts, '');
127
+ };
128
+
129
+ /**
130
+ * Give detailsTokens a toString behavior. To minimize the overhead of
131
+ * creating new detailsTokens, we do this with an
132
+ * inherited `this` sensitive `toString` method, even though we normally
133
+ * avoid `this` sensitivity. To protect the method from inappropriate
134
+ * `this` application, it does something interesting only for objects
135
+ * registered in `redactedDetails`, which should be exactly the detailsTokens.
136
+ *
137
+ * The printing behavior must not reveal anything redacted, so we just use
138
+ * the same `getMessageString` we use to construct the redacted message
139
+ * string for a thrown assertion error.
140
+ */
141
+ const DetailsTokenProto = freeze({
142
+ toString() {
143
+ const hiddenDetails = weakmapGet(hiddenDetailsMap, this);
144
+ if (hiddenDetails === undefined) {
145
+ return '[Not a DetailsToken]';
146
+ }
147
+ return getMessageString(hiddenDetails);
148
+ },
149
+ });
150
+ freeze(DetailsTokenProto.toString);
151
+
152
+ /**
153
+ * Normally this is the function exported as `assert.details` and often
154
+ * spelled `X`. However, if the `{errorTaming: 'unsafe'}` or
155
+ * `{errorTaming: 'unsafe-debug'}` option is
156
+ * given to `lockdown`, then `unredactedDetails` is used instead.
157
+ *
158
+ * There are some unconditional uses of `redactedDetails` in this module. All
159
+ * of them should be uses where the template literal has no redacted
160
+ * substitution values. In those cases, the two are equivalent.
161
+ *
162
+ * @type {AssertionUtilities['details']}
163
+ */
164
+ const redactedDetails = (template, ...args) => {
165
+ // Keep in mind that the vast majority of calls to `details` creates
166
+ // a details token that is never used, so this path must remain as fast as
167
+ // possible. Hence we store what we've got with little processing, postponing
168
+ // all the work to happen only if needed, for example, if an assertion fails.
169
+ const detailsToken = freeze({ __proto__: DetailsTokenProto });
170
+ weakmapSet(hiddenDetailsMap, detailsToken, { template, args });
171
+ return /** @type {DetailsToken} */ (/** @type {unknown} */ (detailsToken));
172
+ };
173
+ freeze(redactedDetails);
174
+
175
+ /**
176
+ * `unredactedDetails` is like `details` except that it does not redact
177
+ * anything. It acts like `details` would act if all substitution values
178
+ * were wrapped with the `quote` function above (the function normally
179
+ * spelled `q`). If the `{errorTaming: 'unsafe'}`
180
+ * or `{errorTaming: 'unsafe-debug'}` option is given to
181
+ * `lockdown`, then the lockdown-shim arranges for the global `assert` to be
182
+ * one whose `details` property is `unredactedDetails`.
183
+ * This setting optimizes the debugging and testing experience at the price
184
+ * of safety. `unredactedDetails` also sacrifices the speed of `details`,
185
+ * which is usually fine in debugging and testing.
186
+ *
187
+ * @type {AssertionUtilities['details']}
188
+ */
189
+ const unredactedDetails = (template, ...args) => {
190
+ args = arrayMap(args, arg =>
191
+ weakmapHas(declassifiers, arg) ? arg : quote(arg),
192
+ );
193
+ return redactedDetails(template, ...args);
194
+ };
195
+ freeze(unredactedDetails);
196
+ export { unredactedDetails };
197
+
198
+ /**
199
+ * @param {HiddenDetails} hiddenDetails
200
+ * @returns {LogArgs}
201
+ */
202
+ const getLogArgs = ({ template, args }) => {
203
+ const logArgs = [template[0]];
204
+ for (let i = 0; i < args.length; i += 1) {
205
+ let arg = args[i];
206
+ if (weakmapHas(declassifiers, arg)) {
207
+ arg = weakmapGet(declassifiers, arg);
208
+ }
209
+ // Remove the extra spaces (since console.error puts them
210
+ // between each cause).
211
+ const priorWithoutSpace = stringReplace(arrayPop(logArgs) || '', / $/, '');
212
+ if (priorWithoutSpace !== '') {
213
+ arrayPush(logArgs, priorWithoutSpace);
214
+ }
215
+ const nextWithoutSpace = stringReplace(template[i + 1], /^ /, '');
216
+ arrayPush(logArgs, arg, nextWithoutSpace);
217
+ }
218
+ if (logArgs[logArgs.length - 1] === '') {
219
+ arrayPop(logArgs);
220
+ }
221
+ return logArgs;
222
+ };
223
+
224
+ /**
225
+ * @type {WeakMap<Error, LogArgs>}
226
+ *
227
+ * Maps from an error object to the log args that are a more informative
228
+ * alternative message for that error. When logging the error, these
229
+ * log args should be preferred to `error.message`.
230
+ */
231
+ const hiddenMessageLogArgs = new WeakMap();
232
+
233
+ // So each error tag will be unique.
234
+ let errorTagNum = 0;
235
+
236
+ /**
237
+ * @type {WeakMap<Error, string>}
238
+ */
239
+ const errorTags = new WeakMap();
240
+
241
+ /**
242
+ * @param {Error} err
243
+ * @param {string=} optErrorName
244
+ * @returns {string}
245
+ */
246
+ const tagError = (err, optErrorName = err.name) => {
247
+ let errorTag = weakmapGet(errorTags, err);
248
+ if (errorTag !== undefined) {
249
+ return errorTag;
250
+ }
251
+ errorTagNum += 1;
252
+ errorTag = `${optErrorName}#${errorTagNum}`;
253
+ weakmapSet(errorTags, err, errorTag);
254
+ return errorTag;
255
+ };
256
+
257
+ /**
258
+ * Make reasonable best efforts to make a `Passable` error.
259
+ * - `sanitizeError` will remove any "extraneous" own properties already added
260
+ * by the host,
261
+ * such as `fileName`,`lineNumber` on FireFox or `line` on Safari.
262
+ * - If any such "extraneous" properties were removed, `sanitizeError` will
263
+ * annotate
264
+ * the error with them, so they still appear on the causal console
265
+ * log output for diagnostic purposes, but not be otherwise visible.
266
+ * - `sanitizeError` will ensure that any expected properties already
267
+ * added by the host are data
268
+ * properties, converting accessor properties to data properties as needed,
269
+ * such as `stack` on v8 (Chrome, Brave, Edge?)
270
+ * - `sanitizeError` will freeze the error, preventing any correct engine from
271
+ * adding or
272
+ * altering any of the error's own properties `sanitizeError` is done.
273
+ *
274
+ * However, `sanitizeError` will not, for example, `harden`
275
+ * (i.e., deeply freeze)
276
+ * or ensure that the `cause` or `errors` property satisfy the `Passable`
277
+ * constraints. The purpose of `sanitizeError` is only to protect against
278
+ * mischief the host may have already added to the error as created,
279
+ * not to ensure that the error is actually Passable. For that,
280
+ * see `toPassableError` in `@endo/pass-style`.
281
+ *
282
+ * @param {Error} error
283
+ */
284
+ export const sanitizeError = error => {
285
+ const descs = getOwnPropertyDescriptors(error);
286
+ const {
287
+ name: _nameDesc,
288
+ message: _messageDesc,
289
+ errors: _errorsDesc = undefined,
290
+ cause: _causeDesc = undefined,
291
+ stack: _stackDesc = undefined,
292
+ ...restDescs
293
+ } = descs;
294
+
295
+ const restNames = ownKeys(restDescs);
296
+ if (restNames.length >= 1) {
297
+ for (const name of restNames) {
298
+ delete error[name];
299
+ }
300
+ const droppedNote = create(objectPrototype, restDescs);
301
+ // eslint-disable-next-line no-use-before-define
302
+ note(
303
+ error,
304
+ redactedDetails`originally with properties ${quote(droppedNote)}`,
305
+ );
306
+ }
307
+ for (const name of ownKeys(error)) {
308
+ // @ts-expect-error TS still confused by symbols as property names
309
+ const desc = descs[name];
310
+ if (desc && hasOwn(desc, 'get')) {
311
+ defineProperty(error, name, {
312
+ value: error[name], // invoke the getter to convert to data property
313
+ });
314
+ }
315
+ }
316
+ freeze(error);
317
+ };
318
+
319
+ /**
320
+ * @type {AssertionUtilities['error']}
321
+ */
322
+ const makeError = (
323
+ optDetails = redactedDetails`Assert failed`,
324
+ errConstructor = globalThis.Error,
325
+ {
326
+ errorName = undefined,
327
+ cause = undefined,
328
+ errors = undefined,
329
+ sanitize = true,
330
+ } = {},
331
+ ) => {
332
+ if (typeof optDetails === 'string') {
333
+ // If it is a string, use it as the literal part of the template so
334
+ // it doesn't get quoted.
335
+ optDetails = redactedDetails([optDetails]);
336
+ }
337
+ const hiddenDetails = weakmapGet(hiddenDetailsMap, optDetails);
338
+ if (hiddenDetails === undefined) {
339
+ throw TypeError(`unrecognized details ${quote(optDetails)}`);
340
+ }
341
+ const messageString = getMessageString(hiddenDetails);
342
+ const opts = cause && { cause };
343
+ let error;
344
+ if (
345
+ typeof AggregateError !== 'undefined' &&
346
+ errConstructor === AggregateError
347
+ ) {
348
+ error = AggregateError(errors || [], messageString, opts);
349
+ } else {
350
+ error = /** @type {ErrorConstructor} */ (errConstructor)(
351
+ messageString,
352
+ opts,
353
+ );
354
+ if (errors !== undefined) {
355
+ // Since we need to tolerate `errors` on an AggregateError, may as
356
+ // well tolerate it on all errors.
357
+ defineProperty(error, 'errors', {
358
+ value: errors,
359
+ writable: true,
360
+ enumerable: false,
361
+ configurable: true,
362
+ });
363
+ }
364
+ }
365
+ weakmapSet(hiddenMessageLogArgs, error, getLogArgs(hiddenDetails));
366
+ if (errorName !== undefined) {
367
+ tagError(error, errorName);
368
+ }
369
+ if (sanitize) {
370
+ sanitizeError(error);
371
+ }
372
+ // The next line is a particularly fruitful place to put a breakpoint.
373
+ return error;
374
+ };
375
+ freeze(makeError);
376
+
377
+ // /////////////////////////////////////////////////////////////////////////////
378
+
379
+ const { addLogArgs, takeLogArgsArray } = makeNoteLogArgsArrayKit();
380
+
381
+ /**
382
+ * @type {WeakMap<Error, NoteCallback[]>}
383
+ *
384
+ * An augmented console will normally only take the hidden noteArgs array once,
385
+ * when it logs the error being annotated. Once that happens, further
386
+ * annotations of that error should go to the console immediately. We arrange
387
+ * that by accepting a note-callback function from the console as an optional
388
+ * part of that taking operation. Normally there will only be at most one
389
+ * callback per error, but that depends on console behavior which we should not
390
+ * assume. We make this an array of callbacks so multiple registrations
391
+ * are independent.
392
+ */
393
+ const hiddenNoteCallbackArrays = new WeakMap();
394
+
395
+ /** @type {AssertionUtilities['note']} */
396
+ const note = (error, detailsNote) => {
397
+ if (typeof detailsNote === 'string') {
398
+ // If it is a string, use it as the literal part of the template so
399
+ // it doesn't get quoted.
400
+ detailsNote = redactedDetails([detailsNote]);
401
+ }
402
+ const hiddenDetails = weakmapGet(hiddenDetailsMap, detailsNote);
403
+ if (hiddenDetails === undefined) {
404
+ throw TypeError(`unrecognized details ${quote(detailsNote)}`);
405
+ }
406
+ const logArgs = getLogArgs(hiddenDetails);
407
+ const callbacks = weakmapGet(hiddenNoteCallbackArrays, error);
408
+ if (callbacks !== undefined) {
409
+ for (const callback of callbacks) {
410
+ callback(error, logArgs);
411
+ }
412
+ } else {
413
+ addLogArgs(error, logArgs);
414
+ }
415
+ };
416
+ freeze(note);
417
+
418
+ /**
419
+ * The unprivileged form that just uses the de facto `error.stack` property.
420
+ * The start compartment normally has a privileged `globalThis.getStackString`
421
+ * which should be preferred if present.
422
+ *
423
+ * @param {Error} error
424
+ * @returns {string}
425
+ */
426
+ const defaultGetStackString = error => {
427
+ if (!('stack' in error)) {
428
+ return '';
429
+ }
430
+ const stackString = `${error.stack}`;
431
+ const pos = stringIndexOf(stackString, '\n');
432
+ if (stringStartsWith(stackString, ' ') || pos === -1) {
433
+ return stackString;
434
+ }
435
+ return stringSlice(stackString, pos + 1); // exclude the initial newline
436
+ };
437
+
438
+ /** @type {LoggedErrorHandler} */
439
+ const loggedErrorHandler = {
440
+ getStackString: globalThis.getStackString || defaultGetStackString,
441
+ tagError: error => tagError(error),
442
+ resetErrorTagNum: () => {
443
+ errorTagNum = 0;
444
+ },
445
+ getMessageLogArgs: error => weakmapGet(hiddenMessageLogArgs, error),
446
+ takeMessageLogArgs: error => {
447
+ const result = weakmapGet(hiddenMessageLogArgs, error);
448
+ weakmapDelete(hiddenMessageLogArgs, error);
449
+ return result;
450
+ },
451
+ takeNoteLogArgsArray: (error, callback) => {
452
+ const result = takeLogArgsArray(error);
453
+ if (callback !== undefined) {
454
+ const callbacks = weakmapGet(hiddenNoteCallbackArrays, error);
455
+ if (callbacks) {
456
+ arrayPush(callbacks, callback);
457
+ } else {
458
+ weakmapSet(hiddenNoteCallbackArrays, error, [callback]);
459
+ }
460
+ }
461
+ return result || [];
462
+ },
463
+ };
464
+ freeze(loggedErrorHandler);
465
+ export { loggedErrorHandler };
466
+
467
+ // /////////////////////////////////////////////////////////////////////////////
468
+
469
+ /**
470
+ * @type {MakeAssert}
471
+ */
472
+ const makeAssert = (optRaise = undefined, unredacted = false) => {
473
+ const details = unredacted ? unredactedDetails : redactedDetails;
474
+ const assertFailedDetails = details`Check failed`;
475
+
476
+ /** @type {AssertionFunctions['fail']} */
477
+ const fail = (
478
+ optDetails = assertFailedDetails,
479
+ errConstructor = undefined,
480
+ options = undefined,
481
+ ) => {
482
+ const reason = makeError(optDetails, errConstructor, options);
483
+ if (optRaise !== undefined) {
484
+ // @ts-ignore returns `never` doesn't mean it isn't callable
485
+ optRaise(reason);
486
+ }
487
+ throw reason;
488
+ };
489
+ freeze(fail);
490
+
491
+ /** @type {AssertionUtilities['Fail']} */
492
+ const Fail = (template, ...args) => fail(details(template, ...args));
493
+
494
+ // Don't freeze or export `baseAssert` until we add methods.
495
+ // TODO If I change this from a `function` function to an arrow
496
+ // function, I seem to get type errors from TypeScript. Why?
497
+ /** @type {BaseAssert} */
498
+ function baseAssert(
499
+ flag,
500
+ optDetails = undefined,
501
+ errConstructor = undefined,
502
+ options = undefined,
503
+ ) {
504
+ flag || fail(optDetails, errConstructor, options);
505
+ }
506
+
507
+ /** @type {AssertionFunctions['equal']} */
508
+ const equal = (
509
+ actual,
510
+ expected,
511
+ optDetails = undefined,
512
+ errConstructor = undefined,
513
+ options = undefined,
514
+ ) => {
515
+ is(actual, expected) ||
516
+ fail(
517
+ optDetails || details`Expected ${actual} is same as ${expected}`,
518
+ errConstructor || RangeError,
519
+ options,
520
+ );
521
+ };
522
+ freeze(equal);
523
+
524
+ /** @type {AssertionFunctions['typeof']} */
525
+ const assertTypeof = (specimen, typename, optDetails) => {
526
+ // This will safely fall through if typename is not a string,
527
+ // which is what we want.
528
+ // eslint-disable-next-line valid-typeof
529
+ if (typeof specimen === typename) {
530
+ return;
531
+ }
532
+ typeof typename === 'string' || Fail`${quote(typename)} must be a string`;
533
+
534
+ if (optDetails === undefined) {
535
+ // Embed the type phrase without quotes.
536
+ const typeWithDeterminer = an(typename);
537
+ optDetails = details`${specimen} must be ${bare(typeWithDeterminer)}`;
538
+ }
539
+ fail(optDetails, TypeError);
540
+ };
541
+ freeze(assertTypeof);
542
+
543
+ /** @type {AssertionFunctions['string']} */
544
+ const assertString = (specimen, optDetails = undefined) =>
545
+ assertTypeof(specimen, 'string', optDetails);
546
+
547
+ // Note that "assert === baseAssert"
548
+ /** @type {Assert} */
549
+ const assert = assign(baseAssert, {
550
+ error: makeError,
551
+ fail,
552
+ equal,
553
+ typeof: assertTypeof,
554
+ string: assertString,
555
+ note,
556
+ details,
557
+ Fail,
558
+ quote,
559
+ bare,
560
+ makeAssert,
561
+ });
562
+ return freeze(assert);
563
+ };
564
+ freeze(makeAssert);
565
+ export { makeAssert };
566
+
567
+ /** @type {Assert} */
568
+ const assert = makeAssert();
569
+ export { assert };
570
+
571
+ // Internal, to obviate polymorphic dispatch, but may become rigorously
572
+ // consistent with @endo/error:
573
+
574
+ /** @type {AssertionFunctions['equal']} */
575
+ const assertEqual = assert.equal;
576
+
577
+ export {
578
+ assertEqual,
579
+ makeError,
580
+ note as annotateError,
581
+ redactedDetails as X,
582
+ quote as q,
583
+ bare as b,
584
+ };