Skip to content

Commit

Permalink
doc: PoC of loading event schema docs from Relay (getsentry#96)
Browse files Browse the repository at this point in the history
  • Loading branch information
untitaker authored Aug 10, 2020
1 parent d8d62f4 commit acb71d8
Show file tree
Hide file tree
Showing 14 changed files with 371 additions and 13 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ jobs:

steps:
- uses: actions/checkout@v2
with:
submodules: true
- uses: volta-cli/action@v1
- run: yarn install
- run: yarn test
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "src/data-schemas"]
path = src/data-schemas
url = https://github.com/getsentry/sentry-data-schemas
3 changes: 3 additions & 0 deletions gatsby-config.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,9 @@ const getPlugins = () => {
path: `${__dirname}/src/pages`,
},
},
{
resolve: require.resolve("./plugins/gatsby-plugin-jsonschema"),
},
// this (optional) plugin enables Progressive Web App + Offline functionality
// To learn more, visit: https://gatsby.app/offline
// 'gatsby-plugin-offline',
Expand Down
2 changes: 1 addition & 1 deletion gatsby-node.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ const { createFilePath } = require("gatsby-source-filesystem");

exports.onCreateNode = ({ node, actions, getNode }) => {
const { createNodeField } = actions;
if (node.internal.type === "Mdx") {
if (node.internal.type === "Mdx" && (!node.parent || getNode(node.parent).internal.type !== "JsonSchemaMarkdown")) {
const value = createFilePath({ node, getNode });
createNodeField({
name: "slug",
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"@sentry/apm": "^5.20.0",
"@sentry/gatsby": "^5.20.0",
"@sentry/react": "^5.20.0",
"@untitaker/quicktype-core-with-markdown": "^6.0.69",
"add": "^2.0.6",
"algoliasearch": "^4.2.0",
"bootstrap": "4.3.1",
Expand Down
70 changes: 70 additions & 0 deletions plugins/gatsby-plugin-jsonschema/gatsby-node.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
const { readFileSync } = require('fs');
const { quicktype, InputData, JSONSchemaInput, JSONSchemaStore } = require("@untitaker/quicktype-core-with-markdown");

exports.sourceNodes = async ({ actions, createNodeId, createContentDigest }) => {
const { createNode } = actions;

let content;
try {
content = readFileSync('./src/data-schemas/relay/event.schema.json', {encoding: "utf8"});
} catch (e) {
console.warn(`Failed to read Relay event schema: ${e}`);
return;
}

createNode({
content,
name: 'Event',
id: 'relay-event', // human-readable ID for referencing in MDX component
parent: null,
children: [],
internal: {
type: `JsonSchema`,
mediaType: 'application/schema+json',
content,
contentDigest: createContentDigest(content),
},
});
};



function quicktypeJSONSchema(targetLanguage, typeName, jsonSchemaString) {
const schemaInput = new JSONSchemaInput(new JSONSchemaStore());
return schemaInput.addSource({ name: typeName, schema: jsonSchemaString })
.then(_ => {
const inputData = new InputData();
inputData.addInput(schemaInput);

return quicktype({
inputData,
lang: targetLanguage,
});
});
}

exports.onCreateNode = async ({ actions, createNodeId, node, createContentDigest }) => {
const { createNode, createParentChildLink } = actions;

if (node.internal.mediaType !== `application/schema+json` || node.internal.type !== `JsonSchema`) {
return;
}

const { lines } = await quicktypeJSONSchema("markdown", node.name, node.content);

const child = {
lines,
content: lines.join("\n"),
id: createNodeId(`${node.id}-markdown`),
parent: node.id,
internal: {
content: lines.join("\n"),
mediaType: 'text/markdown',
contentDigest: createContentDigest(lines),
type: `JsonSchemaMarkdown`
}
};

createNode(child);
createParentChildLink({ parent: node, child });
};
1 change: 1 addition & 0 deletions plugins/gatsby-plugin-jsonschema/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
//noop
12 changes: 12 additions & 0 deletions plugins/gatsby-plugin-jsonschema/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"name": "gatsby-plugin-jsonschema",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"peerDependencies": {
"gatsby": "^2.0.0"
},
"dependencies": {
"unist-util-visit": "^1.4.1"
}
}
42 changes: 42 additions & 0 deletions src/components/jsonschema.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import React from "react"
import { MDXProvider } from "@mdx-js/react";
import { MDXRenderer } from "gatsby-plugin-mdx";
import { graphql, useStaticQuery } from "gatsby"

const JsonSchema = ({id}) => {
// XXX(markus): No clue if this can be replaced by non-static query
//
// This contrived query takes extra care in not referencing allJsonSchema or
// allJsonSchemaMarkdown, as those nodes are not usable if they have not been
// constructed once. That is the case if the data-schema submodule has not
// been checked out in which case we can still show a dummy text instead of
// failing the build.
const query = useStaticQuery(graphql`
{
allMdx(filter: {parent: {internal: {type: {eq: "JsonSchemaMarkdown"}}}}) {
nodes {
body
parent {
parent {
id
}
}
}
}
}
`);

const mdxNode = query.allMdx.nodes.find(node => node.parent.parent.id === id);

if (!mdxNode) {
return "Failed to load JSON Schema. Either the ID you have passed into the component does not exist or you are missing some git submmodules.";
}

return (
<MDXProvider>
<MDXRenderer>{mdxNode.body}</MDXRenderer>
</MDXProvider>
);
}

export default JsonSchema;
2 changes: 2 additions & 0 deletions src/components/layout.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import SmartLink from "./smartLink";
import CodeBlock from "./codeBlock";
import CodeTabs, { CodeContext, useCodeContextState } from "./codeTabs";
import Break from "./break";
import JsonSchema from "./jsonschema";

import "prismjs/themes/prism-tomorrow.css";
import "../css/screen.scss";
Expand All @@ -23,6 +24,7 @@ const mdxComponents = {
CodeBlock,
CodeTabs,
Break,
JsonSchema,
};

const TableOfContents = ({ toc: { items } }) => {
Expand Down
1 change: 1 addition & 0 deletions src/data-schemas
Submodule data-schemas added at b6d94b
4 changes: 4 additions & 0 deletions src/docs/sdk/event-payloads/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -270,3 +270,7 @@ The core data interfaces are:

- <Link to="/sdk/event-payloads/debugmeta">Debug Meta Interface</Link>
- <Link to="/sdk/event-payloads/sdk">SDK Interface</Link>

## Type Definitions

- <Link to="/sdk/event-payloads/types">Event Type Definitions</Link>
15 changes: 15 additions & 0 deletions src/docs/sdk/event-payloads/types.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
title: Event Type Definitions
---

This page documents the event schema for errors, just like the other documents
at <Link to="/sdk/event-payloads/">Event Payloads</Link> do. However, the
sections here are automatically generated from code, and because of that they
are more complete and less out of date. We intend to make this page the single
source of truth and replace all the other "interface" pages, but there is still
some work to be done to make this more human-readable.

Go to [our schemas repo](https://github.com/getsentry/sentry-data-schemas) to
learn more.

<JsonSchema id="relay-event" />
Loading

0 comments on commit acb71d8

Please sign in to comment.