@mnci/az-durable 0.1.2 → 0.1.3
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/eslint-plugin.cjs.js +218 -219
- package/dist/index.cjs.js +160 -997
- package/dist/testing.cjs.js +130 -153
- package/package.json +3 -2
|
@@ -8,7 +8,8 @@
|
|
|
8
8
|
* `@typescript-eslint/utils` because this package ships **zero runtime
|
|
9
9
|
* dependencies**, and a type-only dependency is still a dependency a consumer
|
|
10
10
|
* must be able to resolve. These cover exactly what the three rules use.
|
|
11
|
-
*/
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
12
13
|
* Whether a call expression registers an orchestration.
|
|
13
14
|
*
|
|
14
15
|
* @remarks
|
|
@@ -25,21 +26,22 @@
|
|
|
25
26
|
* @returns `true` when the call registers an orchestration.
|
|
26
27
|
* @throws Never - pure inspection.
|
|
27
28
|
* @typeParam None - this function has no generic type parameters.
|
|
28
|
-
*/
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
}
|
|
33
|
-
if (callee.type === 'Identifier' && callee.name === 'defineOrchestration') {
|
|
34
|
-
return true;
|
|
35
|
-
}
|
|
36
|
-
// df.app.orchestration(...) — match on the trailing property, so any local
|
|
37
|
-
// alias for the namespace still matches.
|
|
38
|
-
if (callee.type === 'MemberExpression') {
|
|
39
|
-
var property = callee.property;
|
|
40
|
-
return (property === null || property === void 0 ? void 0 : property.type) === 'Identifier' && property.name === 'orchestration';
|
|
41
|
-
}
|
|
29
|
+
*/
|
|
30
|
+
function isOrchestrationRegistration(node) {
|
|
31
|
+
const callee = node.callee;
|
|
32
|
+
if (callee === undefined) {
|
|
42
33
|
return false;
|
|
34
|
+
}
|
|
35
|
+
if (callee.type === 'Identifier' && callee.name === 'defineOrchestration') {
|
|
36
|
+
return true;
|
|
37
|
+
}
|
|
38
|
+
// df.app.orchestration(...) — match on the trailing property, so any local
|
|
39
|
+
// alias for the namespace still matches.
|
|
40
|
+
if (callee.type === 'MemberExpression') {
|
|
41
|
+
const property = callee.property;
|
|
42
|
+
return property?.type === 'Identifier' && property.name === 'orchestration';
|
|
43
|
+
}
|
|
44
|
+
return false;
|
|
43
45
|
}
|
|
44
46
|
/**
|
|
45
47
|
* The name a callee refers to, if it is a plain identifier or member access.
|
|
@@ -55,28 +57,30 @@
|
|
|
55
57
|
* @returns The identifier or property name, or `undefined`.
|
|
56
58
|
* @throws Never - pure inspection.
|
|
57
59
|
* @typeParam None - this function has no generic type parameters.
|
|
58
|
-
*/
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
}
|
|
62
|
-
if (node.type === 'Identifier') {
|
|
63
|
-
return node.name;
|
|
64
|
-
}
|
|
65
|
-
if (node.type === 'MemberExpression') {
|
|
66
|
-
var property = node.property;
|
|
67
|
-
if ((property === null || property === void 0 ? void 0 : property.type) === 'Identifier') {
|
|
68
|
-
return property.name;
|
|
69
|
-
}
|
|
70
|
-
}
|
|
60
|
+
*/
|
|
61
|
+
function calleeName(node) {
|
|
62
|
+
if (node === undefined) {
|
|
71
63
|
return undefined;
|
|
64
|
+
}
|
|
65
|
+
if (node.type === 'Identifier') {
|
|
66
|
+
return node.name;
|
|
67
|
+
}
|
|
68
|
+
if (node.type === 'MemberExpression') {
|
|
69
|
+
const property = node.property;
|
|
70
|
+
if (property?.type === 'Identifier') {
|
|
71
|
+
return property.name;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return undefined;
|
|
72
75
|
}
|
|
73
76
|
|
|
74
|
-
/** Global reads that differ on every replay, with the replacement to suggest. */
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
77
|
+
/** Global reads that differ on every replay, with the replacement to suggest. */
|
|
78
|
+
const FORBIDDEN_CALLS = {
|
|
79
|
+
'Date.now': 'now(context).getTime()',
|
|
80
|
+
'Math.random': 'context.df.newGuid(...) or an activity',
|
|
81
|
+
'crypto.randomUUID': 'context.df.newGuid(...)',
|
|
82
|
+
fetch: 'an activity — network calls must not run in an orchestrator',
|
|
83
|
+
axios: 'an activity — network calls must not run in an orchestrator'
|
|
80
84
|
};
|
|
81
85
|
/**
|
|
82
86
|
* Flags non-deterministic operations inside an orchestration body.
|
|
@@ -91,92 +95,88 @@
|
|
|
91
95
|
* only half of what a reader needs.
|
|
92
96
|
*
|
|
93
97
|
* Heuristic by design — see {@link isOrchestrationRegistration}.
|
|
94
|
-
*/
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
schema: [],
|
|
101
|
-
messages: {
|
|
102
|
-
forbidden: '{{what}} is non-deterministic on replay. Use {{fix}} instead.',
|
|
103
|
-
newDate: 'new Date() is non-deterministic on replay. Use now(context) instead.',
|
|
104
|
-
processEnv: 'process.env is read at replay time and may differ between deploys. ' + 'Read it in an activity, or pass it as orchestration input.'
|
|
105
|
-
}
|
|
98
|
+
*/
|
|
99
|
+
const noNondeterministicOrchestrator = {
|
|
100
|
+
meta: {
|
|
101
|
+
type: 'problem',
|
|
102
|
+
docs: {
|
|
103
|
+
description: 'Disallow non-deterministic operations inside an orchestration.'
|
|
106
104
|
},
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
}
|
|
113
|
-
};
|
|
114
|
-
var exit = function exit(node) {
|
|
115
|
-
if (isOrchestrationRegistration(node)) {
|
|
116
|
-
depth -= 1;
|
|
117
|
-
}
|
|
118
|
-
};
|
|
119
|
-
return {
|
|
120
|
-
CallExpression: function CallExpression(node) {
|
|
121
|
-
var _calleeName;
|
|
122
|
-
enter(node);
|
|
123
|
-
if (depth === 0) {
|
|
124
|
-
return;
|
|
125
|
-
}
|
|
126
|
-
var callee = node.callee;
|
|
127
|
-
var object = callee === null || callee === void 0 ? void 0 : callee.object;
|
|
128
|
-
var full = (object === null || object === void 0 ? void 0 : object.type) === 'Identifier' ? "".concat(String(object.name), ".").concat(String(calleeName(callee))) : (_calleeName = calleeName(callee)) !== null && _calleeName !== void 0 ? _calleeName : '';
|
|
129
|
-
var fix = FORBIDDEN_CALLS[full];
|
|
130
|
-
if (fix !== undefined) {
|
|
131
|
-
context.report({
|
|
132
|
-
node: node,
|
|
133
|
-
messageId: 'forbidden',
|
|
134
|
-
data: {
|
|
135
|
-
what: full,
|
|
136
|
-
fix: fix
|
|
137
|
-
}
|
|
138
|
-
});
|
|
139
|
-
}
|
|
140
|
-
},
|
|
141
|
-
'CallExpression:exit': exit,
|
|
142
|
-
NewExpression: function NewExpression(node) {
|
|
143
|
-
var _ref;
|
|
144
|
-
if (depth === 0) {
|
|
145
|
-
return;
|
|
146
|
-
}
|
|
147
|
-
var callee = node.callee;
|
|
148
|
-
var args = node.arguments;
|
|
149
|
-
// `new Date(someInstant)` is fine and common — only the argument-less
|
|
150
|
-
// form reads the wall clock.
|
|
151
|
-
if ((callee === null || callee === void 0 ? void 0 : callee.type) === 'Identifier' && callee.name === 'Date' && ((_ref = args === null || args === void 0 ? void 0 : args.length) !== null && _ref !== void 0 ? _ref : 0) === 0) {
|
|
152
|
-
context.report({
|
|
153
|
-
node: node,
|
|
154
|
-
messageId: 'newDate'
|
|
155
|
-
});
|
|
156
|
-
}
|
|
157
|
-
},
|
|
158
|
-
MemberExpression: function MemberExpression(node) {
|
|
159
|
-
if (depth === 0) {
|
|
160
|
-
return;
|
|
161
|
-
}
|
|
162
|
-
var object = node.object;
|
|
163
|
-
var property = node.property;
|
|
164
|
-
if ((object === null || object === void 0 ? void 0 : object.type) === 'Identifier' && object.name === 'process' && (property === null || property === void 0 ? void 0 : property.type) === 'Identifier' && property.name === 'env') {
|
|
165
|
-
context.report({
|
|
166
|
-
node: node,
|
|
167
|
-
messageId: 'processEnv'
|
|
168
|
-
});
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
};
|
|
105
|
+
schema: [],
|
|
106
|
+
messages: {
|
|
107
|
+
forbidden: '{{what}} is non-deterministic on replay. Use {{fix}} instead.',
|
|
108
|
+
newDate: 'new Date() is non-deterministic on replay. Use now(context) instead.',
|
|
109
|
+
processEnv: 'process.env is read at replay time and may differ between deploys. ' + 'Read it in an activity, or pass it as orchestration input.'
|
|
172
110
|
}
|
|
111
|
+
},
|
|
112
|
+
create(context) {
|
|
113
|
+
let depth = 0;
|
|
114
|
+
const enter = node => {
|
|
115
|
+
if (isOrchestrationRegistration(node)) {
|
|
116
|
+
depth += 1;
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
const exit = node => {
|
|
120
|
+
if (isOrchestrationRegistration(node)) {
|
|
121
|
+
depth -= 1;
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
return {
|
|
125
|
+
CallExpression: node => {
|
|
126
|
+
enter(node);
|
|
127
|
+
if (depth === 0) {
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
const callee = node.callee;
|
|
131
|
+
const object = callee?.object;
|
|
132
|
+
const full = object?.type === 'Identifier' ? `${String(object.name)}.${String(calleeName(callee))}` : calleeName(callee) ?? '';
|
|
133
|
+
const fix = FORBIDDEN_CALLS[full];
|
|
134
|
+
if (fix !== undefined) {
|
|
135
|
+
context.report({
|
|
136
|
+
node,
|
|
137
|
+
messageId: 'forbidden',
|
|
138
|
+
data: {
|
|
139
|
+
what: full,
|
|
140
|
+
fix
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
},
|
|
145
|
+
'CallExpression:exit': exit,
|
|
146
|
+
NewExpression: node => {
|
|
147
|
+
if (depth === 0) {
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
const callee = node.callee;
|
|
151
|
+
const args = node.arguments;
|
|
152
|
+
// `new Date(someInstant)` is fine and common — only the argument-less
|
|
153
|
+
// form reads the wall clock.
|
|
154
|
+
if (callee?.type === 'Identifier' && callee.name === 'Date' && (args?.length ?? 0) === 0) {
|
|
155
|
+
context.report({
|
|
156
|
+
node,
|
|
157
|
+
messageId: 'newDate'
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
},
|
|
161
|
+
MemberExpression: node => {
|
|
162
|
+
if (depth === 0) {
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
const object = node.object;
|
|
166
|
+
const property = node.property;
|
|
167
|
+
if (object?.type === 'Identifier' && object.name === 'process' && property?.type === 'Identifier' && property.name === 'env') {
|
|
168
|
+
context.report({
|
|
169
|
+
node,
|
|
170
|
+
messageId: 'processEnv'
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
};
|
|
175
|
+
}
|
|
173
176
|
};
|
|
174
177
|
|
|
175
|
-
/** SDK handler aliases that erase a handler's real signature. */
|
|
176
|
-
|
|
177
|
-
'OrchestrationHandler',
|
|
178
|
-
'FunctionHandler'
|
|
179
|
-
]);
|
|
178
|
+
/** SDK handler aliases that erase a handler's real signature. */
|
|
179
|
+
const ERASING_TYPES = new Set(['ActivityHandler', 'OrchestrationHandler', 'FunctionHandler']);
|
|
180
180
|
/**
|
|
181
181
|
* The annotation's type name, if it is a bare type reference.
|
|
182
182
|
*
|
|
@@ -184,13 +184,14 @@
|
|
|
184
184
|
* @returns The referenced type's name, or `undefined` when it is not a bare reference.
|
|
185
185
|
* @throws Never - pure inspection.
|
|
186
186
|
* @typeParam None - this function has no generic type parameters.
|
|
187
|
-
*/
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
187
|
+
*/
|
|
188
|
+
function referencedName(annotation) {
|
|
189
|
+
const typeAnnotation = annotation?.typeAnnotation;
|
|
190
|
+
if (typeAnnotation?.type !== 'TSTypeReference') {
|
|
191
|
+
return undefined;
|
|
192
|
+
}
|
|
193
|
+
const typeName = typeAnnotation.typeName;
|
|
194
|
+
return typeName?.type === 'Identifier' ? typeName.name : undefined;
|
|
194
195
|
}
|
|
195
196
|
/**
|
|
196
197
|
* Flags annotations that collapse a typed handler back to `any`.
|
|
@@ -215,51 +216,44 @@
|
|
|
215
216
|
* const withLogging = <I, O>(h: (i: I, c: InvocationContext) => O) =>
|
|
216
217
|
* (i: I, c: InvocationContext): O => { c.log('...'); return h(i, c) }
|
|
217
218
|
* ```
|
|
218
|
-
*/
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
schema: [],
|
|
225
|
-
messages: {
|
|
226
|
-
erased: "Annotating with '{{name}}' erases the handler's real signature — it is an alias for " + '(triggerInput: any, context) => any, so the activity becomes `any` in and `any` out. ' + 'Drop the annotation and let defineActivity infer it.',
|
|
227
|
-
erasedWrapper: "A wrapper typed '{{name}}' collapses every handler it wraps to `any`. " + 'Make it generic: <I, O>(h: (i: I, c: InvocationContext) => O) => (i: I, c: InvocationContext): O.'
|
|
228
|
-
}
|
|
219
|
+
*/
|
|
220
|
+
const noUntypedActivityHandler = {
|
|
221
|
+
meta: {
|
|
222
|
+
type: 'problem',
|
|
223
|
+
docs: {
|
|
224
|
+
description: 'Disallow handler annotations that erase inferred types.'
|
|
229
225
|
},
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
var _node_parent_type, _node_parent, _node_parent_params, _node_parent1;
|
|
235
|
-
var name = referencedName(node.typeAnnotation);
|
|
236
|
-
if (name === undefined || !ERASING_TYPES.has(name)) {
|
|
237
|
-
return;
|
|
238
|
-
}
|
|
239
|
-
// A function PARAMETER annotated this way is the middleware form, which
|
|
240
|
-
// is worse: it erases every handler passed through it, not just one.
|
|
241
|
-
var isParameter = ((_node_parent = node.parent) === null || _node_parent === void 0 ? void 0 : (_node_parent_type = _node_parent.type) === null || _node_parent_type === void 0 ? void 0 : _node_parent_type.startsWith('TS')) === false && ((_node_parent1 = node.parent) === null || _node_parent1 === void 0 ? void 0 : (_node_parent_params = _node_parent1.params) === null || _node_parent_params === void 0 ? void 0 : _node_parent_params.includes(node)) === true;
|
|
242
|
-
context.report({
|
|
243
|
-
node: node,
|
|
244
|
-
messageId: isParameter ? 'erasedWrapper' : 'erased',
|
|
245
|
-
data: {
|
|
246
|
-
name: name
|
|
247
|
-
}
|
|
248
|
-
});
|
|
249
|
-
}
|
|
250
|
-
};
|
|
226
|
+
schema: [],
|
|
227
|
+
messages: {
|
|
228
|
+
erased: "Annotating with '{{name}}' erases the handler's real signature — it is an alias for " + '(triggerInput: any, context) => any, so the activity becomes `any` in and `any` out. ' + 'Drop the annotation and let defineActivity infer it.',
|
|
229
|
+
erasedWrapper: "A wrapper typed '{{name}}' collapses every handler it wraps to `any`. " + 'Make it generic: <I, O>(h: (i: I, c: InvocationContext) => O) => (i: I, c: InvocationContext): O.'
|
|
251
230
|
}
|
|
231
|
+
},
|
|
232
|
+
create(context) {
|
|
233
|
+
return {
|
|
234
|
+
// const handler: ActivityHandler = ...
|
|
235
|
+
Identifier: node => {
|
|
236
|
+
const name = referencedName(node.typeAnnotation);
|
|
237
|
+
if (name === undefined || !ERASING_TYPES.has(name)) {
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
240
|
+
// A function PARAMETER annotated this way is the middleware form, which
|
|
241
|
+
// is worse: it erases every handler passed through it, not just one.
|
|
242
|
+
const isParameter = node.parent?.type?.startsWith('TS') === false && node.parent?.params?.includes(node) === true;
|
|
243
|
+
context.report({
|
|
244
|
+
node,
|
|
245
|
+
messageId: isParameter ? 'erasedWrapper' : 'erased',
|
|
246
|
+
data: {
|
|
247
|
+
name
|
|
248
|
+
}
|
|
249
|
+
});
|
|
250
|
+
}
|
|
251
|
+
};
|
|
252
|
+
}
|
|
252
253
|
};
|
|
253
254
|
|
|
254
|
-
/** The wrapper calls that must be delegated to, not yielded. */
|
|
255
|
-
|
|
256
|
-
'callSubOrchestration',
|
|
257
|
-
'all',
|
|
258
|
-
'any',
|
|
259
|
-
'waitForEvent',
|
|
260
|
-
'sleepFor',
|
|
261
|
-
'sleepUntil'
|
|
262
|
-
]);
|
|
255
|
+
/** The wrapper calls that must be delegated to, not yielded. */
|
|
256
|
+
const DELEGATED = new Set(['callActivity', 'callSubOrchestration', 'all', 'any', 'waitForEvent', 'sleepFor', 'sleepUntil']);
|
|
263
257
|
/**
|
|
264
258
|
* Flags `yield callActivity(...)` where `yield *` is meant.
|
|
265
259
|
*
|
|
@@ -278,48 +272,49 @@
|
|
|
278
272
|
* So this rule earns its place only by reporting a clearer message than
|
|
279
273
|
* `TS2345` does. It is in `recommended` for that reason, not because anything
|
|
280
274
|
* depends on it.
|
|
281
|
-
*/
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
schema: [],
|
|
288
|
-
messages: {
|
|
289
|
-
useYieldStar: "Use 'yield *' rather than 'yield' with {{name}}(). Delegation is what carries the " + 'result type; a bare yield does not typecheck, but the compiler error is obscure.'
|
|
290
|
-
}
|
|
275
|
+
*/
|
|
276
|
+
const requireYieldStar = {
|
|
277
|
+
meta: {
|
|
278
|
+
type: 'suggestion',
|
|
279
|
+
docs: {
|
|
280
|
+
description: 'Require `yield *` when calling a delegating helper.'
|
|
291
281
|
},
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
if (node.delegate === true) {
|
|
296
|
-
return;
|
|
297
|
-
}
|
|
298
|
-
var argument = node.argument;
|
|
299
|
-
if ((argument === null || argument === void 0 ? void 0 : argument.type) !== 'CallExpression') {
|
|
300
|
-
return;
|
|
301
|
-
}
|
|
302
|
-
// A BARE IDENTIFIER only. `c.df.callActivity(...)` is the raw SDK call,
|
|
303
|
-
// which is correct code and must not be flagged — matching the trailing
|
|
304
|
-
// property of a member expression would flag it, which a negative
|
|
305
|
-
// fixture caught.
|
|
306
|
-
var callee = argument.callee;
|
|
307
|
-
if ((callee === null || callee === void 0 ? void 0 : callee.type) !== 'Identifier') {
|
|
308
|
-
return;
|
|
309
|
-
}
|
|
310
|
-
var name = callee.name;
|
|
311
|
-
if (DELEGATED.has(name)) {
|
|
312
|
-
context.report({
|
|
313
|
-
node: node,
|
|
314
|
-
messageId: 'useYieldStar',
|
|
315
|
-
data: {
|
|
316
|
-
name: name
|
|
317
|
-
}
|
|
318
|
-
});
|
|
319
|
-
}
|
|
320
|
-
}
|
|
321
|
-
};
|
|
282
|
+
schema: [],
|
|
283
|
+
messages: {
|
|
284
|
+
useYieldStar: "Use 'yield *' rather than 'yield' with {{name}}(). Delegation is what carries the " + 'result type; a bare yield does not typecheck, but the compiler error is obscure.'
|
|
322
285
|
}
|
|
286
|
+
},
|
|
287
|
+
create(context) {
|
|
288
|
+
return {
|
|
289
|
+
YieldExpression: node => {
|
|
290
|
+
if (node.delegate === true) {
|
|
291
|
+
return;
|
|
292
|
+
}
|
|
293
|
+
const argument = node.argument;
|
|
294
|
+
if (argument?.type !== 'CallExpression') {
|
|
295
|
+
return;
|
|
296
|
+
}
|
|
297
|
+
// A BARE IDENTIFIER only. `c.df.callActivity(...)` is the raw SDK call,
|
|
298
|
+
// which is correct code and must not be flagged — matching the trailing
|
|
299
|
+
// property of a member expression would flag it, which a negative
|
|
300
|
+
// fixture caught.
|
|
301
|
+
const callee = argument.callee;
|
|
302
|
+
if (callee?.type !== 'Identifier') {
|
|
303
|
+
return;
|
|
304
|
+
}
|
|
305
|
+
const name = callee.name;
|
|
306
|
+
if (DELEGATED.has(name)) {
|
|
307
|
+
context.report({
|
|
308
|
+
node,
|
|
309
|
+
messageId: 'useYieldStar',
|
|
310
|
+
data: {
|
|
311
|
+
name
|
|
312
|
+
}
|
|
313
|
+
});
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
};
|
|
317
|
+
}
|
|
323
318
|
};
|
|
324
319
|
|
|
325
320
|
/**
|
|
@@ -328,10 +323,11 @@
|
|
|
328
323
|
* @remarks
|
|
329
324
|
* The keys are the names a config writes after the `az-durable/` prefix, so
|
|
330
325
|
* renaming one is a breaking change for any consumer's config.
|
|
331
|
-
*/
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
326
|
+
*/
|
|
327
|
+
const rules = {
|
|
328
|
+
'no-nondeterministic-orchestrator': noNondeterministicOrchestrator,
|
|
329
|
+
'no-untyped-activity-handler': noUntypedActivityHandler,
|
|
330
|
+
'require-yield-star': requireYieldStar
|
|
335
331
|
};
|
|
336
332
|
/**
|
|
337
333
|
* The plugin object, for a flat config's `plugins` map.
|
|
@@ -339,8 +335,9 @@
|
|
|
339
335
|
* @remarks
|
|
340
336
|
* Shipped from a separate entry point so lint rules are never a runtime import
|
|
341
337
|
* of the wrapper itself.
|
|
342
|
-
*/
|
|
343
|
-
|
|
338
|
+
*/
|
|
339
|
+
const plugin = {
|
|
340
|
+
rules
|
|
344
341
|
};
|
|
345
342
|
/**
|
|
346
343
|
* The recommended rule set.
|
|
@@ -351,15 +348,16 @@
|
|
|
351
348
|
* failures nothing else does — silent replay corruption, and a type collapse
|
|
352
349
|
* TypeScript accepts as legal. `require-yield-star` is a warning because the
|
|
353
350
|
* compiler already rejects the code it flags; it only improves the message.
|
|
354
|
-
*/
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
351
|
+
*/
|
|
352
|
+
const recommended = {
|
|
353
|
+
plugins: {
|
|
354
|
+
'az-durable': plugin
|
|
355
|
+
},
|
|
356
|
+
rules: {
|
|
357
|
+
'az-durable/no-nondeterministic-orchestrator': 'error',
|
|
358
|
+
'az-durable/no-untyped-activity-handler': 'error',
|
|
359
|
+
'az-durable/require-yield-star': 'warn'
|
|
360
|
+
}
|
|
363
361
|
};
|
|
364
362
|
|
|
365
363
|
exports.noNondeterministicOrchestrator = noNondeterministicOrchestrator;
|
|
@@ -368,3 +366,4 @@ exports.plugin = plugin;
|
|
|
368
366
|
exports.recommended = recommended;
|
|
369
367
|
exports.requireYieldStar = requireYieldStar;
|
|
370
368
|
exports.rules = rules;
|
|
369
|
+
//# sourceMappingURL=eslint-plugin.cjs.js.map
|