poe-code 14.0.64 → 14.0.66

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 (73) hide show
  1. package/dist/index.js +8832 -7273
  2. package/dist/index.js.map +4 -4
  3. package/dist/metafile.json +1 -1
  4. package/package.json +1 -1
  5. package/packages/safe-js/dist/chunks/{chunk-3EXDJDQM.js → chunk-MKTUVVEB.js} +2 -2
  6. package/packages/safe-js/dist/chunks/{chunk-XO7B4P27.js → chunk-YKISHTWT.js} +4474 -2978
  7. package/packages/safe-js/dist/chunks/chunk-YKISHTWT.js.map +7 -0
  8. package/packages/safe-js/dist/cli.js +2 -2
  9. package/packages/safe-js/dist/core.js +1 -1
  10. package/packages/safe-js/dist/index.js +2 -2
  11. package/packages/safe-js/dist/index.js.map +1 -1
  12. package/packages/safe-js/dist/interp/accessors.d.ts +9 -0
  13. package/packages/safe-js/dist/interp/accessors.js +68 -0
  14. package/packages/safe-js/dist/interp/async.d.ts +13 -2
  15. package/packages/safe-js/dist/interp/async.js +19 -9
  16. package/packages/safe-js/dist/interp/classes.d.ts +4 -0
  17. package/packages/safe-js/dist/interp/classes.js +182 -0
  18. package/packages/safe-js/dist/interp/exceptions.d.ts +1 -1
  19. package/packages/safe-js/dist/interp/exceptions.js +51 -9
  20. package/packages/safe-js/dist/interp/globals/collections.js +53 -16
  21. package/packages/safe-js/dist/interp/globals/console-json.js +41 -26
  22. package/packages/safe-js/dist/interp/globals/object-array.d.ts +2 -1
  23. package/packages/safe-js/dist/interp/globals/object-array.js +230 -69
  24. package/packages/safe-js/dist/interp/globals/object.js +13 -2
  25. package/packages/safe-js/dist/interp/globals/primitives.js +16 -5
  26. package/packages/safe-js/dist/interp/interpreter.d.ts +2 -2
  27. package/packages/safe-js/dist/interp/interpreter.js +168 -61
  28. package/packages/safe-js/dist/interp/iteration.js +13 -0
  29. package/packages/safe-js/dist/interp/methods/array.d.ts +1 -1
  30. package/packages/safe-js/dist/interp/methods/array.js +368 -109
  31. package/packages/safe-js/dist/interp/methods/function.d.ts +1 -1
  32. package/packages/safe-js/dist/interp/methods/function.js +56 -20
  33. package/packages/safe-js/dist/interp/methods/regex.js +1 -1
  34. package/packages/safe-js/dist/interp/object-model.d.ts +1 -0
  35. package/packages/safe-js/dist/interp/object-model.js +48 -10
  36. package/packages/safe-js/dist/interp/patterns.d.ts +3 -3
  37. package/packages/safe-js/dist/interp/patterns.js +36 -17
  38. package/packages/safe-js/dist/interp/promise.d.ts +1 -1
  39. package/packages/safe-js/dist/interp/promise.js +103 -63
  40. package/packages/safe-js/dist/interp/string-coercion.d.ts +1 -0
  41. package/packages/safe-js/dist/interp/string-coercion.js +47 -37
  42. package/packages/safe-js/dist/interp/values.d.ts +4 -2
  43. package/packages/safe-js/dist/interp/values.js +26 -1
  44. package/packages/safe-js/dist/lint/class-elements.d.ts +5 -0
  45. package/packages/safe-js/dist/lint/class-elements.js +20 -0
  46. package/packages/safe-js/dist/lint/rules/AS-async-not-needed.js +16 -0
  47. package/packages/safe-js/dist/lint/rules/AS-destructure-null-default.js +9 -0
  48. package/packages/safe-js/dist/lint/rules/AS-export-import-meta.js +9 -0
  49. package/packages/safe-js/dist/lint/rules/AS-floating-promise.js +9 -0
  50. package/packages/safe-js/dist/lint/rules/AS-frontmatter-field-unused.js +9 -0
  51. package/packages/safe-js/dist/lint/rules/AS-jsdoc-type.js +9 -0
  52. package/packages/safe-js/dist/lint/rules/AS-large-literal.js +9 -0
  53. package/packages/safe-js/dist/lint/rules/AS-missing-async.js +16 -0
  54. package/packages/safe-js/dist/lint/rules/AS-mutating-frozen.js +9 -0
  55. package/packages/safe-js/dist/lint/rules/AS-needless-template.js +9 -0
  56. package/packages/safe-js/dist/lint/rules/AS-shadow-global.js +12 -0
  57. package/packages/safe-js/dist/lint/rules/AS-unbounded-loop.js +11 -0
  58. package/packages/safe-js/dist/lint/rules/AS-unreachable.js +9 -0
  59. package/packages/safe-js/dist/lint/rules/AS-unused-import.js +16 -2
  60. package/packages/safe-js/dist/lint/rules/AS001.js +0 -1
  61. package/packages/safe-js/dist/lint/rules/AS003.js +16 -2
  62. package/packages/safe-js/dist/lint/rules/AS006-007.js +16 -2
  63. package/packages/safe-js/dist/lint/rules/AS009.js +20 -1
  64. package/packages/safe-js/dist/lint/rules/AS010.js +9 -0
  65. package/packages/safe-js/dist/lint/rules/AS011.js +9 -0
  66. package/packages/safe-js/dist/lint/rules/AS015.js +9 -0
  67. package/packages/safe-js/dist/parse/function-source.d.ts +2 -2
  68. package/packages/safe-js/dist/parse/parser.d.ts +42 -2
  69. package/packages/safe-js/dist/parse/parser.js +208 -35
  70. package/packages/safe-js/dist/parse/tokenizer.js +3 -0
  71. package/packages/safe-js/dist/parse.d.ts +1 -1
  72. package/packages/safe-js/dist/chunks/chunk-XO7B4P27.js.map +0 -7
  73. /package/packages/safe-js/dist/chunks/{chunk-3EXDJDQM.js.map → chunk-MKTUVVEB.js.map} +0 -0
@@ -2,7 +2,9 @@ import { attachErrorSpan, attachWrappedErrorCause, describeThrownValue, formatEr
2
2
  import { isFatalSandboxError, SandboxError } from "./budget.js";
3
3
  import { HostCallResumabilityError } from "./host-call.js";
4
4
  import { withFatalPromiseCleanup } from "./promise-tracker.js";
5
- import { deepCopyToSandbox, ownEnumerableSandboxEntries } from "./values.js";
5
+ import { deepCopyToSandbox, ownEnumerableSandboxKeys } from "./values.js";
6
+ import { hasOwnSandboxProperty } from "./globals/object.js";
7
+ import { retainValues } from "./resources.js";
6
8
  import { getSandboxDataProperty } from "./object-model.js";
7
9
  import { toPropertyKey } from "./property-key.js";
8
10
  const capturedExceptionBrand = Symbol("CapturedException");
@@ -371,7 +373,10 @@ async function bindPattern(pattern, value, context, evaluateNode) {
371
373
  async function bindAssignmentPattern(pattern, value, context, evaluateNode) {
372
374
  let nextValue = value;
373
375
  if (nextValue === undefined) {
374
- const defaultValue = await evaluateNode(pattern.right, context);
376
+ const defaultValue = await evaluateNode(pattern.right, {
377
+ ...context,
378
+ inferredName: pattern.left.type === "Identifier" ? pattern.left.name : undefined
379
+ });
375
380
  if (defaultValue.kind !== "normal") {
376
381
  return {
377
382
  ok: false,
@@ -386,12 +391,38 @@ async function bindArrayPattern(pattern, value, context, evaluateNode) {
386
391
  if (!Array.isArray(value)) {
387
392
  throw new TypeError("Array catch bindings require an array value.");
388
393
  }
394
+ let cursor = 0;
395
+ let done = false;
396
+ const next = async () => {
397
+ if (done || cursor >= value.length) {
398
+ done = true;
399
+ return { done: true, value: undefined };
400
+ }
401
+ const key = cursor++;
402
+ return {
403
+ done: false,
404
+ value: context.getProperty === undefined
405
+ ? getSandboxDataProperty(value, key, context.budget)
406
+ : await context.getProperty(value, key)
407
+ };
408
+ };
389
409
  for (let index = 0; index < pattern.elements.length; index += 1) {
390
410
  const element = pattern.elements[index];
391
411
  if (element === null) {
412
+ await next();
392
413
  continue;
393
414
  }
394
- const elementValue = element.type === "RestElement" ? value.slice(index) : value[index];
415
+ let elementValue;
416
+ if (element.type === "RestElement") {
417
+ const rest = [];
418
+ for (let entry = await next(); !entry.done; entry = await next()) {
419
+ context.budget.allocateArrayLength(rest.length + 1);
420
+ rest.push(entry.value);
421
+ }
422
+ elementValue = rest;
423
+ }
424
+ else
425
+ elementValue = (await next()).value;
395
426
  const binding = await bindPattern(element, elementValue, context, evaluateNode);
396
427
  if (!binding.ok) {
397
428
  return binding;
@@ -406,7 +437,7 @@ async function bindObjectPattern(pattern, value, context, evaluateNode) {
406
437
  const excludedKeys = new Set();
407
438
  for (const property of pattern.properties) {
408
439
  if (property.type === "RestElement") {
409
- const restValue = copyObjectRest(value, excludedKeys);
440
+ const restValue = await copyObjectRest(value, excludedKeys, context);
410
441
  const binding = await bindPattern(property, restValue, context, evaluateNode);
411
442
  if (!binding.ok) {
412
443
  return binding;
@@ -420,7 +451,7 @@ async function bindObjectPattern(pattern, value, context, evaluateNode) {
420
451
  excludedKeys.add(String(key.value));
421
452
  const binding = await bindPattern(property.value, context.getProperty === undefined
422
453
  ? getSandboxDataProperty(value, key.value, context.budget)
423
- : context.getProperty(value, key.value), context, evaluateNode);
454
+ : await context.getProperty(value, key.value), context, evaluateNode);
424
455
  if (!binding.ok) {
425
456
  return binding;
426
457
  }
@@ -457,10 +488,21 @@ function getStaticPropertyKey(property) {
457
488
  throw new TypeError(`Unsupported catch binding property key '${property.type}'.`);
458
489
  }
459
490
  }
460
- function copyObjectRest(value, excludedKeys) {
491
+ async function copyObjectRest(value, excludedKeys, context) {
461
492
  const rest = Object.create(null);
462
- for (const [key, entryValue] of ownEnumerableSandboxEntries(value, excludedKeys)) {
463
- rest[key] = entryValue;
493
+ const release = retainValues(context.budget, () => [value, rest]);
494
+ try {
495
+ for (const key of ownEnumerableSandboxKeys(value)) {
496
+ if (excludedKeys.has(key) || !hasOwnSandboxProperty(value, key, true))
497
+ continue;
498
+ rest[key] =
499
+ context.getProperty === undefined
500
+ ? getSandboxDataProperty(value, key, context.budget)
501
+ : await context.getProperty(value, key);
502
+ }
503
+ return rest;
504
+ }
505
+ finally {
506
+ release();
464
507
  }
465
- return rest;
466
508
  }
@@ -17,20 +17,34 @@ export function createCollectionGlobals(options) {
17
17
  let key;
18
18
  let value;
19
19
  return populateCollection(source, map, {
20
- name: "Map", budget: options.budget, context,
20
+ name: "Map",
21
+ budget: options.budget,
22
+ context,
21
23
  retainedValues: () => [key, value],
22
24
  append: (entry) => {
23
25
  if (typeof entry !== "object" || entry === null)
24
26
  throw new TypeError("Map constructor requires entry objects.");
25
- key = context?.getProperty !== undefined ? context.getProperty(entry, 0) : getSandboxDataProperty(entry, 0, options.budget);
26
- value = context?.getProperty !== undefined ? context.getProperty(entry, 1) : getSandboxDataProperty(entry, 1, options.budget);
27
- const added = map.entries.has(key) ? 0 : 1;
28
- const growth = added +
29
- (options.budget.limits.dataSize === undefined ? 0 : measureSandboxData([key, value]));
30
- options.budget.allocateCollectionEntries(map.entries.size + added);
31
- map.entries.set(key, value);
32
- key = value = undefined;
33
- return growth;
27
+ const store = (entryValue) => {
28
+ value = entryValue;
29
+ const added = map.entries.has(key) ? 0 : 1;
30
+ const growth = added +
31
+ (options.budget.limits.dataSize === undefined ? 0 : measureSandboxData([key, value]));
32
+ options.budget.allocateCollectionEntries(map.entries.size + added);
33
+ map.entries.set(key, value);
34
+ key = value = undefined;
35
+ return growth;
36
+ };
37
+ const readValue = (entryKey) => {
38
+ key = entryKey;
39
+ const result = context?.getProperty !== undefined
40
+ ? context.getProperty(entry, 1)
41
+ : getSandboxDataProperty(entry, 1, options.budget);
42
+ return result instanceof Promise ? result.then(store) : store(result);
43
+ };
44
+ const result = context?.getProperty !== undefined
45
+ ? context.getProperty(entry, 0)
46
+ : getSandboxDataProperty(entry, 0, options.budget);
47
+ return result instanceof Promise ? result.then(readValue) : readValue(result);
34
48
  }
35
49
  });
36
50
  },
@@ -44,7 +58,9 @@ export function createCollectionGlobals(options) {
44
58
  construct: ([source], context) => {
45
59
  const set = createSandboxSet([]);
46
60
  return populateCollection(source, set, {
47
- name: "Set", budget: options.budget, context,
61
+ name: "Set",
62
+ budget: options.budget,
63
+ context,
48
64
  append: (value) => {
49
65
  const added = set.values.has(value) ? 0 : 1;
50
66
  const growth = added +
@@ -77,7 +93,14 @@ function populateCollection(source, collection, { name, budget, context, append,
77
93
  let entry;
78
94
  let failure;
79
95
  const retained = {};
80
- budget.setRetainedValues(retained, () => [source, iterator.retainedValue, collection, entry, failure, ...(retainedValues?.() ?? [])]);
96
+ budget.setRetainedValues(retained, () => [
97
+ source,
98
+ iterator.retainedValue,
99
+ collection,
100
+ entry,
101
+ failure,
102
+ ...(retainedValues?.() ?? [])
103
+ ]);
81
104
  const checkData = createDataCheckpoint(budget, context);
82
105
  const closeOnThrow = (error) => {
83
106
  failure = isCapturedException(error) ? error.reason : error;
@@ -89,7 +112,9 @@ function populateCollection(source, collection, { name, budget, context, append,
89
112
  try {
90
113
  const closing = iterator.return?.();
91
114
  if (iterator.generator || iterator.asynchronous)
92
- return Promise.resolve(closing).then(() => { throw error; }, rethrow);
115
+ return Promise.resolve(closing).then(() => {
116
+ throw error;
117
+ }, rethrow);
93
118
  }
94
119
  catch (closeError) {
95
120
  return rethrow(closeError);
@@ -105,6 +130,14 @@ function populateCollection(source, collection, { name, budget, context, append,
105
130
  try {
106
131
  budget.visitNode();
107
132
  const growth = append(entry);
133
+ if (growth instanceof Promise)
134
+ return growth
135
+ .then((size) => {
136
+ entry = undefined;
137
+ checkData(collection, size);
138
+ return false;
139
+ })
140
+ .catch(closeOnThrow);
108
141
  entry = undefined;
109
142
  checkData(collection, growth);
110
143
  }
@@ -113,11 +146,13 @@ function populateCollection(source, collection, { name, budget, context, append,
113
146
  }
114
147
  return false;
115
148
  };
116
- if (iterator.generator || iterator.asynchronous) {
149
+ if (iterator.generator || iterator.asynchronous || context !== undefined) {
117
150
  return (async () => {
118
151
  try {
119
152
  checkData(collection, 0, true);
120
- while (!(await consume(await iterator.next()))) { /* Consume each entry before advancing. */ }
153
+ while (!(await consume(await iterator.next()))) {
154
+ /* Consume each entry before advancing. */
155
+ }
121
156
  checkData(collection, 0, true);
122
157
  return collection;
123
158
  }
@@ -128,7 +163,9 @@ function populateCollection(source, collection, { name, budget, context, append,
128
163
  }
129
164
  try {
130
165
  checkData(collection, 0, true);
131
- while (!consume(iterator.next())) { /* Synchronous inputs stay synchronous. */ }
166
+ while (!consume(iterator.next())) {
167
+ /* Synchronous inputs stay synchronous. */
168
+ }
132
169
  checkData(collection, 0, true);
133
170
  return collection;
134
171
  }
@@ -1,3 +1,6 @@
1
+ import { retainValues } from "../resources.js";
2
+ import { readPropertyDescriptor } from "../accessors.js";
3
+ import { getSandboxPropertyDescriptor } from "../object-model.js";
1
4
  import { dateMethods, isSandboxDate } from "../date.js";
2
5
  import { boxedValue, isSandboxBox } from "../boxed.js";
3
6
  import { sandboxNumber, sandboxString } from "../string-coercion.js";
@@ -96,27 +99,36 @@ async function stringifyJson(value, replacer, indent, budget, context) {
96
99
  return budget.allocateString(output);
97
100
  }
98
101
  async function stringifyProperty(key, holder, state, indent = "") {
99
- let value = getOwnDataValue(holder, key);
100
- if (isSandboxDate(value)) {
101
- value = dateMethods.get("toJSON").invoke(value, []);
102
- }
103
- else if (isStringifyContainer(value)) {
104
- const toJSON = getOwnDataValue(value, "toJSON");
105
- if (isSandboxClosure(toJSON)) {
106
- value = await callStringifyClosure(toJSON, [key], value, state);
102
+ let value = await getStringifyProperty(holder, key, state);
103
+ const release = retainValues(state.budget, () => [holder, value]);
104
+ try {
105
+ if (isSandboxDate(value)) {
106
+ value = dateMethods.get("toJSON").invoke(value, []);
107
+ }
108
+ else if (isStringifyContainer(value)) {
109
+ const toJSON = await getStringifyProperty(value, "toJSON", state);
110
+ if (isSandboxClosure(toJSON)) {
111
+ value = await callStringifyClosure(toJSON, [key], value, state);
112
+ }
113
+ }
114
+ if (state.replacer !== undefined) {
115
+ value = await callStringifyClosure(state.replacer, [key, toSandboxValue(value)], holder, state);
107
116
  }
117
+ return await stringifyValue(value, state, indent);
108
118
  }
109
- if (state.replacer !== undefined) {
110
- value = await callStringifyClosure(state.replacer, [key, toSandboxValue(value)], holder, state);
119
+ finally {
120
+ release();
111
121
  }
112
- return stringifyValue(value, state, indent);
113
122
  }
114
123
  async function stringifyValue(value, state, indent) {
115
124
  if (isSandboxBox(value)) {
116
125
  const primitive = boxedValue(value);
117
- value = typeof primitive === "number" ? await sandboxNumber(value, state.budget, state.context)
118
- : typeof primitive === "string" ? await sandboxString(value, state.budget, state.context)
119
- : primitive;
126
+ value =
127
+ typeof primitive === "number"
128
+ ? await sandboxNumber(value, state.budget, state.context)
129
+ : typeof primitive === "string"
130
+ ? await sandboxString(value, state.budget, state.context)
131
+ : primitive;
120
132
  }
121
133
  if (value === null) {
122
134
  return "null";
@@ -148,10 +160,12 @@ async function stringifyValue(value, state, indent) {
148
160
  }
149
161
  async function stringifyArray(value, state, indent) {
150
162
  enterStringifyObject(value, state);
163
+ const entries = [];
164
+ const release = retainValues(state.budget, () => entries);
151
165
  try {
152
166
  const nextIndent = indent + state.gap;
153
- const entries = [];
154
- for (let index = 0; index < value.length; index += 1) {
167
+ const length = value.length;
168
+ for (let index = 0; index < length; index += 1) {
155
169
  entries.push((await stringifyProperty(String(index), value, state, nextIndent)) ?? "null");
156
170
  }
157
171
  if (entries.length === 0) {
@@ -163,14 +177,16 @@ async function stringifyArray(value, state, indent) {
163
177
  return `[\n${nextIndent}${entries.join(`,\n${nextIndent}`)}\n${indent}]`;
164
178
  }
165
179
  finally {
180
+ release();
166
181
  leaveStringifyObject(value, state);
167
182
  }
168
183
  }
169
184
  async function stringifyObject(value, state, indent) {
170
185
  enterStringifyObject(value, state);
186
+ const entries = [];
187
+ const release = retainValues(state.budget, () => entries);
171
188
  try {
172
189
  const nextIndent = indent + state.gap;
173
- const entries = [];
174
190
  for (const key of Object.keys(value)) {
175
191
  const serialized = await stringifyProperty(key, value, state, nextIndent);
176
192
  if (serialized !== undefined) {
@@ -186,6 +202,7 @@ async function stringifyObject(value, state, indent) {
186
202
  return `{\n${nextIndent}${entries.join(`,\n${nextIndent}`)}\n${indent}}`;
187
203
  }
188
204
  finally {
205
+ release();
189
206
  leaveStringifyObject(value, state);
190
207
  }
191
208
  }
@@ -250,15 +267,13 @@ function toSandboxValue(value) {
250
267
  }
251
268
  throw new TypeError(`JSON.stringify(value) produced an unsupported value of type ${typeof value}.`);
252
269
  }
253
- function getOwnDataValue(target, key) {
254
- const descriptor = Object.getOwnPropertyDescriptor(target, key);
255
- if (descriptor === undefined) {
256
- return undefined;
257
- }
258
- if ("get" in descriptor || "set" in descriptor) {
259
- throw new TypeError(`JSON.stringify(value) cannot serialize accessor property ${key}.`);
260
- }
261
- return descriptor.value;
270
+ function getStringifyProperty(target, key, state) {
271
+ if (state.context?.getProperty !== undefined)
272
+ return state.context.getProperty(target, key);
273
+ const descriptor = getSandboxPropertyDescriptor(target, key, state.budget);
274
+ return descriptor === undefined
275
+ ? undefined
276
+ : readPropertyDescriptor(descriptor, target, state.context);
262
277
  }
263
278
  function copyJsonToSandbox(value, budget) {
264
279
  if (value === null ||
@@ -1,5 +1,5 @@
1
1
  import { type Budget, type CompileOwner } from "../budget.js";
2
- import { type SandboxClosure } from "../values.js";
2
+ import { type SandboxClosure, type SandboxValue } from "../values.js";
3
3
  export type ObjectArrayGlobals = {
4
4
  Object: SandboxClosure;
5
5
  Array: SandboxClosure;
@@ -11,3 +11,4 @@ export declare function createObjectArrayGlobals(options: {
11
11
  budget: Budget;
12
12
  compileOwner?: CompileOwner;
13
13
  }): ObjectArrayGlobals;
14
+ export declare function defineDataProperty(target: SandboxValue, key: string, descriptor: PropertyDescriptor, budget: Budget): void;