Loading codegen/constructor.ts +37 −20 Original line number Diff line number Diff line Loading @@ -11,48 +11,51 @@ function generateParameterType( const code: string[] = []; if (property.functional || property.singularAccessor) { if (scalar) { code.push(`{ ${property.singularName}?: ${getTypeNames(range, types)} | null }`); code.push( `${property.singularName}?: ${getTypeNames(range, types)} | null;`, ); } else { code.push(`{ ${property.singularName}?: ${getTypeNames(range, types)} | URL | null }`); code.push( `${property.singularName}?: ${ getTypeNames(range, types) } | URL | null;`, ); } } if (!property.functional) { if (scalar) { code.push(`{ ${property.singularName}?: undefined; ${property.pluralName}?: ${getTypeNames(range, types, true)}[] }`); code.push( `${property.pluralName}?: ${getTypeNames(range, types, true)}[];`, ); } else { code.push(`{ ${property.singularName}?: undefined; ${property.pluralName}?: (${getTypeNames(range, types)} | URL)[] }`); code.push( `${property.pluralName}?: (${getTypeNames(range, types)} | URL)[];`, ); } } return code.join(" | "); return code.join("\n"); } async function* generateParametersType( typeUri: string, types: Record<string, TypeSchema>, parentheses = true, ): AsyncIterable<string> { const type = types[typeUri]; if (parentheses) yield "{\n"; if (type.extends == null) { yield `{ id?: URL | null }`; yield `id?: URL | null;\n`; } else { for await (const code of generateParametersType(type.extends, types)) { for await ( const code of generateParametersType(type.extends, types, false) ) { yield code; } } for (const property of type.properties) { yield " & ("; yield generateParameterType(property, types); yield ")"; } if (parentheses) yield "}\n"; } export async function* generateConstructor( Loading Loading @@ -88,6 +91,13 @@ export async function* generateConstructor( yield ` if ("${property.pluralName}" in values && \ values.${property.pluralName} != null) { if ("${property.singularName}" in values && values.${property.singularName} != null) { throw new TypeError( "Cannot initialize both ${property.singularName} and " + "${property.pluralName} at the same time.", ); } this.${fieldName} = values.${property.pluralName}; } `; Loading @@ -114,7 +124,7 @@ export async function* generateCloner( if (type.extends == null) { yield ` // @ts-ignore const clone: ${type.name} = new this.constructor(values); const clone: ${type.name} = new this.constructor({ id: values.id }); `; } else { yield `const clone = super.clone(values) as unknown as ${type.name};`; Loading @@ -134,6 +144,13 @@ export async function* generateCloner( yield ` if ("${property.pluralName}" in values && \ values.${property.pluralName} != null) { if ("${property.singularName}" in values && values.${property.singularName} != null) { throw new TypeError( "Cannot update both ${property.singularName} and " + "${property.pluralName} at the same time.", ); } clone.${fieldName} = values.${property.pluralName}; } `; Loading vocab/mod.test.ts +26 −0 Original line number Diff line number Diff line Loading @@ -2,6 +2,7 @@ import { assertEquals, assertInstanceOf, assertNotEquals, assertThrows, } from "https://deno.land/std@0.217.0/assert/mod.ts"; import { toArray } from "https://deno.land/x/aitertools@0.5.0/mod.ts"; import { LanguageString } from "../runtime/langstr.ts"; Loading @@ -16,6 +17,25 @@ import { Person, } from "./mod.ts"; Deno.test("new Object()", () => { const obj = new Object({ name: "Test", contents: [ new LanguageString("Hello", "en"), new LanguageString("你好", "zh"), ], }); assertEquals(obj.name, "Test"); assertEquals(obj.contents[0], new LanguageString("Hello", "en")); assertEquals(obj.contents[1], new LanguageString("你好", "zh")); assertThrows( () => new Object({ name: "singular", names: ["plural"] }), TypeError, "Cannot initialize both name and names at the same time.", ); }); Deno.test("Object.fromJsonLd()", async () => { const obj = await Object.fromJsonLd({ "@context": "https://www.w3.org/ns/activitystreams", Loading Loading @@ -173,6 +193,12 @@ Deno.test("Activity.clone()", async () => { assertEquals(clone.name, "Test"); assertEquals(activity.summary, "Test"); assertEquals(clone.summary, "Modified"); assertThrows( () => activity.clone({ summary: "singular", summaries: ["plural"] }), TypeError, "Cannot update both summary and summaries at the same time.", ); }); Deno.test("Deno.inspect(Object)", () => { Loading Loading
codegen/constructor.ts +37 −20 Original line number Diff line number Diff line Loading @@ -11,48 +11,51 @@ function generateParameterType( const code: string[] = []; if (property.functional || property.singularAccessor) { if (scalar) { code.push(`{ ${property.singularName}?: ${getTypeNames(range, types)} | null }`); code.push( `${property.singularName}?: ${getTypeNames(range, types)} | null;`, ); } else { code.push(`{ ${property.singularName}?: ${getTypeNames(range, types)} | URL | null }`); code.push( `${property.singularName}?: ${ getTypeNames(range, types) } | URL | null;`, ); } } if (!property.functional) { if (scalar) { code.push(`{ ${property.singularName}?: undefined; ${property.pluralName}?: ${getTypeNames(range, types, true)}[] }`); code.push( `${property.pluralName}?: ${getTypeNames(range, types, true)}[];`, ); } else { code.push(`{ ${property.singularName}?: undefined; ${property.pluralName}?: (${getTypeNames(range, types)} | URL)[] }`); code.push( `${property.pluralName}?: (${getTypeNames(range, types)} | URL)[];`, ); } } return code.join(" | "); return code.join("\n"); } async function* generateParametersType( typeUri: string, types: Record<string, TypeSchema>, parentheses = true, ): AsyncIterable<string> { const type = types[typeUri]; if (parentheses) yield "{\n"; if (type.extends == null) { yield `{ id?: URL | null }`; yield `id?: URL | null;\n`; } else { for await (const code of generateParametersType(type.extends, types)) { for await ( const code of generateParametersType(type.extends, types, false) ) { yield code; } } for (const property of type.properties) { yield " & ("; yield generateParameterType(property, types); yield ")"; } if (parentheses) yield "}\n"; } export async function* generateConstructor( Loading Loading @@ -88,6 +91,13 @@ export async function* generateConstructor( yield ` if ("${property.pluralName}" in values && \ values.${property.pluralName} != null) { if ("${property.singularName}" in values && values.${property.singularName} != null) { throw new TypeError( "Cannot initialize both ${property.singularName} and " + "${property.pluralName} at the same time.", ); } this.${fieldName} = values.${property.pluralName}; } `; Loading @@ -114,7 +124,7 @@ export async function* generateCloner( if (type.extends == null) { yield ` // @ts-ignore const clone: ${type.name} = new this.constructor(values); const clone: ${type.name} = new this.constructor({ id: values.id }); `; } else { yield `const clone = super.clone(values) as unknown as ${type.name};`; Loading @@ -134,6 +144,13 @@ export async function* generateCloner( yield ` if ("${property.pluralName}" in values && \ values.${property.pluralName} != null) { if ("${property.singularName}" in values && values.${property.singularName} != null) { throw new TypeError( "Cannot update both ${property.singularName} and " + "${property.pluralName} at the same time.", ); } clone.${fieldName} = values.${property.pluralName}; } `; Loading
vocab/mod.test.ts +26 −0 Original line number Diff line number Diff line Loading @@ -2,6 +2,7 @@ import { assertEquals, assertInstanceOf, assertNotEquals, assertThrows, } from "https://deno.land/std@0.217.0/assert/mod.ts"; import { toArray } from "https://deno.land/x/aitertools@0.5.0/mod.ts"; import { LanguageString } from "../runtime/langstr.ts"; Loading @@ -16,6 +17,25 @@ import { Person, } from "./mod.ts"; Deno.test("new Object()", () => { const obj = new Object({ name: "Test", contents: [ new LanguageString("Hello", "en"), new LanguageString("你好", "zh"), ], }); assertEquals(obj.name, "Test"); assertEquals(obj.contents[0], new LanguageString("Hello", "en")); assertEquals(obj.contents[1], new LanguageString("你好", "zh")); assertThrows( () => new Object({ name: "singular", names: ["plural"] }), TypeError, "Cannot initialize both name and names at the same time.", ); }); Deno.test("Object.fromJsonLd()", async () => { const obj = await Object.fromJsonLd({ "@context": "https://www.w3.org/ns/activitystreams", Loading Loading @@ -173,6 +193,12 @@ Deno.test("Activity.clone()", async () => { assertEquals(clone.name, "Test"); assertEquals(activity.summary, "Test"); assertEquals(clone.summary, "Modified"); assertThrows( () => activity.clone({ summary: "singular", summaries: ["plural"] }), TypeError, "Cannot update both summary and summaries at the same time.", ); }); Deno.test("Deno.inspect(Object)", () => { Loading