@formspec/build 0.1.0-alpha.30 → 0.1.0-alpha.32
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 +82 -5
- package/dist/analyzer/class-analyzer.d.ts +6 -0
- package/dist/analyzer/class-analyzer.d.ts.map +1 -1
- package/dist/browser.cjs +166 -24
- package/dist/browser.cjs.map +1 -1
- package/dist/browser.js +166 -24
- package/dist/browser.js.map +1 -1
- package/dist/build-alpha.d.ts +180 -0
- package/dist/build-beta.d.ts +180 -0
- package/dist/build-internal.d.ts +180 -0
- package/dist/build.d.ts +180 -0
- package/dist/cli.cjs +584 -33
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +582 -33
- package/dist/cli.js.map +1 -1
- package/dist/generators/discovered-schema.d.ts +112 -0
- package/dist/generators/discovered-schema.d.ts.map +1 -0
- package/dist/index.cjs +573 -33
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +565 -33
- package/dist/index.js.map +1 -1
- package/dist/internals.cjs +197 -33
- package/dist/internals.cjs.map +1 -1
- package/dist/internals.js +197 -33
- package/dist/internals.js.map +1 -1
- package/dist/static-build.d.ts +61 -0
- package/dist/static-build.d.ts.map +1 -0
- package/package.json +1 -1
package/dist/internals.cjs
CHANGED
|
@@ -2142,10 +2142,7 @@ function resolveLiteralDiscriminatorPropertyValue(boundType, fieldName, checker,
|
|
|
2142
2142
|
if (resolvedAnchorNode === null) {
|
|
2143
2143
|
return void 0;
|
|
2144
2144
|
}
|
|
2145
|
-
const propertyType = checker.getTypeOfSymbolAtLocation(
|
|
2146
|
-
propertySymbol,
|
|
2147
|
-
resolvedAnchorNode
|
|
2148
|
-
);
|
|
2145
|
+
const propertyType = checker.getTypeOfSymbolAtLocation(propertySymbol, resolvedAnchorNode);
|
|
2149
2146
|
if (propertyType.isStringLiteral()) {
|
|
2150
2147
|
return propertyType.value;
|
|
2151
2148
|
}
|
|
@@ -3104,14 +3101,39 @@ function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNo
|
|
|
3104
3101
|
collectedDiagnostics
|
|
3105
3102
|
);
|
|
3106
3103
|
const fieldNodeInfo = fieldInfoMap?.get(prop.name);
|
|
3104
|
+
const inlineFieldNodeInfo = fieldNodeInfo === void 0 ? ts3.isPropertySignature(declaration) ? analyzeInterfacePropertyToIR(
|
|
3105
|
+
declaration,
|
|
3106
|
+
checker,
|
|
3107
|
+
file,
|
|
3108
|
+
typeRegistry,
|
|
3109
|
+
visiting,
|
|
3110
|
+
collectedDiagnostics,
|
|
3111
|
+
type,
|
|
3112
|
+
metadataPolicy,
|
|
3113
|
+
extensionRegistry
|
|
3114
|
+
) : ts3.isPropertyDeclaration(declaration) ? analyzeFieldToIR(
|
|
3115
|
+
declaration,
|
|
3116
|
+
checker,
|
|
3117
|
+
file,
|
|
3118
|
+
typeRegistry,
|
|
3119
|
+
visiting,
|
|
3120
|
+
collectedDiagnostics,
|
|
3121
|
+
type,
|
|
3122
|
+
metadataPolicy,
|
|
3123
|
+
extensionRegistry
|
|
3124
|
+
) : null : null;
|
|
3125
|
+
const resolvedFieldNodeInfo = fieldNodeInfo ?? inlineFieldNodeInfo;
|
|
3126
|
+
const resolvedPropertyType = inlineFieldNodeInfo?.type ?? propTypeNode;
|
|
3107
3127
|
properties.push({
|
|
3108
3128
|
name: prop.name,
|
|
3109
|
-
...
|
|
3110
|
-
|
|
3129
|
+
...resolvedFieldNodeInfo?.metadata !== void 0 && {
|
|
3130
|
+
metadata: resolvedFieldNodeInfo.metadata
|
|
3131
|
+
},
|
|
3132
|
+
type: resolvedPropertyType,
|
|
3111
3133
|
optional,
|
|
3112
|
-
constraints:
|
|
3113
|
-
annotations:
|
|
3114
|
-
provenance:
|
|
3134
|
+
constraints: resolvedFieldNodeInfo?.constraints ?? [],
|
|
3135
|
+
annotations: resolvedFieldNodeInfo?.annotations ?? [],
|
|
3136
|
+
provenance: resolvedFieldNodeInfo?.provenance ?? provenanceForFile(file)
|
|
3115
3137
|
});
|
|
3116
3138
|
}
|
|
3117
3139
|
visiting.delete(type);
|
|
@@ -3714,9 +3736,9 @@ function collectFields(elements, properties, required, ctx) {
|
|
|
3714
3736
|
for (const element of elements) {
|
|
3715
3737
|
switch (element.kind) {
|
|
3716
3738
|
case "field":
|
|
3717
|
-
properties[
|
|
3739
|
+
properties[getSerializedFieldName(element)] = generateFieldSchema(element, ctx);
|
|
3718
3740
|
if (element.required) {
|
|
3719
|
-
required.push(
|
|
3741
|
+
required.push(getSerializedFieldName(element));
|
|
3720
3742
|
}
|
|
3721
3743
|
break;
|
|
3722
3744
|
case "group":
|
|
@@ -3787,19 +3809,21 @@ function applyPathTargetedConstraints(schema, pathConstraints, ctx, typeNode) {
|
|
|
3787
3809
|
schema.items = applyPathTargetedConstraints(schema.items, pathConstraints, ctx, nestedType);
|
|
3788
3810
|
return schema;
|
|
3789
3811
|
}
|
|
3790
|
-
const
|
|
3791
|
-
|
|
3792
|
-
|
|
3793
|
-
|
|
3794
|
-
|
|
3795
|
-
|
|
3796
|
-
|
|
3797
|
-
|
|
3798
|
-
|
|
3799
|
-
|
|
3800
|
-
|
|
3801
|
-
|
|
3802
|
-
|
|
3812
|
+
const propertyOverrides = buildPropertyOverrides(pathConstraints, typeNode, ctx);
|
|
3813
|
+
const nullableValueBranch = getNullableUnionValueSchema(schema);
|
|
3814
|
+
if (nullableValueBranch !== void 0) {
|
|
3815
|
+
const updatedNullableValueBranch = applyPathTargetedConstraints(
|
|
3816
|
+
nullableValueBranch,
|
|
3817
|
+
pathConstraints,
|
|
3818
|
+
ctx,
|
|
3819
|
+
resolveTraversableTypeNode(typeNode, ctx)
|
|
3820
|
+
);
|
|
3821
|
+
if (schema.oneOf !== void 0) {
|
|
3822
|
+
schema.oneOf = schema.oneOf.map(
|
|
3823
|
+
(branch) => branch === nullableValueBranch ? updatedNullableValueBranch : branch
|
|
3824
|
+
);
|
|
3825
|
+
}
|
|
3826
|
+
return schema;
|
|
3803
3827
|
}
|
|
3804
3828
|
if (schema.$ref) {
|
|
3805
3829
|
const { $ref, ...rest } = schema;
|
|
@@ -3814,7 +3838,7 @@ function applyPathTargetedConstraints(schema, pathConstraints, ctx, typeNode) {
|
|
|
3814
3838
|
const missingOverrides = {};
|
|
3815
3839
|
for (const [target, overrideSchema] of Object.entries(propertyOverrides)) {
|
|
3816
3840
|
if (schema.properties[target]) {
|
|
3817
|
-
|
|
3841
|
+
mergeSchemaOverride(schema.properties[target], overrideSchema);
|
|
3818
3842
|
} else {
|
|
3819
3843
|
missingOverrides[target] = overrideSchema;
|
|
3820
3844
|
}
|
|
@@ -3888,7 +3912,7 @@ function generateObjectType(type, ctx) {
|
|
|
3888
3912
|
const properties = {};
|
|
3889
3913
|
const required = [];
|
|
3890
3914
|
for (const prop of type.properties) {
|
|
3891
|
-
const propertyName =
|
|
3915
|
+
const propertyName = getSerializedObjectPropertyName(prop);
|
|
3892
3916
|
properties[propertyName] = generatePropertySchema(prop, ctx);
|
|
3893
3917
|
if (!prop.optional) {
|
|
3894
3918
|
required.push(propertyName);
|
|
@@ -3942,7 +3966,16 @@ function isNullableUnion(type) {
|
|
|
3942
3966
|
return nullCount === 1;
|
|
3943
3967
|
}
|
|
3944
3968
|
function generateReferenceType(type, ctx) {
|
|
3945
|
-
return { $ref: `#/$defs/${
|
|
3969
|
+
return { $ref: `#/$defs/${getSerializedTypeName(type.name, ctx)}` };
|
|
3970
|
+
}
|
|
3971
|
+
function getSerializedFieldName(field) {
|
|
3972
|
+
return getSerializedName(field.name, field.metadata);
|
|
3973
|
+
}
|
|
3974
|
+
function getSerializedObjectPropertyName(property) {
|
|
3975
|
+
return getSerializedName(property.name, property.metadata);
|
|
3976
|
+
}
|
|
3977
|
+
function getSerializedTypeName(logicalName, ctx) {
|
|
3978
|
+
return ctx.typeNameMap[logicalName] ?? logicalName;
|
|
3946
3979
|
}
|
|
3947
3980
|
function applyResolvedMetadata(schema, metadata) {
|
|
3948
3981
|
const displayName = getDisplayName(metadata);
|
|
@@ -3953,17 +3986,148 @@ function applyResolvedMetadata(schema, metadata) {
|
|
|
3953
3986
|
function resolveReferencedType(type, ctx) {
|
|
3954
3987
|
return ctx.typeRegistry[type.name]?.type;
|
|
3955
3988
|
}
|
|
3989
|
+
function dereferenceTypeNode(typeNode, ctx) {
|
|
3990
|
+
if (typeNode?.kind !== "reference") {
|
|
3991
|
+
return typeNode;
|
|
3992
|
+
}
|
|
3993
|
+
return resolveReferencedType(typeNode, ctx);
|
|
3994
|
+
}
|
|
3995
|
+
function unwrapNullableTypeNode(typeNode) {
|
|
3996
|
+
if (typeNode?.kind !== "union" || !isNullableUnion(typeNode)) {
|
|
3997
|
+
return typeNode;
|
|
3998
|
+
}
|
|
3999
|
+
return typeNode.members.find(
|
|
4000
|
+
(member) => !(member.kind === "primitive" && member.primitiveKind === "null")
|
|
4001
|
+
);
|
|
4002
|
+
}
|
|
4003
|
+
function resolveTraversableTypeNode(typeNode, ctx) {
|
|
4004
|
+
const dereferenced = dereferenceTypeNode(typeNode, ctx);
|
|
4005
|
+
const unwrapped = unwrapNullableTypeNode(dereferenced);
|
|
4006
|
+
if (unwrapped !== dereferenced) {
|
|
4007
|
+
return resolveTraversableTypeNode(unwrapped, ctx);
|
|
4008
|
+
}
|
|
4009
|
+
return dereferenced;
|
|
4010
|
+
}
|
|
3956
4011
|
function resolveSerializedPropertyName(logicalName, typeNode, ctx) {
|
|
3957
|
-
|
|
3958
|
-
|
|
3959
|
-
return
|
|
4012
|
+
const effectiveType = resolveTraversableTypeNode(typeNode, ctx);
|
|
4013
|
+
if (effectiveType?.kind === "array") {
|
|
4014
|
+
return resolveSerializedPropertyName(logicalName, effectiveType.items, ctx);
|
|
3960
4015
|
}
|
|
3961
|
-
if (
|
|
3962
|
-
const
|
|
3963
|
-
return
|
|
4016
|
+
if (effectiveType?.kind === "object") {
|
|
4017
|
+
const property = effectiveType.properties.find((candidate) => candidate.name === logicalName);
|
|
4018
|
+
return property === void 0 ? logicalName : getSerializedObjectPropertyName(property);
|
|
3964
4019
|
}
|
|
3965
4020
|
return logicalName;
|
|
3966
4021
|
}
|
|
4022
|
+
function resolveTargetTypeNode(logicalName, typeNode, ctx) {
|
|
4023
|
+
const effectiveType = resolveTraversableTypeNode(typeNode, ctx);
|
|
4024
|
+
if (effectiveType?.kind === "array") {
|
|
4025
|
+
return resolveTargetTypeNode(logicalName, effectiveType.items, ctx);
|
|
4026
|
+
}
|
|
4027
|
+
if (effectiveType?.kind !== "object") {
|
|
4028
|
+
return void 0;
|
|
4029
|
+
}
|
|
4030
|
+
return effectiveType.properties.find((candidate) => candidate.name === logicalName)?.type;
|
|
4031
|
+
}
|
|
4032
|
+
function buildPropertyOverrides(pathConstraints, typeNode, ctx) {
|
|
4033
|
+
const byTarget = /* @__PURE__ */ new Map();
|
|
4034
|
+
for (const constraint of pathConstraints) {
|
|
4035
|
+
const target = constraint.path?.segments[0];
|
|
4036
|
+
if (!target) {
|
|
4037
|
+
continue;
|
|
4038
|
+
}
|
|
4039
|
+
const grouped = byTarget.get(target) ?? [];
|
|
4040
|
+
grouped.push(constraint);
|
|
4041
|
+
byTarget.set(target, grouped);
|
|
4042
|
+
}
|
|
4043
|
+
const overrides = {};
|
|
4044
|
+
for (const [target, constraints] of byTarget) {
|
|
4045
|
+
overrides[resolveSerializedPropertyName(target, typeNode, ctx)] = buildPathOverrideSchema(
|
|
4046
|
+
constraints.map(stripLeadingPathSegment),
|
|
4047
|
+
resolveTargetTypeNode(target, typeNode, ctx),
|
|
4048
|
+
ctx
|
|
4049
|
+
);
|
|
4050
|
+
}
|
|
4051
|
+
return overrides;
|
|
4052
|
+
}
|
|
4053
|
+
function buildPathOverrideSchema(constraints, typeNode, ctx) {
|
|
4054
|
+
const schema = {};
|
|
4055
|
+
const directConstraints = [];
|
|
4056
|
+
const nestedConstraints = [];
|
|
4057
|
+
for (const constraint of constraints) {
|
|
4058
|
+
if (constraint.path === void 0 || constraint.path.segments.length === 0) {
|
|
4059
|
+
directConstraints.push(constraint);
|
|
4060
|
+
} else {
|
|
4061
|
+
nestedConstraints.push(constraint);
|
|
4062
|
+
}
|
|
4063
|
+
}
|
|
4064
|
+
applyConstraints(schema, directConstraints, ctx);
|
|
4065
|
+
if (nestedConstraints.length === 0) {
|
|
4066
|
+
return schema;
|
|
4067
|
+
}
|
|
4068
|
+
const effectiveType = resolveTraversableTypeNode(typeNode, ctx);
|
|
4069
|
+
if (effectiveType?.kind === "array") {
|
|
4070
|
+
schema.items = buildPathOverrideSchema(nestedConstraints, effectiveType.items, ctx);
|
|
4071
|
+
return schema;
|
|
4072
|
+
}
|
|
4073
|
+
schema.properties = buildPropertyOverrides(nestedConstraints, effectiveType, ctx);
|
|
4074
|
+
return schema;
|
|
4075
|
+
}
|
|
4076
|
+
function mergeSchemaOverride(target, override) {
|
|
4077
|
+
const nullableValueBranch = getNullableUnionValueSchema(target);
|
|
4078
|
+
if (nullableValueBranch !== void 0) {
|
|
4079
|
+
mergeSchemaOverride(nullableValueBranch, override);
|
|
4080
|
+
return;
|
|
4081
|
+
}
|
|
4082
|
+
if (override.properties !== void 0) {
|
|
4083
|
+
const mergedProperties = target.properties ?? {};
|
|
4084
|
+
for (const [name, propertyOverride] of Object.entries(override.properties)) {
|
|
4085
|
+
const existing = mergedProperties[name];
|
|
4086
|
+
if (existing === void 0) {
|
|
4087
|
+
mergedProperties[name] = propertyOverride;
|
|
4088
|
+
} else {
|
|
4089
|
+
mergeSchemaOverride(existing, propertyOverride);
|
|
4090
|
+
}
|
|
4091
|
+
}
|
|
4092
|
+
target.properties = mergedProperties;
|
|
4093
|
+
}
|
|
4094
|
+
if (override.items !== void 0) {
|
|
4095
|
+
if (target.items === void 0) {
|
|
4096
|
+
target.items = override.items;
|
|
4097
|
+
} else {
|
|
4098
|
+
mergeSchemaOverride(target.items, override.items);
|
|
4099
|
+
}
|
|
4100
|
+
}
|
|
4101
|
+
for (const [key, value] of Object.entries(override)) {
|
|
4102
|
+
if (key === "properties" || key === "items") {
|
|
4103
|
+
continue;
|
|
4104
|
+
}
|
|
4105
|
+
target[key] = value;
|
|
4106
|
+
}
|
|
4107
|
+
}
|
|
4108
|
+
function stripLeadingPathSegment(constraint) {
|
|
4109
|
+
const segments = constraint.path?.segments;
|
|
4110
|
+
if (segments === void 0 || segments.length === 0) {
|
|
4111
|
+
return constraint;
|
|
4112
|
+
}
|
|
4113
|
+
const [, ...rest] = segments;
|
|
4114
|
+
if (rest.length === 0) {
|
|
4115
|
+
const { path: _path, ...stripped } = constraint;
|
|
4116
|
+
return stripped;
|
|
4117
|
+
}
|
|
4118
|
+
return {
|
|
4119
|
+
...constraint,
|
|
4120
|
+
path: { segments: rest }
|
|
4121
|
+
};
|
|
4122
|
+
}
|
|
4123
|
+
function getNullableUnionValueSchema(schema) {
|
|
4124
|
+
if (schema.oneOf?.length !== 2) {
|
|
4125
|
+
return void 0;
|
|
4126
|
+
}
|
|
4127
|
+
const valueSchema = schema.oneOf.find((branch) => branch.type !== "null");
|
|
4128
|
+
const nullSchema = schema.oneOf.find((branch) => branch.type === "null");
|
|
4129
|
+
return valueSchema !== void 0 && nullSchema !== void 0 ? valueSchema : void 0;
|
|
4130
|
+
}
|
|
3967
4131
|
function generateDynamicType(type) {
|
|
3968
4132
|
if (type.dynamicKind === "enum") {
|
|
3969
4133
|
const schema = {
|