bazis 0.96.4 → 0.96.5
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.
|
@@ -232,7 +232,7 @@ export class CodexAppServerClient implements CodexClient {
|
|
|
232
232
|
if (method === "account/updated") this.modelCache = undefined;
|
|
233
233
|
}, () => { this.clearLogin(); this.modelCache = undefined; });
|
|
234
234
|
const initialized = await client.request("initialize", {
|
|
235
|
-
clientInfo: { name: "bazis", title: "Bazis", version: "0.96.
|
|
235
|
+
clientInfo: { name: "bazis", title: "Bazis", version: "0.96.5" }, capabilities: { experimentalApi: true },
|
|
236
236
|
}, 15_000, signal);
|
|
237
237
|
if (resolve(text(initialized.codexHome, 4096)) !== this.paths.home) throw new CodexError("PROTOCOL_ERROR");
|
|
238
238
|
client.notify("initialized");
|
|
@@ -29,8 +29,10 @@ empty or whitespace value. TypeScript forbids unsupported object types.
|
|
|
29
29
|
|
|
30
30
|
A declaration stores no chosen environment, values or cache. `get/has/ensureValid`
|
|
31
31
|
stay for standalone reading of the process env, but `ensureValid` no longer
|
|
32
|
-
switches later reads. Host code gets `resolve`, a service
|
|
33
|
-
`
|
|
32
|
+
switches later reads. Host code gets `resolve`, a service declares
|
|
33
|
+
`ConfigView<T>` in its constructor (codegen binds it to the token of the one
|
|
34
|
+
`defineConfig<T>(...)` declaration; the type argument is required) or injects
|
|
35
|
+
`definition.token` explicitly, a connector gets `ConfigRegistry` as the create argument.
|
|
34
36
|
All built-in connectors use this argument; a custom connector reads
|
|
35
37
|
`configs?.get(config) ?? config`. A direct global get inside a service does not
|
|
36
38
|
read the settings of its kernel.
|
|
@@ -162,6 +162,9 @@ let inferredDiClasses = new Set<ts.ClassDeclaration>();
|
|
|
162
162
|
let explicitlyBoundDiClasses = new Set<ts.ClassDeclaration>();
|
|
163
163
|
// Known runtime token names: createToken descriptions + class names usable as class-tokens.
|
|
164
164
|
let tokenDescriptions = new Set<string>();
|
|
165
|
+
// defineConfig<T>("prefix") declarations by the name of T: a ConfigView<T>
|
|
166
|
+
// constructor parameter binds to the token of that declaration.
|
|
167
|
+
let configPrefixesByType = new Map<string, Set<string>>();
|
|
165
168
|
let knownClassNames = new Set<string>();
|
|
166
169
|
let warnings: string[] = [];
|
|
167
170
|
let fatalErrors: string[] = [];
|
|
@@ -446,7 +449,7 @@ function collectDynamicImportDiagnostics(source: ts.SourceFile, target: string,
|
|
|
446
449
|
function resetTargetAnalysis(files: Set<string>, generatedDir: string): void {
|
|
447
450
|
activeGeneratedDir = generatedDir;
|
|
448
451
|
classDeps = new Map(); inferredDiClasses = new Set(); explicitlyBoundDiClasses = new Set();
|
|
449
|
-
tokenDescriptions = new Set(); knownClassNames = new Set(); warnings = []; fatalErrors = [];
|
|
452
|
+
tokenDescriptions = new Set(); configPrefixesByType = new Map(); knownClassNames = new Set(); warnings = []; fatalErrors = [];
|
|
450
453
|
httpBindings = {}; httpControllerFiles = {}; openApiSchemas = {}; openApiOperations = {};
|
|
451
454
|
grpcBindings = new Map();
|
|
452
455
|
uiProfileResponseModels = new Map(); openApiSchemaModels = new Map(); requestModelClassNames = new Set(); listRequestClassNames = new Set();
|
|
@@ -476,6 +479,7 @@ async function generateTarget(name: string, reachable: Set<string>, production:
|
|
|
476
479
|
}
|
|
477
480
|
collectHttpBindings(source); collectOpenApiSchemas(source); collectUiProfileResponseModels(source);
|
|
478
481
|
}
|
|
482
|
+
resolveConfigViewDeps();
|
|
479
483
|
validateDepsAgainstKnownTokens();
|
|
480
484
|
const requestModelImports = resolveRequestModelImports();
|
|
481
485
|
const requestModelHydration = resolveRequestModelHydration(requestModelImports);
|
|
@@ -711,6 +715,13 @@ function collectTokenDescriptions(source: ts.SourceFile): void {
|
|
|
711
715
|
if (node.expression.text === "createToken" || node.expression.text === "createOpenGenericTokenFamily") {
|
|
712
716
|
tokenDescriptions.add(firstArg.text);
|
|
713
717
|
}
|
|
718
|
+
if (node.expression.text === "defineConfig") {
|
|
719
|
+
// The same description defineConfig gives its token.
|
|
720
|
+
const prefix = firstArg.text || "default";
|
|
721
|
+
tokenDescriptions.add(`Config:${prefix}`);
|
|
722
|
+
const typeName = node.typeArguments?.[0] && getDependencyTypeName(node.typeArguments[0]);
|
|
723
|
+
if (typeName) configPrefixesByType.set(typeName, (configPrefixesByType.get(typeName) ?? new Set()).add(prefix));
|
|
724
|
+
}
|
|
714
725
|
}
|
|
715
726
|
}
|
|
716
727
|
if (ts.isClassDeclaration(node) && node.name) {
|
|
@@ -722,6 +733,39 @@ function collectTokenDescriptions(source: ts.SourceFile): void {
|
|
|
722
733
|
ts.forEachChild(source, visit);
|
|
723
734
|
}
|
|
724
735
|
|
|
736
|
+
/**
|
|
737
|
+
* Replaces each `ConfigView<T>` placeholder with the token of the one
|
|
738
|
+
* `defineConfig<T>(...)` declaration. Runs after every source was read, because
|
|
739
|
+
* a service may come before the file that declares its configuration.
|
|
740
|
+
*/
|
|
741
|
+
function resolveConfigViewDeps(): void {
|
|
742
|
+
for (const [declaration, deps] of classDeps) {
|
|
743
|
+
let changed = false;
|
|
744
|
+
const resolved: CollectedDependency[] = [];
|
|
745
|
+
for (const [index, dep] of deps.entries()) {
|
|
746
|
+
const typeName = /^ConfigView<(.+)>$/.exec(dep.name)?.[1];
|
|
747
|
+
if (typeName === undefined) {
|
|
748
|
+
resolved.push(dep);
|
|
749
|
+
continue;
|
|
750
|
+
}
|
|
751
|
+
const prefixes = [...(configPrefixesByType.get(typeName) ?? [])];
|
|
752
|
+
if (prefixes.length !== 1) {
|
|
753
|
+
classDeps.delete(declaration);
|
|
754
|
+
if (needsInferredDiDeps(declaration)) {
|
|
755
|
+
fatalErrors.push(prefixes.length === 0
|
|
756
|
+
? `BAZIS_DI_CONFIG_UNKNOWN: ${sourceLocation(declaration)}: constructor parameter ${index + 1} of "${declaration.name?.text}" has type "ConfigView<${typeName}>", but no defineConfig<${typeName}>(...) declaration was found. Declare the configuration with an explicit type argument, for example defineConfig<${typeName}>("name", { default: {...} }).`
|
|
757
|
+
: `BAZIS_DI_CONFIG_AMBIGUOUS: ${sourceLocation(declaration)}: constructor parameter ${index + 1} of "${declaration.name?.text}" has type "ConfigView<${typeName}>", which matches several declarations: ${prefixes.map((prefix) => `"${prefix}"`).join(", ")}. Give each declaration its own type, or pass the token explicitly: scoped(Service, Service, [config.token]).`);
|
|
758
|
+
}
|
|
759
|
+
changed = false;
|
|
760
|
+
break;
|
|
761
|
+
}
|
|
762
|
+
resolved.push({ name: `Config:${prefixes[0]}` });
|
|
763
|
+
changed = true;
|
|
764
|
+
}
|
|
765
|
+
if (changed && classDeps.has(declaration)) classDeps.set(declaration, resolved);
|
|
766
|
+
}
|
|
767
|
+
}
|
|
768
|
+
|
|
725
769
|
function validateDepsAgainstKnownTokens(): void {
|
|
726
770
|
for (const [declaration, deps] of classDeps) {
|
|
727
771
|
for (let index = 0; index < deps.length; index += 1) {
|
|
@@ -910,6 +954,11 @@ function dependencyFromType(type: ts.Type): CollectedDependency | undefined {
|
|
|
910
954
|
const name = declaration?.name?.text ?? type.aliasSymbol?.name ?? symbol?.name;
|
|
911
955
|
if (!name || BUILTIN_DEPENDENCY_NAMES.has(name)) return undefined;
|
|
912
956
|
const arguments_ = type.flags & ts.TypeFlags.Object ? checker.getTypeArguments(type as ts.TypeReference) : [];
|
|
957
|
+
if (name === "ConfigView") {
|
|
958
|
+
const configType = arguments_[0];
|
|
959
|
+
const configTypeName = configType && (configType.aliasSymbol?.name ?? configType.getSymbol()?.name);
|
|
960
|
+
return configTypeName ? { name: `ConfigView<${configTypeName}>` } : undefined;
|
|
961
|
+
}
|
|
913
962
|
if (name === "Lazy" || name === "IRepository") {
|
|
914
963
|
const inner = arguments_[0] && dependencyFromType(arguments_[0]);
|
|
915
964
|
if (!inner) return undefined;
|
|
@@ -950,6 +999,15 @@ function readConstructorTypeNames(node: ts.ClassDeclaration): ConstructorDepende
|
|
|
950
999
|
continue;
|
|
951
1000
|
}
|
|
952
1001
|
|
|
1002
|
+
if (refName === "ConfigView" && paramType && ts.isTypeReferenceNode(paramType)) {
|
|
1003
|
+
const configType = paramType.typeArguments?.[0];
|
|
1004
|
+
const configTypeName = configType ? getDependencyTypeName(configType) : undefined;
|
|
1005
|
+
if (configTypeName) {
|
|
1006
|
+
deps.push({ name: `ConfigView<${configTypeName}>` });
|
|
1007
|
+
continue;
|
|
1008
|
+
}
|
|
1009
|
+
}
|
|
1010
|
+
|
|
953
1011
|
if (refName === "IRepository" && paramType && ts.isTypeReferenceNode(paramType)) {
|
|
954
1012
|
const entityType = paramType.typeArguments?.[0];
|
|
955
1013
|
const entityName = entityType ? getDependencyTypeName(entityType) : undefined;
|
package/package.json
CHANGED