schema-dts-gen
Version:
Generate TypeScript Definitions for Schema.org Schema
122 lines • 4.69 kB
JavaScript
/**
* Copyright 2023 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import ts from 'typescript';
const { factory, SyntaxKind } = ts;
import { Log } from '../logging/index.js';
import { GetComment, IsDomainIncludes, IsRangeIncludes, IsSupersededBy, IsTypeName, } from '../triples/wellKnown.js';
import { appendParagraph, withComments } from './util/comments.js';
import { IdReferenceName, SchemaValueReference } from './helper_types.js';
import { typeUnion } from './util/union.js';
import { assertIs } from '../util/assert.js';
/**
* A "class" of properties, not associated with any particuar object.
*/
export class PropertyType {
constructor(subject) {
this.subject = subject;
this.types = [];
this._supersededBy = [];
}
get comment() {
if (!this.deprecated)
return this._comment;
const deprecated = ` Consider using ${this._supersededBy
.map(o => o.id)
.join(' or ')} instead.`;
return appendParagraph(this._comment, deprecated);
}
get deprecated() {
return this._supersededBy.length > 0;
}
add(value, classes) {
const c = GetComment(value);
if (c) {
if (this._comment) {
Log(`Duplicate comments provided on property ${this.subject.id}. It will be overwritten.`);
}
this._comment = c.comment;
return true;
}
if (IsRangeIncludes(value.predicate)) {
if (!IsTypeName(value.object)) {
throw new Error(`Type expected to be a UrlNode always. When adding ${JSON.stringify(value.toJSON(), undefined, 2)}.`);
}
const cls = classes.get(value.object.id);
if (!cls) {
throw new Error(`Could not find class for ${value.object.id} [only foud: ${Array.from(classes.keys()).join(', ')}]`);
}
this.types.push(cls);
return true;
}
if (IsDomainIncludes(value.predicate)) {
const cls = classes.get(value.object.id);
if (!cls) {
throw new Error(`Could not find class for ${value.object.id}. [only foud: ${Array.from(classes.keys()).join(', ')}]`);
}
cls.addProp(new Property(this.subject, this));
return true;
}
if (IsSupersededBy(value.predicate)) {
assertIs(value.object, (o) => o.termType === 'NamedNode');
this._supersededBy.push(value.object);
return true;
}
return false;
}
scalarTypeNode(context) {
const typeNames = this.types.map(cls => cls.className(context)).sort();
if (this.types.some(cls => cls.isNodeType())) {
typeNames.push(IdReferenceName);
}
const typeNodes = typeNames.map(type => factory.createTypeReferenceNode(type, /*typeArguments=*/ []));
return typeUnion(...typeNodes);
}
}
/**
* A Property on a particular object.
*/
export class Property {
constructor(key, type) {
this.key = key;
this.type = type;
}
get deprecated() {
return this.type.deprecated;
}
typeNode(context, properties) {
return SchemaValueReference(properties, () => this.type.scalarTypeNode(context), context.getScopedName(this.key));
}
toNode(context, properties) {
return withComments(this.type.comment, factory.createPropertySignature(
/* modifiers= */ [], factory.createStringLiteral(context.getScopedName(this.key)), factory.createToken(SyntaxKind.QuestionToken),
/*typeNode=*/ this.typeNode(context, properties)));
}
}
export class TypeProperty {
constructor(className) {
this.className = className;
this.deprecated = false;
}
toNode(context) {
return factory.createPropertySignature(
/* modifiers= */ [], factory.createStringLiteral('@type'),
/* questionToken= */ undefined,
/* typeNode= */
factory.createTypeReferenceNode(`"${context.getScopedName(this.className)}"`,
/*typeArguments=*/ undefined));
}
}
//# sourceMappingURL=property.js.map