Skip to content

Commit 3ab9cfb

Browse files
authored
Use import.meta.glob to include examples (#61)
1 parent 7bc321f commit 3ab9cfb

File tree

5 files changed

+52
-39
lines changed

5 files changed

+52
-39
lines changed

Dockerfile

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,3 @@ COPY ./contrib/docker-entrypoint-wrapper.sh .
3636
RUN bash ./test-nginx-conf.sh
3737

3838
COPY --from=playground-builder /app/build/ /usr/share/nginx/html/
39-
40-
COPY examples/schemas/ /usr/share/nginx/html/static/schemas
41-
RUN ls /usr/share/nginx/html/static/schemas > /usr/share/nginx/html/static/schemas/_all

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,13 @@
2222
"color-hash": "^2.0.2",
2323
"d3-scale-chromatic": "^2.0.0",
2424
"dequal": "^2.0.2",
25+
"es-toolkit": "^1.36.0",
2526
"file-saver": "^2.0.5",
2627
"file-select-dialog": "^1.5.4",
2728
"google-protobuf": "^3.21.2",
2829
"graphql": "16.6.0",
2930
"install": "^0.13.0",
3031
"line-column": "^1.0.2",
31-
"lodash.throttle": "^4.1.1",
3232
"markdown-it": "^13.0.1",
3333
"marked": "^4.0.10",
3434
"monaco-editor": "~0.40.0",
@@ -88,7 +88,7 @@
8888
},
8989
"scripts": {
9090
"dev": "HTTPS=true vite",
91-
"build": "tsc -b && vite build && ./scripts/copy-build.sh",
91+
"build": "tsc -b && vite build",
9292
"test": "vitest",
9393
"lint": "eslint .",
9494
"lint-fix": "eslint --fix .",

scripts/copy-build.sh

Lines changed: 0 additions & 7 deletions
This file was deleted.

src/spicedb-common/examples.ts

Lines changed: 45 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import yaml from "yaml";
2+
import { sortBy, zip } from "es-toolkit";
23
import { ParsedValidation } from "./validationfileformat";
34
export interface Example {
45
id: string;
@@ -8,37 +9,54 @@ export interface Example {
89
data: ParsedValidation;
910
}
1011

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+
};
1527

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+
};
1740

1841
/**
1942
* LoadExamples loads the examples defined statically and compiled in.
2043
*/
2144
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+
});
4462
}

yarn.lock

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2761,6 +2761,11 @@ es-to-primitive@^1.3.0:
27612761
is-date-object "^1.0.5"
27622762
is-symbol "^1.0.4"
27632763

2764+
es-toolkit@^1.36.0:
2765+
version "1.36.0"
2766+
resolved "https://registry.yarnpkg.com/es-toolkit/-/es-toolkit-1.36.0.tgz#98a9ddba346cde1aeca099f9bc27c05838c68b9a"
2767+
integrity sha512-5lpkRpDELuTSeAL//Rcg5urg+K/yOD1BobJSiNeCc89snMqgrhckmj8jdljqraDbpREiXTNW311RN518eVHBng==
2768+
27642769
esbuild@^0.21.3:
27652770
version "0.21.5"
27662771
resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.21.5.tgz#9ca301b120922959b766360d8ac830da0d02997d"

0 commit comments

Comments
 (0)