Skip to content

Commit a41de51

Browse files
committed
more type strictness and enforcement
1 parent bc53b0d commit a41de51

File tree

5 files changed

+43
-34
lines changed

5 files changed

+43
-34
lines changed

deno.jsonc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
// auto-generated by package/src/common/create-deno-config.ts
22
// see dev-docs/update-deno_jsonc.md
33
{
4+
"compilerOptions": {
5+
"noErrorTruncation": true
6+
},
47
"lint": {
58
"include": ["src/"],
69
"exclude": [

src/command/render/project.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ import { Format } from "../../config/types.ts";
8080
import { fileExecutionEngine } from "../../execute/engine.ts";
8181
import { projectContextForDirectory } from "../../project/project-context.ts";
8282
import { ProjectType } from "../../project/types/types.ts";
83-
import { ProjectConfig as ProjectConfig_Project } from "../../resources/types/schema-types.ts";
83+
import { Zod } from "../../resources/types/zod/schema-types.ts";
8484

8585
const noMutationValidations = (
8686
projType: ProjectType,
@@ -255,9 +255,11 @@ const mergeExtensionMetadata = async (
255255
context.isSingleFile ? undefined : context.dir,
256256
{ builtIn: false },
257257
);
258-
const projectMetadata = extensions.map((extension) =>
258+
const projectMetadata = extensions.filter((extension) =>
259259
extension.contributes.metadata?.project
260-
).filter((project) => project) as ProjectConfig_Project[];
260+
).map((extension) => {
261+
return Zod.ProjectConfig.parse(extension.contributes.metadata!.project);
262+
});
261263
context.config.project = mergeProjectMetadata(
262264
context.config.project,
263265
...projectMetadata,

src/core/brand/brand.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,13 @@
77
*/
88

99
import {
10-
// Brand as BrandJson,
10+
Brand as BrandJson,
1111
BrandFont,
12+
BrandLogoExplicitResource,
1213
BrandNamedThemeColor,
1314
BrandTypography,
1415
BrandTypographyOptionsBase,
1516
BrandTypographyOptionsHeadings,
16-
} from "../../resources/types/schema-types.ts";
17-
18-
import {
19-
Brand as BrandJson,
20-
BrandLogoExplicitResource,
2117
Zod,
2218
} from "../../resources/types/zod/schema-types.ts";
2319
import { InternalError } from "../lib/error.ts";
@@ -72,11 +68,15 @@ export class Brand {
7268
projectDir: string;
7369
processedData: ProcessedBrandData;
7470

75-
constructor(readonly brand: BrandJson, brandDir: string, projectDir: string) {
71+
constructor(
72+
readonly brand: unknown,
73+
brandDir: string,
74+
projectDir: string,
75+
) {
7676
this.data = Zod.Brand.parse(brand);
7777
this.brandDir = brandDir;
7878
this.projectDir = projectDir;
79-
this.processedData = this.processData(brand);
79+
this.processedData = this.processData(this.data);
8080
}
8181

8282
processData(data: BrandJson): ProcessedBrandData {

src/core/sass/brand.ts

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,12 @@ import {
1616
import { ProjectContext } from "../../project/types.ts";
1717
import {
1818
BrandFont,
19-
BrandFontBunny,
19+
// BrandFontBunny,
2020
BrandFontCommon,
2121
BrandFontGoogle,
2222
BrandFontWeight,
23-
} from "../../resources/types/schema-types.ts";
23+
Zod,
24+
} from "../../resources/types/zod/schema-types.ts";
2425
import { Brand } from "../brand/brand.ts";
2526
import { darkModeDefault } from "../../format/html/format-html-info.ts";
2627

@@ -323,10 +324,11 @@ const brandTypographyLayer = (
323324
): string | undefined => {
324325
let googleFamily = "";
325326
for (const _resolvedFont of font) {
326-
const resolvedFont = _resolvedFont as (BrandFontGoogle | BrandFontBunny);
327-
if (resolvedFont.source !== "google") {
327+
const safeResolvedFont = Zod.BrandFontGoogle.safeParse(_resolvedFont);
328+
if (!safeResolvedFont.success) {
328329
return undefined;
329330
}
331+
const resolvedFont = safeResolvedFont.data;
330332
const thisFamily = resolvedFont.family;
331333
if (!thisFamily) {
332334
continue;
@@ -351,17 +353,15 @@ const brandTypographyLayer = (
351353
): string | undefined => {
352354
let googleFamily = "";
353355
for (const _resolvedFont of font) {
354-
const resolvedFont =
355-
_resolvedFont as (BrandFont | BrandFontGoogle | BrandFontBunny);
356+
const safeResolvedFont = Zod.BrandFontBunny.safeParse(_resolvedFont);
357+
if (!safeResolvedFont.success) {
358+
return undefined;
359+
}
360+
const resolvedFont = safeResolvedFont.data;
356361
// Typescript's type checker doesn't understand that it's ok to attempt
357362
// to access a property that might not exist on a type when you're
358363
// only testing for its existence.
359364

360-
// deno-lint-ignore no-explicit-any
361-
const source = (resolvedFont as any).source;
362-
if (source && source !== "bunny") {
363-
return undefined;
364-
}
365365
const thisFamily = resolvedFont.family;
366366
if (!thisFamily) {
367367
continue;
@@ -384,6 +384,7 @@ const brandTypographyLayer = (
384384
type HTMLFontInformation = { [key: string]: unknown };
385385

386386
type FontKind =
387+
| "link"
387388
| "base"
388389
| "headings"
389390
| "monospace"
@@ -398,9 +399,14 @@ const brandTypographyLayer = (
398399
} else if (typeof resolvedFontOptions === "string") {
399400
resolvedFontOptions = { family: resolvedFontOptions };
400401
}
401-
const family = resolvedFontOptions.family;
402-
const font = getFontFamilies(family);
403402
const result: HTMLFontInformation = {};
403+
// This is an ugly hack:
404+
// resolvedFontOptions doesn't always have 'family', but at this
405+
// point in the code we know resolvedFontOptions is an object
406+
// that we can attempt to extract the family from.
407+
const family =
408+
(resolvedFontOptions as Record<string, string | undefined>).family;
409+
const font = getFontFamilies(family);
404410
result.family = resolveGoogleFontFamily(font) ??
405411
resolveBunnyFontFamily(font) ??
406412
// resolveFilesFontFamily(font) ??
@@ -524,11 +530,9 @@ const brandTypographyLayer = (
524530
"monospace",
525531
"headings",
526532
"base",
527-
]
533+
] as const
528534
) {
529-
const fontInformation = resolveHTMLFontInformation(
530-
kind as FontKind,
531-
);
535+
const fontInformation = resolveHTMLFontInformation(kind);
532536
if (!fontInformation) {
533537
continue;
534538
}

src/project/project-shared.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,9 @@ import { DirectiveCell } from "../core/lib/break-quarto-md-types.ts";
4848
import { QuartoJSONSchema, readYamlFromMarkdown } from "../core/yaml.ts";
4949
import { refSchema } from "../core/lib/yaml-schema/common.ts";
5050
import {
51-
Brand as BrandJson,
5251
BrandPathBoolLightDark,
53-
} from "../resources/types/schema-types.ts";
52+
Zod,
53+
} from "../resources/types/zod/schema-types.ts";
5454
import { Brand } from "../core/brand/brand.ts";
5555
import { assert } from "testing/asserts";
5656

@@ -524,7 +524,7 @@ export async function projectResolveBrand(
524524
brandPath,
525525
refSchema("brand", "Format-independent brand configuration."),
526526
"Brand validation failed for " + brandPath + ".",
527-
) as BrandJson;
527+
);
528528
return new Brand(brand, dirname(brandPath), project.dir);
529529
}
530530
async function loadRelativeBrand(
@@ -582,7 +582,7 @@ export async function projectResolveBrand(
582582
return project.brandCache.brand;
583583
} else {
584584
const metadata = await project.fileMetadata(fileName);
585-
const brand = metadata.brand as BrandPathBoolLightDark;
585+
const brand = Zod.BrandPathBoolLightDark.parse(metadata.brand); // as BrandPathBoolLightDark;
586586
if (brand === false) {
587587
return undefined;
588588
}
@@ -611,7 +611,7 @@ export async function projectResolveBrand(
611611
}
612612
if (typeof brand.dark === "string") {
613613
dark = await loadRelativeBrand(brand.dark);
614-
} else if(brand.dark) {
614+
} else if (brand.dark) {
615615
dark = new Brand(
616616
brand.dark,
617617
dirname(fileName),
@@ -622,7 +622,7 @@ export async function projectResolveBrand(
622622
} else {
623623
fileInformation.brand = {
624624
light: new Brand(
625-
brand as BrandJson,
625+
brand,
626626
dirname(fileName),
627627
project.dir,
628628
),

0 commit comments

Comments
 (0)