@sjcx/vorma 0.0.0-pre.0 → 0.0.0-pre.1
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/build/cli.js +8 -17
- package/dist/build/development-sources.d.ts +1 -2
- package/dist/build/index.js +1 -1
- package/dist/build/inspect-projects.d.ts +2 -2
- package/dist/build/render-types.d.ts +4 -4
- package/dist/build/typescript-projects.d.ts +3 -1
- package/dist/{build-JgARonaY.js → build-DcP5_DUV.js} +299 -280
- package/package.json +2 -2
package/dist/build/cli.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { C as
|
|
2
|
+
import { C as encodeCanonicalJson, S as projectBrowserContracts, _ as createClientPublicUrlPlugin, a as acquireOutputOwnership, b as CLIENT_SHARED_PACKAGES, c as writeAndCheckApplicationGeneration, d as readTypescriptProjectRoots, f as runTypescriptOperation, g as createCssPublicAssets, h as resolveVormaConfig, i as publishApplicationArtifacts, l as collectPublicAssets, m as getGeneratedSourceDirectories, n as loadApplicationSourceLayout, o as checkOutputPath, p as withTypescriptProjects, r as preparePublicOutput, s as assembleApplicationGeneration, t as buildApplication, u as inspectProjects, v as compileServerApplication, w as toContentDigest, x as getClientViewEntries, y as containsRelativePath } from "../build-DcP5_DUV.js";
|
|
3
3
|
import { g as DEVELOPMENT_PROTOCOL, y as FRAMEWORK_IDENTITY_PROTOCOL } from "../value-transport-Bst4Hk-n.js";
|
|
4
4
|
import { t as VORMA_BUILD_PLUGIN_NAME } from "../build-invocation-D7Fu8gBK.js";
|
|
5
5
|
import { VormaConfigSchema } from "../server/config/index.js";
|
|
@@ -510,22 +510,13 @@ function inspectDevelopmentSources(layout) {
|
|
|
510
510
|
projects,
|
|
511
511
|
layout
|
|
512
512
|
});
|
|
513
|
-
const sources = yield*
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
};
|
|
521
|
-
},
|
|
522
|
-
catch: (cause) => {
|
|
523
|
-
return {
|
|
524
|
-
_tag: "TypescriptProjectError",
|
|
525
|
-
message: "Could not read TypeScript development inputs",
|
|
526
|
-
cause
|
|
527
|
-
};
|
|
528
|
-
}
|
|
513
|
+
const sources = yield* runTypescriptOperation(async () => {
|
|
514
|
+
return {
|
|
515
|
+
serverRootFiles: new Set(projects.server.rootFiles.map(normalizePath)),
|
|
516
|
+
clientRootFiles: new Set(projects.client.rootFiles.map(normalizePath)),
|
|
517
|
+
serverFiles: new Set((await projects.server.program.getSourceFileNames()).map(normalizePath)),
|
|
518
|
+
clientFiles: new Set((await projects.client.program.getSourceFileNames()).map(normalizePath))
|
|
519
|
+
};
|
|
529
520
|
});
|
|
530
521
|
return {
|
|
531
522
|
inspection,
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { Effect, Path } from "effect";
|
|
2
2
|
import type { ApplicationSourceLayout } from "./source-layout.ts";
|
|
3
|
-
import { type TypescriptProjectError } from "./typescript-projects.ts";
|
|
4
3
|
export type DevelopmentSourceInputs = {
|
|
5
4
|
readonly serverFiles: ReadonlySet<string>;
|
|
6
5
|
readonly clientFiles: ReadonlySet<string>;
|
|
@@ -15,7 +14,7 @@ export type DevelopmentSourceInputs = {
|
|
|
15
14
|
export declare function inspectDevelopmentSources(layout: ApplicationSourceLayout): Effect.Effect<{
|
|
16
15
|
inspection: import("./inspect-projects.ts").InspectedProjects;
|
|
17
16
|
inputs: DevelopmentSourceInputs;
|
|
18
|
-
}, import("./inspect-projects.ts").InspectionIssue | TypescriptProjectError, Path.Path>;
|
|
17
|
+
}, import("./inspect-projects.ts").InspectionIssue | import("./typescript-projects.ts").TypescriptProjectError, Path.Path>;
|
|
19
18
|
/** Watches native compiler inputs while keeping generated writes out of the event stream. */
|
|
20
19
|
export declare function getDevelopmentSourceWatchPaths(input: {
|
|
21
20
|
readonly layout: ApplicationSourceLayout;
|
package/dist/build/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as buildApplication } from "../build-
|
|
1
|
+
import { t as buildApplication } from "../build-DcP5_DUV.js";
|
|
2
2
|
export { buildApplication };
|
|
@@ -3,7 +3,7 @@ import * as Path from "effect/Path";
|
|
|
3
3
|
import type { HttpMethod, InputTransport } from "../server/graph/declarations.ts";
|
|
4
4
|
import type { EffectTransportMarkKind } from "../universal/value-transport.ts";
|
|
5
5
|
import type { ApplicationSourceLayout } from "./source-layout.ts";
|
|
6
|
-
import type
|
|
6
|
+
import { type TypescriptProjectError, type TypescriptProjects } from "./typescript-projects.ts";
|
|
7
7
|
export type DeclarationSource = {
|
|
8
8
|
readonly filePath: string;
|
|
9
9
|
readonly exportName: string;
|
|
@@ -66,4 +66,4 @@ export type InspectionIssue = {
|
|
|
66
66
|
export declare function inspectProjects(input: {
|
|
67
67
|
readonly projects: TypescriptProjects;
|
|
68
68
|
readonly layout: ApplicationSourceLayout;
|
|
69
|
-
}): Effect.Effect<InspectedProjects, InspectionIssue, Path.Path>;
|
|
69
|
+
}): Effect.Effect<InspectedProjects, InspectionIssue | TypescriptProjectError, Path.Path>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Result } from "effect";
|
|
2
|
-
import { type Checker, type Emitter, type Program, type Symbol as TypeSymbol, type Type } from "typescript/unstable/
|
|
2
|
+
import { type Checker, type Emitter, type Program, type Symbol as TypeSymbol, type Type } from "typescript/unstable/async";
|
|
3
3
|
import type { EffectTransportMarkKind } from "../universal/value-transport.ts";
|
|
4
4
|
export type TypeRenderIssue = {
|
|
5
5
|
readonly _tag: "UnrenderableContractType";
|
|
@@ -11,7 +11,7 @@ export type TypeRenderer = {
|
|
|
11
11
|
readonly renderType: (input: {
|
|
12
12
|
readonly type: Type;
|
|
13
13
|
readonly depth: number;
|
|
14
|
-
}) => Result.Result<string, TypeRenderIssue
|
|
14
|
+
}) => Promise<Result.Result<string, TypeRenderIssue>>;
|
|
15
15
|
/** The alias declarations that rendering needed, each at depth zero. */
|
|
16
16
|
readonly renderAliases: () => ReadonlyArray<string>;
|
|
17
17
|
/** The Effect modules that rendered text names, for the generated file's type imports. */
|
|
@@ -23,9 +23,9 @@ export type TypeRenderer = {
|
|
|
23
23
|
export declare function matchesLibrarySymbol(input: {
|
|
24
24
|
readonly program: Program;
|
|
25
25
|
readonly symbol: TypeSymbol;
|
|
26
|
-
}): boolean
|
|
26
|
+
}): Promise<boolean>;
|
|
27
27
|
export declare function createTypeRenderer(input: {
|
|
28
28
|
readonly checker: Checker;
|
|
29
29
|
readonly program: Program;
|
|
30
30
|
readonly emitter: Emitter;
|
|
31
|
-
}): TypeRenderer
|
|
31
|
+
}): Promise<TypeRenderer>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Effect } from "effect";
|
|
2
|
-
import { type APIOptions, type Project } from "typescript/unstable/
|
|
2
|
+
import { type APIOptions, type Project } from "typescript/unstable/async";
|
|
3
3
|
export type TypescriptProjectError = {
|
|
4
4
|
readonly _tag: "TypescriptProjectError";
|
|
5
5
|
readonly message: string;
|
|
@@ -34,3 +34,5 @@ export declare function withTypescriptProjects<A, E, R>(input: {
|
|
|
34
34
|
readonly fileSystem?: APIOptions["fs"];
|
|
35
35
|
readonly useFn: (projects: TypescriptProjects) => Effect.Effect<A, E, R>;
|
|
36
36
|
}): Effect.Effect<A, E | TypescriptProjectError, R>;
|
|
37
|
+
/** Native compiler operations have no cancellation API; settle each operation before its session can close. */
|
|
38
|
+
export declare function runTypescriptOperation<Value>(fn: () => Promise<Value>): Effect.Effect<Value, TypescriptProjectError, never>;
|
|
@@ -12,7 +12,7 @@ import { RolldownMagicString, build as build$1 } from "rolldown";
|
|
|
12
12
|
import { readFile } from "node:fs/promises";
|
|
13
13
|
import * as Path$1 from "effect/Path";
|
|
14
14
|
import { SyntaxKind, TokenFlags, isAsExpression, isCallExpression, isElementAccessExpression, isExportSpecifier, isIdentifier, isImportClause, isImportSpecifier, isNamespaceImport, isNoSubstitutionTemplateLiteral, isNonNullExpression, isParenthesizedExpression, isPropertyAccessExpression, isSatisfiesExpression, isStringLiteral, isTypeAssertion, isTypeNode } from "typescript/unstable/ast";
|
|
15
|
-
import { API, ElementFlags, SignatureKind, SymbolFlags } from "typescript/unstable/
|
|
15
|
+
import { API, ElementFlags, SignatureKind, SymbolFlags } from "typescript/unstable/async";
|
|
16
16
|
import { createTemplateHead, createTemplateMiddle, createTemplateTail } from "typescript/unstable/ast/factory";
|
|
17
17
|
import * as FileSystem$1 from "effect/FileSystem";
|
|
18
18
|
import { pid, platform } from "node:process";
|
|
@@ -455,8 +455,8 @@ function toRelativeSpecifier(relativePath) {
|
|
|
455
455
|
//#endregion
|
|
456
456
|
//#region src/build/render-types.ts
|
|
457
457
|
/** Removes the checker's missing-value marker, which is distinct from the ordinary `undefined` type. */
|
|
458
|
-
function withoutAbsence(input) {
|
|
459
|
-
const members = input.type.isUnionType() ? input.type.getTypes() : [input.type];
|
|
458
|
+
async function withoutAbsence(input) {
|
|
459
|
+
const members = input.type.isUnionType() ? await input.type.getTypes() : [input.type];
|
|
460
460
|
const present = members.filter((member) => {
|
|
461
461
|
return !(member.isIntrinsicType() && member.intrinsicName === "undefined" && member.id !== input.undefinedType.id);
|
|
462
462
|
});
|
|
@@ -543,26 +543,26 @@ function sortProperties(properties) {
|
|
|
543
543
|
});
|
|
544
544
|
}
|
|
545
545
|
/** True when a symbol is declared outside the application: in a default library or an installed package. */
|
|
546
|
-
function matchesLibrarySymbol(input) {
|
|
546
|
+
async function matchesLibrarySymbol(input) {
|
|
547
547
|
const declaration = input.symbol.declarations[0];
|
|
548
548
|
if (declaration === void 0) return false;
|
|
549
549
|
const declarationPath = String(declaration.path);
|
|
550
|
-
const metadata = input.program.getSourceFileMetadata(declarationPath);
|
|
550
|
+
const metadata = await input.program.getSourceFileMetadata(declarationPath);
|
|
551
551
|
return metadata !== void 0 && (metadata.isDefaultLibrary || metadata.isFromExternalLibrary || declarationPath.includes("/node_modules/"));
|
|
552
552
|
}
|
|
553
|
-
function createTypeRenderer(input) {
|
|
553
|
+
async function createTypeRenderer(input) {
|
|
554
554
|
const { checker, program, emitter } = input;
|
|
555
|
-
const undefinedType = checker.getUndefinedType();
|
|
555
|
+
const undefinedType = await checker.getUndefinedType();
|
|
556
556
|
const aliases = /* @__PURE__ */ new Map();
|
|
557
557
|
const rendered = [];
|
|
558
558
|
const visiting = /* @__PURE__ */ new Set();
|
|
559
559
|
const effectModules = /* @__PURE__ */ new Set();
|
|
560
560
|
const transportTypeNames = /* @__PURE__ */ new Set();
|
|
561
|
-
function fail(type, reason) {
|
|
561
|
+
async function fail(type, reason) {
|
|
562
562
|
return Result.fail({
|
|
563
563
|
_tag: "UnrenderableContractType",
|
|
564
564
|
reason,
|
|
565
|
-
typeText: checker.typeToString(type)
|
|
565
|
+
typeText: await checker.typeToString(type)
|
|
566
566
|
});
|
|
567
567
|
}
|
|
568
568
|
function getDeclarationPath(symbol) {
|
|
@@ -576,72 +576,72 @@ function createTypeRenderer(input) {
|
|
|
576
576
|
return entry.symbolName === symbol.name && declarationPath.endsWith(`/effect/dist/${entry.module}.d.ts`);
|
|
577
577
|
});
|
|
578
578
|
}
|
|
579
|
-
function matchesReadonlyProperty(property) {
|
|
579
|
+
async function matchesReadonlyProperty(property) {
|
|
580
580
|
if ((property.checkFlags & CHECK_FLAG_READONLY) !== 0) return true;
|
|
581
|
-
const declaration = property.valueDeclaration?.resolve();
|
|
581
|
+
const declaration = await property.valueDeclaration?.resolve();
|
|
582
582
|
if (declaration === void 0) return false;
|
|
583
583
|
const modifiers = declaration.modifiers;
|
|
584
584
|
return modifiers !== void 0 && modifiers.some((modifier) => {
|
|
585
585
|
return modifier.kind === SyntaxKind.ReadonlyKeyword;
|
|
586
586
|
});
|
|
587
587
|
}
|
|
588
|
-
function renderTypeArguments(type, depth) {
|
|
588
|
+
async function renderTypeArguments(type, depth) {
|
|
589
589
|
const parts = [];
|
|
590
|
-
for (const argument of checker.getTypeArguments(type)) {
|
|
591
|
-
const text = renderNode(argument, depth);
|
|
590
|
+
for (const argument of await checker.getTypeArguments(type)) {
|
|
591
|
+
const text = await renderNode(argument, depth);
|
|
592
592
|
if (Result.isFailure(text)) return text;
|
|
593
593
|
parts.push(text.success);
|
|
594
594
|
}
|
|
595
595
|
return Result.succeed(parts.length === 0 ? "" : `<${parts.join(", ")}>`);
|
|
596
596
|
}
|
|
597
|
-
function renderNamedType(type, depth) {
|
|
598
|
-
const aliasSymbol = type.getAliasSymbol();
|
|
599
|
-
const symbol = type.getSymbol();
|
|
597
|
+
async function renderNamedType(type, depth) {
|
|
598
|
+
const aliasSymbol = await type.getAliasSymbol();
|
|
599
|
+
const symbol = await type.getSymbol();
|
|
600
600
|
for (const candidate of [aliasSymbol, symbol]) {
|
|
601
601
|
if (candidate === void 0) continue;
|
|
602
602
|
const effectType = matchesEffectType(candidate);
|
|
603
603
|
if (effectType !== void 0) {
|
|
604
604
|
effectModules.add(effectType.module);
|
|
605
605
|
transportTypeNames.add(effectType.kind);
|
|
606
|
-
const argumentTypes = candidate === aliasSymbol ? type.getAliasTypeArguments() : type.isTypeReference() ? checker.getTypeArguments(type) : [];
|
|
606
|
+
const argumentTypes = candidate === aliasSymbol ? await type.getAliasTypeArguments() : type.isTypeReference() ? await checker.getTypeArguments(type) : [];
|
|
607
607
|
const parts = [];
|
|
608
608
|
for (const argument of argumentTypes) {
|
|
609
|
-
const text = renderNode(argument, depth);
|
|
609
|
+
const text = await renderNode(argument, depth);
|
|
610
610
|
if (Result.isFailure(text)) return text;
|
|
611
611
|
parts.push(text.success);
|
|
612
612
|
}
|
|
613
613
|
return Result.succeed(parts.length === 0 ? effectType.printedName : `${effectType.printedName}<${parts.join(", ")}>`);
|
|
614
614
|
}
|
|
615
615
|
}
|
|
616
|
-
if (symbol !== void 0 && PLATFORM_TYPE_NAMES.has(symbol.name) && matchesLibrarySymbol({
|
|
616
|
+
if (symbol !== void 0 && PLATFORM_TYPE_NAMES.has(symbol.name) && await matchesLibrarySymbol({
|
|
617
617
|
program,
|
|
618
618
|
symbol
|
|
619
619
|
})) {
|
|
620
|
-
const argumentsText = type.isTypeReference() ? renderTypeArguments(type, depth) : Result.succeed("");
|
|
620
|
+
const argumentsText = type.isTypeReference() ? await renderTypeArguments(type, depth) : Result.succeed("");
|
|
621
621
|
return Result.map(argumentsText, (text) => `${symbol.name}${text}`);
|
|
622
622
|
}
|
|
623
623
|
return Result.succeed(null);
|
|
624
624
|
}
|
|
625
|
-
function renderProperty(input) {
|
|
626
|
-
if (checker.getSignaturesOfType(input.propertyType, SignatureKind.Call).length > 0) return fail(input.propertyType, `the property ${input.property.name} is a function, which cannot cross the wire`);
|
|
625
|
+
async function renderProperty(input) {
|
|
626
|
+
if ((await checker.getSignaturesOfType(input.propertyType, SignatureKind.Call)).length > 0) return await fail(input.propertyType, `the property ${input.property.name} is a function, which cannot cross the wire`);
|
|
627
627
|
const optional = (input.property.flags & SymbolFlags.Optional) !== 0;
|
|
628
|
-
const text = optional ? renderOptionalType(input.propertyType, input.depth) : renderNode(input.propertyType, input.depth);
|
|
628
|
+
const text = optional ? await renderOptionalType(input.propertyType, input.depth) : await renderNode(input.propertyType, input.depth);
|
|
629
629
|
if (Result.isFailure(text)) return text;
|
|
630
|
-
const readonly = matchesReadonlyProperty(input.property) ? "readonly " : "";
|
|
630
|
+
const readonly = await matchesReadonlyProperty(input.property) ? "readonly " : "";
|
|
631
631
|
return Result.succeed(`${toIndent(input.depth)}${readonly}${renderPropertyName(input.property.name)}${optional ? "?" : ""}: ${text.success};`);
|
|
632
632
|
}
|
|
633
633
|
/** A class instance crosses the wire as the record of its schema fields; the fields come from the class's static `fields`. */
|
|
634
|
-
function renderClassInstance(type, classSymbol, depth) {
|
|
635
|
-
const constructorType = checker.getTypeOfSymbol(classSymbol);
|
|
636
|
-
const fields = constructorType === void 0 ? void 0 : checker.getPropertyOfType(constructorType, "fields");
|
|
637
|
-
const fieldsType = fields === void 0 ? void 0 : checker.getTypeOfSymbol(fields);
|
|
638
|
-
if (fieldsType === void 0) return fail(type, `the class ${classSymbol.name} is not an Effect Schema class, so its wire form is unknown`);
|
|
634
|
+
async function renderClassInstance(type, classSymbol, depth) {
|
|
635
|
+
const constructorType = await checker.getTypeOfSymbol(classSymbol);
|
|
636
|
+
const fields = constructorType === void 0 ? void 0 : await checker.getPropertyOfType(constructorType, "fields");
|
|
637
|
+
const fieldsType = fields === void 0 ? void 0 : await checker.getTypeOfSymbol(fields);
|
|
638
|
+
if (fieldsType === void 0) return await fail(type, `the class ${classSymbol.name} is not an Effect Schema class, so its wire form is unknown`);
|
|
639
639
|
const lines = [];
|
|
640
|
-
for (const field of sortProperties(checker.getPropertiesOfType(fieldsType))) {
|
|
641
|
-
const property = checker.getPropertyOfType(type, field.name);
|
|
642
|
-
const propertyType = property === void 0 ? void 0 : checker.getTypeOfSymbol(property);
|
|
643
|
-
if (property === void 0 || propertyType === void 0) return fail(type, `the class ${classSymbol.name} declares the field ${field.name} without a property of that name`);
|
|
644
|
-
const line = renderProperty({
|
|
640
|
+
for (const field of sortProperties(await checker.getPropertiesOfType(fieldsType))) {
|
|
641
|
+
const property = await checker.getPropertyOfType(type, field.name);
|
|
642
|
+
const propertyType = property === void 0 ? void 0 : await checker.getTypeOfSymbol(property);
|
|
643
|
+
if (property === void 0 || propertyType === void 0) return await fail(type, `the class ${classSymbol.name} declares the field ${field.name} without a property of that name`);
|
|
644
|
+
const line = await renderProperty({
|
|
645
645
|
property,
|
|
646
646
|
propertyType,
|
|
647
647
|
depth: depth + 1
|
|
@@ -655,16 +655,16 @@ function createTypeRenderer(input) {
|
|
|
655
655
|
`${toIndent(depth)}}`
|
|
656
656
|
].join("\n"));
|
|
657
657
|
}
|
|
658
|
-
function renderObject(type, depth) {
|
|
659
|
-
const symbol = type.getSymbol();
|
|
660
|
-
if (symbol !== void 0 && (symbol.flags & SymbolFlags.Class) !== 0) return renderClassInstance(type, symbol, depth);
|
|
661
|
-
if (checker.getSignaturesOfType(type, SignatureKind.Call).length > 0 || checker.getSignaturesOfType(type, SignatureKind.Construct).length > 0) return fail(type, "a function cannot cross the wire");
|
|
658
|
+
async function renderObject(type, depth) {
|
|
659
|
+
const symbol = await type.getSymbol();
|
|
660
|
+
if (symbol !== void 0 && (symbol.flags & SymbolFlags.Class) !== 0) return await renderClassInstance(type, symbol, depth);
|
|
661
|
+
if ((await checker.getSignaturesOfType(type, SignatureKind.Call)).length > 0 || (await checker.getSignaturesOfType(type, SignatureKind.Construct)).length > 0) return await fail(type, "a function cannot cross the wire");
|
|
662
662
|
const lines = [];
|
|
663
|
-
for (const property of sortProperties(checker.getPropertiesOfType(type))) {
|
|
663
|
+
for (const property of sortProperties(await checker.getPropertiesOfType(type))) {
|
|
664
664
|
if (String(property.escapedName).startsWith("__@")) continue;
|
|
665
|
-
const propertyType = checker.getTypeOfSymbol(property);
|
|
666
|
-
if (propertyType === void 0) return fail(type, `the property ${property.name} has no type`);
|
|
667
|
-
const line = renderProperty({
|
|
665
|
+
const propertyType = await checker.getTypeOfSymbol(property);
|
|
666
|
+
if (propertyType === void 0) return await fail(type, `the property ${property.name} has no type`);
|
|
667
|
+
const line = await renderProperty({
|
|
668
668
|
property,
|
|
669
669
|
propertyType,
|
|
670
670
|
depth: depth + 1
|
|
@@ -672,10 +672,10 @@ function createTypeRenderer(input) {
|
|
|
672
672
|
if (Result.isFailure(line)) return line;
|
|
673
673
|
lines.push(line.success);
|
|
674
674
|
}
|
|
675
|
-
for (const signature of checker.getIndexInfosOfType(type)) {
|
|
676
|
-
const keyText = renderNode(signature.keyType, depth + 1);
|
|
675
|
+
for (const signature of await checker.getIndexInfosOfType(type)) {
|
|
676
|
+
const keyText = await renderNode(signature.keyType, depth + 1);
|
|
677
677
|
if (Result.isFailure(keyText)) return keyText;
|
|
678
|
-
const valueText = renderNode(signature.valueType, depth + 1);
|
|
678
|
+
const valueText = await renderNode(signature.valueType, depth + 1);
|
|
679
679
|
if (Result.isFailure(valueText)) return valueText;
|
|
680
680
|
lines.push(`${toIndent(depth + 1)}${signature.isReadonly ? "readonly " : ""}[key: ${keyText.success}]: ${valueText.success};`);
|
|
681
681
|
}
|
|
@@ -685,19 +685,19 @@ function createTypeRenderer(input) {
|
|
|
685
685
|
`${toIndent(depth)}}`
|
|
686
686
|
].join("\n"));
|
|
687
687
|
}
|
|
688
|
-
function renderOptionalType(type, depth) {
|
|
689
|
-
const present = withoutAbsence({
|
|
688
|
+
async function renderOptionalType(type, depth) {
|
|
689
|
+
const present = await withoutAbsence({
|
|
690
690
|
type,
|
|
691
691
|
undefinedType
|
|
692
692
|
});
|
|
693
|
-
return present === void 0 ? renderNode(type, depth) : present.length === 1 && present[0] !== void 0 ? renderNode(present[0], depth) : renderUnion(present, depth, " | ");
|
|
693
|
+
return present === void 0 ? await renderNode(type, depth) : present.length === 1 && present[0] !== void 0 ? await renderNode(present[0], depth) : await renderUnion(present, depth, " | ");
|
|
694
694
|
}
|
|
695
|
-
function renderTuple(type, depth) {
|
|
696
|
-
const target = type.getTarget();
|
|
695
|
+
async function renderTuple(type, depth) {
|
|
696
|
+
const target = await type.getTarget();
|
|
697
697
|
const members = [];
|
|
698
|
-
for (const [index, element] of checker.getTypeArguments(type).entries()) {
|
|
698
|
+
for (const [index, element] of (await checker.getTypeArguments(type)).entries()) {
|
|
699
699
|
const flags = target.elementFlags[index] ?? ElementFlags.Required;
|
|
700
|
-
const text = (flags & ElementFlags.Optional) !== 0 ? renderOptionalType(element, depth) : renderNode(element, depth);
|
|
700
|
+
const text = (flags & ElementFlags.Optional) !== 0 ? await renderOptionalType(element, depth) : await renderNode(element, depth);
|
|
701
701
|
if (Result.isFailure(text)) return text;
|
|
702
702
|
if ((flags & ElementFlags.Rest) !== 0) members.push(`...Array<${text.success}>`);
|
|
703
703
|
else if ((flags & ElementFlags.Variadic) !== 0) members.push(`...(${text.success})`);
|
|
@@ -706,7 +706,7 @@ function createTypeRenderer(input) {
|
|
|
706
706
|
}
|
|
707
707
|
return Result.succeed(`${target.readonly ? "readonly " : ""}[${members.join(", ")}]`);
|
|
708
708
|
}
|
|
709
|
-
function renderUnion(members, depth, separator) {
|
|
709
|
+
async function renderUnion(members, depth, separator) {
|
|
710
710
|
const parts = [];
|
|
711
711
|
let sawTrue = false;
|
|
712
712
|
let sawFalse = false;
|
|
@@ -716,7 +716,7 @@ function createTypeRenderer(input) {
|
|
|
716
716
|
else sawFalse = true;
|
|
717
717
|
continue;
|
|
718
718
|
}
|
|
719
|
-
const text = renderNode(member, depth);
|
|
719
|
+
const text = await renderNode(member, depth);
|
|
720
720
|
if (Result.isFailure(text)) return text;
|
|
721
721
|
parts.push(separator === " & " && member.isUnionType() ? `(${text.success})` : text.success);
|
|
722
722
|
}
|
|
@@ -732,26 +732,26 @@ function createTypeRenderer(input) {
|
|
|
732
732
|
return Result.succeed(parts.length === 0 ? "never" : parts.join(separator));
|
|
733
733
|
}
|
|
734
734
|
/** Keeps literal contents independent of indentation in the containing declaration. */
|
|
735
|
-
function renderTemplateToken(node) {
|
|
736
|
-
return emitter.printNode(node).replaceAll("\r", "\\r").replaceAll("\n", "\\n");
|
|
735
|
+
async function renderTemplateToken(node) {
|
|
736
|
+
return (await emitter.printNode(node)).replaceAll("\r", "\\r").replaceAll("\n", "\\n");
|
|
737
737
|
}
|
|
738
|
-
function renderTemplateLiteral(type, depth) {
|
|
739
|
-
if (!type.isTemplateLiteralType()) return fail(type, "not a template literal type");
|
|
738
|
+
async function renderTemplateLiteral(type, depth) {
|
|
739
|
+
if (!type.isTemplateLiteralType()) return await fail(type, "not a template literal type");
|
|
740
740
|
const spans = [];
|
|
741
|
-
for (const span of type.getTypes()) {
|
|
742
|
-
const text = renderNode(span, depth);
|
|
741
|
+
for (const span of await type.getTypes()) {
|
|
742
|
+
const text = await renderNode(span, depth);
|
|
743
743
|
if (Result.isFailure(text)) return text;
|
|
744
744
|
spans.push(text.success);
|
|
745
745
|
}
|
|
746
746
|
const [head, ...tail] = type.texts;
|
|
747
|
-
let text = renderTemplateToken(createTemplateHead(head ?? "", "", TokenFlags.None));
|
|
747
|
+
let text = await renderTemplateToken(createTemplateHead(head ?? "", "", TokenFlags.None));
|
|
748
748
|
for (const [index, span] of spans.entries()) {
|
|
749
749
|
const createLiteral = index === spans.length - 1 ? createTemplateTail : createTemplateMiddle;
|
|
750
|
-
text += span + renderTemplateToken(createLiteral(tail[index] ?? "", "", TokenFlags.None));
|
|
750
|
+
text += span + await renderTemplateToken(createLiteral(tail[index] ?? "", "", TokenFlags.None));
|
|
751
751
|
}
|
|
752
752
|
return Result.succeed(text);
|
|
753
753
|
}
|
|
754
|
-
function renderNode(type, depth) {
|
|
754
|
+
async function renderNode(type, depth) {
|
|
755
755
|
const existingAlias = aliases.get(type.id);
|
|
756
756
|
if (existingAlias !== void 0) return Result.succeed(existingAlias);
|
|
757
757
|
if (visiting.has(type.id)) {
|
|
@@ -760,41 +760,41 @@ function createTypeRenderer(input) {
|
|
|
760
760
|
return Result.succeed(name);
|
|
761
761
|
}
|
|
762
762
|
visiting.add(type.id);
|
|
763
|
-
const text = renderTypeStructure(type, depth);
|
|
763
|
+
const text = await renderTypeStructure(type, depth);
|
|
764
764
|
visiting.delete(type.id);
|
|
765
765
|
if (Result.isFailure(text)) return text;
|
|
766
766
|
const createdAlias = aliases.get(type.id);
|
|
767
767
|
if (createdAlias === void 0) return text;
|
|
768
|
-
const declared = depth === 0 ? text : renderTypeStructure(type, 0);
|
|
768
|
+
const declared = depth === 0 ? text : await renderTypeStructure(type, 0);
|
|
769
769
|
if (Result.isFailure(declared)) return declared;
|
|
770
770
|
rendered.push(`type ${createdAlias} = ${declared.success};`);
|
|
771
771
|
return Result.succeed(createdAlias);
|
|
772
772
|
}
|
|
773
|
-
function renderTypeStructure(type, depth) {
|
|
774
|
-
if (type.isErrorType()) return fail(type, "the type could not be resolved");
|
|
773
|
+
async function renderTypeStructure(type, depth) {
|
|
774
|
+
if (type.isErrorType()) return await fail(type, "the type could not be resolved");
|
|
775
775
|
if (type.isStringLiteralType()) return Result.succeed(JSON.stringify(type.value));
|
|
776
776
|
if (type.isNumberLiteralType()) return Result.succeed(String(type.value));
|
|
777
777
|
if (type.isBigIntLiteralType()) return Result.succeed(`${type.value}n`);
|
|
778
778
|
if (type.isBooleanLiteralType()) return Result.succeed(type.value ? "true" : "false");
|
|
779
779
|
if (type.isIntrinsicType()) return Result.succeed(type.intrinsicName);
|
|
780
|
-
const named = renderNamedType(type, depth);
|
|
780
|
+
const named = await renderNamedType(type, depth);
|
|
781
781
|
if (Result.isFailure(named)) return Result.fail(named.failure);
|
|
782
782
|
if (named.success !== null) return Result.succeed(named.success);
|
|
783
|
-
if (type.isTemplateLiteralType()) return renderTemplateLiteral(type, depth);
|
|
784
|
-
if (type.isUnionType()) return renderUnion(type.getTypes(), depth, " | ");
|
|
785
|
-
if (type.isIntersectionType()) return renderUnion(type.getTypes(), depth, " & ");
|
|
786
|
-
if (type.isTypeParameter()) return fail(type, "a contract type cannot be generic");
|
|
787
|
-
if (!type.isObjectType()) return fail(type, "the type has no wire form");
|
|
788
|
-
if (checker.isArrayType(type) && type.isTypeReference()) {
|
|
789
|
-
const [element] = checker.getTypeArguments(type);
|
|
790
|
-
if (element === void 0) return fail(type, "an array type without an element type");
|
|
791
|
-
const text = renderNode(element, depth);
|
|
783
|
+
if (type.isTemplateLiteralType()) return await renderTemplateLiteral(type, depth);
|
|
784
|
+
if (type.isUnionType()) return await renderUnion(await type.getTypes(), depth, " | ");
|
|
785
|
+
if (type.isIntersectionType()) return await renderUnion(await type.getTypes(), depth, " & ");
|
|
786
|
+
if (type.isTypeParameter()) return await fail(type, "a contract type cannot be generic");
|
|
787
|
+
if (!type.isObjectType()) return await fail(type, "the type has no wire form");
|
|
788
|
+
if (await checker.isArrayType(type) && type.isTypeReference()) {
|
|
789
|
+
const [element] = await checker.getTypeArguments(type);
|
|
790
|
+
if (element === void 0) return await fail(type, "an array type without an element type");
|
|
791
|
+
const text = await renderNode(element, depth);
|
|
792
792
|
if (Result.isFailure(text)) return text;
|
|
793
|
-
const wrapper = type.getSymbol()?.name === "ReadonlyArray" ? "ReadonlyArray" : "Array";
|
|
793
|
+
const wrapper = (await type.getSymbol())?.name === "ReadonlyArray" ? "ReadonlyArray" : "Array";
|
|
794
794
|
return Result.succeed(`${wrapper}<${text.success}>`);
|
|
795
795
|
}
|
|
796
|
-
if (checker.isTupleType(type) && type.isTypeReference()) return renderTuple(type, depth);
|
|
797
|
-
return renderObject(type, depth);
|
|
796
|
+
if (await checker.isTupleType(type) && type.isTypeReference()) return await renderTuple(type, depth);
|
|
797
|
+
return await renderObject(type, depth);
|
|
798
798
|
}
|
|
799
799
|
return {
|
|
800
800
|
renderType: (input) => renderNode(input.type, input.depth),
|
|
@@ -923,37 +923,146 @@ function makePublicAssetsBasePathError(cause) {
|
|
|
923
923
|
};
|
|
924
924
|
}
|
|
925
925
|
//#endregion
|
|
926
|
+
//#region src/build/typescript-projects.ts
|
|
927
|
+
/** Reads native project membership without loading programs or declaration types. */
|
|
928
|
+
function readTypescriptProjectRoots(input) {
|
|
929
|
+
return withTypescriptApi({
|
|
930
|
+
configDirectory: input.configDirectory,
|
|
931
|
+
useFn: (api) => {
|
|
932
|
+
return runTypescriptOperation(async () => {
|
|
933
|
+
return {
|
|
934
|
+
server: (await api.parseConfigFile(input.serverTsconfigFilePath)).fileNames,
|
|
935
|
+
client: (await api.parseConfigFile(input.clientTsconfigFilePath)).fileNames
|
|
936
|
+
};
|
|
937
|
+
});
|
|
938
|
+
}
|
|
939
|
+
});
|
|
940
|
+
}
|
|
941
|
+
/** Checks actual compiler membership after generation, including restrictive files/include/exclude settings. */
|
|
942
|
+
function checkGeneratedTypeInclusion(input) {
|
|
943
|
+
return withTypescriptProjects({
|
|
944
|
+
...input,
|
|
945
|
+
useFn: (projects) => {
|
|
946
|
+
return Effect.gen(function* () {
|
|
947
|
+
const missing = yield* runTypescriptOperation(async () => {
|
|
948
|
+
const missing = [];
|
|
949
|
+
for (const [project, files, config] of [[
|
|
950
|
+
projects.server,
|
|
951
|
+
input.serverFiles,
|
|
952
|
+
input.serverTsconfigFilePath
|
|
953
|
+
], [
|
|
954
|
+
projects.client,
|
|
955
|
+
input.clientFiles,
|
|
956
|
+
input.clientTsconfigFilePath
|
|
957
|
+
]]) for (const file of files) if (await project.program.getSourceFileMetadata(file) === void 0) missing.push({
|
|
958
|
+
project: config,
|
|
959
|
+
file
|
|
960
|
+
});
|
|
961
|
+
return missing;
|
|
962
|
+
});
|
|
963
|
+
return yield* missing.length === 0 ? Effect.void : Effect.fail({
|
|
964
|
+
_tag: "TypescriptProjectError",
|
|
965
|
+
message: missing.map(({ project, file }) => `${project} does not include generated type file ${file}. Include the entry's _vorma directory in that TypeScript project.`).join("\n")
|
|
966
|
+
});
|
|
967
|
+
});
|
|
968
|
+
}
|
|
969
|
+
});
|
|
970
|
+
}
|
|
971
|
+
/** Opens the two configured TypeScript projects for the duration of `useFn`, then closes the checker session. */
|
|
972
|
+
function withTypescriptProjects(input) {
|
|
973
|
+
return withTypescriptApi({
|
|
974
|
+
...input,
|
|
975
|
+
useFn: (api) => {
|
|
976
|
+
return Effect.scoped(Effect.gen(function* () {
|
|
977
|
+
const projects = findProjects({
|
|
978
|
+
snapshot: yield* Effect.acquireRelease(runTypescriptOperation(() => {
|
|
979
|
+
return api.updateSnapshot({ openProjects: [input.serverTsconfigFilePath, input.clientTsconfigFilePath] });
|
|
980
|
+
}), (snapshot) => Effect.promise(() => snapshot.dispose())),
|
|
981
|
+
...input
|
|
982
|
+
});
|
|
983
|
+
return yield* Result.isFailure(projects) ? Effect.fail(projects.failure) : input.useFn(projects.success);
|
|
984
|
+
}));
|
|
985
|
+
}
|
|
986
|
+
});
|
|
987
|
+
}
|
|
988
|
+
/** Native compiler operations have no cancellation API; settle each operation before its session can close. */
|
|
989
|
+
function runTypescriptOperation(fn) {
|
|
990
|
+
return Effect.tryPromise({
|
|
991
|
+
try: fn,
|
|
992
|
+
catch: (cause) => {
|
|
993
|
+
return {
|
|
994
|
+
_tag: "TypescriptProjectError",
|
|
995
|
+
message: "Vorma could not read the application's TypeScript projects",
|
|
996
|
+
cause
|
|
997
|
+
};
|
|
998
|
+
}
|
|
999
|
+
}).pipe(Effect.uninterruptible);
|
|
1000
|
+
}
|
|
1001
|
+
function withTypescriptApi(input) {
|
|
1002
|
+
return Effect.scoped(Effect.gen(function* () {
|
|
1003
|
+
const api = yield* Effect.acquireRelease(runTypescriptOperation(async () => {
|
|
1004
|
+
return new API({
|
|
1005
|
+
cwd: input.configDirectory,
|
|
1006
|
+
...input.fileSystem === void 0 ? {} : { fs: input.fileSystem }
|
|
1007
|
+
});
|
|
1008
|
+
}), (api) => Effect.promise(() => api.close()));
|
|
1009
|
+
return yield* input.useFn(api);
|
|
1010
|
+
}));
|
|
1011
|
+
}
|
|
1012
|
+
function findProjects(input) {
|
|
1013
|
+
const server = input.snapshot.getProject(input.serverTsconfigFilePath);
|
|
1014
|
+
const client = input.snapshot.getProject(input.clientTsconfigFilePath);
|
|
1015
|
+
if (server === void 0 || client === void 0) return Result.fail({
|
|
1016
|
+
_tag: "TypescriptProjectError",
|
|
1017
|
+
message: `TypeScript did not load ${server === void 0 ? input.serverTsconfigFilePath : input.clientTsconfigFilePath}`
|
|
1018
|
+
});
|
|
1019
|
+
return Result.succeed({
|
|
1020
|
+
server,
|
|
1021
|
+
client
|
|
1022
|
+
});
|
|
1023
|
+
}
|
|
1024
|
+
//#endregion
|
|
926
1025
|
//#region src/build/inspect-projects.ts
|
|
927
1026
|
/** Reads every registerable declaration, view, the client application, and every public URL call from the two projects. */
|
|
928
1027
|
function inspectProjects(input) {
|
|
929
1028
|
return Effect.gen(function* () {
|
|
930
1029
|
const path = yield* Path$1.Path;
|
|
931
1030
|
const excludedDirectories = getGeneratedSourceDirectories(input.layout);
|
|
932
|
-
const serverFiles =
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
1031
|
+
const serverFiles = yield* runTypescriptOperation(() => {
|
|
1032
|
+
return listOwnSourceFiles({
|
|
1033
|
+
project: input.projects.server,
|
|
1034
|
+
excludedDirectories,
|
|
1035
|
+
path
|
|
1036
|
+
});
|
|
936
1037
|
});
|
|
937
|
-
const clientFiles =
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
1038
|
+
const clientFiles = yield* runTypescriptOperation(() => {
|
|
1039
|
+
return listOwnSourceFiles({
|
|
1040
|
+
project: input.projects.client,
|
|
1041
|
+
excludedDirectories,
|
|
1042
|
+
path
|
|
1043
|
+
});
|
|
941
1044
|
});
|
|
942
|
-
const serverRenderer =
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
1045
|
+
const serverRenderer = yield* runTypescriptOperation(() => {
|
|
1046
|
+
return createTypeRenderer({
|
|
1047
|
+
checker: input.projects.server.checker,
|
|
1048
|
+
program: input.projects.server.program,
|
|
1049
|
+
emitter: input.projects.server.emitter
|
|
1050
|
+
});
|
|
946
1051
|
});
|
|
947
|
-
const serverDeclarations = yield* Effect.fromResult(
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
1052
|
+
const serverDeclarations = yield* Effect.fromResult(yield* runTypescriptOperation(() => {
|
|
1053
|
+
return inspectServerDeclarations({
|
|
1054
|
+
checker: input.projects.server.checker,
|
|
1055
|
+
program: input.projects.server.program,
|
|
1056
|
+
files: serverFiles,
|
|
1057
|
+
renderer: serverRenderer
|
|
1058
|
+
});
|
|
952
1059
|
}));
|
|
953
|
-
const client = yield* Effect.fromResult(
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
1060
|
+
const client = yield* Effect.fromResult(yield* runTypescriptOperation(() => {
|
|
1061
|
+
return inspectClientProject({
|
|
1062
|
+
checker: input.projects.client.checker,
|
|
1063
|
+
files: clientFiles,
|
|
1064
|
+
clientEntryFilePath: input.layout.clientEntryFilePath
|
|
1065
|
+
});
|
|
957
1066
|
}));
|
|
958
1067
|
return {
|
|
959
1068
|
serverDeclarations,
|
|
@@ -968,10 +1077,10 @@ function inspectProjects(input) {
|
|
|
968
1077
|
});
|
|
969
1078
|
}
|
|
970
1079
|
/** The project's own modules: not a library, not a declaration file, and not under a Vorma output directory. */
|
|
971
|
-
function listOwnSourceFiles(input) {
|
|
1080
|
+
async function listOwnSourceFiles(input) {
|
|
972
1081
|
const { program } = input.project;
|
|
973
1082
|
const files = [];
|
|
974
|
-
for (const fileName of program.getSourceFileNames()) {
|
|
1083
|
+
for (const fileName of await program.getSourceFileNames()) {
|
|
975
1084
|
if (fileName.includes("/node_modules/") || input.excludedDirectories.some((directory) => {
|
|
976
1085
|
const relativePath = input.path.relative(directory, fileName);
|
|
977
1086
|
return containsRelativePath({
|
|
@@ -980,9 +1089,9 @@ function listOwnSourceFiles(input) {
|
|
|
980
1089
|
absolute: input.path.isAbsolute(relativePath)
|
|
981
1090
|
});
|
|
982
1091
|
})) continue;
|
|
983
|
-
const metadata = program.getSourceFileMetadata(fileName);
|
|
1092
|
+
const metadata = await program.getSourceFileMetadata(fileName);
|
|
984
1093
|
if (metadata?.isDefaultLibrary || metadata?.isFromExternalLibrary) continue;
|
|
985
|
-
const sourceFile = program.getSourceFile(fileName);
|
|
1094
|
+
const sourceFile = await program.getSourceFile(fileName);
|
|
986
1095
|
if (sourceFile === void 0 || sourceFile.isDeclarationFile) continue;
|
|
987
1096
|
files.push(sourceFile);
|
|
988
1097
|
}
|
|
@@ -994,15 +1103,15 @@ function listOwnSourceFiles(input) {
|
|
|
994
1103
|
});
|
|
995
1104
|
}
|
|
996
1105
|
/** Export bindings retain their public names while aliases resolve to one declaration identity. */
|
|
997
|
-
function listModuleExports(input) {
|
|
1106
|
+
async function listModuleExports(input) {
|
|
998
1107
|
const { checker, sourceFile } = input;
|
|
999
|
-
const moduleSymbol = checker.getSymbolAtLocation(sourceFile);
|
|
1108
|
+
const moduleSymbol = await checker.getSymbolAtLocation(sourceFile);
|
|
1000
1109
|
if (moduleSymbol === void 0) return [];
|
|
1001
1110
|
const exports = [];
|
|
1002
|
-
for (const exported of checker.getExportsOfModule(moduleSymbol)) {
|
|
1003
|
-
const symbol = (exported.flags & SymbolFlags.Alias) !== 0 ? checker.getAliasedSymbol(exported) : exported;
|
|
1004
|
-
if (checker.isUnknownSymbol(symbol)) continue;
|
|
1005
|
-
const type = checker.getTypeOfSymbol(symbol);
|
|
1111
|
+
for (const exported of await checker.getExportsOfModule(moduleSymbol)) {
|
|
1112
|
+
const symbol = (exported.flags & SymbolFlags.Alias) !== 0 ? await checker.getAliasedSymbol(exported) : exported;
|
|
1113
|
+
if (await checker.isUnknownSymbol(symbol)) continue;
|
|
1114
|
+
const type = await checker.getTypeOfSymbol(symbol);
|
|
1006
1115
|
if (type === void 0) continue;
|
|
1007
1116
|
exports.push({
|
|
1008
1117
|
exportName: exported.name,
|
|
@@ -1013,9 +1122,9 @@ function listModuleExports(input) {
|
|
|
1013
1122
|
return exports;
|
|
1014
1123
|
}
|
|
1015
1124
|
/** Prefer a declaration's own exported module so a re-export barrel does not enlarge a view's import closure. */
|
|
1016
|
-
function listRegistrationExports(input) {
|
|
1125
|
+
async function listRegistrationExports(input) {
|
|
1017
1126
|
const exports = /* @__PURE__ */ new Map();
|
|
1018
|
-
for (const sourceFile of input.files) for (const moduleExport of listModuleExports({
|
|
1127
|
+
for (const sourceFile of input.files) for (const moduleExport of await listModuleExports({
|
|
1019
1128
|
checker: input.checker,
|
|
1020
1129
|
sourceFile
|
|
1021
1130
|
})) {
|
|
@@ -1030,55 +1139,55 @@ function listRegistrationExports(input) {
|
|
|
1030
1139
|
return [...exports.values()];
|
|
1031
1140
|
}
|
|
1032
1141
|
/** The phantom property that carries a definition's static types, by the unique symbol that keys it. */
|
|
1033
|
-
function findPhantomProperty(input) {
|
|
1142
|
+
async function findPhantomProperty(input) {
|
|
1034
1143
|
const prefix = `__@${input.symbolName}@`;
|
|
1035
|
-
return input.checker.getPropertiesOfType(input.type).find((property) => String(property.escapedName).startsWith(prefix));
|
|
1144
|
+
return (await input.checker.getPropertiesOfType(input.type)).find((property) => String(property.escapedName).startsWith(prefix));
|
|
1036
1145
|
}
|
|
1037
|
-
function readPropertyType(input) {
|
|
1038
|
-
const property = input.checker.getPropertyOfType(input.type, input.name);
|
|
1039
|
-
return property === void 0 ? void 0 : input.checker.getTypeOfSymbol(property);
|
|
1146
|
+
async function readPropertyType(input) {
|
|
1147
|
+
const property = await input.checker.getPropertyOfType(input.type, input.name);
|
|
1148
|
+
return property === void 0 ? void 0 : await input.checker.getTypeOfSymbol(property);
|
|
1040
1149
|
}
|
|
1041
|
-
function readLiteralProperty(input) {
|
|
1042
|
-
const propertyType = readPropertyType(input);
|
|
1150
|
+
async function readLiteralProperty(input) {
|
|
1151
|
+
const propertyType = await readPropertyType(input);
|
|
1043
1152
|
if (propertyType === void 0) return Result.fail(`the declaration has no ${input.name} property`);
|
|
1044
|
-
if (!propertyType.isStringLiteralType()) return Result.fail(`${input.name} must have a literal type; its type is ${input.checker.typeToString(propertyType)}`);
|
|
1153
|
+
if (!propertyType.isStringLiteralType()) return Result.fail(`${input.name} must have a literal type; its type is ${await input.checker.typeToString(propertyType)}`);
|
|
1045
1154
|
return Result.succeed(propertyType.value);
|
|
1046
1155
|
}
|
|
1047
1156
|
function matchesUndefinedType(type) {
|
|
1048
1157
|
return type.isIntrinsicType() && type.intrinsicName === "undefined";
|
|
1049
1158
|
}
|
|
1050
|
-
function inspectServerDeclarations(input) {
|
|
1159
|
+
async function inspectServerDeclarations(input) {
|
|
1051
1160
|
const { checker, program, renderer } = input;
|
|
1052
1161
|
const declarations = [];
|
|
1053
1162
|
const candidates = [];
|
|
1054
|
-
for (const { sourceFile, moduleExport } of listRegistrationExports(input)) {
|
|
1163
|
+
for (const { sourceFile, moduleExport } of await listRegistrationExports(input)) {
|
|
1055
1164
|
const source = {
|
|
1056
1165
|
filePath: sourceFile.fileName,
|
|
1057
1166
|
exportName: moduleExport.exportName
|
|
1058
1167
|
};
|
|
1059
|
-
const phantom = findPhantomProperty({
|
|
1168
|
+
const phantom = await findPhantomProperty({
|
|
1060
1169
|
checker,
|
|
1061
1170
|
type: moduleExport.type,
|
|
1062
1171
|
symbolName: "DEFINITION_TYPES"
|
|
1063
1172
|
});
|
|
1064
1173
|
if (phantom === void 0) continue;
|
|
1065
|
-
const tag = readPropertyType({
|
|
1174
|
+
const tag = await readPropertyType({
|
|
1066
1175
|
checker,
|
|
1067
1176
|
type: moduleExport.type,
|
|
1068
1177
|
name: "_tag"
|
|
1069
1178
|
});
|
|
1070
1179
|
if (tag === void 0 || !tag.isStringLiteralType()) continue;
|
|
1071
1180
|
if (tag.value !== "UiLoader" && tag.value !== "Endpoint") continue;
|
|
1072
|
-
const phantomType = checker.getTypeOfSymbol(phantom);
|
|
1073
|
-
const types = phantomType === void 0 ? void 0 : checker.getNonNullableType(phantomType);
|
|
1181
|
+
const phantomType = await checker.getTypeOfSymbol(phantom);
|
|
1182
|
+
const types = phantomType === void 0 ? void 0 : await checker.getNonNullableType(phantomType);
|
|
1074
1183
|
if (types === void 0) return Result.fail(makeIssue(source, "the definition carries no static types"));
|
|
1075
|
-
const pattern = readLiteralProperty({
|
|
1184
|
+
const pattern = await readLiteralProperty({
|
|
1076
1185
|
checker,
|
|
1077
1186
|
type: moduleExport.type,
|
|
1078
1187
|
name: "pattern"
|
|
1079
1188
|
});
|
|
1080
1189
|
if (Result.isFailure(pattern)) return Result.fail(makeIssue(source, pattern.failure));
|
|
1081
|
-
const method = readPropertyType({
|
|
1190
|
+
const method = await readPropertyType({
|
|
1082
1191
|
checker,
|
|
1083
1192
|
type: moduleExport.type,
|
|
1084
1193
|
name: "method"
|
|
@@ -1102,13 +1211,13 @@ function inspectServerDeclarations(input) {
|
|
|
1102
1211
|
});
|
|
1103
1212
|
});
|
|
1104
1213
|
for (const { source, kind, type, types } of candidates) {
|
|
1105
|
-
const inspected = kind === "UiLoader" ? inspectUiLoader({
|
|
1214
|
+
const inspected = kind === "UiLoader" ? await inspectUiLoader({
|
|
1106
1215
|
checker,
|
|
1107
1216
|
renderer,
|
|
1108
1217
|
source,
|
|
1109
1218
|
type,
|
|
1110
1219
|
types
|
|
1111
|
-
}) : inspectEndpoint({
|
|
1220
|
+
}) : await inspectEndpoint({
|
|
1112
1221
|
checker,
|
|
1113
1222
|
program,
|
|
1114
1223
|
renderer,
|
|
@@ -1129,8 +1238,8 @@ function makeIssue(source, message) {
|
|
|
1129
1238
|
message: `${source.filePath} (export ${source.exportName}): ${message}`
|
|
1130
1239
|
};
|
|
1131
1240
|
}
|
|
1132
|
-
function renderContract(input) {
|
|
1133
|
-
return Result.mapError(input.renderer.renderType({
|
|
1241
|
+
async function renderContract(input) {
|
|
1242
|
+
return Result.mapError(await input.renderer.renderType({
|
|
1134
1243
|
type: input.type,
|
|
1135
1244
|
depth: 2
|
|
1136
1245
|
}), (issue) => {
|
|
@@ -1138,27 +1247,27 @@ function renderContract(input) {
|
|
|
1138
1247
|
});
|
|
1139
1248
|
}
|
|
1140
1249
|
/** A contract's text, or `undefined` for the absent contract that the type `undefined` denotes. */
|
|
1141
|
-
function renderOptionalContract(input) {
|
|
1142
|
-
const type = readPropertyType({
|
|
1250
|
+
async function renderOptionalContract(input) {
|
|
1251
|
+
const type = await readPropertyType({
|
|
1143
1252
|
checker: input.checker,
|
|
1144
1253
|
type: input.types,
|
|
1145
1254
|
name: input.field
|
|
1146
1255
|
});
|
|
1147
1256
|
if (type === void 0 || matchesUndefinedType(type)) return Result.succeed(void 0);
|
|
1148
|
-
return renderContract({
|
|
1257
|
+
return await renderContract({
|
|
1149
1258
|
...input,
|
|
1150
1259
|
type
|
|
1151
1260
|
});
|
|
1152
1261
|
}
|
|
1153
|
-
function inspectUiLoader(input) {
|
|
1262
|
+
async function inspectUiLoader(input) {
|
|
1154
1263
|
const { checker, renderer, source } = input;
|
|
1155
|
-
const pattern = readLiteralProperty({
|
|
1264
|
+
const pattern = await readLiteralProperty({
|
|
1156
1265
|
checker,
|
|
1157
1266
|
type: input.type,
|
|
1158
1267
|
name: "pattern"
|
|
1159
1268
|
});
|
|
1160
1269
|
if (Result.isFailure(pattern)) return Result.fail(makeIssue(source, pattern.failure));
|
|
1161
|
-
const loaderInput = renderOptionalContract({
|
|
1270
|
+
const loaderInput = await renderOptionalContract({
|
|
1162
1271
|
checker,
|
|
1163
1272
|
renderer,
|
|
1164
1273
|
source,
|
|
@@ -1166,13 +1275,13 @@ function inspectUiLoader(input) {
|
|
|
1166
1275
|
types: input.types
|
|
1167
1276
|
});
|
|
1168
1277
|
if (Result.isFailure(loaderInput)) return Result.fail(loaderInput.failure);
|
|
1169
|
-
const outputType = readPropertyType({
|
|
1278
|
+
const outputType = await readPropertyType({
|
|
1170
1279
|
checker,
|
|
1171
1280
|
type: input.types,
|
|
1172
1281
|
name: "output"
|
|
1173
1282
|
});
|
|
1174
1283
|
if (outputType === void 0) return Result.fail(makeIssue(source, "a UI loader must have an output contract"));
|
|
1175
|
-
const output = renderContract({
|
|
1284
|
+
const output = await renderContract({
|
|
1176
1285
|
renderer,
|
|
1177
1286
|
source,
|
|
1178
1287
|
field: "output",
|
|
@@ -1187,7 +1296,7 @@ function inspectUiLoader(input) {
|
|
|
1187
1296
|
output: output.success
|
|
1188
1297
|
});
|
|
1189
1298
|
}
|
|
1190
|
-
function inspectEndpoint(input) {
|
|
1299
|
+
async function inspectEndpoint(input) {
|
|
1191
1300
|
const { checker, program, renderer, source } = input;
|
|
1192
1301
|
const literals = {
|
|
1193
1302
|
kind: "",
|
|
@@ -1199,7 +1308,7 @@ function inspectEndpoint(input) {
|
|
|
1199
1308
|
"method",
|
|
1200
1309
|
"pattern"
|
|
1201
1310
|
]) {
|
|
1202
|
-
const literal = readLiteralProperty({
|
|
1311
|
+
const literal = await readLiteralProperty({
|
|
1203
1312
|
checker,
|
|
1204
1313
|
type: input.type,
|
|
1205
1314
|
name
|
|
@@ -1212,25 +1321,25 @@ function inspectEndpoint(input) {
|
|
|
1212
1321
|
if (operation !== "query" && operation !== "mutation") return Result.fail(makeIssue(source, `unknown endpoint kind ${operation}`));
|
|
1213
1322
|
const method = literals.method;
|
|
1214
1323
|
if (!matchesHttpMethod(method)) return Result.fail(makeIssue(source, `unknown endpoint method ${method}`));
|
|
1215
|
-
const inputType = readPropertyType({
|
|
1324
|
+
const inputType = await readPropertyType({
|
|
1216
1325
|
checker,
|
|
1217
1326
|
type: input.types,
|
|
1218
1327
|
name: "input"
|
|
1219
1328
|
});
|
|
1220
1329
|
const hasInput = inputType !== void 0 && !matchesUndefinedType(inputType);
|
|
1221
|
-
const inputTransport = !hasInput ? "none" : method === "GET" ? "search" : matchesFormInput({
|
|
1330
|
+
const inputTransport = !hasInput ? "none" : method === "GET" ? "search" : await matchesFormInput({
|
|
1222
1331
|
checker,
|
|
1223
1332
|
program,
|
|
1224
1333
|
types: input.types
|
|
1225
1334
|
}) ? "formData" : "json";
|
|
1226
|
-
const endpointInput = inputType === void 0 || !hasInput || inputTransport === "formData" ? Result.succeed(void 0) : renderContract({
|
|
1335
|
+
const endpointInput = inputType === void 0 || !hasInput || inputTransport === "formData" ? Result.succeed(void 0) : await renderContract({
|
|
1227
1336
|
renderer,
|
|
1228
1337
|
source,
|
|
1229
1338
|
field: "input",
|
|
1230
1339
|
type: inputType
|
|
1231
1340
|
});
|
|
1232
1341
|
if (Result.isFailure(endpointInput)) return Result.fail(endpointInput.failure);
|
|
1233
|
-
const output = renderOptionalContract({
|
|
1342
|
+
const output = await renderOptionalContract({
|
|
1234
1343
|
checker,
|
|
1235
1344
|
renderer,
|
|
1236
1345
|
source,
|
|
@@ -1238,7 +1347,7 @@ function inspectEndpoint(input) {
|
|
|
1238
1347
|
types: input.types
|
|
1239
1348
|
});
|
|
1240
1349
|
if (Result.isFailure(output)) return Result.fail(output.failure);
|
|
1241
|
-
const event = renderOptionalContract({
|
|
1350
|
+
const event = await renderOptionalContract({
|
|
1242
1351
|
checker,
|
|
1243
1352
|
renderer,
|
|
1244
1353
|
source,
|
|
@@ -1246,7 +1355,7 @@ function inspectEndpoint(input) {
|
|
|
1246
1355
|
types: input.types
|
|
1247
1356
|
});
|
|
1248
1357
|
if (Result.isFailure(event)) return Result.fail(event.failure);
|
|
1249
|
-
const errors = inspectEndpointErrors({
|
|
1358
|
+
const errors = await inspectEndpointErrors({
|
|
1250
1359
|
checker,
|
|
1251
1360
|
renderer,
|
|
1252
1361
|
source,
|
|
@@ -1271,51 +1380,52 @@ function inspectEndpoint(input) {
|
|
|
1271
1380
|
* form-transport marker carried by Vorma's FormData schema and its derived
|
|
1272
1381
|
* codecs. The runtime recognizes the same factory's schema annotation.
|
|
1273
1382
|
*/
|
|
1274
|
-
function matchesFormInput(input) {
|
|
1275
|
-
const symbol = readPropertyType({
|
|
1383
|
+
async function matchesFormInput(input) {
|
|
1384
|
+
const symbol = await (await readPropertyType({
|
|
1276
1385
|
checker: input.checker,
|
|
1277
1386
|
type: input.types,
|
|
1278
1387
|
name: "inputEncoded"
|
|
1279
|
-
})?.getSymbol();
|
|
1388
|
+
}))?.getSymbol();
|
|
1280
1389
|
return symbol !== void 0 && symbol.name === "FormDataEncoded" && symbol.declarations.some((declaration) => {
|
|
1281
1390
|
return /\/vorma\/(?:src|dist)\/server\/form-data\.(?:d\.)?ts$/.test(String(declaration.path));
|
|
1282
|
-
}) && matchesLibrarySymbol({
|
|
1391
|
+
}) && await matchesLibrarySymbol({
|
|
1283
1392
|
program: input.program,
|
|
1284
1393
|
symbol
|
|
1285
1394
|
});
|
|
1286
1395
|
}
|
|
1287
1396
|
/** Each declared error: its decoded `_tag` and transportable schema fields. */
|
|
1288
|
-
function inspectEndpointErrors(input) {
|
|
1397
|
+
async function inspectEndpointErrors(input) {
|
|
1289
1398
|
const { checker, renderer, source } = input;
|
|
1290
|
-
const errorsType = readPropertyType({
|
|
1399
|
+
const errorsType = await readPropertyType({
|
|
1291
1400
|
checker,
|
|
1292
1401
|
type: input.types,
|
|
1293
1402
|
name: "errors"
|
|
1294
1403
|
});
|
|
1295
1404
|
if (errorsType === void 0) return Result.succeed([]);
|
|
1296
|
-
const
|
|
1297
|
-
|
|
1405
|
+
const numberType = await checker.getNumberType();
|
|
1406
|
+
const elementType = (await checker.getIndexInfosOfType(errorsType)).find((index) => {
|
|
1407
|
+
return index.keyType.id === numberType.id;
|
|
1298
1408
|
})?.valueType;
|
|
1299
1409
|
if (elementType === void 0) return Result.fail(makeIssue(source, "declared errors must have an array element type"));
|
|
1300
1410
|
const errors = [];
|
|
1301
1411
|
const variantsByTag = [];
|
|
1302
|
-
const elements = elementType.isUnionType() ? elementType.getTypes() : [elementType];
|
|
1412
|
+
const elements = elementType.isUnionType() ? await elementType.getTypes() : [elementType];
|
|
1303
1413
|
for (const element of elements) {
|
|
1304
1414
|
if (element.isIntrinsicType() && element.intrinsicName === "never") continue;
|
|
1305
|
-
const schemaType = readPropertyType({
|
|
1415
|
+
const schemaType = await readPropertyType({
|
|
1306
1416
|
checker,
|
|
1307
1417
|
type: element,
|
|
1308
1418
|
name: "schema"
|
|
1309
1419
|
});
|
|
1310
|
-
const decodedType = schemaType === void 0 ? void 0 : readPropertyType({
|
|
1420
|
+
const decodedType = schemaType === void 0 ? void 0 : await readPropertyType({
|
|
1311
1421
|
checker,
|
|
1312
1422
|
type: schemaType,
|
|
1313
1423
|
name: "Type"
|
|
1314
1424
|
});
|
|
1315
1425
|
if (decodedType === void 0) return Result.fail(makeIssue(source, "each declared error's schema must expose its decoded Type"));
|
|
1316
|
-
const variants = decodedType.isUnionType() ? decodedType.getTypes() : [decodedType];
|
|
1426
|
+
const variants = decodedType.isUnionType() ? await decodedType.getTypes() : [decodedType];
|
|
1317
1427
|
for (const variant of variants) {
|
|
1318
|
-
const tag = readLiteralProperty({
|
|
1428
|
+
const tag = await readLiteralProperty({
|
|
1319
1429
|
checker,
|
|
1320
1430
|
type: variant,
|
|
1321
1431
|
name: "_tag"
|
|
@@ -1334,7 +1444,7 @@ function inspectEndpointErrors(input) {
|
|
|
1334
1444
|
});
|
|
1335
1445
|
});
|
|
1336
1446
|
for (const variant of variantsByTag) {
|
|
1337
|
-
const fields = renderContract({
|
|
1447
|
+
const fields = await renderContract({
|
|
1338
1448
|
renderer,
|
|
1339
1449
|
source,
|
|
1340
1450
|
field: `error ${variant.tag}`,
|
|
@@ -1348,23 +1458,23 @@ function inspectEndpointErrors(input) {
|
|
|
1348
1458
|
}
|
|
1349
1459
|
return Result.succeed(errors);
|
|
1350
1460
|
}
|
|
1351
|
-
function inspectClientProject(input) {
|
|
1461
|
+
async function inspectClientProject(input) {
|
|
1352
1462
|
const { checker } = input;
|
|
1353
1463
|
const views = [];
|
|
1354
1464
|
const applications = /* @__PURE__ */ new Map();
|
|
1355
1465
|
const publicUrlSites = [];
|
|
1356
1466
|
const sourceTexts = /* @__PURE__ */ new Map();
|
|
1357
|
-
for (const { sourceFile, moduleExport } of listRegistrationExports(input)) {
|
|
1467
|
+
for (const { sourceFile, moduleExport } of await listRegistrationExports(input)) {
|
|
1358
1468
|
const source = {
|
|
1359
1469
|
filePath: sourceFile.fileName,
|
|
1360
1470
|
exportName: moduleExport.exportName
|
|
1361
1471
|
};
|
|
1362
|
-
if (findPhantomProperty({
|
|
1472
|
+
if (await findPhantomProperty({
|
|
1363
1473
|
checker,
|
|
1364
1474
|
type: moduleExport.type,
|
|
1365
1475
|
symbolName: "UI_VIEW_TYPES"
|
|
1366
1476
|
}) !== void 0) {
|
|
1367
|
-
const pattern = readLiteralProperty({
|
|
1477
|
+
const pattern = await readLiteralProperty({
|
|
1368
1478
|
checker,
|
|
1369
1479
|
type: moduleExport.type,
|
|
1370
1480
|
name: "pattern"
|
|
@@ -1378,10 +1488,10 @@ function inspectClientProject(input) {
|
|
|
1378
1488
|
}
|
|
1379
1489
|
for (const sourceFile of input.files) {
|
|
1380
1490
|
if (sourceFile.fileName === input.clientEntryFilePath) {
|
|
1381
|
-
for (const moduleExport of listModuleExports({
|
|
1491
|
+
for (const moduleExport of await listModuleExports({
|
|
1382
1492
|
checker,
|
|
1383
1493
|
sourceFile
|
|
1384
|
-
})) if (findPhantomProperty({
|
|
1494
|
+
})) if (await findPhantomProperty({
|
|
1385
1495
|
checker,
|
|
1386
1496
|
type: moduleExport.type,
|
|
1387
1497
|
symbolName: "CLIENT_APPLICATION_TYPES"
|
|
@@ -1390,7 +1500,7 @@ function inspectClientProject(input) {
|
|
|
1390
1500
|
exportName: moduleExport.exportName
|
|
1391
1501
|
});
|
|
1392
1502
|
}
|
|
1393
|
-
const sites = collectPublicUrlSites({
|
|
1503
|
+
const sites = await collectPublicUrlSites({
|
|
1394
1504
|
checker,
|
|
1395
1505
|
sourceFile
|
|
1396
1506
|
});
|
|
@@ -1414,14 +1524,14 @@ function inspectClientProject(input) {
|
|
|
1414
1524
|
});
|
|
1415
1525
|
}
|
|
1416
1526
|
/** Whether a symbol is the `getPublicUrl` declared by `vorma/client`, however the module reached it. */
|
|
1417
|
-
function matchesPublicUrlSymbol(input) {
|
|
1418
|
-
const symbol = (input.symbol.flags & SymbolFlags.Alias) !== 0 ? input.checker.getAliasedSymbol(input.symbol) : input.symbol;
|
|
1527
|
+
async function matchesPublicUrlSymbol(input) {
|
|
1528
|
+
const symbol = (input.symbol.flags & SymbolFlags.Alias) !== 0 ? await input.checker.getAliasedSymbol(input.symbol) : input.symbol;
|
|
1419
1529
|
if (symbol.name !== "getPublicUrl") return false;
|
|
1420
1530
|
const declaration = symbol.declarations[0];
|
|
1421
1531
|
return declaration !== void 0 && String(declaration.path).endsWith("/vorma/dist/client/index.d.ts");
|
|
1422
1532
|
}
|
|
1423
1533
|
/** Every call of `getPublicUrl` in one file. A use that is not a direct call with a string literal cannot be replaced by the build. */
|
|
1424
|
-
function collectPublicUrlSites(input) {
|
|
1534
|
+
async function collectPublicUrlSites(input) {
|
|
1425
1535
|
const { checker, sourceFile } = input;
|
|
1426
1536
|
const sites = [];
|
|
1427
1537
|
let issue;
|
|
@@ -1437,16 +1547,16 @@ function collectPublicUrlSites(input) {
|
|
|
1437
1547
|
};
|
|
1438
1548
|
}
|
|
1439
1549
|
}
|
|
1440
|
-
function visit(node) {
|
|
1550
|
+
async function visit(node) {
|
|
1441
1551
|
if (issue !== void 0 || isTypeNode(node)) return;
|
|
1442
1552
|
if (isIdentifier(node) || isPropertyAccessExpression(node) || isElementAccessExpression(node)) {
|
|
1443
1553
|
const parent = node.parent;
|
|
1444
1554
|
if (isImportSpecifier(parent) || isImportClause(parent) || isNamespaceImport(parent) || isExportSpecifier(parent)) return;
|
|
1445
|
-
const symbol = isElementAccessExpression(node) ? getElementAccessSymbol({
|
|
1555
|
+
const symbol = isElementAccessExpression(node) ? await getElementAccessSymbol({
|
|
1446
1556
|
checker,
|
|
1447
1557
|
node
|
|
1448
|
-
}) : checker.getSymbolAtLocation(node);
|
|
1449
|
-
if (symbol !== void 0 && matchesPublicUrlSymbol({
|
|
1558
|
+
}) : await checker.getSymbolAtLocation(node);
|
|
1559
|
+
if (symbol !== void 0 && await matchesPublicUrlSymbol({
|
|
1450
1560
|
checker,
|
|
1451
1561
|
symbol
|
|
1452
1562
|
})) {
|
|
@@ -1472,9 +1582,13 @@ function collectPublicUrlSites(input) {
|
|
|
1472
1582
|
return;
|
|
1473
1583
|
}
|
|
1474
1584
|
}
|
|
1475
|
-
|
|
1585
|
+
const children = [];
|
|
1586
|
+
node.forEachChild((child) => {
|
|
1587
|
+
children.push(child);
|
|
1588
|
+
});
|
|
1589
|
+
for (const child of children) await visit(child);
|
|
1476
1590
|
}
|
|
1477
|
-
visit(sourceFile);
|
|
1591
|
+
await visit(sourceFile);
|
|
1478
1592
|
return issue === void 0 ? Result.succeed(sites) : Result.fail(issue);
|
|
1479
1593
|
}
|
|
1480
1594
|
/** Parentheses and erased TypeScript wrappers preserve the underlying expression. */
|
|
@@ -1485,105 +1599,10 @@ function unwrapExpression(node) {
|
|
|
1485
1599
|
while (matchesTransparentExpression(node)) node = node.expression;
|
|
1486
1600
|
return node;
|
|
1487
1601
|
}
|
|
1488
|
-
function getElementAccessSymbol(input) {
|
|
1489
|
-
const objectType = input.checker.getTypeAtLocation(input.node.expression);
|
|
1490
|
-
const keyType = input.checker.getTypeAtLocation(input.node.argumentExpression);
|
|
1491
|
-
return objectType !== void 0 && keyType?.isStringLiteralType() ? input.checker.getPropertyOfType(objectType, keyType.value) : void 0;
|
|
1492
|
-
}
|
|
1493
|
-
//#endregion
|
|
1494
|
-
//#region src/build/typescript-projects.ts
|
|
1495
|
-
/** Reads native project membership without loading programs or declaration types. */
|
|
1496
|
-
function readTypescriptProjectRoots(input) {
|
|
1497
|
-
return withTypescriptApi({
|
|
1498
|
-
configDirectory: input.configDirectory,
|
|
1499
|
-
useFn: (api) => {
|
|
1500
|
-
return openCompilerResource(() => {
|
|
1501
|
-
return {
|
|
1502
|
-
server: api.parseConfigFile(input.serverTsconfigFilePath).fileNames,
|
|
1503
|
-
client: api.parseConfigFile(input.clientTsconfigFilePath).fileNames
|
|
1504
|
-
};
|
|
1505
|
-
});
|
|
1506
|
-
}
|
|
1507
|
-
});
|
|
1508
|
-
}
|
|
1509
|
-
/** Checks actual compiler membership after generation, including restrictive files/include/exclude settings. */
|
|
1510
|
-
function checkGeneratedTypeInclusion(input) {
|
|
1511
|
-
return withTypescriptProjects({
|
|
1512
|
-
...input,
|
|
1513
|
-
useFn: (projects) => {
|
|
1514
|
-
const missing = [...input.serverFiles.filter((file) => {
|
|
1515
|
-
return projects.server.program.getSourceFileMetadata(file) === void 0;
|
|
1516
|
-
}).map((file) => {
|
|
1517
|
-
return {
|
|
1518
|
-
project: input.serverTsconfigFilePath,
|
|
1519
|
-
file
|
|
1520
|
-
};
|
|
1521
|
-
}), ...input.clientFiles.filter((file) => {
|
|
1522
|
-
return projects.client.program.getSourceFileMetadata(file) === void 0;
|
|
1523
|
-
}).map((file) => {
|
|
1524
|
-
return {
|
|
1525
|
-
project: input.clientTsconfigFilePath,
|
|
1526
|
-
file
|
|
1527
|
-
};
|
|
1528
|
-
})];
|
|
1529
|
-
return missing.length === 0 ? Effect.void : Effect.fail({
|
|
1530
|
-
_tag: "TypescriptProjectError",
|
|
1531
|
-
message: missing.map(({ project, file }) => `${project} does not include generated type file ${file}. Include the entry's _vorma directory in that TypeScript project.`).join("\n")
|
|
1532
|
-
});
|
|
1533
|
-
}
|
|
1534
|
-
});
|
|
1535
|
-
}
|
|
1536
|
-
/** Opens the two configured TypeScript projects for the duration of `useFn`, then closes the checker session. */
|
|
1537
|
-
function withTypescriptProjects(input) {
|
|
1538
|
-
return withTypescriptApi({
|
|
1539
|
-
...input,
|
|
1540
|
-
useFn: (api) => {
|
|
1541
|
-
return Effect.scoped(Effect.gen(function* () {
|
|
1542
|
-
const projects = findProjects({
|
|
1543
|
-
snapshot: yield* Effect.acquireRelease(openCompilerResource(() => {
|
|
1544
|
-
return api.updateSnapshot({ openProjects: [input.serverTsconfigFilePath, input.clientTsconfigFilePath] });
|
|
1545
|
-
}), (snapshot) => Effect.sync(() => snapshot.dispose())),
|
|
1546
|
-
...input
|
|
1547
|
-
});
|
|
1548
|
-
return yield* Result.isFailure(projects) ? Effect.fail(projects.failure) : input.useFn(projects.success);
|
|
1549
|
-
}));
|
|
1550
|
-
}
|
|
1551
|
-
});
|
|
1552
|
-
}
|
|
1553
|
-
function openCompilerResource(fn) {
|
|
1554
|
-
return Effect.try({
|
|
1555
|
-
try: fn,
|
|
1556
|
-
catch: (cause) => {
|
|
1557
|
-
return {
|
|
1558
|
-
_tag: "TypescriptProjectError",
|
|
1559
|
-
message: "Vorma could not read the application's TypeScript projects",
|
|
1560
|
-
cause
|
|
1561
|
-
};
|
|
1562
|
-
}
|
|
1563
|
-
});
|
|
1564
|
-
}
|
|
1565
|
-
function withTypescriptApi(input) {
|
|
1566
|
-
return Effect.scoped(Effect.gen(function* () {
|
|
1567
|
-
const api = yield* Effect.acquireRelease(openCompilerResource(() => {
|
|
1568
|
-
return new API({
|
|
1569
|
-
cwd: input.configDirectory,
|
|
1570
|
-
...input.fileSystem === void 0 ? {} : { fs: input.fileSystem }
|
|
1571
|
-
});
|
|
1572
|
-
}), (api) => Effect.sync(() => api.close()));
|
|
1573
|
-
return yield* input.useFn(api);
|
|
1574
|
-
}));
|
|
1575
|
-
}
|
|
1576
|
-
function findProjects(input) {
|
|
1577
|
-
const server = input.snapshot.getProject(input.serverTsconfigFilePath);
|
|
1578
|
-
const client = input.snapshot.getProject(input.clientTsconfigFilePath);
|
|
1579
|
-
if (server === void 0 || client === void 0) return Result.fail({
|
|
1580
|
-
_tag: "TypescriptProjectError",
|
|
1581
|
-
message: `TypeScript did not load ${server === void 0 ? input.serverTsconfigFilePath : input.clientTsconfigFilePath}`
|
|
1582
|
-
});
|
|
1583
|
-
return Result.succeed({
|
|
1584
|
-
server,
|
|
1585
|
-
client
|
|
1586
|
-
});
|
|
1602
|
+
async function getElementAccessSymbol(input) {
|
|
1603
|
+
const objectType = await input.checker.getTypeAtLocation(input.node.expression);
|
|
1604
|
+
const keyType = await input.checker.getTypeAtLocation(input.node.argumentExpression);
|
|
1605
|
+
return objectType !== void 0 && keyType?.isStringLiteralType() ? await input.checker.getPropertyOfType(objectType, keyType.value) : void 0;
|
|
1587
1606
|
}
|
|
1588
1607
|
//#endregion
|
|
1589
1608
|
//#region src/build/compile-application.ts
|
|
@@ -3211,4 +3230,4 @@ function buildApplication(input) {
|
|
|
3211
3230
|
}));
|
|
3212
3231
|
}
|
|
3213
3232
|
//#endregion
|
|
3214
|
-
export {
|
|
3233
|
+
export { encodeCanonicalJson as C, projectBrowserContracts as S, createClientPublicUrlPlugin as _, acquireOutputOwnership as a, CLIENT_SHARED_PACKAGES as b, writeAndCheckApplicationGeneration as c, readTypescriptProjectRoots as d, runTypescriptOperation as f, createCssPublicAssets as g, resolveVormaConfig as h, publishApplicationArtifacts as i, collectPublicAssets as l, getGeneratedSourceDirectories as m, loadApplicationSourceLayout as n, checkOutputPath as o, withTypescriptProjects as p, preparePublicOutput as r, assembleApplicationGeneration as s, buildApplication as t, inspectProjects as u, compileServerApplication as v, toContentDigest as w, getClientViewEntries as x, containsRelativePath as y };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sjcx/vorma",
|
|
3
|
-
"version": "0.0.0-pre.
|
|
3
|
+
"version": "0.0.0-pre.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"license": "MIT",
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
"@effect/platform-node-shared": "^4.0.0-rc.115",
|
|
43
43
|
"@noble/hashes": "^2.4.0",
|
|
44
44
|
"@scure/base": "^2.4.0",
|
|
45
|
-
"@vorma/primitives": "npm:@sjcx/vorma-primitives@0.0.0-pre.
|
|
45
|
+
"@vorma/primitives": "npm:@sjcx/vorma-primitives@0.0.0-pre.1",
|
|
46
46
|
"chokidar": "^5.0.0",
|
|
47
47
|
"lightningcss": "^1.33.0",
|
|
48
48
|
"rolldown": "^1.2.6",
|