chore: use arktype for schema validation
This commit is contained in:
parent
03cd0f35bc
commit
be2a96ac22
8
.vscode/settings.json
vendored
8
.vscode/settings.json
vendored
@ -1,3 +1,9 @@
|
|||||||
{
|
{
|
||||||
"editor.defaultFormatter": "biomejs.biome"
|
"editor.defaultFormatter": "biomejs.biome",
|
||||||
|
// allow autocomplete for ArkType expressions like "string | num"
|
||||||
|
"editor.quickSuggestions": {
|
||||||
|
"strings": "on"
|
||||||
|
},
|
||||||
|
// prioritize ArkType's "type" for autoimports
|
||||||
|
"typescript.preferences.autoImportSpecifierExcludeRegexes": ["^(node:)?os$"]
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,6 +14,7 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@biomejs/biome": "^1.9.4",
|
"@biomejs/biome": "^1.9.4",
|
||||||
"@types/reveal.js": "^5.0.5"
|
"@types/reveal.js": "^5.0.5",
|
||||||
|
"arktype": "^2.0.4"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
23
pnpm-lock.yaml
generated
23
pnpm-lock.yaml
generated
@ -21,9 +21,18 @@ importers:
|
|||||||
'@types/reveal.js':
|
'@types/reveal.js':
|
||||||
specifier: ^5.0.5
|
specifier: ^5.0.5
|
||||||
version: 5.0.5
|
version: 5.0.5
|
||||||
|
arktype:
|
||||||
|
specifier: ^2.0.4
|
||||||
|
version: 2.0.4
|
||||||
|
|
||||||
packages:
|
packages:
|
||||||
|
|
||||||
|
'@ark/schema@0.39.0':
|
||||||
|
resolution: {integrity: sha512-LQbQUb3Sj461LgklXObAyUJNtsUUCBxZlO2HqRLYvRSqpStm0xTMrXn51DwBNNxeSULvKVpXFwoxiSec9kwKww==}
|
||||||
|
|
||||||
|
'@ark/util@0.39.0':
|
||||||
|
resolution: {integrity: sha512-90APHVklk8BP4kku7hIh1BgrhuyKYqoZ4O7EybtFRo7cDl9mIyc/QUbGvYDg//73s0J2H0I/gW9pzroA1R4IBQ==}
|
||||||
|
|
||||||
'@astrojs/compiler@2.10.3':
|
'@astrojs/compiler@2.10.3':
|
||||||
resolution: {integrity: sha512-bL/O7YBxsFt55YHU021oL+xz+B/9HvGNId3F9xURN16aeqDK9juHGktdkCSXz+U4nqFACq6ZFvWomOzhV+zfPw==}
|
resolution: {integrity: sha512-bL/O7YBxsFt55YHU021oL+xz+B/9HvGNId3F9xURN16aeqDK9juHGktdkCSXz+U4nqFACq6ZFvWomOzhV+zfPw==}
|
||||||
|
|
||||||
@ -658,6 +667,9 @@ packages:
|
|||||||
resolution: {integrity: sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==}
|
resolution: {integrity: sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==}
|
||||||
engines: {node: '>= 0.4'}
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
|
arktype@2.0.4:
|
||||||
|
resolution: {integrity: sha512-S68rWVDnJauwH7/QCm8zCUM3aTe9Xk6oRihdcc3FSUAtxCo/q1Fwq46JhcwB5Ufv1YStwdQRz+00Y/URlvbhAQ==}
|
||||||
|
|
||||||
array-iterate@2.0.1:
|
array-iterate@2.0.1:
|
||||||
resolution: {integrity: sha512-I1jXZMjAgCMmxT4qxXfPXa6SthSoE8h6gkSI9BGGNv8mP8G/v0blc+qFnZu6K42vTOiuME596QaLO0TP3Lk0xg==}
|
resolution: {integrity: sha512-I1jXZMjAgCMmxT4qxXfPXa6SthSoE8h6gkSI9BGGNv8mP8G/v0blc+qFnZu6K42vTOiuME596QaLO0TP3Lk0xg==}
|
||||||
|
|
||||||
@ -1675,6 +1687,12 @@ packages:
|
|||||||
|
|
||||||
snapshots:
|
snapshots:
|
||||||
|
|
||||||
|
'@ark/schema@0.39.0':
|
||||||
|
dependencies:
|
||||||
|
'@ark/util': 0.39.0
|
||||||
|
|
||||||
|
'@ark/util@0.39.0': {}
|
||||||
|
|
||||||
'@astrojs/compiler@2.10.3': {}
|
'@astrojs/compiler@2.10.3': {}
|
||||||
|
|
||||||
'@astrojs/internal-helpers@0.5.0': {}
|
'@astrojs/internal-helpers@0.5.0': {}
|
||||||
@ -2153,6 +2171,11 @@ snapshots:
|
|||||||
|
|
||||||
aria-query@5.3.2: {}
|
aria-query@5.3.2: {}
|
||||||
|
|
||||||
|
arktype@2.0.4:
|
||||||
|
dependencies:
|
||||||
|
'@ark/schema': 0.39.0
|
||||||
|
'@ark/util': 0.39.0
|
||||||
|
|
||||||
array-iterate@2.0.1: {}
|
array-iterate@2.0.1: {}
|
||||||
|
|
||||||
astro@5.2.3(rollup@4.28.1)(sass@1.83.0)(typescript@5.7.2):
|
astro@5.2.3(rollup@4.28.1)(sass@1.83.0)(typescript@5.7.2):
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
---
|
---
|
||||||
export const title = "CSS Flexbox"
|
export const title = "CSS Flexbox";
|
||||||
export const authors = ["Henrique Ramos"]
|
export const authors = ["Henrique Ramos"];
|
||||||
export const publishedAt = "2025-01-27"
|
export const publishedAt = "2025-01-27";
|
||||||
export const description = "Do you even flex?"
|
export const description = "Do you even flex?";
|
||||||
---
|
---
|
||||||
|
|
||||||
<section>
|
<section>
|
||||||
|
|||||||
@ -1,8 +1,9 @@
|
|||||||
import type { AstroInstance } from "astro";
|
import type { AstroInstance } from "astro";
|
||||||
|
import { type } from "arktype";
|
||||||
|
|
||||||
type Opts<T extends Record<string, unknown>> = {
|
type Opts<T extends Record<string, unknown>> = {
|
||||||
files: Record<string, T>;
|
files: Record<string, T>;
|
||||||
requiredFields?: string[];
|
schema: type;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -14,16 +15,12 @@ type Opts<T extends Record<string, unknown>> = {
|
|||||||
*/
|
*/
|
||||||
const getAstroPages = <T extends Record<string, unknown> & AstroInstance>({
|
const getAstroPages = <T extends Record<string, unknown> & AstroInstance>({
|
||||||
files,
|
files,
|
||||||
requiredFields = [],
|
schema,
|
||||||
}: Opts<T>) =>
|
}: Opts<T>) =>
|
||||||
Object.values(files).map((module) => {
|
Object.values(files).map((module) => {
|
||||||
if (!requiredFields.every((field) => module[field as keyof T])) {
|
const validate = schema(module);
|
||||||
throw new Error(
|
if (validate instanceof type.errors)
|
||||||
`Missing required fields for ${module.file}: ${requiredFields
|
return console.error(`Invalid module${module.file}: ${validate.summary}`);
|
||||||
.filter((field) => !module[field as keyof T])
|
|
||||||
.join(", ")}`,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: (
|
id: (
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
import type { AstroInstance } from "astro";
|
import type { AstroInstance } from "astro";
|
||||||
import getAstroPages from "./getAstroPages";
|
import getAstroPages from "./getAstroPages";
|
||||||
|
import { type } from "arktype";
|
||||||
|
|
||||||
type Slide = AstroInstance & {
|
type Slide = AstroInstance & {
|
||||||
[key: string]: unknown;
|
[key: string]: unknown;
|
||||||
@ -9,8 +10,7 @@ type Slide = AstroInstance & {
|
|||||||
publishedAt: string;
|
publishedAt: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
const slideRequiredFields = ["title", "description", "authors", "publishedAt"];
|
/**
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get all slides from the slides directory.
|
* Get all slides from the slides directory.
|
||||||
* @returns The slides.
|
* @returns The slides.
|
||||||
@ -21,5 +21,10 @@ export const getSlides = () =>
|
|||||||
["@slides/**/index.astro", "@slides/*.astro"],
|
["@slides/**/index.astro", "@slides/*.astro"],
|
||||||
{ eager: true },
|
{ eager: true },
|
||||||
),
|
),
|
||||||
requiredFields: slideRequiredFields,
|
schema: type({
|
||||||
|
title: "string",
|
||||||
|
description: "string",
|
||||||
|
authors: "string[]",
|
||||||
|
publishedAt: "string",
|
||||||
|
}),
|
||||||
});
|
});
|
||||||
|
|||||||
@ -14,7 +14,10 @@
|
|||||||
},
|
},
|
||||||
"moduleResolution": "Bundler",
|
"moduleResolution": "Bundler",
|
||||||
"strictNullChecks": true,
|
"strictNullChecks": true,
|
||||||
"allowJs": true
|
"allowJs": true,
|
||||||
|
"strict": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"exactOptionalPropertyTypes": true
|
||||||
},
|
},
|
||||||
"exclude": ["dist"]
|
"exclude": ["dist"]
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user