Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor catalog router to use separate modules #1368

Merged
merged 1 commit into from
Oct 15, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions packages/site-server/src/catalog/graphql.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/**
* @license
* Copyright 2022 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/

import {ApolloClient, InMemoryCache} from '@apollo/client/core/index.js';

const CATALOG_GRAPHQL_URL =
process.env['CATALOG_GRAPHQL_URL'] || `http://localhost:6451/graphql`;

export const client = new ApolloClient({
uri: CATALOG_GRAPHQL_URL,
cache: new InMemoryCache(),
});
85 changes: 4 additions & 81 deletions packages/site-server/src/catalog/router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,88 +5,11 @@
*/

import Router from '@koa/router';
import {ApolloClient, InMemoryCache, gql} from '@apollo/client/core/index.js';
import {renderPage} from '../templates/base.js';
import {renderElement} from './element-template.js';

const CATALOG_GRAPHQL_URL =
process.env['CATALOG_GRAPHQL_URL'] || `http://localhost:6451/graphql`;

const client = new ApolloClient({
uri: CATALOG_GRAPHQL_URL,
cache: new InMemoryCache(),
});
import {handleCatalogRoute} from './routes/catalog/catalog-route.js';
import {handleElementRoute} from './routes/element/element-route.js';

export const catalogRouter = new Router();

catalogRouter.get('/element/:path+', async (context) => {
const {params} = context;

// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const elementPath = params['path']!;
const elementPathSegments = elementPath.split('/');
const isScoped = elementPathSegments[0]?.startsWith('@');
const packageName = isScoped
? elementPathSegments[0] + '/' + elementPathSegments[1]
: elementPathSegments[0]!; // eslint-disable-line @typescript-eslint/no-non-null-assertion
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const elementName = elementPathSegments[isScoped ? 2 : 1]!;

// TODO (justinfagnani): To make this type-safe, we need to write
// a query .graphql document and generate a TypedDocumentNode from it.
const result = await client.query({
query: gql`
{
package(packageName: "${packageName}") {
... on ReadablePackageInfo {
name
description
version {
... on ReadablePackageVersion {
version
description
customElements(tagName: "${elementName}") {
tagName
declaration
customElementExport
declaration
}
customElementsManifest
}
}
}
}
}
`,
});

if (result.errors !== undefined && result.errors.length > 0) {
throw new Error(result.errors.map((e) => e.message).join('\n'));
}
const {data} = result;
const packageVersion = data.package?.version;
if (packageVersion === undefined) {
throw new Error(`No such package version: ${packageName}`);
}
const customElementsManifest =
packageVersion.customElementsManifest !== undefined &&
JSON.parse(packageVersion.customElementsManifest);

const customElement = packageVersion.customElements?.[0];

if (customElement === undefined || customElement.tagName !== elementName) {
throw new Error('Internal error');
}

const content = renderElement({
packageName: packageName,
elementName: elementName,
declarationReference: customElement.declaration,
customElementExport: customElement.export,
manifest: customElementsManifest,
});
catalogRouter.get('/', handleCatalogRoute);

context.body = renderPage({title: `${packageName}/${elementName}`, content});
context.type = 'html';
context.status = 200;
});
catalogRouter.get('/element/:path+', handleElementRoute);
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/**
* @license
* Copyright 2022 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/

import Router from '@koa/router';
import {renderPage} from '../../../templates/base.js';
import {DefaultContext, DefaultState, ParameterizedContext} from 'koa';

export const handleCatalogRoute = async (
context: ParameterizedContext<
DefaultState,
DefaultContext & Router.RouterParamContext<DefaultState, DefaultContext>,
unknown
>
) => {
context.body = renderPage({
title: `Web Components Catalog`,
content: `
<h1>Catalog</h1>
`,
});
context.type = 'html';
context.status = 200;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
/**
* @license
* Copyright 2022 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/

import Router from '@koa/router';
import {gql} from '@apollo/client/core/index.js';
import {renderPage} from '../../../templates/base.js';
import {renderElement} from './element-template.js';
import {DefaultContext, DefaultState, ParameterizedContext} from 'koa';
import { client } from '../../graphql.js';

export const handleElementRoute = async (
context: ParameterizedContext<
DefaultState,
DefaultContext & Router.RouterParamContext<DefaultState, DefaultContext>,
unknown
>
) => {
const {params} = context;

// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const elementPath = params['path']!;
const elementPathSegments = elementPath.split('/');
const isScoped = elementPathSegments[0]?.startsWith('@');
const packageName = isScoped
? elementPathSegments[0] + '/' + elementPathSegments[1]
: elementPathSegments[0]!; // eslint-disable-line @typescript-eslint/no-non-null-assertion
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const elementName = elementPathSegments[isScoped ? 2 : 1]!;

// TODO (justinfagnani): To make this type-safe, we need to write
// a query .graphql document and generate a TypedDocumentNode from it.
const result = await client.query({
query: gql`
{
package(packageName: "${packageName}") {
... on ReadablePackageInfo {
name
description
version {
... on ReadablePackageVersion {
version
description
customElements(tagName: "${elementName}") {
tagName
declaration
customElementExport
declaration
}
customElementsManifest
}
}
}
}
}
`,
});

if (result.errors !== undefined && result.errors.length > 0) {
throw new Error(result.errors.map((e) => e.message).join('\n'));
}
const {data} = result;
const packageVersion = data.package?.version;
if (packageVersion === undefined) {
throw new Error(`No such package version: ${packageName}`);
}
const customElementsManifest =
packageVersion.customElementsManifest !== undefined &&
JSON.parse(packageVersion.customElementsManifest);

const customElement = packageVersion.customElements?.[0];

if (customElement === undefined || customElement.tagName !== elementName) {
throw new Error('Internal error');
}

const content = renderElement({
packageName: packageName,
elementName: elementName,
declarationReference: customElement.declaration,
customElementExport: customElement.export,
manifest: customElementsManifest,
});

context.body = renderPage({title: `${packageName}/${elementName}`, content});
context.type = 'html';
context.status = 200;
};
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
resolveReference,
normalizeModulePath,
} from '@webcomponents/custom-elements-manifest-tools';
import {escapeHTML} from './escape-html.js';
import {escapeHTML} from '../../escape-html.js';

export const renderElement = ({
packageName,
Expand Down