@astrale-os/sdk 0.6.0-beta.36 → 0.6.0-beta.38
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/application/action/context.d.ts +14 -11
- package/dist/application/action/index.d.ts +1 -1
- package/dist/application/dependency/invoker.d.ts +10 -4
- package/dist/application/integration/define.d.ts +8 -1
- package/dist/application/integration/index.d.ts +2 -2
- package/dist/application/integration/integration.d.ts +13 -1
- package/dist/application/integration/operation.d.ts +14 -1
- package/dist/application/mutation/execution/execute.js +1 -1
- package/dist/application/mutation/failure.d.ts +6 -0
- package/dist/application/mutation/failure.js +24 -18
- package/dist/application/query/collection/union.js +11 -4
- package/dist/application/query/conformance.d.ts +15 -0
- package/dist/application/query/conformance.js +46 -0
- package/dist/application/query/define.js +4 -3
- package/dist/application/query/execution/execute.d.ts +0 -1
- package/dist/application/query/execution/execute.js +7 -1
- package/dist/application/query/failure.d.ts +8 -0
- package/dist/application/query/failure.js +8 -0
- package/dist/application/query/index.d.ts +1 -1
- package/dist/application/query/index.js +1 -1
- package/dist/application/workflow/authoring.d.ts +1 -1
- package/dist/application/workflow/context.d.ts +1 -1
- package/dist/application/workflow/durable.d.ts +55 -20
- package/dist/application/workflow/index.d.ts +1 -1
- package/dist/execution/identity/authentication.js +12 -6
- package/dist/execution/identity/callback.d.ts +7 -8
- package/dist/execution/identity/callback.js +17 -14
- package/dist/execution/invocation/capabilities/bind.d.ts +11 -0
- package/dist/execution/invocation/capabilities/bind.js +25 -0
- package/dist/execution/invocation/capabilities/index.d.ts +1 -0
- package/dist/execution/invocation/capabilities/index.js +1 -0
- package/dist/execution/invocation/dispatch/context.js +2 -21
- package/dist/execution/invocation/integration/authentication.d.ts +3 -3
- package/dist/execution/invocation/integration/authentication.js +7 -7
- package/dist/execution/invocation/integration/call.js +2 -2
- package/dist/execution/invocation/integration/index.d.ts +1 -0
- package/dist/execution/invocation/integration/index.js +1 -0
- package/dist/execution/invocation/invocation.js +2 -2
- package/dist/execution/invocation/lifecycle/active.d.ts +8 -2
- package/dist/execution/invocation/lifecycle/active.js +3 -3
- package/dist/execution/invocation/lifecycle/index.d.ts +1 -1
- package/dist/execution/service/create.js +1 -0
- package/dist/execution/workflows/engine.d.ts +12 -2
- package/dist/execution/workflows/index.d.ts +1 -1
- package/dist/execution/workflows/integrations.d.ts +13 -0
- package/dist/execution/workflows/integrations.js +25 -0
- package/dist/execution/workflows/options.js +3 -1
- package/dist/execution/workflows/receiver.d.ts +3 -0
- package/dist/execution/workflows/receiver.js +7 -2
- package/dist/execution/workflows/run.d.ts +3 -4
- package/dist/execution/workflows/run.js +32 -60
- package/dist/execution/workflows/steps.d.ts +42 -0
- package/dist/execution/workflows/steps.js +67 -0
- package/dist/testing/durable/engine.d.ts +111 -0
- package/dist/testing/durable/engine.js +540 -0
- package/dist/testing/durable/index.d.ts +3 -0
- package/dist/testing/durable/index.js +1 -0
- package/dist/testing/durable/steps.d.ts +30 -0
- package/dist/testing/durable/steps.js +40 -0
- package/dist/testing/index.d.ts +6 -1
- package/dist/testing/index.js +5 -1
- package/dist/tooling/cli/dotenv.d.ts +3 -3
- package/dist/tooling/cli/dotenv.js +3 -3
- package/dist/tooling/cli/log.d.ts +0 -2
- package/dist/tooling/cli/log.js +0 -2
- package/dist/tooling/linter/adapters/typescript/imports.d.ts +0 -1
- package/dist/tooling/linter/adapters/typescript/imports.js +1 -5
- package/dist/tooling/linter/adapters/typescript/index.d.ts +1 -1
- package/dist/tooling/linter/adapters/typescript/index.js +1 -1
- package/dist/tooling/linter/adapters/typescript/syntax.d.ts +3 -3
- package/dist/tooling/linter/adapters/typescript/syntax.js +13 -25
- package/dist/tooling/linter/implementations/source/callable-requirements.d.ts +0 -1
- package/dist/tooling/linter/implementations/source/callable-requirements.js +1 -6
- package/dist/tooling/linter/implementations/source/dependencies.js +1 -62
- package/dist/tooling/linter/implementations/source/mutations.js +1 -12
- package/dist/tooling/linter/implementations/source/queries.js +1 -17
- package/dist/tooling/linter/implementations/source/shared.d.ts +7 -4
- package/dist/tooling/linter/implementations/source/shared.js +93 -46
- package/dist/tooling/linter/implementations/source/workflows.js +406 -16
- package/dist/tooling/linter/policy/generated.js +2 -2
- package/dist/tooling/linter/requirements/registry.js +3 -1
- package/package.json +6 -6
package/dist/tooling/cli/log.js
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
/** CLI output helpers and ANSI colours for the one project command owner. */
|
|
2
|
-
export const GREEN = '\x1b[32m';
|
|
3
2
|
export const DIM = '\x1b[2m';
|
|
4
|
-
export const BOLD = '\x1b[1m';
|
|
5
3
|
export const YELLOW = '\x1b[33m';
|
|
6
4
|
export const RED = '\x1b[31m';
|
|
7
5
|
export const RESET = '\x1b[0m';
|
|
@@ -3,4 +3,3 @@ import type { SourceProject, SourceDependencyIssue, SourceFile, SourceImport } f
|
|
|
3
3
|
export declare function collectImports(source: ts.SourceFile): SourceImport[];
|
|
4
4
|
export declare function collectDependencyIssues(source: ts.SourceFile): SourceDependencyIssue[];
|
|
5
5
|
export declare function resolveProjectImport(project: SourceProject, importer: SourceFile, specifier: string): SourceFile | undefined;
|
|
6
|
-
export declare function isWithin(directory: string, path: string): boolean;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { dirname, extname,
|
|
1
|
+
import { dirname, extname, join, relative, resolve } from 'node:path';
|
|
2
2
|
import ts from 'typescript';
|
|
3
3
|
import { isLocallyDeclared } from './syntax.js';
|
|
4
4
|
export function collectImports(source) {
|
|
@@ -166,7 +166,3 @@ function visit(node, callback) {
|
|
|
166
166
|
callback(node);
|
|
167
167
|
node.forEachChild((child) => visit(child, callback));
|
|
168
168
|
}
|
|
169
|
-
export function isWithin(directory, path) {
|
|
170
|
-
const child = relative(directory, path);
|
|
171
|
-
return child === '' || (!child.startsWith('..') && !isAbsolute(child));
|
|
172
|
-
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export { discoverProject } from './discover.js';
|
|
2
2
|
export { sourceEvidenceAdmission } from './evidence-admission.js';
|
|
3
3
|
export { collectDependencyIssues, resolveProjectImport } from './imports.js';
|
|
4
|
-
export { importedSymbol, isLocallyDeclared, resolveImportedSymbol, location, objectProperty, propertyChain, staticText, unwrap, visit, } from './syntax.js';
|
|
4
|
+
export { bindingContains, importedSymbol, isLocallyDeclared, resolveImportedSymbol, location, objectProperty, propertyChain, staticText, unwrap, visit, visitOwnBody, } from './syntax.js';
|
|
5
5
|
export { assertSingleTypeUniverse } from './type-universe.js';
|
|
6
6
|
export { observeQueryDefinitions } from './query-observation.js';
|
|
7
7
|
export { queryCollectionKind } from './query-collection-type.js';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export { discoverProject } from './discover.js';
|
|
2
2
|
export { sourceEvidenceAdmission } from './evidence-admission.js';
|
|
3
3
|
export { collectDependencyIssues, resolveProjectImport } from './imports.js';
|
|
4
|
-
export { importedSymbol, isLocallyDeclared, resolveImportedSymbol, location, objectProperty, propertyChain, staticText, unwrap, visit, } from './syntax.js';
|
|
4
|
+
export { bindingContains, importedSymbol, isLocallyDeclared, resolveImportedSymbol, location, objectProperty, propertyChain, staticText, unwrap, visit, visitOwnBody, } from './syntax.js';
|
|
5
5
|
export { assertSingleTypeUniverse } from './type-universe.js';
|
|
6
6
|
export { observeQueryDefinitions } from './query-observation.js';
|
|
7
7
|
export { queryCollectionKind } from './query-collection-type.js';
|
|
@@ -27,12 +27,12 @@ export type ImportedSymbolResolution = Readonly<{
|
|
|
27
27
|
*/
|
|
28
28
|
export declare function resolveImportedSymbol(file: SourceFile, expression: ts.Expression): ImportedSymbolResolution;
|
|
29
29
|
export declare function isLocallyDeclared(identifier: ts.Identifier): boolean;
|
|
30
|
+
export declare function bindingContains(binding: ts.BindingName, name: string): boolean;
|
|
31
|
+
/** Visit a function body, without descending into the functions nested in it. */
|
|
32
|
+
export declare function visitOwnBody(fn: ts.FunctionLikeDeclaration, callback: (node: ts.Node) => void): void;
|
|
30
33
|
export declare function unwrap(expression: ts.Expression): ts.Expression;
|
|
31
34
|
export declare function staticText(expression: ts.Expression | undefined): string | undefined;
|
|
32
35
|
export declare function objectProperty(object: ts.ObjectLiteralExpression | undefined, name: string): ts.ObjectLiteralElementLike | undefined;
|
|
33
36
|
export declare function propertyName(name: ts.PropertyName): string | undefined;
|
|
34
|
-
export declare function callbackOf(property: ts.ObjectLiteralElementLike | undefined): ts.FunctionLikeDeclaration | undefined;
|
|
35
|
-
export declare function objectArgument(call: ts.CallExpression): ts.ObjectLiteralExpression | undefined;
|
|
36
|
-
export declare function isImportedCall(file: SourceFile, node: ts.Node, modules: ReadonlySet<string>, name: string): node is ts.CallExpression;
|
|
37
37
|
export declare function propertyChain(expression: ts.Expression): readonly string[] | undefined;
|
|
38
38
|
export declare function containingFunction(node: ts.Node): ts.FunctionLikeDeclaration | undefined;
|
|
@@ -103,11 +103,23 @@ function statementDeclares(statement, name) {
|
|
|
103
103
|
}
|
|
104
104
|
return false;
|
|
105
105
|
}
|
|
106
|
-
function bindingContains(binding, name) {
|
|
106
|
+
export function bindingContains(binding, name) {
|
|
107
107
|
if (ts.isIdentifier(binding))
|
|
108
108
|
return binding.text === name;
|
|
109
109
|
return binding.elements.some((element) => !ts.isOmittedExpression(element) && bindingContains(element.name, name));
|
|
110
110
|
}
|
|
111
|
+
/** Visit a function body, without descending into the functions nested in it. */
|
|
112
|
+
export function visitOwnBody(fn, callback) {
|
|
113
|
+
if (!fn.body)
|
|
114
|
+
return;
|
|
115
|
+
const walk = (node) => {
|
|
116
|
+
callback(node);
|
|
117
|
+
if (node !== fn.body && ts.isFunctionLike(node))
|
|
118
|
+
return;
|
|
119
|
+
node.forEachChild(walk);
|
|
120
|
+
};
|
|
121
|
+
walk(fn.body);
|
|
122
|
+
}
|
|
111
123
|
export function unwrap(expression) {
|
|
112
124
|
let current = expression;
|
|
113
125
|
while (ts.isParenthesizedExpression(current) ||
|
|
@@ -138,30 +150,6 @@ export function propertyName(name) {
|
|
|
138
150
|
return name.text;
|
|
139
151
|
return ts.isComputedPropertyName(name) ? staticText(name.expression) : undefined;
|
|
140
152
|
}
|
|
141
|
-
export function callbackOf(property) {
|
|
142
|
-
if (!property)
|
|
143
|
-
return undefined;
|
|
144
|
-
if (ts.isMethodDeclaration(property))
|
|
145
|
-
return property;
|
|
146
|
-
if (ts.isPropertyAssignment(property)) {
|
|
147
|
-
const value = unwrap(property.initializer);
|
|
148
|
-
if (ts.isArrowFunction(value) || ts.isFunctionExpression(value))
|
|
149
|
-
return value;
|
|
150
|
-
}
|
|
151
|
-
return undefined;
|
|
152
|
-
}
|
|
153
|
-
export function objectArgument(call) {
|
|
154
|
-
const value = call.arguments[0];
|
|
155
|
-
return value && ts.isObjectLiteralExpression(unwrap(value))
|
|
156
|
-
? unwrap(value)
|
|
157
|
-
: undefined;
|
|
158
|
-
}
|
|
159
|
-
export function isImportedCall(file, node, modules, name) {
|
|
160
|
-
if (!ts.isCallExpression(node))
|
|
161
|
-
return false;
|
|
162
|
-
const symbol = importedSymbol(file, node.expression);
|
|
163
|
-
return symbol?.name === name && modules.has(symbol.module);
|
|
164
|
-
}
|
|
165
153
|
export function propertyChain(expression) {
|
|
166
154
|
const target = unwrap(expression);
|
|
167
155
|
if (ts.isIdentifier(target))
|
|
@@ -25,4 +25,3 @@ export declare function callableReference(expression: ts.Expression): {
|
|
|
25
25
|
};
|
|
26
26
|
/** Resolve only one immutable lexical alias; the linter does not emulate program execution. */
|
|
27
27
|
export declare function lexicalConstInitializer(identifier: ts.Identifier): ts.Expression | undefined;
|
|
28
|
-
export declare function bindingContains(binding: ts.BindingName, name: string): boolean;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import ts from 'typescript';
|
|
2
|
-
import { objectProperty, resolveImportedSymbol, resolveProjectImport, unwrap, visit, } from '../../adapters/typescript/index.js';
|
|
2
|
+
import { bindingContains, objectProperty, resolveImportedSymbol, resolveProjectImport, unwrap, visit, } from '../../adapters/typescript/index.js';
|
|
3
3
|
import { definitionObjects, DSL_MODULES, production, propertyExpression } from './shared.js';
|
|
4
4
|
export function domainFunctionRequirements(project) {
|
|
5
5
|
const domainPath = project.policy.rootFiles.find(({ id }) => id === 'domain')?.sourcePath;
|
|
@@ -227,8 +227,3 @@ export function lexicalConstInitializer(identifier) {
|
|
|
227
227
|
}
|
|
228
228
|
return undefined;
|
|
229
229
|
}
|
|
230
|
-
export function bindingContains(binding, name) {
|
|
231
|
-
if (ts.isIdentifier(binding))
|
|
232
|
-
return binding.text === name;
|
|
233
|
-
return binding.elements.some((element) => !ts.isOmittedExpression(element) && bindingContains(element.name, name));
|
|
234
|
-
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import ts from 'typescript';
|
|
2
2
|
import { propertyChain, resolveImportedSymbol, unwrap, visit, } from '../../adapters/typescript/index.js';
|
|
3
3
|
import { domainFunctionRequirements, callableReference, callableSelector, declaredDomainDependencies, remoteCallableKey, } from './callable-requirements.js';
|
|
4
|
-
import { ambiguity, calls, isForeignDomain, production, violation } from './shared.js';
|
|
4
|
+
import { ambiguity, calls, contextPath, isForeignDomain, production, violation } from './shared.js';
|
|
5
5
|
export const dependencyRules = [
|
|
6
6
|
{
|
|
7
7
|
id: 'FNC-XDOM-DECLARED',
|
|
@@ -158,64 +158,3 @@ function selectedCallable(input) {
|
|
|
158
158
|
const chain = expression && propertyChain(expression);
|
|
159
159
|
return chain && chain[0] === parameter.text ? chain.slice(1) : undefined;
|
|
160
160
|
}
|
|
161
|
-
/** Resolve handler context bindings and one immutable local alias without following arbitrary helpers. */
|
|
162
|
-
function contextPath(input, run, aliases = 1) {
|
|
163
|
-
const expression = unwrap(input);
|
|
164
|
-
if (ts.isPropertyAccessExpression(expression)) {
|
|
165
|
-
const base = contextPath(expression.expression, run, aliases);
|
|
166
|
-
return base && [...base, expression.name.text];
|
|
167
|
-
}
|
|
168
|
-
if (ts.isElementAccessExpression(expression)) {
|
|
169
|
-
const base = contextPath(expression.expression, run, aliases);
|
|
170
|
-
return base && [...base, '[computed]'];
|
|
171
|
-
}
|
|
172
|
-
if (!ts.isIdentifier(expression))
|
|
173
|
-
return undefined;
|
|
174
|
-
let current = expression.parent;
|
|
175
|
-
while (current) {
|
|
176
|
-
if (ts.isFunctionLike(current)) {
|
|
177
|
-
for (const parameter of current.parameters) {
|
|
178
|
-
const path = bindingPath(parameter.name, expression.text);
|
|
179
|
-
if (path)
|
|
180
|
-
return current === run && parameter === run.parameters[0] ? path : undefined;
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
if (ts.isBlock(current) || ts.isSourceFile(current)) {
|
|
184
|
-
for (const statement of current.statements) {
|
|
185
|
-
if (ts.isFunctionDeclaration(statement) && statement.name?.text === expression.text)
|
|
186
|
-
return undefined;
|
|
187
|
-
if (!ts.isVariableStatement(statement))
|
|
188
|
-
continue;
|
|
189
|
-
for (const declaration of statement.declarationList.declarations) {
|
|
190
|
-
const path = bindingPath(declaration.name, expression.text);
|
|
191
|
-
if (!path)
|
|
192
|
-
continue;
|
|
193
|
-
if (aliases === 0 ||
|
|
194
|
-
!declaration.initializer ||
|
|
195
|
-
declaration.end > expression.pos ||
|
|
196
|
-
!(statement.declarationList.flags & ts.NodeFlags.Const))
|
|
197
|
-
return undefined;
|
|
198
|
-
const base = contextPath(declaration.initializer, run, aliases - 1);
|
|
199
|
-
return base && [...base, ...path];
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
current = current.parent;
|
|
204
|
-
}
|
|
205
|
-
return undefined;
|
|
206
|
-
}
|
|
207
|
-
function bindingPath(name, identifier) {
|
|
208
|
-
if (ts.isIdentifier(name))
|
|
209
|
-
return name.text === identifier ? [] : undefined;
|
|
210
|
-
if (!ts.isObjectBindingPattern(name))
|
|
211
|
-
return undefined;
|
|
212
|
-
for (const element of name.elements) {
|
|
213
|
-
if (element.dotDotDotToken)
|
|
214
|
-
continue;
|
|
215
|
-
const nested = bindingPath(element.name, identifier);
|
|
216
|
-
const property = element.propertyName ?? (ts.isIdentifier(element.name) ? element.name : undefined);
|
|
217
|
-
if (nested && property && (ts.isIdentifier(property) || ts.isStringLiteral(property)))
|
|
218
|
-
return [property.text, ...nested];
|
|
219
|
-
}
|
|
220
|
-
return undefined;
|
|
221
|
-
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import ts from 'typescript';
|
|
2
2
|
import { isLocalAlias } from '../../../../platform/graph/alias.js';
|
|
3
|
-
import { expressionType, importedSymbol, propertyChain, staticText, unwrap, visit, } from '../../adapters/typescript/index.js';
|
|
3
|
+
import { expressionType, importedSymbol, propertyChain, staticText, unwrap, visit, visitOwnBody, } from '../../adapters/typescript/index.js';
|
|
4
4
|
import { ambiguity, callback, calls, DSL_MODULES, definitionOriginAmbiguity, definitionObjects, domainProjectorEvidence, forbiddenIoImport, hasForbiddenGlobalCall, production, violation, } from './shared.js';
|
|
5
5
|
import { stateMachineIdentity, statePropertyIdentity } from './state-machine.js';
|
|
6
6
|
const FORBIDDEN_LAYERS = new Set(['integrations', 'functions', 'providers', 'queries']);
|
|
@@ -1399,17 +1399,6 @@ function referencesIdentifier(arguments_, name) {
|
|
|
1399
1399
|
}
|
|
1400
1400
|
return found;
|
|
1401
1401
|
}
|
|
1402
|
-
function visitOwnBody(fn, callback) {
|
|
1403
|
-
if (!fn.body)
|
|
1404
|
-
return;
|
|
1405
|
-
const walk = (node) => {
|
|
1406
|
-
callback(node);
|
|
1407
|
-
if (node !== fn.body && ts.isFunctionLike(node))
|
|
1408
|
-
return;
|
|
1409
|
-
node.forEachChild(walk);
|
|
1410
|
-
};
|
|
1411
|
-
walk(fn.body);
|
|
1412
|
-
}
|
|
1413
1402
|
function returnedValues(fn) {
|
|
1414
1403
|
if (!fn.body)
|
|
1415
1404
|
return 0;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import ts from 'typescript';
|
|
2
|
-
import { importedSymbol, observeQueryDefinitions, propertyChain, queryCollectionKind, unwrap, visit, } from '../../adapters/typescript/index.js';
|
|
2
|
+
import { bindingContains, importedSymbol, observeQueryDefinitions, propertyChain, queryCollectionKind, unwrap, visit, visitOwnBody, } from '../../adapters/typescript/index.js';
|
|
3
3
|
import { decideCanonicalQuery, decideSingleQuery } from '../../analysis/query/index.js';
|
|
4
4
|
import { ambiguity, callback, definitionOriginAmbiguity, definitionObjects, domainProjectorEvidence, propertyExpression, production, returnedExpressions, staticId, violation, } from './shared.js';
|
|
5
5
|
import { sourceEvidence } from './verifier.js';
|
|
@@ -1130,22 +1130,6 @@ function enclosingFunction(node) {
|
|
|
1130
1130
|
current = current.parent;
|
|
1131
1131
|
return current;
|
|
1132
1132
|
}
|
|
1133
|
-
function bindingContains(binding, name) {
|
|
1134
|
-
if (ts.isIdentifier(binding))
|
|
1135
|
-
return binding.text === name;
|
|
1136
|
-
return binding.elements.some((element) => !ts.isOmittedExpression(element) && bindingContains(element.name, name));
|
|
1137
|
-
}
|
|
1138
|
-
function visitOwnBody(fn, callback) {
|
|
1139
|
-
if (!fn.body)
|
|
1140
|
-
return;
|
|
1141
|
-
const walk = (node) => {
|
|
1142
|
-
callback(node);
|
|
1143
|
-
if (node !== fn.body && ts.isFunctionLike(node))
|
|
1144
|
-
return;
|
|
1145
|
-
node.forEachChild(walk);
|
|
1146
|
-
};
|
|
1147
|
-
walk(fn.body);
|
|
1148
|
-
}
|
|
1149
1133
|
function isCompositeLeaf(expression, file) {
|
|
1150
1134
|
if (!expression || !ts.isIdentifier(unwrap(expression)))
|
|
1151
1135
|
return false;
|
|
@@ -25,20 +25,23 @@ export declare function domainProjectorEvidence(file: SourceFile, importedName:
|
|
|
25
25
|
export declare function violation(file: SourceFile, node: ts.Node, evidence: string): SourceRuleEvidence;
|
|
26
26
|
export declare function ambiguity(file: SourceFile, node: ts.Node, evidence: string): SourceRuleEvidence;
|
|
27
27
|
export declare function localTarget(project: SourceProject, file: SourceFile, sourceImport: SourceImport): SourceFile | undefined;
|
|
28
|
-
export declare function importedLayer(project: SourceProject, file: SourceFile, sourceImport: SourceImport): string | undefined;
|
|
29
28
|
export declare function isForeignDomain(specifier: string): boolean;
|
|
30
29
|
export declare function packageRoot(specifier: string): string;
|
|
31
30
|
export declare function isDeepPackageImport(specifier: string): boolean;
|
|
32
31
|
export declare function propertyExpression(object: ts.ObjectLiteralExpression | undefined, name: string): ts.Expression | undefined;
|
|
33
32
|
export declare function callback(object: ts.ObjectLiteralExpression | undefined, name: string): ts.FunctionLikeDeclaration | undefined;
|
|
34
33
|
export declare function returnedExpressions(fn: ts.FunctionLikeDeclaration): ts.Expression[];
|
|
35
|
-
export declare function callChain(expression: ts.Expression): readonly string[] | undefined;
|
|
36
34
|
export declare function staticId(expression: ts.Expression | undefined): string | undefined;
|
|
37
35
|
export declare function hasForbiddenGlobalCall(file: SourceFile): Array<{
|
|
38
36
|
node: ts.Node;
|
|
39
37
|
name: string;
|
|
40
38
|
}>;
|
|
39
|
+
/** The global a call reaches, as `name(…)` with no import or local binding, or `globalThis.name(…)`. */
|
|
40
|
+
export declare function globalCallName(file: SourceFile, node: ts.CallExpression): string | undefined;
|
|
41
|
+
/**
|
|
42
|
+
* Resolve the path of `input` from the first parameter of `run`, or of a durable Step callback in
|
|
43
|
+
* it, through one immutable local alias, without following arbitrary helpers.
|
|
44
|
+
*/
|
|
45
|
+
export declare function contextPath(input: ts.Expression, run: ts.FunctionLikeDeclaration, aliases?: number): readonly string[] | undefined;
|
|
41
46
|
export declare function isLocallyBoundIdentifier(node: ts.Identifier): boolean;
|
|
42
47
|
export declare function forbiddenIoImport(specifier: string): boolean;
|
|
43
|
-
export declare function variableName(call: ts.CallExpression): string | undefined;
|
|
44
|
-
export declare function allPropertyNames(object: ts.ObjectLiteralExpression): string[];
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import ts from 'typescript';
|
|
2
|
-
import { importedSymbol, location, objectProperty, propertyChain, resolveImportedSymbol, resolveProjectImport, staticText, unwrap, visit, } from '../../adapters/typescript/index.js';
|
|
2
|
+
import { bindingContains, importedSymbol, location, objectProperty, propertyChain, resolveImportedSymbol, resolveProjectImport, staticText, unwrap, visit, } from '../../adapters/typescript/index.js';
|
|
3
3
|
export const SDK_MODULES = new Set([
|
|
4
4
|
'@astrale-os/sdk',
|
|
5
5
|
'@astrale-os/sdk/action',
|
|
@@ -159,9 +159,6 @@ export function ambiguity(file, node, evidence) {
|
|
|
159
159
|
export function localTarget(project, file, sourceImport) {
|
|
160
160
|
return resolveProjectImport(project, file, sourceImport.specifier);
|
|
161
161
|
}
|
|
162
|
-
export function importedLayer(project, file, sourceImport) {
|
|
163
|
-
return localTarget(project, file, sourceImport)?.layer;
|
|
164
|
-
}
|
|
165
162
|
export function isForeignDomain(specifier) {
|
|
166
163
|
if (specifier.startsWith('@astrale-domains/'))
|
|
167
164
|
return true;
|
|
@@ -209,14 +206,6 @@ export function returnedExpressions(fn) {
|
|
|
209
206
|
fn.body.forEachChild(walk);
|
|
210
207
|
return expressions;
|
|
211
208
|
}
|
|
212
|
-
export function callChain(expression) {
|
|
213
|
-
const target = unwrap(expression);
|
|
214
|
-
if (ts.isCallExpression(target))
|
|
215
|
-
return propertyChain(target.expression);
|
|
216
|
-
if (ts.isPropertyAccessExpression(target))
|
|
217
|
-
return propertyChain(target);
|
|
218
|
-
return undefined;
|
|
219
|
-
}
|
|
220
209
|
export function staticId(expression) {
|
|
221
210
|
return staticText(expression);
|
|
222
211
|
}
|
|
@@ -226,22 +215,101 @@ export function hasForbiddenGlobalCall(file) {
|
|
|
226
215
|
visit(file.source, (node) => {
|
|
227
216
|
if (!ts.isCallExpression(node))
|
|
228
217
|
return;
|
|
229
|
-
const
|
|
230
|
-
if (
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
218
|
+
const name = globalCallName(file, node);
|
|
219
|
+
if (name !== undefined && forbidden.has(name))
|
|
220
|
+
result.push({ node, name });
|
|
221
|
+
});
|
|
222
|
+
return result;
|
|
223
|
+
}
|
|
224
|
+
/** The global a call reaches, as `name(…)` with no import or local binding, or `globalThis.name(…)`. */
|
|
225
|
+
export function globalCallName(file, node) {
|
|
226
|
+
const expression = unwrap(node.expression);
|
|
227
|
+
if (ts.isIdentifier(expression)) {
|
|
228
|
+
const name = expression.text;
|
|
229
|
+
return importedSymbol(file, expression) || isLocallyBound(expression, name) ? undefined : name;
|
|
230
|
+
}
|
|
231
|
+
const chain = propertyChain(expression);
|
|
232
|
+
if (chain?.length !== 2 || chain[0] !== 'globalThis')
|
|
233
|
+
return undefined;
|
|
234
|
+
let root = expression;
|
|
235
|
+
while (ts.isPropertyAccessExpression(root))
|
|
236
|
+
root = unwrap(root.expression);
|
|
237
|
+
return ts.isIdentifier(root) && isLocallyBound(root, root.text) ? undefined : chain[1];
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* Resolve the path of `input` from the first parameter of `run`, or of a durable Step callback in
|
|
241
|
+
* it, through one immutable local alias, without following arbitrary helpers.
|
|
242
|
+
*/
|
|
243
|
+
export function contextPath(input, run, aliases = 1) {
|
|
244
|
+
const expression = unwrap(input);
|
|
245
|
+
if (ts.isPropertyAccessExpression(expression)) {
|
|
246
|
+
const base = contextPath(expression.expression, run, aliases);
|
|
247
|
+
return base && [...base, expression.name.text];
|
|
248
|
+
}
|
|
249
|
+
if (ts.isElementAccessExpression(expression)) {
|
|
250
|
+
const base = contextPath(expression.expression, run, aliases);
|
|
251
|
+
return base && [...base, '[computed]'];
|
|
252
|
+
}
|
|
253
|
+
if (!ts.isIdentifier(expression))
|
|
254
|
+
return undefined;
|
|
255
|
+
let current = expression.parent;
|
|
256
|
+
while (current) {
|
|
257
|
+
if (ts.isFunctionLike(current)) {
|
|
258
|
+
for (const parameter of current.parameters) {
|
|
259
|
+
const path = bindingPath(parameter.name, expression.text);
|
|
260
|
+
if (path)
|
|
261
|
+
return parameter === current.parameters[0] &&
|
|
262
|
+
(current === run || stepCallback(current, run))
|
|
263
|
+
? path
|
|
264
|
+
: undefined;
|
|
236
265
|
}
|
|
237
|
-
return;
|
|
238
266
|
}
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
267
|
+
if (ts.isBlock(current) || ts.isSourceFile(current)) {
|
|
268
|
+
for (const statement of current.statements) {
|
|
269
|
+
if (ts.isFunctionDeclaration(statement) && statement.name?.text === expression.text)
|
|
270
|
+
return undefined;
|
|
271
|
+
if (!ts.isVariableStatement(statement))
|
|
272
|
+
continue;
|
|
273
|
+
for (const declaration of statement.declarationList.declarations) {
|
|
274
|
+
const path = bindingPath(declaration.name, expression.text);
|
|
275
|
+
if (!path)
|
|
276
|
+
continue;
|
|
277
|
+
if (aliases === 0 ||
|
|
278
|
+
!declaration.initializer ||
|
|
279
|
+
declaration.end > expression.pos ||
|
|
280
|
+
!(statement.declarationList.flags & ts.NodeFlags.Const))
|
|
281
|
+
return undefined;
|
|
282
|
+
const base = contextPath(declaration.initializer, run, aliases - 1);
|
|
283
|
+
return base && [...base, ...path];
|
|
284
|
+
}
|
|
285
|
+
}
|
|
242
286
|
}
|
|
243
|
-
|
|
244
|
-
|
|
287
|
+
current = current.parent;
|
|
288
|
+
}
|
|
289
|
+
return undefined;
|
|
290
|
+
}
|
|
291
|
+
/** A durable Step callback receives the handler's capabilities under the same names. */
|
|
292
|
+
function stepCallback(callback, run) {
|
|
293
|
+
const call = callback.parent;
|
|
294
|
+
if (!ts.isCallExpression(call) || call.arguments[1] !== callback)
|
|
295
|
+
return false;
|
|
296
|
+
const callee = contextPath(call.expression, run, 0);
|
|
297
|
+
return callee?.length === 2 && callee[0] === 'step' && callee[1] === 'run';
|
|
298
|
+
}
|
|
299
|
+
function bindingPath(name, identifier) {
|
|
300
|
+
if (ts.isIdentifier(name))
|
|
301
|
+
return name.text === identifier ? [] : undefined;
|
|
302
|
+
if (!ts.isObjectBindingPattern(name))
|
|
303
|
+
return undefined;
|
|
304
|
+
for (const element of name.elements) {
|
|
305
|
+
if (element.dotDotDotToken)
|
|
306
|
+
continue;
|
|
307
|
+
const nested = bindingPath(element.name, identifier);
|
|
308
|
+
const property = element.propertyName ?? (ts.isIdentifier(element.name) ? element.name : undefined);
|
|
309
|
+
if (nested && property && (ts.isIdentifier(property) || ts.isStringLiteral(property)))
|
|
310
|
+
return [property.text, ...nested];
|
|
311
|
+
}
|
|
312
|
+
return undefined;
|
|
245
313
|
}
|
|
246
314
|
export function isLocallyBoundIdentifier(node) {
|
|
247
315
|
return isLocallyBound(node, node.text);
|
|
@@ -251,22 +319,6 @@ export function forbiddenIoImport(specifier) {
|
|
|
251
319
|
!specifier.startsWith('node:assert') &&
|
|
252
320
|
!specifier.startsWith('node:util/types'));
|
|
253
321
|
}
|
|
254
|
-
export function variableName(call) {
|
|
255
|
-
const parent = call.parent;
|
|
256
|
-
return ts.isVariableDeclaration(parent) && ts.isIdentifier(parent.name)
|
|
257
|
-
? parent.name.text
|
|
258
|
-
: undefined;
|
|
259
|
-
}
|
|
260
|
-
export function allPropertyNames(object) {
|
|
261
|
-
return object.properties.flatMap((property) => {
|
|
262
|
-
if (!('name' in property) || !property.name)
|
|
263
|
-
return [];
|
|
264
|
-
const name = ts.isIdentifier(property.name) || ts.isStringLiteral(property.name)
|
|
265
|
-
? property.name.text
|
|
266
|
-
: undefined;
|
|
267
|
-
return name ? [name] : [];
|
|
268
|
-
});
|
|
269
|
-
}
|
|
270
322
|
function isLocallyBound(node, name) {
|
|
271
323
|
let current = node.parent;
|
|
272
324
|
while (current) {
|
|
@@ -312,8 +364,3 @@ function statementDeclares(statement, name) {
|
|
|
312
364
|
}
|
|
313
365
|
return false;
|
|
314
366
|
}
|
|
315
|
-
function bindingContains(binding, name) {
|
|
316
|
-
if (ts.isIdentifier(binding))
|
|
317
|
-
return binding.text === name;
|
|
318
|
-
return binding.elements.some((element) => ts.isOmittedExpression(element) ? false : bindingContains(element.name, name));
|
|
319
|
-
}
|