Skip to content

Commit

Permalink
fix: JSON schema had incorrect value types
Browse files Browse the repository at this point in the history
Resolves #1389
  • Loading branch information
Gerrit0 committed Nov 26, 2020
1 parent 80c4524 commit 26a9c0d
Show file tree
Hide file tree
Showing 18 changed files with 203 additions and 306 deletions.
1 change: 0 additions & 1 deletion src/lib/converter/symbols.ts
Expand Up @@ -21,7 +21,6 @@ import { convertDefaultValue } from "./convert-expression";
import { ConverterEvents } from "./converter-events";
import { createSignature } from "./factories/signature";

// TODO: implementationOf / overwrites
// TODO: Index signatures

function getSymbolExportsWithFlag(symbol: ts.Symbol, flag: ts.SymbolFlags) {
Expand Down
1 change: 0 additions & 1 deletion src/lib/serialization/index.ts
Expand Up @@ -17,7 +17,6 @@ export {
IntrinsicTypeSerializer,
LiteralTypeSerializer,
ParameterReflectionSerializer,
ProjectReflectionSerializer,
ReferenceTypeSerializer,
ReflectionCategorySerializer,
ReflectionGroupSerializer,
Expand Down
43 changes: 24 additions & 19 deletions src/lib/serialization/schema.ts
Expand Up @@ -143,8 +143,15 @@ export interface SignatureReflection
extends Reflection,
S<
M.SignatureReflection,
"type" | "overwrites" | "inheritedFrom" | "implementationOf"
> {}
| "parameters"
| "type"
| "overwrites"
| "inheritedFrom"
| "implementationOf"
> {
// Weird not to call this typeParameters... preserving backwards compatibility for now.
typeParameter?: ModelToObject<M.SignatureReflection["typeParameters"]>;
}

export interface ParameterReflection
extends Reflection,
Expand All @@ -155,15 +162,26 @@ export interface DeclarationReflection
S<
M.DeclarationReflection,
| "type"
| "signatures"
| "indexSignature"
| "defaultValue"
| "overwrites"
| "inheritedFrom"
| "implementationOf"
| "extendedTypes"
| "extendedBy"
| "implementedTypes"
| "implementedBy"
| "implementationOf"
> {}
> {
// Weird not to call this typeParameters... preserving backwards compatibility for now.
typeParameter?: ModelToObject<M.DeclarationReflection["typeParameters"]>;

// Yep... backwards compatibility. This is an optional one-tuple.
getSignature?: [ModelToObject<M.DeclarationReflection["getSignature"]>];

// Yep... backwards compatibility. This is an optional one-tuple.
setSignature?: [ModelToObject<M.DeclarationReflection["setSignature"]>];
}

export interface TypeParameterReflection
extends Reflection,
Expand All @@ -174,32 +192,19 @@ export interface ProjectReflection extends ContainerReflection {}

export interface ContainerReflection
extends Reflection,
S<M.ContainerReflection, "groups" | "categories"> {
S<M.ContainerReflection, "children" | "groups" | "categories"> {
sources?: ModelToObject<SourceReferenceWrapper[]>;
}

/**
* If a 3rd party serializer creates a loop when serializing, a pointer will be created
* instead of re-serializing the [[DeclarationReflection]]
*/
export interface ReflectionPointer extends S<M.Reflection, "id"> {}

export interface Reflection
extends S<
M.Reflection,
"id" | "name" | "kind" | "kindString" | "comment" | "decorates"
> {
/** Will not be present if name === originalName */
originalName?: M.Reflection["originalName"];
flags: ReflectionFlags;
decorators?: ModelToObject<DecoratorWrapper[]>;

children?: ModelToObject<M.Reflection>[];
parameters?: ModelToObject<M.Reflection>[];
typeParameter?: ModelToObject<M.Reflection>[];
signatures?: ModelToObject<M.Reflection>[];
indexSignature?: ModelToObject<M.Reflection>[];
getSignature?: ModelToObject<M.Reflection>[];
setSignature?: ModelToObject<M.Reflection>[];
}

// Types
Expand Down
12 changes: 11 additions & 1 deletion src/lib/serialization/serializer.ts
Expand Up @@ -44,6 +44,17 @@ export class Serializer extends EventDispatcher {
}

toObject<T>(value: T, init: object = {}): ModelToObject<T> {
if (value == null || typeof value !== "object") {
return value as any; // Serializing some primitive
}

if (Array.isArray(value)) {
if (value.length === 0) {
return undefined as any;
}
return value.map((val) => this.toObject(val)) as any;
}

// Note: This type *could* potentially lie, if a serializer declares a partial type but fails to provide
// the defined property, but the benefit of being mostly typed is probably worth it.
// TypeScript errors out if init is correctly typed as `Partial<ModelToObject<T>>`
Expand Down Expand Up @@ -117,7 +128,6 @@ const serializerComponents: (new (owner: Serializer) => SerializerComponent<
S.ContainerReflectionSerializer,
S.DeclarationReflectionSerializer,
S.ParameterReflectionSerializer,
S.ProjectReflectionSerializer,
S.SignatureReflectionSerializer,
S.TypeParameterReflectionSerializer,

Expand Down
37 changes: 7 additions & 30 deletions src/lib/serialization/serializers/reflections/abstract.ts
@@ -1,8 +1,8 @@
import { Reflection, TraverseProperty } from "../../../models";
import { Reflection } from "../../../models";

import { ReflectionSerializerComponent } from "../../components";
import { DecoratorWrapper } from "../models";
import { Reflection as JSONReflection } from "../../schema";
import type { Reflection as JSONReflection } from "../../schema";

export class ReflectionSerializer extends ReflectionSerializerComponent<
Reflection
Expand All @@ -24,16 +24,17 @@ export class ReflectionSerializer extends ReflectionSerializerComponent<
kind: reflection.kind,
kindString: reflection.kindString,
flags: {},
comment: this.owner.toObject(reflection.comment),
decorates: this.owner.toObject(reflection.decorates),
decorators: this.owner.toObject(
reflection.decorators?.map((d) => new DecoratorWrapper(d))
),
};

if (reflection.originalName !== reflection.name) {
result.originalName = reflection.originalName;
}

if (reflection.comment) {
result.comment = this.owner.toObject(reflection.comment);
}

const flags = [
"isPrivate",
"isProtected",
Expand All @@ -56,30 +57,6 @@ export class ReflectionSerializer extends ReflectionSerializerComponent<
}
}

if (reflection.decorates && reflection.decorates.length > 0) {
result.decorates = reflection.decorates.map((t) =>
this.owner.toObject(t)
);
}

if (reflection.decorators && reflection.decorators.length > 0) {
result.decorators = reflection.decorators.map((d) =>
this.owner.toObject(new DecoratorWrapper(d))
);
}

reflection.traverse((child, property) => {
if (property === TraverseProperty.TypeLiteral) {
return;
}
let name = TraverseProperty[property];
name = name[0].toLowerCase() + name.substr(1);
if (!(result as any)[name]) {
(result as any)[name] = [];
}
(result as any)[name].push(this.owner.toObject(child));
});

return result;
}
}
34 changes: 7 additions & 27 deletions src/lib/serialization/serializers/reflections/container.ts
Expand Up @@ -23,34 +23,14 @@ export class ContainerReflectionSerializer extends ReflectionSerializerComponent
container: ContainerReflection,
obj: JSONReflection
): JSONContainerReflection {
const result: JSONContainerReflection = {
return {
...obj,
children: this.owner.toObject(container.children),
groups: this.owner.toObject(container.groups),
categories: this.owner.toObject(container.categories),
sources: this.owner.toObject(
container.sources?.map((s) => new SourceReferenceWrapper(s))
),
};

if (container.groups && container.groups.length > 0) {
result.groups = container.groups.map((group) =>
this.owner.toObject(group)
);
}

if (container.categories && container.categories.length > 0) {
result.categories = container.categories.map((category) =>
this.owner.toObject(category)
);
}

if (container.sources && container.sources.length > 0) {
result.sources = container.sources.map((source) =>
this.owner.toObject(
new SourceReferenceWrapper({
fileName: source.fileName,
line: source.line,
character: source.character,
})
)
);
}

return result;
}
}
66 changes: 19 additions & 47 deletions src/lib/serialization/serializers/reflections/declaration.ts
Expand Up @@ -17,61 +17,33 @@ export class DeclarationReflectionSerializer extends ReflectionSerializerCompone
}

toObject(
declaration: DeclarationReflection,
d: DeclarationReflection,
obj: JSONContainerReflection
): JSONDeclarationReflection {
const result: JSONDeclarationReflection = {
...obj,
typeParameter: this.owner.toObject(d.typeParameters),
type: this.owner.toObject(d.type),
signatures: this.owner.toObject(d.signatures),
indexSignature: this.owner.toObject(d.indexSignature),
};

if (declaration.type) {
result.type = this.owner.toObject(declaration.type);
if (d.getSignature) {
result.getSignature = [this.owner.toObject(d.getSignature)];
}

if (declaration.defaultValue) {
result.defaultValue = declaration.defaultValue;
}

if (declaration.overwrites) {
result.overwrites = this.owner.toObject(declaration.overwrites);
}

if (declaration.inheritedFrom) {
result.inheritedFrom = this.owner.toObject(
declaration.inheritedFrom
);
}

if (declaration.extendedTypes) {
result.extendedTypes = declaration.extendedTypes.map((t) =>
this.owner.toObject(t)
);
}

if (declaration.extendedBy) {
result.extendedBy = declaration.extendedBy.map((t) =>
this.owner.toObject(t)
);
}

if (declaration.implementedTypes) {
result.implementedTypes = declaration.implementedTypes.map((t) =>
this.owner.toObject(t)
);
}

if (declaration.implementedBy) {
result.implementedBy = declaration.implementedBy.map((t) =>
this.owner.toObject(t)
);
}

if (declaration.implementationOf) {
result.implementationOf = this.owner.toObject(
declaration.implementationOf
);
if (d.setSignature) {
result.setSignature = [this.owner.toObject(d.setSignature)];
}

return result;
return Object.assign(result, {
defaultValue: this.owner.toObject(d.defaultValue),
overwrites: this.owner.toObject(d.overwrites),
inheritedFrom: this.owner.toObject(d.inheritedFrom),
implementationOf: this.owner.toObject(d.implementationOf),
extendedTypes: this.owner.toObject(d.extendedTypes),
extendedBy: this.owner.toObject(d.extendedBy),
implementedTypes: this.owner.toObject(d.implementedTypes),
implementedBy: this.owner.toObject(d.implementedBy),
});
}
}
1 change: 0 additions & 1 deletion src/lib/serialization/serializers/reflections/index.ts
Expand Up @@ -2,7 +2,6 @@ export * from "./abstract";
export * from "./container";
export * from "./declaration";
export * from "./parameter";
export * from "./project";
export * from "./reference";
export * from "./signature";
export * from "./type-parameter";
10 changes: 2 additions & 8 deletions src/lib/serialization/serializers/reflections/parameter.ts
Expand Up @@ -19,16 +19,10 @@ export class ParameterReflectionSerializer extends ReflectionSerializerComponent
): JSONParameterReflection {
const result: JSONParameterReflection = {
...obj,
type: this.owner.toObject(parameter.type),
defaultValue: this.owner.toObject(parameter.defaultValue),
};

if (parameter.type) {
result.type = this.owner.toObject(parameter.type);
}

if (parameter.defaultValue) {
result.defaultValue = parameter.defaultValue;
}

return result;
}
}
25 changes: 0 additions & 25 deletions src/lib/serialization/serializers/reflections/project.ts

This file was deleted.

30 changes: 9 additions & 21 deletions src/lib/serialization/serializers/reflections/signature.ts
Expand Up @@ -17,26 +17,14 @@ export class SignatureReflectionSerializer extends ReflectionSerializerComponent
signature: SignatureReflection,
obj: JSONReflection
): JSONSignatureReflection {
const result: JSONSignatureReflection = { ...obj };

if (signature.type) {
result.type = this.owner.toObject(signature.type);
}

if (signature.overwrites) {
result.overwrites = this.owner.toObject(signature.overwrites);
}

if (signature.inheritedFrom) {
result.inheritedFrom = this.owner.toObject(signature.inheritedFrom);
}

if (signature.implementationOf) {
result.implementationOf = this.owner.toObject(
signature.implementationOf
);
}

return result;
return {
...obj,
typeParameter: this.owner.toObject(signature.typeParameters),
parameters: this.owner.toObject(signature.parameters),
type: this.owner.toObject(signature.type),
overwrites: this.owner.toObject(signature.overwrites),
inheritedFrom: this.owner.toObject(signature.inheritedFrom),
implementationOf: this.owner.toObject(signature.implementationOf),
};
}
}

0 comments on commit 26a9c0d

Please sign in to comment.