1
1
import yaml from "yaml" ;
2
+ import { sortBy , zip } from "es-toolkit" ;
2
3
import { ParsedValidation } from "./validationfileformat" ;
3
4
export interface Example {
4
5
id : string ;
@@ -8,37 +9,54 @@ export interface Example {
8
9
data : ParsedValidation ;
9
10
}
10
11
11
- async function get ( path : string ) : Promise < string > {
12
- const result = await fetch ( path ) ;
13
- return await result . text ( ) ;
14
- }
12
+ const readmesImports = import . meta. glob ( "/examples/schemas/*/README.md" , {
13
+ // Get just the raw text
14
+ query : "?raw" ,
15
+ } ) ;
16
+ const schemasImports = import . meta. glob (
17
+ "/examples/schemas/*/schema-and-data.yaml" ,
18
+ {
19
+ // Get just the raw text
20
+ query : "?raw" ,
21
+ } ,
22
+ ) ;
23
+
24
+ const isTextImport = ( input : unknown ) : input is { default : string } => {
25
+ return typeof input === "object" && input !== null && "default" in input ;
26
+ } ;
15
27
16
- const prefix = `/static/schemas` ;
28
+ const sortAndRealizeImports = async (
29
+ imports : Record < string , ( ) => Promise < unknown > > ,
30
+ ) => {
31
+ const realizedImports = await Promise . all (
32
+ sortBy ( Object . entries ( imports ) , [ 0 ] ) . map ( ( [ , importThunk ] ) =>
33
+ importThunk ( ) ,
34
+ ) ,
35
+ ) ;
36
+ return realizedImports
37
+ . filter ( isTextImport )
38
+ . map ( ( { default : defaultExport } ) => defaultExport ) ;
39
+ } ;
17
40
18
41
/**
19
42
* LoadExamples loads the examples defined statically and compiled in.
20
43
*/
21
44
export async function LoadExamples ( ) : Promise < Example [ ] > {
22
- // NOTE: the format of the file tree here is defined by the Dockerfile for playground-ui/playground
23
- // and matches the tree structure found in https://github.com/authzed/examples/tree/main/schemas.
24
- // `_all` is added by the Dockerfile at build time.
25
- const exampleNames = ( await get ( `${ prefix } /_all` ) )
26
- . split ( "\n" )
27
- . filter ( ( n ) => ! ! n && n !== "_all" ) ;
28
- const examples : Example [ ] = [ ] ;
29
- for ( const n of exampleNames ) {
30
- const documentation = await get ( `${ prefix } /${ n } /README.md` ) ;
31
- const data = await get ( `${ prefix } /${ n } /schema-and-data.yaml` ) ;
32
- const title = documentation . split ( "\n" ) [ 0 ] . trim ( ) . substring ( 1 ) . trim ( ) ; // Strip the # for the markdown header
33
- const subtitle = documentation . split ( "\n" ) [ 2 ] . trim ( ) ;
34
-
35
- examples . push ( {
36
- id : n ,
37
- title : title ,
38
- subtitle : subtitle ,
39
- documentation : documentation ,
40
- data : yaml . parse ( data ) as ParsedValidation ,
41
- } ) ;
42
- }
43
- return examples ;
45
+ const names = Object . entries ( readmesImports ) . map ( ( [ path ] ) => path ) ;
46
+ names . sort ( ) ;
47
+ const sortedReadmes = await sortAndRealizeImports ( readmesImports ) ;
48
+ const sortedSchemas = await sortAndRealizeImports ( schemasImports ) ;
49
+ const zippedImports = zip ( names , sortedReadmes , sortedSchemas ) ;
50
+ return zippedImports . map ( ( [ name , readme , schema ] ) => {
51
+ const lines = readme . split ( "\n" ) ;
52
+ const title = lines [ 0 ] . trim ( ) . substring ( 1 ) . trim ( ) ; // Strip the # for the markdown header
53
+ const subtitle = lines [ 2 ] . trim ( ) ;
54
+ return {
55
+ id : name ,
56
+ title,
57
+ subtitle,
58
+ documentation : readme ,
59
+ data : yaml . parse ( schema ) ,
60
+ } ;
61
+ } ) ;
44
62
}
0 commit comments