poe-code 13.0.3 → 13.0.4
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/dist/index.js +14418 -13628
- package/dist/index.js.map +4 -4
- package/dist/metafile.json +1 -1
- package/package.json +1 -1
- package/packages/safe-js/dist/chunks/{chunk-73LWNNUG.js → chunk-WGS5B4OT.js} +14505 -13744
- package/packages/safe-js/dist/chunks/chunk-WGS5B4OT.js.map +7 -0
- package/packages/safe-js/dist/chunks/{chunk-QCJ7UAMC.js → chunk-ZGWWEL43.js} +2 -2
- package/packages/safe-js/dist/cli.js +2 -2
- package/packages/safe-js/dist/core.js +1 -1
- package/packages/safe-js/dist/index.d.ts +11 -3
- package/packages/safe-js/dist/index.js +14 -6
- package/packages/safe-js/dist/index.js.map +4 -4
- package/packages/safe-js/dist/interp/async.d.ts +2 -0
- package/packages/safe-js/dist/interp/async.js +31 -15
- package/packages/safe-js/dist/interp/budget.d.ts +29 -0
- package/packages/safe-js/dist/interp/budget.js +143 -0
- package/packages/safe-js/dist/interp/globals/console-json.d.ts +2 -1
- package/packages/safe-js/dist/interp/globals/console-json.js +24 -6
- package/packages/safe-js/dist/interp/globals/regex.d.ts +2 -1
- package/packages/safe-js/dist/interp/globals/regex.js +24 -3
- package/packages/safe-js/dist/interp/host-bridge.d.ts +2 -1
- package/packages/safe-js/dist/interp/host-bridge.js +98 -55
- package/packages/safe-js/dist/interp/host-call.d.ts +3 -2
- package/packages/safe-js/dist/interp/host-call.js +91 -52
- package/packages/safe-js/dist/interp/interpreter.d.ts +4 -1
- package/packages/safe-js/dist/interp/interpreter.js +115 -79
- package/packages/safe-js/dist/interp/methods/string.d.ts +2 -1
- package/packages/safe-js/dist/interp/methods/string.js +111 -100
- package/packages/safe-js/dist/interp/regex/compile-guard.d.ts +33 -0
- package/packages/safe-js/dist/interp/regex/compile-guard.js +179 -0
- package/packages/safe-js/dist/interp/regex/parse.d.ts +2 -1
- package/packages/safe-js/dist/interp/regex/parse.js +87 -16
- package/packages/safe-js/dist/interp/values.d.ts +7 -2
- package/packages/safe-js/dist/interp/values.js +91 -9
- package/packages/safe-js/dist/modules/registry.d.ts +2 -1
- package/packages/safe-js/dist/modules/registry.js +1 -0
- package/packages/safe-js/dist/parse/hash.d.ts +2 -1
- package/packages/safe-js/dist/parse/hash.js +7 -4
- package/packages/safe-js/dist/parse/parser.d.ts +5 -3
- package/packages/safe-js/dist/parse/parser.js +53 -27
- package/packages/safe-js/dist/parse/tokenizer.d.ts +2 -0
- package/packages/safe-js/dist/parse/tokenizer.js +48 -26
- package/packages/safe-js/dist/parse.d.ts +3 -1
- package/packages/safe-js/dist/parse.js +3 -1
- package/packages/safe-js/dist/restore.d.ts +2 -1
- package/packages/safe-js/dist/restore.js +3 -3
- package/packages/safe-js/dist/run.js +289 -263
- package/packages/safe-js/dist/snapshot/migration.d.ts +3 -2
- package/packages/safe-js/dist/snapshot/migration.js +12 -5
- package/packages/safe-js/dist/snapshot/replay-data.d.ts +2 -1
- package/packages/safe-js/dist/snapshot/replay-data.js +172 -162
- package/packages/safe-js/dist/snapshot/replay-inputs.d.ts +2 -1
- package/packages/safe-js/dist/snapshot/replay-inputs.js +18 -11
- package/packages/safe-js/dist/snapshot/restore.d.ts +2 -2
- package/packages/safe-js/dist/snapshot/restore.js +142 -113
- package/packages/safe-js/dist/chunks/chunk-73LWNNUG.js.map +0 -7
- /package/packages/safe-js/dist/chunks/{chunk-QCJ7UAMC.js.map → chunk-ZGWWEL43.js.map} +0 -0
|
@@ -5,6 +5,8 @@ import { formatParseError } from "./format-error.js";
|
|
|
5
5
|
import { createExportDefaultDeclaration, createExportNamedDeclaration } from "./parse-export.js";
|
|
6
6
|
import { createImportMeta, isImportMetaTokenSequence } from "./parse-import-meta.js";
|
|
7
7
|
import { parseRegex } from "../interp/regex/parse.js";
|
|
8
|
+
import { CompileScope, RegexCompileGuard } from "../interp/regex/compile-guard.js";
|
|
9
|
+
import { SandboxError } from "../interp/budget.js";
|
|
8
10
|
const MAX_CONDITIONAL_EXPRESSION_DEPTH = 256;
|
|
9
11
|
const MAX_IF_STATEMENT_DEPTH = 2_048;
|
|
10
12
|
export class DisallowedSyntaxError extends Error {
|
|
@@ -37,9 +39,10 @@ const TOP_LEVEL_STATEMENT_KEYWORDS = new Set([
|
|
|
37
39
|
"try",
|
|
38
40
|
"while"
|
|
39
41
|
]);
|
|
40
|
-
export function parse(source, filename = "<input>") {
|
|
42
|
+
export function parse(source, filename = "<input>", owner) {
|
|
43
|
+
const compilation = new CompileScope(owner);
|
|
41
44
|
try {
|
|
42
|
-
const result = assignIds(parseTokens(tokenize(source, { allowRegexLiterals: true })));
|
|
45
|
+
const result = assignIds(parseTokens(tokenize(source, { allowRegexLiterals: true, compilation }), compilation));
|
|
43
46
|
const regexLiteral = findRegexLiteral(result);
|
|
44
47
|
if (regexLiteral !== undefined) {
|
|
45
48
|
throw new Error(`Regular expression literals are not supported at line ${regexLiteral.span.start.line}, column ${regexLiteral.span.start.column}.`);
|
|
@@ -48,7 +51,7 @@ export function parse(source, filename = "<input>") {
|
|
|
48
51
|
return result;
|
|
49
52
|
}
|
|
50
53
|
catch (error) {
|
|
51
|
-
if (error instanceof DisallowedSyntaxError) {
|
|
54
|
+
if (error instanceof DisallowedSyntaxError || error instanceof SandboxError) {
|
|
52
55
|
throw error;
|
|
53
56
|
}
|
|
54
57
|
if (error instanceof Error) {
|
|
@@ -56,13 +59,17 @@ export function parse(source, filename = "<input>") {
|
|
|
56
59
|
}
|
|
57
60
|
throw error;
|
|
58
61
|
}
|
|
62
|
+
finally {
|
|
63
|
+
compilation.dispose();
|
|
64
|
+
}
|
|
59
65
|
}
|
|
60
|
-
export function parseModule(source, filename = "<input>") {
|
|
66
|
+
export function parseModule(source, filename = "<input>", owner) {
|
|
67
|
+
const compilation = new CompileScope(owner);
|
|
61
68
|
try {
|
|
62
|
-
return assignIds(parseModuleTokens(tokenize(source, { allowRegexLiterals: true })));
|
|
69
|
+
return assignIds(parseModuleTokens(tokenize(source, { allowRegexLiterals: true, compilation }), compilation));
|
|
63
70
|
}
|
|
64
71
|
catch (error) {
|
|
65
|
-
if (error instanceof DisallowedSyntaxError) {
|
|
72
|
+
if (error instanceof DisallowedSyntaxError || error instanceof SandboxError) {
|
|
66
73
|
throw error;
|
|
67
74
|
}
|
|
68
75
|
if (error instanceof Error) {
|
|
@@ -70,15 +77,19 @@ export function parseModule(source, filename = "<input>") {
|
|
|
70
77
|
}
|
|
71
78
|
throw error;
|
|
72
79
|
}
|
|
80
|
+
finally {
|
|
81
|
+
compilation.dispose();
|
|
82
|
+
}
|
|
73
83
|
}
|
|
74
|
-
export function parseExecutableModule(source, filename = "<input>") {
|
|
84
|
+
export function parseExecutableModule(source, filename = "<input>", owner) {
|
|
85
|
+
const compilation = new CompileScope(owner);
|
|
75
86
|
try {
|
|
76
|
-
const result = assignIds(parseModuleTokens(tokenize(source, { allowRegexLiterals: true })));
|
|
87
|
+
const result = assignIds(parseModuleTokens(tokenize(source, { allowRegexLiterals: true, compilation }), compilation));
|
|
77
88
|
throwIfImportMetaAssignment(result);
|
|
78
89
|
return result;
|
|
79
90
|
}
|
|
80
91
|
catch (error) {
|
|
81
|
-
if (error instanceof DisallowedSyntaxError) {
|
|
92
|
+
if (error instanceof DisallowedSyntaxError || error instanceof SandboxError) {
|
|
82
93
|
throw error;
|
|
83
94
|
}
|
|
84
95
|
if (error instanceof Error) {
|
|
@@ -86,18 +97,22 @@ export function parseExecutableModule(source, filename = "<input>") {
|
|
|
86
97
|
}
|
|
87
98
|
throw error;
|
|
88
99
|
}
|
|
100
|
+
finally {
|
|
101
|
+
compilation.dispose();
|
|
102
|
+
}
|
|
89
103
|
}
|
|
90
|
-
function parseTokens(tokens) {
|
|
91
|
-
return new Parser(tokens).parseTopLevel();
|
|
104
|
+
function parseTokens(tokens, compilation) {
|
|
105
|
+
return new Parser(tokens, compilation).parseTopLevel();
|
|
92
106
|
}
|
|
93
|
-
function parseModuleTokens(tokens) {
|
|
94
|
-
return new Parser(tokens).parseModule();
|
|
107
|
+
function parseModuleTokens(tokens, compilation) {
|
|
108
|
+
return new Parser(tokens, compilation).parseModule();
|
|
95
109
|
}
|
|
96
|
-
function parseExpressionTokens(tokens) {
|
|
97
|
-
return new Parser(tokens).parseExpressionOnly();
|
|
110
|
+
function parseExpressionTokens(tokens, compilation) {
|
|
111
|
+
return new Parser(tokens, compilation).parseExpressionOnly();
|
|
98
112
|
}
|
|
99
113
|
class Parser {
|
|
100
114
|
tokens;
|
|
115
|
+
compilation;
|
|
101
116
|
index = 0;
|
|
102
117
|
breakableDepth = 0;
|
|
103
118
|
conditionalExpressionDepth = 0;
|
|
@@ -107,8 +122,9 @@ class Parser {
|
|
|
107
122
|
scopes = [new Map()];
|
|
108
123
|
functionScopes = new WeakSet();
|
|
109
124
|
varNames = new WeakMap();
|
|
110
|
-
constructor(tokens) {
|
|
125
|
+
constructor(tokens, compilation) {
|
|
111
126
|
this.tokens = tokens;
|
|
127
|
+
this.compilation = compilation;
|
|
112
128
|
this.functionScopes.add(this.scopes[0]);
|
|
113
129
|
}
|
|
114
130
|
parseTopLevel() {
|
|
@@ -1646,7 +1662,7 @@ class Parser {
|
|
|
1646
1662
|
continue;
|
|
1647
1663
|
}
|
|
1648
1664
|
if (this.currentToken().type === "template") {
|
|
1649
|
-
const quasi = createTemplateLiteral(this.currentToken(), { allowMalformedEscapes: true });
|
|
1665
|
+
const quasi = createTemplateLiteral(this.currentToken(), { allowMalformedEscapes: true }, this.compilation);
|
|
1650
1666
|
this.index += 1;
|
|
1651
1667
|
expression = {
|
|
1652
1668
|
node: {
|
|
@@ -1727,14 +1743,14 @@ class Parser {
|
|
|
1727
1743
|
if (token.type === "regex") {
|
|
1728
1744
|
this.index += 1;
|
|
1729
1745
|
return {
|
|
1730
|
-
node: createRegexLiteral(token),
|
|
1746
|
+
node: createRegexLiteral(token, this.compilation),
|
|
1731
1747
|
parenthesized: false
|
|
1732
1748
|
};
|
|
1733
1749
|
}
|
|
1734
1750
|
if (token.type === "template") {
|
|
1735
1751
|
this.index += 1;
|
|
1736
1752
|
return {
|
|
1737
|
-
node: createTemplateLiteral(token, { allowMalformedEscapes: false }),
|
|
1753
|
+
node: createTemplateLiteral(token, { allowMalformedEscapes: false }, this.compilation),
|
|
1738
1754
|
parenthesized: false
|
|
1739
1755
|
};
|
|
1740
1756
|
}
|
|
@@ -2918,10 +2934,16 @@ function createStringLiteral(token) {
|
|
|
2918
2934
|
span: createTokenSpan(token)
|
|
2919
2935
|
};
|
|
2920
2936
|
}
|
|
2921
|
-
function createRegexLiteral(token) {
|
|
2937
|
+
function createRegexLiteral(token, parent) {
|
|
2938
|
+
const compilation = new CompileScope(parent?.owner);
|
|
2939
|
+
const guard = new RegexCompileGuard(compilation);
|
|
2922
2940
|
const lastSlash = token.value.lastIndexOf("/");
|
|
2923
2941
|
try {
|
|
2924
|
-
|
|
2942
|
+
guard.checkLength(Math.max(0, lastSlash - 1));
|
|
2943
|
+
guard.checkLength(token.value.length - lastSlash - 1, true);
|
|
2944
|
+
guard.allocate(Math.max(0, token.value.length - 2));
|
|
2945
|
+
guard.work(Math.max(0, token.value.length - 2));
|
|
2946
|
+
parseRegex(token.value.slice(1, lastSlash), token.value.slice(lastSlash + 1), compilation);
|
|
2925
2947
|
}
|
|
2926
2948
|
catch (error) {
|
|
2927
2949
|
if (error instanceof SyntaxError) {
|
|
@@ -2933,6 +2955,10 @@ function createRegexLiteral(token) {
|
|
|
2933
2955
|
}
|
|
2934
2956
|
throw error;
|
|
2935
2957
|
}
|
|
2958
|
+
finally {
|
|
2959
|
+
guard.close();
|
|
2960
|
+
compilation.dispose();
|
|
2961
|
+
}
|
|
2936
2962
|
return {
|
|
2937
2963
|
type: "RegexLiteral",
|
|
2938
2964
|
raw: token.value,
|
|
@@ -2983,7 +3009,7 @@ function createLiteralFromToken(token) {
|
|
|
2983
3009
|
}
|
|
2984
3010
|
return createKeywordLiteral(token);
|
|
2985
3011
|
}
|
|
2986
|
-
function createTemplateLiteral(token, options = { allowMalformedEscapes: false }) {
|
|
3012
|
+
function createTemplateLiteral(token, options = { allowMalformedEscapes: false }, compilation) {
|
|
2987
3013
|
const raw = token.value;
|
|
2988
3014
|
const expressions = [];
|
|
2989
3015
|
const quasis = [];
|
|
@@ -2999,7 +3025,7 @@ function createTemplateLiteral(token, options = { allowMalformedEscapes: false }
|
|
|
2999
3025
|
quasis.push(createTemplateElement(token.start, raw, quasiStart, cursor, false, options));
|
|
3000
3026
|
const expressionStart = cursor + 2;
|
|
3001
3027
|
const expressionEnd = findTemplateExpressionEnd(raw, expressionStart);
|
|
3002
|
-
expressions.push(parseEmbeddedExpression(raw.slice(expressionStart, expressionEnd), positionWithinRaw(token.start, raw, expressionStart)));
|
|
3028
|
+
expressions.push(parseEmbeddedExpression(raw.slice(expressionStart, expressionEnd), positionWithinRaw(token.start, raw, expressionStart), compilation));
|
|
3003
3029
|
quasiStart = expressionEnd + 1;
|
|
3004
3030
|
cursor = expressionEnd + 1;
|
|
3005
3031
|
continue;
|
|
@@ -3360,15 +3386,15 @@ function decodeHexEscape(value, start) {
|
|
|
3360
3386
|
end: index + 2
|
|
3361
3387
|
};
|
|
3362
3388
|
}
|
|
3363
|
-
function parseEmbeddedExpression(source, base) {
|
|
3364
|
-
const tokens = tokenize(source, { allowRegexLiterals: true }).map((token) => ({
|
|
3389
|
+
function parseEmbeddedExpression(source, base, compilation) {
|
|
3390
|
+
const tokens = tokenize(source, { allowRegexLiterals: true, compilation }).map((token) => ({
|
|
3365
3391
|
...token,
|
|
3366
3392
|
start: rebasePosition(token.start, base),
|
|
3367
3393
|
end: rebasePosition(token.end, base)
|
|
3368
3394
|
}));
|
|
3369
|
-
return parseExpressionTokens(tokens);
|
|
3395
|
+
return parseExpressionTokens(tokens, compilation);
|
|
3370
3396
|
}
|
|
3371
|
-
function findRegexLiteral(node) {
|
|
3397
|
+
export function findRegexLiteral(node) {
|
|
3372
3398
|
if (node === null || node === undefined) {
|
|
3373
3399
|
return undefined;
|
|
3374
3400
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type CompileScope } from "../interp/regex/compile-guard.js";
|
|
1
2
|
export type Position = {
|
|
2
3
|
line: number;
|
|
3
4
|
column: number;
|
|
@@ -19,6 +20,7 @@ export type Comment = {
|
|
|
19
20
|
export type TokenizeOptions = {
|
|
20
21
|
allowRegexLiterals?: boolean;
|
|
21
22
|
comments?: Comment[];
|
|
23
|
+
compilation?: CompileScope;
|
|
22
24
|
};
|
|
23
25
|
export declare function tokenize(source: string, options?: TokenizeOptions): Token[];
|
|
24
26
|
export declare function collectComments(source: string): Comment[];
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { RegexCompileGuard } from "../interp/regex/compile-guard.js";
|
|
1
2
|
const KEYWORDS = new Set([
|
|
2
3
|
"const",
|
|
3
4
|
"let",
|
|
@@ -646,37 +647,58 @@ class Lexer {
|
|
|
646
647
|
return undefined;
|
|
647
648
|
}
|
|
648
649
|
scanRegexLiteral(start) {
|
|
649
|
-
this.
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
650
|
+
const guard = new RegexCompileGuard(this.options.compilation);
|
|
651
|
+
try {
|
|
652
|
+
guard.work(1);
|
|
653
|
+
this.advance();
|
|
654
|
+
const patternStart = this.index;
|
|
655
|
+
let inCharacterClass = false;
|
|
656
|
+
const advancePattern = () => {
|
|
657
|
+
const width = this.currentChar() === "\r" && this.peekChar(1) === "\n" ? 2 : 1;
|
|
658
|
+
guard.checkLength(this.index - patternStart + width);
|
|
659
|
+
guard.work(width);
|
|
660
|
+
this.advance();
|
|
661
|
+
};
|
|
662
|
+
while (!this.isAtEnd()) {
|
|
663
|
+
const char = this.currentChar();
|
|
664
|
+
if (char === "\\") {
|
|
665
|
+
advancePattern();
|
|
666
|
+
if (!this.isAtEnd())
|
|
667
|
+
advancePattern();
|
|
668
|
+
continue;
|
|
657
669
|
}
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
if (char === "/" && !inCharacterClass) {
|
|
671
|
-
this.advance();
|
|
672
|
-
while (!this.isAtEnd() && isAsciiLetter(this.currentChar())) {
|
|
670
|
+
if (char === "[" && !inCharacterClass) {
|
|
671
|
+
inCharacterClass = true;
|
|
672
|
+
advancePattern();
|
|
673
|
+
continue;
|
|
674
|
+
}
|
|
675
|
+
if (char === "]" && inCharacterClass) {
|
|
676
|
+
inCharacterClass = false;
|
|
677
|
+
advancePattern();
|
|
678
|
+
continue;
|
|
679
|
+
}
|
|
680
|
+
if (char === "/" && !inCharacterClass) {
|
|
681
|
+
guard.work(1);
|
|
673
682
|
this.advance();
|
|
683
|
+
const flagsStart = this.index;
|
|
684
|
+
while (!this.isAtEnd() && isAsciiLetter(this.currentChar())) {
|
|
685
|
+
guard.checkLength(this.index - flagsStart + 1, true);
|
|
686
|
+
guard.work(1);
|
|
687
|
+
this.advance();
|
|
688
|
+
}
|
|
689
|
+
break;
|
|
674
690
|
}
|
|
675
|
-
|
|
691
|
+
advancePattern();
|
|
676
692
|
}
|
|
677
|
-
this.
|
|
693
|
+
guard.allocate(this.index - start.offset);
|
|
694
|
+
guard.work(this.index - start.offset);
|
|
695
|
+
const raw = this.source.slice(start.offset, this.index);
|
|
696
|
+
guard.retainScratch();
|
|
697
|
+
return raw;
|
|
698
|
+
}
|
|
699
|
+
finally {
|
|
700
|
+
guard.close();
|
|
678
701
|
}
|
|
679
|
-
return this.source.slice(start.offset, this.index);
|
|
680
702
|
}
|
|
681
703
|
pushToken(type, start, value) {
|
|
682
704
|
const previousToken = this.lastSignificantToken();
|
|
@@ -1,2 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
import { type ParseResult as ParsedNode } from "./parse/parser.js";
|
|
2
|
+
export { DisallowedSyntaxError } from "./parse/parser.js";
|
|
3
|
+
export declare const parse: (source: string, filename?: string) => ParsedNode;
|
|
2
4
|
export type { ArrayPattern, ArrayExpression, ArrowFunctionExpression, AssignmentExpression, AssignmentPattern, AssignmentProperty, AwaitExpression, BinaryExpression, BlockStatement, BooleanLiteral, BreakStatement, CallExpression, CatchClause, ConditionalExpression, ContinueStatement, DoWhileStatement, EmptyStatement, Expression, ExpressionStatement, ExportDefaultDeclaration, ExportNamedDeclaration, ImportDeclaration, ImportDefaultSpecifier, ImportNamespaceSpecifier, ImportSpecifier, ForInStatement, ForOfStatement, ForStatement, FunctionDeclaration, FunctionExpression, Identifier, IfStatement, LogicalExpression, MemberExpression, MetaProperty, NewExpression, NullLiteral, NumericLiteral, ObjectExpression, ObjectPattern, ParseResult, PatternTarget, Property, RegexLiteral, RestElement, ReturnStatement, SequenceExpression, SourceSpan, SpreadElement, Statement, StringLiteral, SwitchCase, SwitchStatement, TaggedTemplateExpression, TemplateElement, TemplateLiteral, ThisExpression, ThrowStatement, TryStatement, UnaryExpression, UndefinedLiteral, UpdateExpression, UpdateTarget, VariableDeclaration, VariableDeclarationKind, VariableDeclarator, WhileStatement } from "./parse/parser.js";
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { CompileOwner } from "./interp/budget.js";
|
|
1
2
|
import { type SnapshotMigration } from "./snapshot/migration.js";
|
|
2
3
|
export type SafeJSSnapshot = {
|
|
3
4
|
version?: number;
|
|
@@ -22,4 +23,4 @@ export declare class SnapshotMismatchError extends Error {
|
|
|
22
23
|
readonly expectedHash: string;
|
|
23
24
|
constructor(expectedHash: string, actualHash: string);
|
|
24
25
|
}
|
|
25
|
-
export declare function restore<TSnapshot extends SafeJSSnapshot>(snapshot: TSnapshot, options: RestoreOptions): TSnapshot;
|
|
26
|
+
export declare function restore<TSnapshot extends SafeJSSnapshot>(snapshot: TSnapshot, options: RestoreOptions, owner?: CompileOwner): TSnapshot;
|
|
@@ -15,10 +15,10 @@ export class SnapshotMismatchError extends Error {
|
|
|
15
15
|
replaceErrorStack(this);
|
|
16
16
|
}
|
|
17
17
|
}
|
|
18
|
-
export function restore(snapshot, options) {
|
|
18
|
+
export function restore(snapshot, options, owner) {
|
|
19
19
|
assertSnapshotInactive(snapshot);
|
|
20
20
|
validateDumpEnvelope(snapshot);
|
|
21
|
-
validateSnapshotMigration(snapshot.migration, snapshot.sourceHash);
|
|
21
|
+
validateSnapshotMigration(snapshot.migration, snapshot.sourceHash, owner);
|
|
22
22
|
if (snapshot.executionSemantics !== EXECUTION_SEMANTICS &&
|
|
23
23
|
snapshot.executionSemantics !== "jobs-v6" &&
|
|
24
24
|
(snapshot.executionSemantics !== undefined ||
|
|
@@ -27,7 +27,7 @@ export function restore(snapshot, options) {
|
|
|
27
27
|
snapshot.initialInputs !== undefined)) {
|
|
28
28
|
throw new SnapshotValidationError("unsupportedVersion", "$.executionSemantics", "incompatible execution semantics; resume with the SafeJS version that created this snapshot. Migration requires explicit reconciliation, not changing its version marker.");
|
|
29
29
|
}
|
|
30
|
-
const currentSourceHash = hashSource(options.source);
|
|
30
|
+
const currentSourceHash = hashSource(options.source, owner);
|
|
31
31
|
if (snapshot.sourceHash !== currentSourceHash) {
|
|
32
32
|
throw new SnapshotMismatchError(snapshot.sourceHash, currentSourceHash);
|
|
33
33
|
}
|