@astrale-os/sdk 0.5.0-beta.99 → 0.6.0-beta.0
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/README.md +165 -2
- package/dist/application/action/action.d.ts +7 -4
- package/dist/application/action/authoring.d.ts +2 -1
- package/dist/application/action/context.d.ts +18 -13
- package/dist/application/action/define.d.ts +5 -1
- package/dist/application/action/define.js +6 -1
- package/dist/application/action/index.d.ts +2 -1
- package/dist/application/dependency/index.d.ts +1 -0
- package/dist/application/dependency/invoker.d.ts +26 -0
- package/dist/application/error/error.d.ts +23 -0
- package/dist/application/error/error.js +87 -0
- package/dist/application/error/index.d.ts +2 -0
- package/dist/application/error/index.js +1 -0
- package/dist/application/index.d.ts +2 -2
- package/dist/application/integration/authentication.d.ts +10 -0
- package/dist/application/integration/authentication.typecheck.js +18 -0
- package/dist/application/integration/client.d.ts +2 -0
- package/dist/application/integration/client.js +19 -2
- package/dist/application/integration/index.d.ts +1 -0
- package/dist/application/integration/operation.d.ts +3 -0
- package/dist/application/mutation/authoring/builder.js +2 -2
- package/dist/application/mutation/authoring/endpoint.d.ts +3 -3
- package/dist/application/mutation/authoring/endpoint.js +9 -0
- package/dist/application/mutation/failure.js +13 -7
- package/dist/application/mutation/index.d.ts +1 -0
- package/dist/application/requirements/{profiles.d.ts → core.d.ts} +5 -3
- package/dist/application/requirements/{profiles.js → core.js} +6 -6
- package/dist/application/requirements/index.d.ts +4 -4
- package/dist/application/requirements/index.js +5 -5
- package/dist/application/requirements/requirement.d.ts +3 -2
- package/dist/application/runtime/authoring.d.ts +1 -0
- package/dist/application/runtime/callables.js +2 -2
- package/dist/application/runtime/declarations.d.ts +43 -0
- package/dist/application/runtime/define.d.ts +2 -1
- package/dist/application/view/index.d.ts +1 -1
- package/dist/application/view/route.d.ts +4 -0
- package/dist/application/view/route.js +5 -1
- package/dist/application/workflow/authoring.d.ts +1 -0
- package/dist/application/workflow/context.d.ts +2 -1
- package/dist/application/workflow/define.d.ts +5 -1
- package/dist/application/workflow/define.js +6 -1
- package/dist/application/workflow/index.d.ts +1 -0
- package/dist/application/workflow/runner/runner.d.ts +3 -2
- package/dist/application/workflow/workflow.d.ts +4 -3
- package/dist/deployment/adapter/adapter.d.ts +12 -7
- package/dist/deployment/adapter/define.d.ts +5 -2
- package/dist/deployment/adapter/define.js +15 -17
- package/dist/deployment/adapter/deploy/context.d.ts +6 -0
- package/dist/deployment/adapter/deploy/result.d.ts +2 -0
- package/dist/deployment/adapter/index.d.ts +2 -3
- package/dist/deployment/adapter/index.js +1 -1
- package/dist/deployment/adapter/prepare/context.d.ts +13 -5
- package/dist/deployment/authoring.d.ts +1 -1
- package/dist/deployment/build/compile.js +21 -19
- package/dist/deployment/build/frontend/compilation.d.ts +2 -1
- package/dist/deployment/build/frontend/compilation.js +1 -0
- package/dist/deployment/build/material.js +5 -5
- package/dist/deployment/deploy.d.ts +10 -4
- package/dist/deployment/deploy.js +5 -5
- package/dist/deployment/deployment.d.ts +8 -5
- package/dist/deployment/deployment.js +10 -1
- package/dist/deployment/index.d.ts +5 -4
- package/dist/deployment/index.js +3 -2
- package/dist/deployment/release/addressing.d.ts +6 -2
- package/dist/deployment/release/addressing.js +9 -4
- package/dist/deployment/release/publication/callables.js +1 -1
- package/dist/deployment/release/publication/index.d.ts +1 -1
- package/dist/deployment/release/publication/index.js +1 -1
- package/dist/deployment/release/publication/routes.js +1 -1
- package/dist/deployment/release/publication/seal.d.ts +0 -1
- package/dist/deployment/release/publication/seal.js +4 -5
- package/dist/deployment/release/publication/views.js +2 -1
- package/dist/deployment/verify/preflight/artifact.js +1 -1
- package/dist/deployment/verify/readiness/deployment.js +7 -3
- package/dist/deployment/verify/readiness/identity.js +1 -1
- package/dist/deployment/verify/readiness/publication.js +2 -2
- package/dist/execution/identity/authentication.js +0 -1
- package/dist/execution/identity/exchange.d.ts +1 -0
- package/dist/execution/identity/exchange.js +1 -1
- package/dist/execution/identity/jwks.js +1 -1
- package/dist/execution/invocation/admission/authentication.d.ts +6 -3
- package/dist/execution/invocation/admission/authentication.js +16 -6
- package/dist/execution/invocation/admission/authority.d.ts +2 -2
- package/dist/execution/invocation/dependency/bind.d.ts +5 -0
- package/dist/execution/invocation/dependency/bind.js +68 -0
- package/dist/execution/invocation/dependency/index.d.ts +1 -0
- package/dist/execution/invocation/dependency/index.js +1 -0
- package/dist/execution/invocation/dispatch/action.js +19 -2
- package/dist/execution/invocation/dispatch/context.d.ts +4 -4
- package/dist/execution/invocation/dispatch/context.js +29 -9
- package/dist/execution/invocation/dispatch/workflow.js +17 -4
- package/dist/execution/invocation/integration/authentication.d.ts +5 -0
- package/dist/execution/invocation/integration/authentication.js +53 -0
- package/dist/execution/invocation/integration/call.d.ts +7 -1
- package/dist/execution/invocation/integration/call.js +8 -3
- package/dist/execution/invocation/integration/clients.d.ts +2 -2
- package/dist/execution/invocation/integration/clients.js +2 -2
- package/dist/execution/invocation/lifecycle/active.js +30 -5
- package/dist/execution/invocation/result/errors.d.ts +1 -0
- package/dist/execution/invocation/result/errors.js +15 -10
- package/dist/execution/service/create.js +3 -1
- package/dist/execution/service/service.d.ts +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +1 -0
- package/dist/platform/auth/index.d.ts +1 -1
- package/dist/platform/auth/index.js +0 -1
- package/dist/platform/graph/alias.d.ts +6 -0
- package/dist/platform/graph/alias.js +6 -0
- package/dist/platform/graph/document/index.d.ts +2 -1
- package/dist/platform/graph/document/index.js +2 -1
- package/dist/platform/graph/index.d.ts +2 -1
- package/dist/platform/graph/index.js +2 -1
- package/dist/platform/schema/class-authoring.d.ts +37 -0
- package/dist/platform/schema/class-authoring.js +20 -0
- package/dist/platform/schema/class-icon.d.ts +15 -0
- package/dist/platform/schema/class-icon.js +46 -0
- package/dist/platform/schema/error.d.ts +11 -0
- package/dist/platform/schema/error.js +34 -0
- package/dist/platform/schema/errors/index.d.ts +3 -0
- package/dist/platform/schema/errors/index.js +2 -0
- package/dist/platform/schema/icons/index.d.ts +2 -0
- package/dist/platform/schema/icons/index.js +2 -0
- package/dist/platform/schema/index.d.ts +20 -13
- package/dist/platform/schema/index.js +9 -4
- package/dist/platform/schema/kernel.d.ts +22 -0
- package/dist/platform/schema/kernel.js +5 -0
- package/dist/platform/schema/node-id.d.ts +3 -0
- package/dist/platform/schema/node-id.js +6 -0
- package/dist/platform/schema/property.d.ts +12 -0
- package/dist/platform/schema/property.js +3 -0
- package/dist/platform/schema/schema-authoring.d.ts +48 -0
- package/dist/platform/schema/schema-authoring.js +3 -0
- package/dist/platform/schema/state-property.d.ts +11 -0
- package/dist/platform/schema/state-property.js +3 -0
- package/dist/project/admit.d.ts +4 -0
- package/dist/project/admit.js +22 -0
- package/dist/project/define.d.ts +12 -0
- package/dist/project/define.js +106 -0
- package/dist/project/index.d.ts +4 -0
- package/dist/project/index.js +2 -0
- package/dist/project/project.d.ts +24 -0
- package/dist/project/project.js +1 -0
- package/dist/testing/dataset/admission.d.ts +13 -0
- package/dist/testing/dataset/admission.js +107 -0
- package/dist/testing/dataset/builder.d.ts +42 -0
- package/dist/testing/dataset/builder.js +127 -0
- package/dist/testing/dataset/codec.d.ts +6 -0
- package/dist/testing/dataset/codec.js +113 -0
- package/dist/testing/dataset/dataset.d.ts +58 -0
- package/dist/testing/dataset/dataset.js +2 -0
- package/dist/testing/dataset/define.d.ts +33 -0
- package/dist/testing/dataset/define.js +105 -0
- package/dist/testing/dataset/index.d.ts +8 -0
- package/dist/testing/dataset/index.js +4 -0
- package/dist/testing/dataset/references.d.ts +14 -0
- package/dist/testing/dataset/references.js +56 -0
- package/dist/testing/index.d.ts +9 -0
- package/dist/testing/index.js +5 -0
- package/dist/testing/load.d.ts +14 -0
- package/dist/testing/load.js +44 -0
- package/dist/testing/reference.d.ts +11 -0
- package/dist/testing/reference.js +19 -0
- package/dist/testing/tests.d.ts +12 -0
- package/dist/testing/tests.js +31 -0
- package/dist/tooling/cli/arguments.d.ts +7 -4
- package/dist/tooling/cli/arguments.js +82 -107
- package/dist/tooling/cli/astrale/authority.d.ts +5 -0
- package/dist/tooling/cli/astrale/authority.js +11 -0
- package/dist/tooling/cli/astrale/executable.d.ts +2 -0
- package/dist/tooling/cli/astrale/executable.js +47 -0
- package/dist/tooling/cli/astrale/failure.d.ts +6 -0
- package/dist/tooling/cli/astrale/failure.js +48 -0
- package/dist/tooling/cli/astrale/instance.d.ts +11 -0
- package/dist/tooling/cli/astrale/instance.js +52 -0
- package/dist/tooling/cli/astrale/process.d.ts +13 -0
- package/dist/tooling/cli/astrale/process.js +94 -0
- package/dist/tooling/cli/astrale/version.d.ts +18 -0
- package/dist/tooling/cli/astrale/version.js +55 -0
- package/dist/tooling/cli/bun.js +1 -1
- package/dist/tooling/cli/credential.d.ts +2 -0
- package/dist/tooling/cli/credential.js +57 -0
- package/dist/tooling/cli/development/candidate.d.ts +25 -0
- package/dist/tooling/cli/development/candidate.js +176 -0
- package/dist/tooling/cli/development/deployment.d.ts +16 -0
- package/dist/tooling/cli/development/deployment.js +39 -0
- package/dist/tooling/cli/development/develop.d.ts +4 -3
- package/dist/tooling/cli/development/develop.js +125 -289
- package/dist/tooling/cli/development/lease.d.ts +18 -0
- package/dist/tooling/cli/development/lease.js +163 -0
- package/dist/tooling/cli/development/lifecycle.js +4 -0
- package/dist/tooling/cli/development/project-imports.d.ts +22 -0
- package/dist/tooling/cli/development/project-imports.js +39 -0
- package/dist/tooling/cli/development/project-lock.d.ts +3 -4
- package/dist/tooling/cli/development/project-lock.js +14 -166
- package/dist/tooling/cli/development/release-evidence.d.ts +4 -0
- package/dist/tooling/cli/development/release-evidence.js +10 -0
- package/dist/tooling/cli/development/report.d.ts +6 -0
- package/dist/tooling/cli/development/report.js +14 -0
- package/dist/tooling/cli/development/source-watch.js +53 -5
- package/dist/tooling/cli/development/sources.d.ts +7 -0
- package/dist/tooling/cli/development/sources.js +48 -0
- package/dist/tooling/cli/development/target-lock.d.ts +16 -0
- package/dist/tooling/cli/development/target-lock.js +68 -0
- package/dist/tooling/cli/development/view.d.ts +28 -0
- package/dist/tooling/cli/development/view.js +151 -0
- package/dist/tooling/cli/environment-release.d.ts +21 -0
- package/dist/tooling/cli/environment-release.js +46 -0
- package/dist/tooling/cli/evidence.d.ts +11 -0
- package/dist/tooling/cli/evidence.js +53 -0
- package/dist/tooling/cli/help.js +78 -34
- package/dist/tooling/cli/index.d.ts +1 -1
- package/dist/tooling/cli/index.js +1 -1
- package/dist/tooling/cli/installation/index.d.ts +2 -0
- package/dist/tooling/cli/installation/index.js +1 -0
- package/dist/tooling/cli/installation/observation.d.ts +10 -0
- package/dist/tooling/cli/installation/observation.js +44 -0
- package/dist/tooling/cli/installation/reconcile.d.ts +32 -0
- package/dist/tooling/cli/installation/reconcile.js +122 -0
- package/dist/tooling/cli/orchestrate.js +84 -44
- package/dist/tooling/cli/project.d.ts +17 -0
- package/dist/tooling/cli/project.js +18 -0
- package/dist/tooling/cli/test.d.ts +12 -0
- package/dist/tooling/cli/test.js +47 -0
- package/dist/tooling/cli/upgrade/index.d.ts +6 -0
- package/dist/tooling/cli/upgrade/index.js +115 -0
- package/dist/tooling/cli/upgrade/manifest.d.ts +18 -0
- package/dist/tooling/cli/upgrade/manifest.js +77 -0
- package/dist/tooling/cli/upgrade/process.d.ts +2 -0
- package/dist/tooling/cli/upgrade/process.js +57 -0
- package/dist/tooling/linter/adapters/typescript/imports.js +2 -0
- package/dist/tooling/linter/adapters/typescript/index.d.ts +1 -0
- package/dist/tooling/linter/adapters/typescript/index.js +1 -0
- package/dist/tooling/linter/adapters/typescript/query-collection-type.js +4 -51
- package/dist/tooling/linter/adapters/typescript/type-analysis.d.ts +9 -0
- package/dist/tooling/linter/adapters/typescript/type-analysis.js +55 -0
- package/dist/tooling/linter/implementations/source/callable-requirements.d.ts +28 -0
- package/dist/tooling/linter/implementations/source/callable-requirements.js +234 -0
- package/dist/tooling/linter/implementations/source/dependencies.d.ts +2 -0
- package/dist/tooling/linter/implementations/source/dependencies.js +219 -0
- package/dist/tooling/linter/implementations/source/global.js +52 -2
- package/dist/tooling/linter/implementations/source/mutations.js +520 -38
- package/dist/tooling/linter/implementations/source/providers.js +19 -164
- package/dist/tooling/linter/implementations/source/schema.js +454 -2
- package/dist/tooling/linter/implementations/source/verifiers.js +2 -0
- package/dist/tooling/linter/implementations/source/workflows.js +8 -35
- package/dist/tooling/linter/policy/generated.js +2 -2
- package/dist/tooling/linter/requirements/registry.js +9 -3
- package/dist/tooling/packaging/declarations/normalize.js +3 -38
- package/dist/tooling/packaging/declarations/paths.d.ts +5 -0
- package/dist/tooling/packaging/declarations/paths.js +38 -0
- package/dist/tooling/packaging/finalize.d.ts +13 -0
- package/dist/tooling/packaging/finalize.js +62 -0
- package/dist/tooling/packaging/index.d.ts +2 -0
- package/dist/tooling/packaging/index.js +1 -0
- package/dist/tooling/packaging/javascript.d.ts +3 -0
- package/dist/tooling/packaging/javascript.js +45 -2
- package/dist/tooling/packaging/packaging.d.ts +2 -5
- package/dist/tooling/packaging/packaging.js +6 -30
- package/package.json +42 -12
- package/CHANGELOG.md +0 -1506
- package/dist/deployment/adapter/development/context.d.ts +0 -18
- package/dist/deployment/adapter/development/index.d.ts +0 -4
- package/dist/deployment/adapter/development/input.d.ts +0 -6
- package/dist/deployment/adapter/development/placement.d.ts +0 -15
- package/dist/deployment/adapter/development/session.d.ts +0 -9
- /package/dist/{deployment/adapter/development → application/dependency}/index.js +0 -0
- /package/dist/{deployment/adapter/development/context.js → application/dependency/invoker.js} +0 -0
- /package/dist/{deployment/adapter/development/input.js → application/integration/authentication.js} +0 -0
- /package/dist/{deployment/adapter/development/placement.js → application/integration/authentication.typecheck.d.ts} +0 -0
- /package/dist/{deployment/adapter/development/session.js → application/runtime/declarations.js} +0 -0
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import spawn from 'cross-spawn';
|
|
2
|
+
/** pnpm owns registry configuration, installation policy, and lockfile resolution. */
|
|
3
|
+
export function runPnpm(cwd, args, install = false) {
|
|
4
|
+
return new Promise((resolve, reject) => {
|
|
5
|
+
const child = spawn('pnpm', [...args], {
|
|
6
|
+
cwd,
|
|
7
|
+
stdio: install ? 'inherit' : ['ignore', 'pipe', 'pipe'],
|
|
8
|
+
shell: false,
|
|
9
|
+
});
|
|
10
|
+
let stdout = '';
|
|
11
|
+
let stderr = '';
|
|
12
|
+
let failure;
|
|
13
|
+
let escalation;
|
|
14
|
+
const stop = (reason) => {
|
|
15
|
+
if (failure)
|
|
16
|
+
return;
|
|
17
|
+
failure = new Error(reason);
|
|
18
|
+
child.kill('SIGTERM');
|
|
19
|
+
escalation = setTimeout(() => child.kill('SIGKILL'), 1_000);
|
|
20
|
+
};
|
|
21
|
+
const interrupt = () => stop('Upgrade interrupted; inspect local changes before retrying.');
|
|
22
|
+
process.once('SIGINT', interrupt);
|
|
23
|
+
process.once('SIGTERM', interrupt);
|
|
24
|
+
const timer = setTimeout(() => stop('pnpm timed out.'), install ? 600_000 : 60_000);
|
|
25
|
+
child.stdout?.on('data', (chunk) => {
|
|
26
|
+
stdout += chunk.toString('utf8');
|
|
27
|
+
if (stdout.length > 4 * 1024 * 1024)
|
|
28
|
+
stop('pnpm output exceeded the supported limit.');
|
|
29
|
+
});
|
|
30
|
+
child.stderr?.on('data', (chunk) => {
|
|
31
|
+
stderr += chunk.toString('utf8');
|
|
32
|
+
if (stderr.length > 4 * 1024 * 1024)
|
|
33
|
+
stop('pnpm output exceeded the supported limit.');
|
|
34
|
+
});
|
|
35
|
+
const cleanup = () => {
|
|
36
|
+
clearTimeout(timer);
|
|
37
|
+
if (escalation)
|
|
38
|
+
clearTimeout(escalation);
|
|
39
|
+
process.removeListener('SIGINT', interrupt);
|
|
40
|
+
process.removeListener('SIGTERM', interrupt);
|
|
41
|
+
};
|
|
42
|
+
child.once('error', (cause) => {
|
|
43
|
+
cleanup();
|
|
44
|
+
reject(new Error("Could not start pnpm. Install the project's declared pnpm version.", { cause }));
|
|
45
|
+
});
|
|
46
|
+
child.once('close', (code, signal) => {
|
|
47
|
+
cleanup();
|
|
48
|
+
if (failure)
|
|
49
|
+
reject(failure);
|
|
50
|
+
else if (code !== 0) {
|
|
51
|
+
reject(new Error(`pnpm ${args[0]} failed (${signal ?? code}).${stderr ? `\n${stderr.trim()}` : ''}`));
|
|
52
|
+
}
|
|
53
|
+
else
|
|
54
|
+
resolve(stdout);
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
}
|
|
@@ -150,6 +150,8 @@ function importCandidates(path) {
|
|
|
150
150
|
if (['.js', '.jsx', '.mjs', '.cjs'].includes(extension)) {
|
|
151
151
|
const stem = path.slice(0, -extension.length);
|
|
152
152
|
candidates.push(`${stem}.ts`, `${stem}.tsx`, `${stem}.mts`, `${stem}.cts`);
|
|
153
|
+
const declarationExtension = extension === '.mjs' ? '.d.mts' : extension === '.cjs' ? '.d.cts' : '.d.ts';
|
|
154
|
+
candidates.push(`${stem}${declarationExtension}`);
|
|
153
155
|
}
|
|
154
156
|
if (!extension) {
|
|
155
157
|
candidates.push(`${path}.ts`, `${path}.tsx`, `${path}.mts`, `${path}.cts`);
|
|
@@ -5,6 +5,7 @@ export { importedSymbol, isLocallyDeclared, resolveImportedSymbol, location, obj
|
|
|
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';
|
|
8
|
+
export { expressionType, type ExpressionType } from './type-analysis.js';
|
|
8
9
|
export { collectSuppressionDirectives } from './suppression-directives.js';
|
|
9
10
|
import type ts from 'typescript';
|
|
10
11
|
import type { DomainPolicy } from '../../policy/index.js';
|
|
@@ -5,4 +5,5 @@ export { importedSymbol, isLocallyDeclared, resolveImportedSymbol, location, obj
|
|
|
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';
|
|
8
|
+
export { expressionType } from './type-analysis.js';
|
|
8
9
|
export { collectSuppressionDirectives } from './suppression-directives.js';
|
|
@@ -1,60 +1,13 @@
|
|
|
1
|
-
import { dirname } from 'node:path';
|
|
2
1
|
import ts from 'typescript';
|
|
3
|
-
|
|
2
|
+
import { expressionType } from './type-analysis.js';
|
|
4
3
|
/** Infer the closed collection graph kind only when the Domain's real TypeScript program proves it. */
|
|
5
4
|
export function queryCollectionKind(project, file, expression) {
|
|
6
|
-
const
|
|
7
|
-
if (
|
|
5
|
+
const resolved = expressionType(project, file, expression);
|
|
6
|
+
if (resolved === undefined)
|
|
8
7
|
return undefined;
|
|
9
|
-
const
|
|
10
|
-
if (source === undefined)
|
|
11
|
-
return undefined;
|
|
12
|
-
const node = matchingNode(source, expression.getStart(file.source), expression.end);
|
|
13
|
-
if (node === undefined || !ts.isExpression(node))
|
|
14
|
-
return undefined;
|
|
15
|
-
const kinds = graphKinds(context.checker, context.checker.getTypeAtLocation(node), node);
|
|
8
|
+
const kinds = graphKinds(resolved.checker, resolved.type, resolved.node);
|
|
16
9
|
return kinds.size === 1 ? [...kinds][0] : undefined;
|
|
17
10
|
}
|
|
18
|
-
function typeContext(project) {
|
|
19
|
-
const existing = contexts.get(project);
|
|
20
|
-
if (existing !== undefined)
|
|
21
|
-
return existing;
|
|
22
|
-
try {
|
|
23
|
-
const configPath = ts.findConfigFile(project.root, ts.sys.fileExists);
|
|
24
|
-
if (configPath === undefined)
|
|
25
|
-
return remember(project, null);
|
|
26
|
-
const loaded = ts.readConfigFile(configPath, ts.sys.readFile);
|
|
27
|
-
if (loaded.error !== undefined)
|
|
28
|
-
return remember(project, null);
|
|
29
|
-
const parsed = ts.parseJsonConfigFileContent(loaded.config, ts.sys, dirname(configPath), { noEmit: true }, configPath);
|
|
30
|
-
const context = {
|
|
31
|
-
program: ts.createProgram({ rootNames: parsed.fileNames, options: parsed.options }),
|
|
32
|
-
};
|
|
33
|
-
return remember(project, {
|
|
34
|
-
program: context.program,
|
|
35
|
-
checker: context.program.getTypeChecker(),
|
|
36
|
-
});
|
|
37
|
-
}
|
|
38
|
-
catch {
|
|
39
|
-
return remember(project, null);
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
function remember(project, context) {
|
|
43
|
-
contexts.set(project, context);
|
|
44
|
-
return context;
|
|
45
|
-
}
|
|
46
|
-
function matchingNode(source, start, end) {
|
|
47
|
-
let match;
|
|
48
|
-
const visit = (node) => {
|
|
49
|
-
if (node.getStart(source) > start || node.end < end)
|
|
50
|
-
return;
|
|
51
|
-
if (node.getStart(source) === start && node.end === end)
|
|
52
|
-
match = node;
|
|
53
|
-
node.forEachChild(visit);
|
|
54
|
-
};
|
|
55
|
-
visit(source);
|
|
56
|
-
return match;
|
|
57
|
-
}
|
|
58
11
|
function graphKinds(checker, type, location) {
|
|
59
12
|
const kinds = new Set();
|
|
60
13
|
const inspect = (candidate) => {
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import ts from 'typescript';
|
|
2
|
+
import type { SourceFile, SourceProject } from './index.js';
|
|
3
|
+
export interface ExpressionType {
|
|
4
|
+
readonly checker: ts.TypeChecker;
|
|
5
|
+
readonly node: ts.Expression;
|
|
6
|
+
readonly type: ts.Type;
|
|
7
|
+
}
|
|
8
|
+
/** Resolve an expression against the Domain's admitted TypeScript program. */
|
|
9
|
+
export declare function expressionType(project: SourceProject, file: SourceFile, expression: ts.Expression): ExpressionType | undefined;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { dirname } from 'node:path';
|
|
2
|
+
import ts from 'typescript';
|
|
3
|
+
const contexts = new WeakMap();
|
|
4
|
+
/** Resolve an expression against the Domain's admitted TypeScript program. */
|
|
5
|
+
export function expressionType(project, file, expression) {
|
|
6
|
+
const context = typeContext(project);
|
|
7
|
+
if (context === null)
|
|
8
|
+
return undefined;
|
|
9
|
+
const source = context.program.getSourceFile(file.absolutePath);
|
|
10
|
+
if (source === undefined)
|
|
11
|
+
return undefined;
|
|
12
|
+
const node = matchingNode(source, expression.getStart(file.source), expression.end);
|
|
13
|
+
if (node === undefined || !ts.isExpression(node))
|
|
14
|
+
return undefined;
|
|
15
|
+
return {
|
|
16
|
+
checker: context.checker,
|
|
17
|
+
node,
|
|
18
|
+
type: context.checker.getTypeAtLocation(node),
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
function typeContext(project) {
|
|
22
|
+
const existing = contexts.get(project);
|
|
23
|
+
if (existing !== undefined)
|
|
24
|
+
return existing;
|
|
25
|
+
try {
|
|
26
|
+
const configPath = ts.findConfigFile(project.root, ts.sys.fileExists);
|
|
27
|
+
if (configPath === undefined)
|
|
28
|
+
return remember(project, null);
|
|
29
|
+
const loaded = ts.readConfigFile(configPath, ts.sys.readFile);
|
|
30
|
+
if (loaded.error !== undefined)
|
|
31
|
+
return remember(project, null);
|
|
32
|
+
const parsed = ts.parseJsonConfigFileContent(loaded.config, ts.sys, dirname(configPath), { noEmit: true }, configPath);
|
|
33
|
+
const program = ts.createProgram({ rootNames: parsed.fileNames, options: parsed.options });
|
|
34
|
+
return remember(project, { program, checker: program.getTypeChecker() });
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
return remember(project, null);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
function remember(project, context) {
|
|
41
|
+
contexts.set(project, context);
|
|
42
|
+
return context;
|
|
43
|
+
}
|
|
44
|
+
function matchingNode(source, start, end) {
|
|
45
|
+
let match;
|
|
46
|
+
const visit = (node) => {
|
|
47
|
+
if (node.getStart(source) > start || node.end < end)
|
|
48
|
+
return;
|
|
49
|
+
if (node.getStart(source) === start && node.end === end)
|
|
50
|
+
match = node;
|
|
51
|
+
node.forEachChild(visit);
|
|
52
|
+
};
|
|
53
|
+
visit(source);
|
|
54
|
+
return match;
|
|
55
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import ts from 'typescript';
|
|
2
|
+
import { type SourceFile, type SourceProject } from '../../adapters/typescript/index.js';
|
|
3
|
+
export interface RemoteCallable {
|
|
4
|
+
readonly file: SourceFile;
|
|
5
|
+
readonly node: ts.CallExpression;
|
|
6
|
+
readonly module: string;
|
|
7
|
+
readonly selector: readonly string[];
|
|
8
|
+
}
|
|
9
|
+
export interface FunctionRequirements {
|
|
10
|
+
readonly keys: ReadonlySet<string>;
|
|
11
|
+
readonly indeterminate: boolean;
|
|
12
|
+
}
|
|
13
|
+
export declare function applicationFunctionRequirements(project: SourceProject): FunctionRequirements;
|
|
14
|
+
export declare function requiredCallable(project: SourceProject, file: SourceFile, input: ts.Expression): Pick<RemoteCallable, 'module' | 'selector'> | undefined;
|
|
15
|
+
export declare function declaredDomainDependencies(project: SourceProject): {
|
|
16
|
+
readonly aliases: ReadonlyMap<string, string>;
|
|
17
|
+
readonly indeterminate: boolean;
|
|
18
|
+
};
|
|
19
|
+
export declare function callableSelector(selector: readonly string[]): boolean;
|
|
20
|
+
export declare function externalFacade(module: string): boolean;
|
|
21
|
+
export declare function remoteCallableKey(input: Pick<RemoteCallable, 'module' | 'selector'>): string;
|
|
22
|
+
export declare function callableReference(expression: ts.Expression): {
|
|
23
|
+
readonly expression: ts.Expression;
|
|
24
|
+
readonly resolved: boolean;
|
|
25
|
+
};
|
|
26
|
+
/** Resolve only one immutable lexical alias; the linter does not emulate program execution. */
|
|
27
|
+
export declare function lexicalConstInitializer(identifier: ts.Identifier): ts.Expression | undefined;
|
|
28
|
+
export declare function bindingContains(binding: ts.BindingName, name: string): boolean;
|
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
import ts from 'typescript';
|
|
2
|
+
import { objectProperty, resolveImportedSymbol, resolveProjectImport, unwrap, visit, } from '../../adapters/typescript/index.js';
|
|
3
|
+
import { definitionObjects, DSL_MODULES, production, propertyExpression } from './shared.js';
|
|
4
|
+
export function applicationFunctionRequirements(project) {
|
|
5
|
+
const applicationPath = project.policy.rootFiles.find(({ id }) => id === 'application')?.sourcePath;
|
|
6
|
+
const file = applicationPath && project.filesByPath.get(applicationPath);
|
|
7
|
+
if (!file)
|
|
8
|
+
return { keys: new Set(), indeterminate: true };
|
|
9
|
+
const applications = [];
|
|
10
|
+
visit(file.source, (node) => {
|
|
11
|
+
if (!ts.isCallExpression(node))
|
|
12
|
+
return;
|
|
13
|
+
const symbol = resolveImportedSymbol(file, node.expression);
|
|
14
|
+
if (symbol.kind === 'resolved' &&
|
|
15
|
+
symbol.name === 'defineApplication' &&
|
|
16
|
+
(symbol.module === '@astrale-os/sdk' || symbol.module === '@astrale-os/sdk/application')) {
|
|
17
|
+
applications.push(node);
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
if (applications.length !== 1)
|
|
21
|
+
return { keys: new Set(), indeterminate: true };
|
|
22
|
+
const input = applications[0].arguments[0];
|
|
23
|
+
if (!input || !ts.isObjectLiteralExpression(unwrap(input))) {
|
|
24
|
+
return { keys: new Set(), indeterminate: true };
|
|
25
|
+
}
|
|
26
|
+
const requirementsProperty = objectProperty(unwrap(input), 'requirements');
|
|
27
|
+
if (requirementsProperty === undefined)
|
|
28
|
+
return { keys: new Set(), indeterminate: false };
|
|
29
|
+
const requirementsInput = ts.isPropertyAssignment(requirementsProperty)
|
|
30
|
+
? requirementsProperty.initializer
|
|
31
|
+
: ts.isShorthandPropertyAssignment(requirementsProperty)
|
|
32
|
+
? requirementsProperty.name
|
|
33
|
+
: undefined;
|
|
34
|
+
if (!requirementsInput)
|
|
35
|
+
return { keys: new Set(), indeterminate: true };
|
|
36
|
+
const requirementsCall = callableReference(unwrap(requirementsInput)).expression;
|
|
37
|
+
if (!ts.isCallExpression(requirementsCall))
|
|
38
|
+
return { keys: new Set(), indeterminate: true };
|
|
39
|
+
const requirementsSymbol = resolveImportedSymbol(file, requirementsCall.expression);
|
|
40
|
+
if (requirementsSymbol.kind !== 'resolved' ||
|
|
41
|
+
requirementsSymbol.name !== 'requirements' ||
|
|
42
|
+
(requirementsSymbol.module !== '@astrale-os/sdk' &&
|
|
43
|
+
requirementsSymbol.module !== '@astrale-os/sdk/application')) {
|
|
44
|
+
return { keys: new Set(), indeterminate: true };
|
|
45
|
+
}
|
|
46
|
+
const definition = requirementsCall.arguments[0];
|
|
47
|
+
if (definition === undefined)
|
|
48
|
+
return { keys: new Set(), indeterminate: false };
|
|
49
|
+
if (!ts.isObjectLiteralExpression(unwrap(definition))) {
|
|
50
|
+
return { keys: new Set(), indeterminate: true };
|
|
51
|
+
}
|
|
52
|
+
const functions = objectProperty(unwrap(definition), 'functions');
|
|
53
|
+
if (functions === undefined)
|
|
54
|
+
return { keys: new Set(), indeterminate: false };
|
|
55
|
+
if (!ts.isPropertyAssignment(functions))
|
|
56
|
+
return { keys: new Set(), indeterminate: true };
|
|
57
|
+
const values = unwrap(functions.initializer);
|
|
58
|
+
if (!ts.isArrayLiteralExpression(values))
|
|
59
|
+
return { keys: new Set(), indeterminate: true };
|
|
60
|
+
const keys = new Set();
|
|
61
|
+
let indeterminate = false;
|
|
62
|
+
for (const element of values.elements) {
|
|
63
|
+
if (ts.isSpreadElement(element)) {
|
|
64
|
+
indeterminate = true;
|
|
65
|
+
continue;
|
|
66
|
+
}
|
|
67
|
+
const target = requiredCallable(project, file, element);
|
|
68
|
+
if (target === undefined)
|
|
69
|
+
indeterminate = true;
|
|
70
|
+
else
|
|
71
|
+
keys.add(remoteCallableKey(target));
|
|
72
|
+
}
|
|
73
|
+
return { keys, indeterminate };
|
|
74
|
+
}
|
|
75
|
+
export function requiredCallable(project, file, input) {
|
|
76
|
+
const admitted = callableReference(unwrap(input));
|
|
77
|
+
if (!admitted.resolved)
|
|
78
|
+
return undefined;
|
|
79
|
+
let current = admitted.expression;
|
|
80
|
+
const selector = [];
|
|
81
|
+
while (ts.isPropertyAccessExpression(unwrap(current))) {
|
|
82
|
+
const property = unwrap(current);
|
|
83
|
+
selector.unshift(property.name.text);
|
|
84
|
+
current = unwrap(property.expression);
|
|
85
|
+
}
|
|
86
|
+
if (ts.isIdentifier(current))
|
|
87
|
+
current = callableReference(current).expression;
|
|
88
|
+
if (!ts.isCallExpression(current))
|
|
89
|
+
return undefined;
|
|
90
|
+
const resolve = unwrap(current.expression);
|
|
91
|
+
if (!ts.isPropertyAccessExpression(resolve) || resolve.name.text !== 'resolve')
|
|
92
|
+
return undefined;
|
|
93
|
+
const schemaSymbol = resolveImportedSymbol(file, resolve.expression);
|
|
94
|
+
if (schemaSymbol.kind !== 'resolved' ||
|
|
95
|
+
schemaSymbol.name !== 'schema' ||
|
|
96
|
+
schemaSymbol.module !== '@astrale-os/sdk/schema') {
|
|
97
|
+
return undefined;
|
|
98
|
+
}
|
|
99
|
+
const schemaValue = current.arguments[0];
|
|
100
|
+
if (!schemaValue)
|
|
101
|
+
return undefined;
|
|
102
|
+
const facade = resolveImportedSymbol(file, schemaValue);
|
|
103
|
+
if (facade.kind === 'resolved' && externalFacade(facade.module)) {
|
|
104
|
+
if (!callableSelector(selector))
|
|
105
|
+
return undefined;
|
|
106
|
+
return { module: facade.module, selector: Object.freeze(selector) };
|
|
107
|
+
}
|
|
108
|
+
if (facade.kind === 'local')
|
|
109
|
+
return undefined;
|
|
110
|
+
const localSchema = resolveProjectImport(project, file, facade.module);
|
|
111
|
+
if (facade.name !== 'schema' ||
|
|
112
|
+
localSchema?.layer !== 'schema' ||
|
|
113
|
+
selector[0] !== 'dependencies' ||
|
|
114
|
+
selector[1] === undefined) {
|
|
115
|
+
return undefined;
|
|
116
|
+
}
|
|
117
|
+
const callable = selector.slice(2);
|
|
118
|
+
if (!callableSelector(callable))
|
|
119
|
+
return undefined;
|
|
120
|
+
const dependency = declaredDomainDependencies(project).aliases.get(selector[1]);
|
|
121
|
+
return dependency === undefined
|
|
122
|
+
? undefined
|
|
123
|
+
: { module: dependency, selector: Object.freeze(callable) };
|
|
124
|
+
}
|
|
125
|
+
export function declaredDomainDependencies(project) {
|
|
126
|
+
const aliases = new Map();
|
|
127
|
+
let indeterminate = false;
|
|
128
|
+
let definitions = 0;
|
|
129
|
+
for (const file of production(project, 'schema')) {
|
|
130
|
+
for (const definition of definitionObjects(file, 'defineSchema', undefined, DSL_MODULES, 1)) {
|
|
131
|
+
definitions++;
|
|
132
|
+
if (definition.origin !== 'resolved' || !definition.object) {
|
|
133
|
+
indeterminate = true;
|
|
134
|
+
continue;
|
|
135
|
+
}
|
|
136
|
+
const value = propertyExpression(definition.object, 'dependencies');
|
|
137
|
+
if (!value)
|
|
138
|
+
continue;
|
|
139
|
+
if (!ts.isObjectLiteralExpression(value)) {
|
|
140
|
+
indeterminate = true;
|
|
141
|
+
continue;
|
|
142
|
+
}
|
|
143
|
+
for (const property of value.properties) {
|
|
144
|
+
const input = ts.isPropertyAssignment(property)
|
|
145
|
+
? property.initializer
|
|
146
|
+
: ts.isShorthandPropertyAssignment(property)
|
|
147
|
+
? property.name
|
|
148
|
+
: undefined;
|
|
149
|
+
const name = property.name;
|
|
150
|
+
const alias = name && (ts.isIdentifier(name) || ts.isStringLiteral(name)) ? name.text : undefined;
|
|
151
|
+
if (!input || !alias) {
|
|
152
|
+
indeterminate = true;
|
|
153
|
+
continue;
|
|
154
|
+
}
|
|
155
|
+
const symbol = resolveImportedSymbol(file, input);
|
|
156
|
+
if (symbol.kind === 'resolved' &&
|
|
157
|
+
symbol.name === 'KernelSchema' &&
|
|
158
|
+
['@astrale-os/sdk/schema', '@astrale-os/kernel-core'].includes(symbol.module)) {
|
|
159
|
+
continue;
|
|
160
|
+
}
|
|
161
|
+
if (symbol.kind !== 'resolved' || !externalFacade(symbol.module)) {
|
|
162
|
+
indeterminate = true;
|
|
163
|
+
continue;
|
|
164
|
+
}
|
|
165
|
+
if (aliases.has(alias) && aliases.get(alias) !== symbol.module) {
|
|
166
|
+
aliases.delete(alias);
|
|
167
|
+
indeterminate = true;
|
|
168
|
+
continue;
|
|
169
|
+
}
|
|
170
|
+
aliases.set(alias, symbol.module);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
return { aliases, indeterminate: indeterminate || definitions !== 1 };
|
|
175
|
+
}
|
|
176
|
+
export function callableSelector(selector) {
|
|
177
|
+
return ((selector.length === 2 && selector[0] === 'functions') ||
|
|
178
|
+
(selector.length === 4 && selector[0] === 'classes' && selector[2] === 'methods') ||
|
|
179
|
+
(selector.length === 5 &&
|
|
180
|
+
selector[0] === 'classes' &&
|
|
181
|
+
selector[2] === 'static' &&
|
|
182
|
+
selector[3] === 'methods'));
|
|
183
|
+
}
|
|
184
|
+
export function externalFacade(module) {
|
|
185
|
+
return (!module.startsWith('.') &&
|
|
186
|
+
!module.startsWith('#') &&
|
|
187
|
+
!module.startsWith('@astrale-os/sdk') &&
|
|
188
|
+
!module.startsWith('@astrale-os/kernel-'));
|
|
189
|
+
}
|
|
190
|
+
export function remoteCallableKey(input) {
|
|
191
|
+
return `${input.module}\0${input.selector.join('\0')}`;
|
|
192
|
+
}
|
|
193
|
+
export function callableReference(expression) {
|
|
194
|
+
if (!ts.isIdentifier(expression))
|
|
195
|
+
return { expression, resolved: true };
|
|
196
|
+
const initializer = lexicalConstInitializer(expression);
|
|
197
|
+
return initializer === undefined
|
|
198
|
+
? { expression, resolved: false }
|
|
199
|
+
: { expression: unwrap(initializer), resolved: true };
|
|
200
|
+
}
|
|
201
|
+
/** Resolve only one immutable lexical alias; the linter does not emulate program execution. */
|
|
202
|
+
export function lexicalConstInitializer(identifier) {
|
|
203
|
+
let child = identifier;
|
|
204
|
+
let current = identifier.parent;
|
|
205
|
+
while (current) {
|
|
206
|
+
if (ts.isFunctionLike(current)) {
|
|
207
|
+
if (current.parameters.some(({ name }) => bindingContains(name, identifier.text))) {
|
|
208
|
+
return undefined;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
if (ts.isBlock(current) || ts.isSourceFile(current) || ts.isModuleBlock(current)) {
|
|
212
|
+
const index = current.statements.findIndex((statement) => statement.pos <= child.pos && statement.end >= child.end);
|
|
213
|
+
const before = index < 0 ? current.statements : current.statements.slice(0, index);
|
|
214
|
+
for (const statement of [...before].reverse()) {
|
|
215
|
+
if (!ts.isVariableStatement(statement))
|
|
216
|
+
continue;
|
|
217
|
+
const declaration = statement.declarationList.declarations.find(({ name }) => ts.isIdentifier(name) && name.text === identifier.text);
|
|
218
|
+
if (!declaration)
|
|
219
|
+
continue;
|
|
220
|
+
return (statement.declarationList.flags & ts.NodeFlags.Const) !== 0
|
|
221
|
+
? declaration.initializer
|
|
222
|
+
: undefined;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
child = current;
|
|
226
|
+
current = current.parent;
|
|
227
|
+
}
|
|
228
|
+
return undefined;
|
|
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
|
+
}
|